@[toc]
预处理器像是个小软件,可以在编译之前处理C语言程序。
宏(macro)
define指令定义了一个宏——用来代表其他东西的一个名字,包括常量和表达式。
include指令告诉预处理器打开一个特定的文件,将它的内容作为正在编译的文件的一部分包含进来。
预处理器会删除#define指令,会引入stdio.h指令,并且替换之后所有的#define定义的指令的内容。
观察预处理器的输出
大部分c的编译器提供了一种方法来观察预处理器的输出。
#define N = 10
#define INC(x) x+1
#define SUB(x,y) x - y
#define SQR(x) ((x)*(x))
#define CUBE(x) (SQR(x)*(x))
#define M1(x,y) x##y
#define M2(x,y) #x #y
int main(){
int a[N],i,j,k,m;
#ifdef N
i = j;
#else
j = i;
#endif
i = 10 *INC(j);
i = SUB(j,k);
i = SQR(SQR(j));
i = CUBE(j);
i = M1(j,k);
puts(M2(i,j));
#undef SQR
i = SQR(j);
#define SQR
i = SQR(j);
return 0;
}
gcc编译器可以使用-E来查看预处理之后的输出。
在cmd命令行环境下输入gcc -E macro_error.c -o macro
,会产生macro文件,使用记事本打开之后就会看到预处理器的输出。
预处理指令
define 定义一个宏
undef 删除一个宏定义
include 导致一个指定文件的内容被包含到程序中
条件编译 #if #ifdef #ifndef #elif #else #endif
根据预处理器的条件确定是否包含
带参数的宏
#define N 10 //一般的宏
#define MAX(x,y) ((x)>(y)?(x):(y)) //带参数的宏
#define IS_EVEN(n) ((n)%2==0)
括号不可缺少!!!
宏的优点
宏更“通用”
程序可能稍微快一些
宏的缺点
编译之后的代码通常会变大
宏参数没有类型检查
无法用一个指针指向一个宏
宏可能不止一次计算它的参数
n = MAX(i++,j);
n = (i++)>j?(i++):(j));
#运算符
:字符串化
#define PRINT_INT(n) printf(#n " = %d\n",n)
PRINT_INT(i/j);
result:
printf("i/j"" = %d\n",i/j);
printf("i/j = %d\n",i/j);
##运算符
:记号粘合
#define MK_ID(n) i##n
int MK_ID(1),MK_ID(2),MK_ID(3);
result:
int i1,i2,i3;
宏的通用属性
宏的替换列表可以包含对其他宏的调用。
预处理器只会替换完整的记号,不会替换记号的片断。
宏定义的作用范围通常到出现这个宏的文件末尾。
宏不可以被定义两遍,除非定义完全相同。
预定义宏、空的宏参数、参数个数可变的宏等内容我们就不过多介绍了。
网友评论