1. 程式人生 > >C/C++ 巨集的高階使用1.0

C/C++ 巨集的高階使用1.0

  1. 單個#

引例1.

#include<stdio.h>

#define P(x) printf("%s=%d\n",#x,x)
int main(){
    /*  #x 的作用就是把x轉成"x",轉成字串*/ 
    int a1=10,a2=20,a3=30;
    P(a1);  // 列印  a1=10 
    P(a2);  // 列印  a2=20 
    P(a3);  // 列印  a3=30 
    return 0;
}

引例2

#include<stdio.h>

#define printFUN(x) printf("%s",#x)
void  gogogo()  /* 在函式裡面列印函式名 */
{ //printf("%s",gogogo); //打印出亂碼 printFUN(gogogo); // 打印出 "gogogo" } int main(){ //函式名只是函式地址 gogogo(); return 0; }

2.兩個 ##
引例1

#include<stdio.h>

#define PP(x) printf##x
void printf1(){
    printf("1111\n");
}
void printf2(){
    printf("2222\n");
}
void printf3(){
    printf("3333\n"
)
; } int main(){ // ## 相當於把 printf 和 x 連線成printfx PP(1)(); // PP(1) 等價於 printf1 // PP(1)()等價於 printf1() PP(2)(); PP(3)(); return 0; }

引例2

#include<stdio.h>

#define P(x) printf("%s=%d\n",#x,x)
#define I(x) I##x
int main(){
    int I(1)=11,I(2)=22,I(3)=33;  
    I1=100
; //I1 等價於 I(1),I(1)值也改變 I2=200; I3=300; P(I(1)); // 打印出 I(1)=100 P(I(2)); // 打印出 I(2)=200 P(I(3)); // 打印出 I(3)=300 return 0; }

3.巨集變數
巨集變數主要有
__FILE__ :巨集在預編譯時會替換成 當前程式的檔名
__LINE__ :巨集在預編譯時會替換成 當前行數
__FUNCTION__:巨集在預編譯時會替換成 當前的函式名稱

#include<stdio.h>
#include<stdlib.h>


void sss(){
    printf("Function:%s\n",__FUNCTION__);  //列印結果為 "sss" 
}
int main(){
    //myprintf(); 
    printf("Function:%s\n",__FUNCTION__);
    sss();
    printf("File:%s\n",__FILE__);
    printf("Line:%d\n",__LINE__);
    return 0;
}

列印的結果

Function:main
Function:sss
File:E:\Code2017\test2.cpp
Line:13

4.__VA_ARGS__ 可變引數巨集

#include<stdio.h>

#define myprint(fm,...)  printf(fm,__VA_ARGS__)
int main(){
    int a=10;
    myprint("hello %d\n",a); 
    //但是如果沒有引數的話, 會報錯,如下 
    //myprint("hello ");
    return 0; 
}

這裡,如果可變引數被忽略或為空,’##’操作將使前處理器(preprocessor)去除掉它前面的那個逗號
因此應該改為

#include<stdio.h>

#define myprint(fm,...)  printf(fm,##__VA_ARGS__)  //加上##
int main(){
    //int a=10;
    myprint("hello \n"); 

    return 0; 
}