原文来自http://www.2cto.com/kf/201503/381187.html
在C/C++的宏中,“#”的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。
而“##”被称为连接符(concatenator),用来将两个子串Token连接为一个Token。注意这里连接的对象是Token就行,而不一定是宏的变量。还可以n个##符号连接n+1个Token,这个特性是“#”符号所不具备的。
凡是宏定义里有用“#”或“##”的地方宏参数是不会再展开。
若要使“#”和“##”的宏参数被展开,可以加多一层中间转换宏。加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的那一个宏就能得到正确的宏参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #include "stdafx.h" #include <iostream> using namespace std;
#define WARN_IF(EXP) if (EXP) fprintf(stderr, warning: #EXP);
#define STR(s) #s
#define _STRI(s) #s #define STRI(s) _STRI(s)
#define paster(n) printf(token#n = %d, token##n)
#define _CONS(a, b) int(a##+##b) #define CONS(a, b) _CONS(a, b)
#define _GET_FILE_NAME(f) #f #define GET_FILE_NAME(f) _GET_FILE_NAME(f)
#define _TYPE_BUF_SIZE(type) sizeof #type #define TYPE_BUF_SIZE(type) _TYPE_BUF_SIZE(type)
#define D(x) #@x int main(int argc, char* argv[]) { int divider = 0; WARN_IF(divider == 0); printf(int max: %s, STR(INT_MAX)); printf(int max: %s, STRI(INT_MAX)); int token9 = 9; paster(9); int A = 15, B = 2; printf(A + B = %d, CONS(A, B)); char FILE_NAME[] = GET_FILE_NAME(__FILE__); cout<<file_name<<endl;
|