C语言提供了预处理命令主要有以下三种:
1. 宏替换
2. 文件包含
3. 条件编译
不带参数的宏
不带参数的宏指定标识符来代替一个字符串,其一般格式为:
#define 标识符 字符串
使用宏可以增加程序的可读性,另一个好处是使程序更易于修改。
Note:
1. 宏定义以换行结束,不要用分号结束;
2. 如果双引号内出现与宏名相同的字符串,则这个字符串不被替代。
带参数的宏
宏可以带参数,其定义的一般形式为:
#define 标识符(参数表) 字符串
Note:
1. 在宏定义种宏名和括起参数的左圆括号之间不能有空格。
2. 整个宏扩展及各种参数要用括号括起。
宏与函数(区别)
l C预处理程序并不认识C,不做任何C语法检查,更不管程序的意思,只是机械地按照宏定义把宏调用替换为对应的字符串。
l 使用带参数的宏比函数调用更快。因为宏在真正编译之前已被相应的替换,在执行时,不必打断调用程序的运行,也没有参数的传递,而使用函数调用,当执行到有函数调用的语句时,主调函数要把参数传给被调函数,同时把控制权转给被调函数,被调函数运行完后返回给主调函数,这些都需要时间的开销。
l 但是宏调用所占空间较多,因为预处理时每遇到宏调用就将对应的内容替换过来,因而程序较长。反观函数,不管调用多少次,程序都那么长,所占空间比较少。
文件包含
所谓文件包含是指一个源文件可以将另一个源文件的全被内容包含到自己的文件中,文件包含的命令一般形式是
#include “文件名”
总是把包括宏定义的文件叫做头文件,后缀用.h.
文件包好命令中的文件名,也可以用尖括号括起来,如#include <文件名>
两者的区别是:用尖括号时,系统只是在“标准”目录中寻找文件,如UNIX系统在user/include目录中查找文件,而用双引号括起文件时,系统现在当前目录中查找,如找不到,再到其它目录中查找,最后查找所谓“标准”目录。
条件编译
一般情况下,源程序中所有的语句都参加编译。但有时也希望根据一定的条件去编译源文件的不同部分,这就是条件编译。条件编译使得同一源程序在不同得编译条件下得到不同得目标代码。商业软件公司总是使用条件编译来提供和维护某一程序得多个顾客版本。
条件编译得常用形式:
1.#ifdef 标识符
程序段1
#else
程序段2
#endif
如果标识符已被#define行定义,则编译程序段1,否则编译程序段2。
2.#ifndef 标识符
程序段1
#else
程序段2
#endif
如果标识符没在#define行定义就编译程序段1,如果定义了就编译程序段2。
3.#if 表达式1
程序段1
#elif 表达式2
程序段2
#else
程序段n
#endif
如果表达式1为真就编译程序段1,否则如果表达式2为真就编译程序段2,…,如果各表达式为真就编译程序段n。
使用条件编译的原因:
- 便于程序的移植。Turbo C和MS C。
- 调试程序。
预处理命令常见错误
- 定义宏时在末尾加分号。
- 丢失“#”。
- 定义字符串常量没有用引号。
- 宏扩展的整体或参数没有括号括起。