C 中的预编译宏定义 注:在VC 中,想看到宏展开后的代码,设置在项目->属性->C/C++->预处理器->生成预处理文件 打开这个选项后,去工程下找相应的.i 文件,就能看见宏展开后到底是个什么了:) 在将一个C 源程序转换为可执行程序的过程中, 编译预处理是最初的步骤. 这一步骤是由预处理器(preprocessor)来完成的. 在源流程序被编译器处理之前, 预处理器首先对源程序中的"宏(macro)"进行处理. C 初学者可能对预处理器没什么概念, 这是情有可原的: 一般的C 编译器都将预处理, 汇编, 编译, 连接过程集成到一起了.编译预处理往往在后台运行. 在有的C 编译器中, 这些过程统统由一个单独的程序来完成, 编译的不同阶段实现这些不同的功能.可以指定相应的命令选项来执行这些功能. 有的C 编译器使用分别的程序来完成这些步骤. 可单独调用这些程序来完成. 在gcc 中,进行编译预处理的程序被称为 CPP, 它的可执行文件名为 cpp. 编译预处理命令的语法与 C 语言的语法是完全独立的. 比如: 你可以将一个宏扩展为与 C 语法格格不入的内容, 但该内容与后面的语句结合在一个若能生成合法的C 语句, 也是可以正确编译的. (一) 预处理命令简介 注意: 函数宏对参数类型是不敏感的, 你不必考虑将何种数据类型传递给宏. 那么, 如何构建对参数类型敏感的宏呢? 参考本章的第九部分, 关于"##"的介绍. 关于定义宏的另外一些问题 (1) 宏可以被多次定义, 前提是这些定义必须是相同的. 这里的"相同"要求先后定义中空白符出现的位置相同, 但具体的空白符类型或数量可不同, 比如原先的空格可替换为多个其他类型的空白符: 可为 tab, 注释... e.g. #define NULL 0 #define NULL /* null pointer */ 0 上面的重定义是相同的, 但下面的重定义不同: #define fun(x) x+1 #define fun(x) x + 1 或: #define fun(y) y+1 如果多次定义时, 再次定义的宏内容是不同的, gcc 会给出"NAME redefined"警告信息. 应该避免重新定义函数宏, 不管是在预处理命令中还是C 语句中, 最好对某个对象只有单一的定义. 在gcc 中, 若宏出现了重定义, gcc 会给出警告. (2) 在gcc 中, 可在命令行中指定对象宏的定义: e.g. $ gcc -Wall -DMAX=100 -o tmp tmp.c 相当于在tmp.c 中添加" #define MAX 100". 那么, 如果原先 tmp.c 中含有MAX 宏的定义, 那么再在gcc 调用命令中使用-DMAX, ...