#define f(a,b) a##b #define d(a) #a #define s(a) d(a) void main( void ) { puts(d(f(a,b))); puts(s(f(a,b))); } 输出结果: f(a,b) ab分析: ##把两个符号连起来 #a指把a当成符号,就是把#后面的看成字符串# 和 ## 操作符是和#define宏使用的. 使用# 使在#后的首个参数返回为一个带引号的字符串. 例如, 命令 #define to_string( s ) # s 将会使编译器把以下命令 cout理解为 cout使用##连结##前后的内容. 例如, 命令 #define concatenate( x, y ) x ## y ... int xy = 10; ... 将会使编译器把 cout解释为 cout理所当然,将会在标准输出处显示'10'. puts(d(f(a,b))); ----> 因为d宏中的参数是另外一个宏,且带##,所以作为参数的宏不展开,相当于 puts(#f(a,b));----->puts("f(a,b)"); puts(s(f(a,b))); ----> 因为s宏中的参数是另外一个宏,但不带##,所以作为参数的宏先展开,相当于 puts(s(ab));----->puts(d(ab));---->puts(#ab);---->puts("ab"); #define f(a,b) a##b #define d(a) #a --》 以"#"开头的,直接替换,不展开:immediately replaced by the unexpanded actual argument #define s(a) d(a) --》 非以"#"开头的,先展开,再替换,也就是一般的情况 所以就两种情况: 1,不以"#"开头的,先展开参数a,然后是替换代码:puts(s(f(a,b)));-->puts(s(ab))-->puts(d(ab))-->puts("ab") 2,以"#"开头的,直接替换,不展开:puts(d(f(a,b)))-->puts("f(a,b)")