编译一个C程序的第1个步骤是预处理(preprocessing)阶段。C预处理器在源代码编译以前对其进行一些文本性质的操做。它的主要任务包括删除注释、插入被#include指令包含的文件的内容、定义和替换由#define指令定义的符合以及肯定代码的部份内容是否应该根据一些条件编译指令进行编译。express
用法:函数
#define name stuff测试
有了这条指令之后,每当有符合name出如今这条指令后面时,与处理器就会把它替换成stuffspa
全部用于对数值表达式进行求值的宏定义都应该整个表达式两边加上一对括号。调试
使用#undef移除一个宏定义。code
#if constant-expressionblog
statementsio
#endif编译
其中,constant-expression(常量表达式)由预处理器进行求值,若是它的值非零值(真), 那么statements部分就被正常编译,不然预处理器就安静第删除它们。class
例如,将你全部的调试代码都如下面这种形式出现:
#if DEBUG printf("x=%d, y=%d\n",x,y); #endif
这样,无论咱们是想编译仍是忽略这个代码都很容易办到。若是想要编译它,只要使得
#define DEBUG 1
这个符号定义就能够了。若是想要忽略它,只要把这个符号定义为0就能够了。
条件编译的另外一个用途是在编译时选择不一样的代码部分。为了支持这个功能,#if指令还具备可选的#elif和#else子句。
测试一个符号是否已被定义:
#ifdef symbol
#ifndef symbol
#include指令使另外一个文件的内容被编译。替换方式:预处理器删除这条指令,并用包含文件的内容取而代之。这样,一个头文件若是被包含到10个源文件中,它实际上被编译了10次。
开销问题:若是两个源文件都须要同一组声明,把这些声明复制到每一个源文件中所花费的编译时间跟把这些声明放入一个头文件,而后再用#include指令把它包含于每一个源文件所花费编译时间相差无几。同时,这种开销只是在程序被编译时才存在,因此对运行时效率并没有影响。更重要的是,把这些声明放于一个头文件中具备重要的意义。
因此,和把一个程序须要的全部声明都放入一个巨大的头文件相比,使用几个头文件,每一个头文件包含于某个特定函数或模块 。