编译器的一些预处理机制

 
有些新手会对编译器的一些预处理机制不是很明白,所以写点相关的东西。内容主要来源 : c primer plus 》及  c++ primer

在程序编译之前,首先由预处理器检查程序。在  GCC  工具链中, gcc   g++  分别是 C/C++  编译程序,而预处理程序叫  cpp ,是独立的。根据程序中使用的预处理器指令,预处理器使用符号缩略语所代表的内容替换程序中的缩略语。预处理指令以  #  为行首,一条指令占据一行。预处理器不能理解 c/c++ ,它一般可以接收任何文本并按照替换规则将其转换成其他文本。

头文件通过  include  预处理器指示符 (preprocessor include directive)  而成为我们程序的一部分。预处理器发现  #include  指令后,就会寻找后跟的文件名并把这个文件的内容包含到当前文件中。被包含文件中的文本将替换源代码文件中的 #include  指令,  就像你把被包含文件中的全部内容键入到源文件中的这个位置一样。
#include 
指令有两种使用形式
#include <stdio.h> 
文件名放在尖括号中
#include “mystuff.h” 
文件名放在双引号中

尖括号 括起来表明这个文件是一个工程或标准头文件。查找过程会检查预定义的目录,我们可以通过设置搜索路径环境变量或命令行选项来修改这些目录。在  gcc  中可以使用  -I  参数修改默认查找路径。
如果文件名用一对引号括起来则表明该文件是用户提供的头文件,查找该
文件时将从当前文件目录(或文件名指定的其他目录)中寻找文件,然后再在标准位置寻找文件。
因为计算机系统的结构不完全相同,  所以 ANSI C 不要求对文件采用一样的目录模式。一般而言,命名文件的方法依赖于系统,但是尖括号和双引号的使用则与系统无关。
为什么要包含文件呢?
因为这些文件包含了编译器所需的信息,如函数的声明、常量的定义等。例如,  标准库头文件 stdio.h 文件通常包含 EOF,NULL,getchar() putchar() 的定义。
包含大型头文件并不一定显著增加程序的大小。很多情况下,头文件中的内容是编译器产生最终代码所需的信息,而不是加到最终代码里的具体语句。

被包含的文件还可以含有 #include  指示符由于嵌套包含文件的原因一个头文件可能会被多次包含在一个源文件中条件指示符可防止这种头文件的重复处理。
例如:
#ifndef BOOKSTORE_H
#define BOOKSTORE_H

/* Bookstore.h 
的内容  */

#endif
条件指示符 #ifndef  检查 BOOKSTORE_H  在前面是否已经被定义,这里 BOOKSTORE_H 是一个预编译器常量习惯上预编译器常量往往被写成大写字母,如 BOOKSTORE_H 在前面没有被定义则条件指示符的值为真于是从 #ifndef  #endif  之间的所有语句都被包含进来进行处理。相反,如果 #ifndef  指示符的值为假则它与 #endif  指示符之间的行将被忽略,为了保证头文件只被处理一次,把如下 #define  指示符
#define BOOKSTORE_H
放在 #ifndef  后面这样在头文件的内容第一次被处理时 BOOKSTORE_H  将被定义
从而防止了在程序文本文件中以后 #ifndef  指示符的值为真。
只要不存在两个必须包含的头文件要检查一个同名的预处理器常量这样的情形这
个策略就能够很好地运作。 #ifdef  指示符常被用来判断一个预处理器常量是否已被定义以便有条件地包含程序代码。
#ifdef 
除了用于防止重复包含,还可以用于针对不同环境的条件编译。经常出现的有
#if defined (__GCC__) || defined (__SUN_C__) 
之类的指令,就是针对不同编译器、平台进行选择编译的预处理指令。当编译环境没有定义这个特定的符号的时候,则预处理器会自动忽略这一部分的代码。除了用  #ifdef  判断符号是否定义,还可以判断符号的值。 VC  中常见的将  MSC_VER  与特定值比较以判断  VC  的版本的做法就是这个道理。
除了以上提到的一些内容,还有一些相对少见的预处理器指令,如  #pragma 。它们分别提供了一些特殊的优化手段和编译器控制方法,可以显著提高代码质量减轻编码负担,但是很多时候使用这些编译指令可能是不兼容于其他编译环境的,因此在项目中选用非标准预处理指令的时候,应该在可移植性和编码的优势中进行衡量后作决定。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值