C/C++ 关于#/##在宏定义中的用法

本文介绍了C/C++中宏定义的高级用法,包括如何使用#运算符将宏参数转换为字符串字面量,使用##运算符进行记号粘合以创建新的记号,以及如何利用这些特性实现复杂宏,支持可变参数列表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在C/C++的宏定义中,#/##存在特殊的作用
1. #运算符将一个宏的参数转换为字符串字面量。它仅允许出现在带参数的宏的替换列表中。

  
  1. #include <cstdio>  
  2. #define PRINT_STR(s)      printf(#s" = %s/n", s)  
  3. int main()   
  4. {   
  5.     char *s1 = "aaa";  
  6.     PRINT_STR(s1);  
  7.     return 0;   
  8. }   
输出:
s1 = aaa
注:
printf(#s" = %s/n", s) -> printf(s1" = %s/n", s1) -> printf("s1 = %s/n", s1)->printf("s1 = %s/n", "aaa")
#s只是做宏参数字面替换
s则仍然是一个变量名
2.##运算符可以将两个记号(例如标识符)“粘”在一起,成为一个记号。(无需惊讶,##运算符被称为“记号粘合”。)
如果其中一个操作数是宏参数,“粘合”会在当形式参数被相应的实际参数替换后发生。

  
  1. #include <cstdio>  
  2. #define PRINT_STR(i)      printf("str = %s/n", s##i)  
  3. int main()   
  4. {   
  5.     char *s1 = "s1";  
  6.     char *s2 = "s2";  
  7.     char *s3 = "s3";  
  8.    
  9.     PRINT_STR(1);  
  10.     PRINT_STR(2);  
  11.     PRINT_STR(3);  
  12.    
  13.     return 0;   
  14. }   
输出:
str = s1
str = s2
str = s3

 

3.C99的复杂宏:可变参数

  
  1. #include <cstdio>  
  2. #define PRINT_STR(format, ...)      do{printf(format, __VA_ARGS__);}while(0)  
  3. int main()   
  4. {   
  5.     char *str1 = "s1";  
  6.     char *str2 = "s2";  
  7.    
  8.     PRINT_STR("str1 is %s /nstr2 is %s/n",str1, str2);  
  9.    
  10.     return 0;   
  11. }  
输出:
str1 is s1 
str2 is s2
but attention!

  
  1. #include <cstdio>  
  2. #define PRINT_STR(format, ...)      do{printf(format, __VA_ARGS__);}while(0)  
  3. int main()   
  4. {   
  5.     char *str1 = "s1";  
  6.     char *str2 = "s2";  
  7.    
  8.     PRINT_STR("str1 is over/n");  
  9.    
  10.     return 0;   
  11. }   
编译:
macro1.cpp: In function ‘int main()’:
macro1.cpp:8: error: expected primary-expression before ‘)’ token
这里提示错误,原因是少了变参列表,只有format参数,这里在format参数后就多了一个','。
so,GNU CPP想出了一个特殊的##操作,没错,##操作又来了,但是不是上面的拼接行为了。
如果可变参数被忽略或为空,“##”操作将使预处理器去除掉它前面的那个逗号。
如果在宏调用时,确实提供了一些可变参数,GNU CPP也会工作正常,它会把这些可变参数放到逗号的后面。

  
  1. #include <cstdio>  
  2. #define PRINT_STR(format, ...)      do{printf(format, ##__VA_ARGS__);}while(0)  
  3. int main()   
  4. {   
  5.     char *str1 = "s1";  
  6.     char *str2 = "s2";  
  7.    
  8.     PRINT_STR("str1 is over/n");  
  9.    
  10.     return 0;   
  11. }   

输出:
str1 is over

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值