预处理详解(二)

发布时间:2026/5/27 8:13:29

预处理详解(二) 一、宏替换的规则在程序扩展中#define 定义符号和宏时需要设计几个步骤。1.在调用宏时首先对参数进行检查看看是否包含任何由#define定义的符号如果是他们首先被替换替换。2.文本随后插入到程序中原来的文本位置对于宏参数名被它们的值所替换。3.最后再次对结果文件进行扫描看看它是否包含任何由#define定义的符号。如果是就重复上述处理过程。二、宏和函数的对比宏通常被应用于执行简单的运算例如比较两个数中较大的一个数。#define MAX(a,b) ((a) (b)?(a):(b))2.1.宏于函数相比的优点为什么不用函数来完成这个任务呢原因有两个2.1.1用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多所以宏比函数在程序的规模和速度方面略胜一筹。2.1.2更为重要的是函数的参数必须声明为特定的类型所以函数只能在类型合适的表达式上使用但是宏的参数与类型无关。2.2.宏与函数相比的劣势2.2.1.每次使用宏的时候一份宏定义的代码将插入到程序中除非宏比较短否则可能大幅度增加程序的长度。2.2.2.宏是没法调试的。2.2.3.宏由于与类型无关也就不够严谨。2.2.4.宏很可能会带来运算符优先级的问题导致程序容易出现错误。2.3.宏有时候也可以做函数做不到的事情比如宏的参数可以重新类型但函数做不到。三、#和##3.1.#运算符#运算符将宏的一个参数转换为字符串字面量。它允许出现在带参数的宏的替换列表中。#运算符所执行的操作可以理解为“字符串化”。3.2.举例代码如下可自行测试#define PRINT(n) printf(the value of#nis %d\n,n)#includestdio.hint main() {int n 6;int ret PRINT(n);return 0;}3.3.##运算符##可以把我以为它两边的符号合成一个符号它允许宏定义从分离的文本片段创建标识符。##被称为记号粘合这样的连接必须产生一个合法的标识符否则其结果就是未定义的。四、命名约定一般来讲函数的宏的时候语法很相似所以语言本身没法帮我们区分二者。平时的一个习惯就是把宏名全部大写函数名不要全部大写。五、#undef这条指令用于移除一个宏定义.#undef NAME// 如果现存的一个名字需要被重新定义,那么它的旧名字就需要被移除。

相关新闻