如果想在下一行延续指令,则在当前行末尾使用\字符
带参数的宏
#define MAX(x,y) ((x)>(y)?(x):(y))
#define IS_EVEN(n) ((n)%2==0)
则
i=MAX(j+k,m-n);
if(IS_EVEN(i)) i++;
将被替换为
i=((j+k)>(m-n)?(j+k):(m-n));
if((i)%2==0) i++;
宏的替换列表可以包含对其他宏当调用,如:
#define PI 3.14
#define TWOPI (2*PI)
则TWOPI为2*PI,也就是2×3.14,6.28
可以用#undef来取消定义,
#undef 标识符
创建较长的的宏
使用逗号运算符
#defineECHO (s) (gets(s),puts(s))
则ECHO (str);替换为(gets(str),puts(str));
预定义宏
__LINE__ 被编译文件中的行号
__FILE__ 被编译的文件名
__DATA__ 编译的日期
__TIME__ 编译的时间
__STDC__ 如果编译器符合C标准(C99,C89),那么值为1
printf("compiledon %s at %s\n",__DATE__,__TIME__);
检查被0除而导致的错误
#defineCHECK_ZERO(divisor) \
if(divisor==0) \
printf("**Attempt to divide by zero on line%d " \
"of file %s **\n",__LINE__,__FILE__)
int main()
int i=5,j=3,k=0; while(1){ CHECK_ZERO(j); k=i/j; j--; printf("k=%d\n",k);}{
__func__标识符
#defineFUNCTION_CALLED() printf(“%scalled\n”,__func__)
//若函数f调用,则输出f called
#if指令和#endif指令
#defineDEBUG 1
…
#if DEBUG
printf(...);
#endif
可以通过修改DEBUG 所定义的值来决定#if与#endif之间的代码是否执行,如果值不为0,则执行
#defined指令
仅检测某个宏是否有定义,有则返回1,无则返回0,常与#if结合使用:
#ifdefined(DEBUG)
…
#endif
不一定需要给宏赋值,如下例的DEBUG ,#define DEBUG
#ifdef指令和#ifndef指令
#ifdef等价与#if defined,所以严格来说并不需要此指令
#elif指令和#else指令
#if、#ifdef、#ifndef可以像普通的if语句那样嵌套使用。
在#if和#endif之间可以有多个#elif,但只能有一个#else
使用条件编译
- 编写在多台机器或多种操作系统间可移植的程序
#ifdefined(WIN32)
…
#elifdefined(MAC_OS)
…
#elifdefined(LINUX)
…
#endif
- 编写可以用不同的编译器编译的程序
#if__STDC__
函数原型
#else
老式的函数声明
#endif
- 为宏提供默认定义
#ifndefBUFFER
#defineBUFFER 256
#endif
- 临时屏蔽包含注释的代码
不能用/**/注释直接注释掉已经包含/**/的代码
#error
如果预处理器遇到#error指令,会显示一条包含消息的出错消息,有些编译器会立即终止编译而不再检查其他错误。
例如需要确保一个程序无法在一台int类型不能存储100 000的机器上编译:
#if INT_MAX< 100000
#errorint type is too small //#error后面的为消息
#endif
#line
#pragma
对非常大的程序或需要使用特定编译器的特殊功能的程序非常有用
_Pragma运算符
可以使用#单独占一行,作为空指令,增加间隔