在C语言中,所有以#开头的行被认为是需要预处理器处理的“预处理器指令”。#include、#define等常见的用法不再赘诉,可以参考任何一本C语言的书籍。这里仍然讲一些需要注意的用法。下面的代码主要说明#出现在宏定义内部作为“字符串化”操作符的用法,另外附带介绍一些特别的习惯和用法。
#include <stdio.h>
# //此行只包含一个#,被当作空行处理
#define PRINT_ADD(a, b) \
do \
{ \
char fmt[] = "%s + %s = %d\n"; \
printf(fmt, #a, #b, ((a)+(b))); \
} while (0) \
int main(int argc, char** argv)
{
int var_a = 6;
int var_b = 9;
PRINT_ADD(3, 5);
PRINT_ADD(var_a, var_b);
PRINT_ADD(var_a * 2 , var_b);
return 0;
}
只包含一个#的行会被如何处理?
第3行:只包含一个#的行被标准C语言认为是空行,#会被预处理器用空行替换掉。
宏函数定义为什么要使用do while循环的格式书写?
第5行到第10行定义了一个宏函数PRINT_ADD(a, b)。
1. 在宏函数中我们希望能够定义局部变量,但是C99以前的标准C语言要求所有变量必须一个作用域开始处定义。而宏展开后即变成了普通的代码行,并不能保证满足满足这一点的要求,所以宏函数需要采用大括号的形式。
2. 我们希望在程序中尽量像调用普通函数那样使用宏函数,即要求其后有一个分号作为结尾。使用这种形式有效地要求了用户必须使用分号。
3. 编译器随后的处理中,会有效地优化掉这种注定只执行一次的循环语句。所以一般来说不会影响性能。
第9行中#的作用是什么?
#出现在宏定义内部被认为是“字符串化”操作符。它的作用是将传入的参数整体宏替换为相对应的字符串。
例如:
第17行传入的3和5: #a被替换为"3",#b被替换为"5", a被替换为3, b被替换为5
第18行传入的var_a和var_b: #a被替换为"var_a",#b被替换为"var_a", a被替换为var_a, b被替换为var_b
第19行传入的var_a * 2和var_b: #a被替换为"var_a * 2",#b被替换为"var_a", a被替换为var_a * 2, b被替换为var_b
所以,程序运行的结果为:
3 + 5 = 8
var_a + var_b = 15
var_a * 2 + var_b = 21
P.S.:以下是VS2008预处理器处理后输出的代码:
int main(int argc, char** argv)
{
int var_a = 6;
int var_b = 9;
do { char fmt[] = "%s + %s = %d\n"; printf(fmt, "3", "5", ((3)+(5))); } while (0);
do { char fmt[] = "%s + %s = %d\n"; printf(fmt, "var_a", "var_b", ((var_a)+(var_b))); } while (0);
do { char fmt[] = "%s + %s = %d\n"; printf(fmt, "var_a * 2", "var_b", ((var_a * 2)+(var_b))); } while (0);
return 0;
}
(■版权声明: 原创内容,转载仅限非商业用途,并需注明出处: http://blog.youkuaiyun.com/LoveASPDotNet)