C++带参数宏解惑教程

本文介绍使用带参数宏过程中遇到的几个问题和坑,希望对你有帮助。

带参数宏定义语法如下:

#define macro_identifier(<arg_list>) <token_sequence>

不能有空格分隔macro_identifier 和 “(” 。可选参数arg_list是一组用逗号分割的标识符,与函数参数类似。但在括号参数内部的逗号被视为参数的一部分,不是参数分隔符,每个逗号分割的标识符扮演形参或占位符角色。

调用宏语法:

macro_identifier<whitespace>(<actual_arg_list>)

看上去和函数调用一样,但有一些差异、副作用以及潜在坑。可选的_actual_arg_list_必须包含与#define行定义形式参数_arg_list_数量相同的逗号分隔的标记序列(也称为实际参数),如果两个参数数量不一致会导致错误。

宏调调用即两组参数替换过程。首先,_macro_identifier_和圆括号内的参数被_token_sequence_替换。接下来,任何出现在_token_sequence_中的形式参数都被出现在_actual_arg_list_中的相应的实际参数所替换,与简单宏定义一样,需要重新扫描以检测任何符合扩展条件的嵌入宏标识符。

嵌套括号和逗号

actual_arg_list 可以包含嵌套圆括号(但必须要对称),逗号出现在原括号内部的不作为参数分隔符。

#define ERRMSG(x, str) printf("Error: %d \n%s", x, str)
#define SUM(x,y)  ((x) + (y))

ERRMSG(2, "Press Enter, then ESC");
/*展开结果为:  printf("Error: %d \n%s", 2, "Press Enter, then ESC"); */

return SUM(f(i, j), g(k, l));
/*展开结果为:  return ( (f(i, j)) + (g(k, l)) ); */

一些坑

函数调用与宏调用有一些差异。宏调用没有内置类型检查,所以形式参数与实际参数类型不匹配会产生奇怪、难以调试结果,且没有任何警告。宏调用还可能导致难以理解的问题,特别是当实际参数被解析多次时。请看示例:


#define CUBE(x)  ( (x) * (x) * (x) )

int cube(int x) {
   return x*x*x;
}


int b = 0, a = 3;
b = cube(a++);
/* 给cube()传的实参 a = 3; 所以 b = 27; 现在 a = 4 */


a = 3;
b = CUBE(a++);
/* 扩展为 ( (a++) * (a++) * (a++) ); 再次 b = 27 ,但现在 a = 6 */

使用#转换实参至字符串

在形式参数前面可以使用#号,用于转换实际参数,使得替换之后为字符串:

#define TRACE(flag) printf(#flag "=%d\n", flag)


/* 调用宏*/
int highval = 1024;
TRACE(highval);

/*


/*结果为下面代码*/
int highval = 1024;
printf("highval" "=%d\n", highval);

/*进一步转为下面代码*/
int highval = 1024;
printf("highval=%d\n", highval);

再看一个示例:

// stringizer.cpp
#include <stdio.h>
#define stringer( x ) printf_s( #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" );
}

main函数代码被扩展为:

int main() {
   printf_s( "In quotes in the printf function call" "\n" );
   printf_s( "\"In quotes when printed to the screen\"" "\n" );
   printf_s( "\"This: \\\" prints an escaped double quote\"" "\n" );
}

最后输出结果为:

In quotes in the printf function call
"In quotes when printed to the screen"
"This: \"  prints an escaped double quote"
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值