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源程序的名称。预编译程序对于在源程序中出现的这些串将用合适的值进行替换。

注意:

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

#pragma是一个预处理指令,会把后面的值传给编译器

这个预处理指令是用于向编译器提供窗外信息的标准方法。

对于这个指令C标准中没有明确规定,所以不同编译器实现是不同的。

同一个#pragma命令,换一个编译器可能完全没有意义或者是不同意义。

格式一般为: #pragma Para。其中Para 为参数。

例如:

#pragma REGPARMS

使用REGPARMS 是让编译器透过暂存器来传函数参数。这样中间的函数速度快些。

伪指令顾名思义他不是条指令,所以才叫伪指令。

并且指令是有具体含义的,是能够被汇编成机器代码并且执行的。所以,伪指令显然不会被汇编成机器码,亦即他不会被执行。

那么他的作用就仅仅体现在编译的过程当中了,也就是在asm转到obj的时候,这些伪指令能够帮助编译器怎么去编译源文件。

比如ORG

100H表示下一行代码的地址是100H,这个时候编译器就会将下一行的代码放置在100H处。如果你编写过16位的DOS程序,那么可以看看.lst列表文件,可以清晰的发现所有的伪指令全部没有机器码,只是在帮助编译器怎么去更好的组织那些指令而已!