一、一般用法
我們使用#
把巨集引數變為乙個字串,用
##把兩個巨集引數貼合在一起.
用法:
#include
#include
using namespace std;
#define str(s) #s
#define cons(a,b) int(a##e##b)
int main()
printf(str(vck)); // 輸出字串
"vck"
printf("%d\n", cons(2,3)); // 2e3 輸出
:2000
return 0;
二、當巨集引數是另乙個巨集的時候
需要注意的是凡巨集定義裡有用'#'
或'##'
的地方巨集引數是不會再展開.
1, 非
'#'和
'##'
的情況
#define tow (2)
#define mul(a,b) (a*b)
printf("%d*%d=%d\n", tow, tow, mul(tow,tow));
這行的巨集會被展開為:
printf("%d*%d=%d\n", (2), (2), ((2)*(2)));
mul裡的引數
tow會被展開為
(2).
2, 當有
'#'或
'##'
的時候
#define a (2)
#define str(s) #s
#define cons(a,b) int(a##e##b)
printf("int max: %s\n", str(int_max)); // int_max #
include
這行會被展開為:
printf("int max: %s\n", "int_max");
printf("%s\n", cons(a, a)); // compile error
這一行則是:
printf("%s\n", int(aea));
int_max和
a都不會再被展開
, 然而解決這個問題的方法很簡單
. 加多一層中間轉換巨集.
加這層巨集的用意是把所有巨集的引數在這層裡全部展開,
那麼在轉換巨集裡的那乙個巨集
(_str)
就能得到正確的巨集
引數.
#define a (2)
#define _str(s) #s
#define str(s) _str(s) // 轉換巨集
#define _cons(a,b) int(a##e##b)
#define cons(a,b) _cons(a,b) // 轉換巨集
printf("int max: %s\n", str(int_max)); // int_max,int型的最大值,為乙個變數 #
include
輸出為: int max: 0x7fffffff
str(int_max) --> _str(0x7fffffff) 然後再轉換成字串;
printf("%d\n", cons(a, a));
輸出為:200
cons(a, a) --> _cons((2), (2)) --> int((2)e(2))
三、'#'
和'##'
的一些應用特例
1、合併匿名變數名
#define ___anonymous1(type, var, line) type var##line
#define __anonymous0(type, line) ___anonymous1(type, _anonymous, line)
#define anonymous(type) __anonymous0(type, __line__)
例:anonymous(static int);
即: static int _anonymous70; 70
表示該行行號;
第一層:anonymous(static int); --> __anonymous0(static int, __line__);
第二層: --> ___anonymous1(static int, _anonymous, 70);
第三層: --> static int _anonymous70;
即每次只能解開當前層的巨集,所以__line__
在第二層才能被解開;
2、填充結構
#define fill(a)
enum idd;
typedef struct msgmsg;
msg _msg = ;
相當於:
msg _msg = ,
}; 3、記錄檔名
#define _get_file_name(f) #f
#define get_file_name(f) _get_file_name(f)
static char file_name = get_file_name(__file__);
4、得到乙個數值型別所對應的字串緩衝大小
#define _type_buf_size(type) sizeof #type
#define type_buf_size(type) _type_buf_size(type)
char buf[type_buf_size(int_max)];
--> char buf[_type_buf_size(0x7fffffff)];
--> char buf[sizeof "0x7fffffff"];
這裡相當於:
char buf[11];
【alps_008】:
基本看了一遍,樓主的情況屬於一般用法:
「#把巨集引數變為乙個字串,用
##把兩個巨集引數貼合在一起」
#include
#include
#define strcpy(a,b) strcpy(a##_p,#b) //把第乙個引數後邊加上字元
_p,把第二個引數變成字串
int main()
char var1_p[20];
char var2_p[30];
strcpy(var1_p,"aaaa");
strcpy(var2_p,"bbbb");
strcpy(var1,var2); //等於
strcpy(var1_p,"var2");
strcpy(var2,var1); //等於
strcpy(var2_p,"var1");
printf("%s\n",var1_p);
printf("%s\n",var2_p);
return 0;
【jeffer007】:
token-pasting operator (##)
// preprocessor_token_pasting.cpp
#include
#define paster( n ) printf_s( "token" #n " = %d", token##n )
int token9 = 9;
int main()
paster(9);
output
token9 = 9
stringizing operator (#)
// stringizer.cpp
#include
#define stringer( x ) printf( #x "\n" )
int main() {
stringer( in quotes in the printf function call );
stringer( "in quotes when printed to the screen" );
stringer( "this: \" prints an escaped double quote" );
output
in quotes in the printf function call
"in quotes when printed to the screen"
"this: \" prints an escaped double quote"
C語言巨集中 和 的用法
c語言巨集中 和 的用法 一 一般用法 我們使用 把巨集引數變為乙個字串,用 把兩個巨集引數貼合在一起.用法 include include using namespace std define str s s define cons a,b int a e b int main printf st...
C語言 巨集中 和 的用法
巨集中 和 的用法 一 一般用法 我們使用 把巨集引數變為乙個字串,用 把兩個巨集引數貼合在一起.用法 include include using namespace std define str s s define cons a,b int a e b int main 二 當巨集引數是另乙個巨...
C語言巨集中 和 的用法
c語言巨集中 和 的用法 在檢視linux 核心原始碼的過程中,遇到了許多巨集,這裡面有許多都涉及到 和 一 一般用法 我們使用 把巨集引數變為乙個字串,用 把兩個巨集引數貼合在一起 用法 include include using namespace std define str s s defi...