c语言编译预处理

Python012

c语言编译预处理,第1张

编译,编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序。

如果用一张图来表示:

读取c源程序,对其中的伪指令(以#开头的指令)和特殊符号进行处理

[析] 伪指令主要包括以下四个方面

(1)宏定义指令,如#define Name TokenString,#undef等。对于前一个伪指令,预编译所要做的是将程序中的所有Name用TokenString替换,但作为字符串常量的Name则不被替换。对于后者,则将取消对某个宏的定义,使以后该串的'出现不再被替换。

(2)条件编译指令,如#ifdef,#ifndef,#else,#elif,#endif,等等。这些伪指令的引入使得程序员可以通过定义不同的宏来决定编译程序对哪些代码进行处理。预编译程序将根据有关的文件,将那些不必要的代码过滤掉

(3)头文件包含指令,如#include "FileName"或者#include 等。在头文件中一般用伪指令#define定义了大量的宏(最常见的是字符常量),同时包含有各种外部符号的声明。采用头文件的目的主要是为了使某些定义可以供多个不同的C源程序使用。因为在需要用到这些定义的C源程序中,只需加上一条#include语句即可,而不必再在此文件中将这些定义重复一遍。预编译程序将把头文件中的定义统统都加入到它所产生的输出文件中,以供编译程序对之进行处理。

包含到c源程序中的头文件可以是系统提供的,这些头文件一般被放在/usr/include目录下。在程序中#include它们要使用尖括号(<>)。另外开发人员也可以定义自己的头文件,这些文件一般与c源程序放在同一目录下,此时在#include中要用双引号("")。

(4)特殊符号,预编译程序可以识别一些特殊的符号。例如在源程序中出现的LINE标识将被解释为当前行号(十进制数),FILE则被解释为当前被编译的C源程序的名称。预编译程序对于在源程序中出现的这些串将用合适的值进行替换。

注意:

预编译程序所完成的基本上是对源程序的“替代”工作。经过此种替代,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。这个文件的含义同没有经过预处理的源文件是相同的,但内容有所不同。下一步,此输出文件将作为编译程序的输出而被翻译成为机器指令。

所谓预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作。它由预处理程序负责完成。当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预处理部分作处理,处理完毕自动对源程序编译

2018年9月计算机二级C语言考点解析:编译预处理和动态存储分配

13.1宏定义(不带参数的宏定义,带参数的宏定义)

1.编译预处理就是对C源程序进行编译前,由″编译预处理程序″对预处理命令行进行处理的过程。

2.C语言中,凡是以″#″开头的行,都称为″编译预处理″命令行。C语言中的编译预处命令有:#define,#undef,#include,#if,#else,#elif,#endif,#ifdef,#ifndef,#line,#pragma,#error。这些预处理命令组成的预处理命令行必须在一行的开头以″#″号开始,每行的未尾不得加″″号,以区别于C语句、定义和说明语句。

3.不带参数的宏定义:命令的一般形式为:

#define标识符字符串

定义中的″标识符″为用户定义的标识符,称为宏名。在预编译时,C预编译程序将出现的宏名替换成″字符串″的内容,这一过程也称为宏展开。

4.带参数的宏定义:命令的一般形式为

#define宏名(形式参数)字符串

定义中的″字符串″应包含括号中所指定的形式参数。注意宏名与括号之间不要加空格,否则就成为不带参数的宏定义了。

5.预编译时,遇到带实参的宏名,则按命令行中指定的字符串从左到右进行置换,原则是:遇到实参则以实参代替,非形参字符原样保留,从而成展开后的内容。

13.2“文件包含”处理

1.文件包含的一般形式为:

#include″头文件名″

#include<头文件名>

头文件名一般由C语言提供,也可以是用户自己编写的,头文件通常用.h作为后缀。

2.当头文件名用双引号括起来时,系统首先在使用此命令的文件所在的目录中查找被包含的文件,找不到时,再按系统指定的标准方式检索其它目录当头文件名用尖括号括起来时,则直接按系统指定的标准检索方式查找被包含的文件。

3.预编译时,将被包含文件的内容全部复制到包含文件中,这就是文件″包含处理″。

13.3条件编译

C语言中的条件编译命令可对源程序代码的各部分有选择地进行编译。条件编译主要有如下3种使用格式:

使用格式1:

#ifdef标识符

程序段1

#else

程序段2

#endif

使用格式2:

#ifndef标识符

程序段1

#else

程序段2

#endif

使用格式3:

#if表达式

程序段1

#else

程序段2

#endif

使用格式1表示如果已定义了“标识符”,则编译“程序段1”,否则编译“程序段2”使用格式2表示如没有定义了“标识符”,则编译“程序段1”,否则编译“程序段2”使用格式3表示如“表达式”的值为“真”时,则编译“程序段1”,否则编译“程序段2”。