1.预定义符号(共支持5个符号)
_FILE_进行编译的文件名
_LINE_ 文件当前行的行号
上两个在确认调试输入的来源方面有用处
_DATA_ 文件被编译的日期
_TIME_ 文件被编译的时间
上两个用于在被编译的程序中加入版本信息
_STDC_ 如果编译器遵循ANSI C,其值就为1,否则未定义。
2.宏定义#define
带参数宏注意:
1.所有用于对数值表达式进行求值的宏定义都应该尽量加上括号,避免出错。
如 #define double( x )( ( 5 ) + ( 5 ) )
2.判定if条件只对它后面的一个语句有效,if语句后带有宏参数时注意加上do{ ;} while(0)
如 #define func( a , b )do{ a+b ; a++; } while( 0 )
if ( a > b )
func(a ,b )
else
;
宏代替函数,可以解决函数无法解决的任务,如将类型作为参数进行传递
#define MALLOC( n , type ) \
( ( type * ) malloc ( ( n ) * sizeof ( type ) ) )
type 作为类型在函数中是无法作为参数传递的。
宏参数副作用:
宏参数在宏定义中出现次数超过一次,可能会出现不可预料的结果。
如x++
#define MAX( a, b )( ( a) > ( b) ) ? ( a ) :( b ) )
...
x = 5 ;
y = 8 ;
z = MAX ( x++ , y++ );
替换结果 :( ( x++ ) > ( y++ ) ) ? ( x++ ) :( y++ ) )
输出结果 :6,10,9
#undef : 移除一个宏定义。如果一个现存的名字需被重新定义,其旧定义必须先被移除
提供符号命令行定义的编译器通常也提供在命令行中去除符号的定义。如在UNIX编译器中,-U选项执行该任务。
3.条件编译
目的:维护性修改源代码时,如果不想将某些语句物理删除,可以选择条件编译。
#define DEBUG 1
#if DEBUG //如果为真,就编译
STATEMENTS
#elif DEBUG
OTHER STATEMENTS
#else
OTHER STATEMENTS
#endif
4.文件包含#include
包括函数库文件包含#include<filename.h>和本地文件包含#define "filename.h"
嵌套文件包含:在一个将被其他文件包含的文件中使用#include指令。
5.其他指令
#error允许生成错误信息
#line number "string" 通知预处理器number是一个下一行输入的行号。“string”被预处理器当做当前文件的名字。
#progma允许编译选项或其他任何方式无法实现的一些处理方式。
无效指令以#开头,后面不跟任何内容的一行。这类指令只是被预处理器简单地删除。