C/C++ 宏详解
收藏
众多 C++书籍都忠告我们 C 语言宏是万恶之首,但事情总不如我们想象的那么坏,就如同
goto 一样。宏有
一个很大的作用,就是自动为我们产生代码。如果说模板可以为我们产生各种型别的代码
(型别替换),
那么宏其实可以为我们在符号上产生新的代码(即符号替换、增加)。
关于宏的一些语法问题,可以在 google 上找到。相信我,你对于宏的了解绝对没你想象的
那么多。如果你
还不知道#和##,也不知道 prescan,那么你肯定对宏的了解不够。
我稍微讲解下宏的一些语法问题(说语法问题似乎不妥,macro 只与 preprocessor 有关,跟语
义分析又无关):
1. 宏可以像函数一样被定义,例如:
#define min(x,y) (x 但是在实际使用时,只有当写上 min(),必须加括号,min 才会被作为宏
展开,否则不做任何处理。
2. 如果宏需要参数,你可以不传,编译器会给你警告(宏参数不够),但是这会导致错误。
如 C++书籍中所描
述的,编译器(预处理器)对宏的语法检查不够,所以更多的检查性工作得你自己来做。
3. 很多程序员不知道的#和##
#符号把一个符号直接转换为字符串,例如:
#define STRING(x) #x
const char *str = STRING( test_string ); str 的内容就是"test_string",也就是说#会把其后的符
号
直接加上双引号。
##符号会连接两个符号,从而产生新的符号(词法层次),例如:
#define SIGN( x ) INT_##x
int SIGN( 1 ); 宏被展开后将成为:int INT_1;
4. 变参宏,这个比较酷,它使得你可以定义类似的宏:
#define LOG( format, ... ) printf( format, __VA_ARGS__ )
LOG( "%s %d", str, count );
__VA_ARGS__是系统预定义宏,被自动替换为参数列表。
5. 当一个宏自己调用自己时,会发生什么?例如:
#define TEST( x ) ( x + TEST( x ) )
TEST( 1 ); 会发生什么?为了防止无限制递归展开,语法规定,当一个宏遇到自己时,就
停止展开,也就是
评论0