C++ 编译预处理
一、简介
1、编译预处理命令均以#开头,以回车符结束;
2、每条预处理命令独占一行;
3、可以出现在程序的任意位置,但通常置于源程序的开始;
4、在C++编译对源程序进行编译之前,先对程序中这些命令进行预处理;
5、C++预处理主要有三种:文件包含、宏定义和条件编译。
二、文件包含
1、格式
格式1:#include <filename>
C++编译系统预定义的包含文件,这些文件在c++编译系统的include目录或其子目录中,通知预处理程序按系统规定路径检索文件。
格式2:#include “filename”
从当前工作目录开始查找,一般为自定义头文件。
2、预处理程序对源文件进行扫描时,将产生一个临时文件,用于存放预处理结果,当遇到#include “文件名”时,则将源文件复制到一个临时文件,并用指定的包含文件替代#include命令行。
3、通常,头文件中声明的是共用的数据结构类型、函数原型、宏定义、全局变量等。主要好处是对后续编程约定。
三、宏定义
1、不带参数的宏定义
#define 标示符 字符或字符串
2、带参数的宏
#define 宏名(参数表) 使用参数的字符或字符串
3、宏的作用域:从宏定义到本源程序文件结束。
终止宏作用域:#undef 宏名
如:
#define PI 3.14
……
#undef PI
4、在宏定义时,宏名与左括号之间不能有空格,
如:
编译程序会认为是无参宏AREA定义为(a,b) (a)*(b)
5、当一个宏定义多于一行时必须使用续行符“\”。
如:
6、宏定义只是简单扩展。
7、宏定义和内联函数比较。
四、条件编译
1、仅在满足条件时才对某部分进行编译,否则该部分相当于被注释掉了。
2、作用一:调试程序或编写通用程序
如在程序中加入下面调试输出语句,只有在源文件中定义了宏DEBUG才输出这些语句,一旦程序调试好,删除宏定义DEBUG即可,而不需要删除每一条调试语句。
作用二:防止包含文件重复
五、程序的多文件组织
1、在一个源程序文件中定义的函数,若限定他只能在本文件内使用,这种函数成为内部函数,在函数的类型标识符前加static修饰:
static int f()
{}
2、若源文件中的函数也可以在其他文件中使用,加extern,可不加,编译器默认是extern
extern int f()
{}
3、定义全局变量,若加static 表示在本文件中使用,不加或加extern可供其他文件使用。
在其他文件中使用是要进行引用性说明,
如:t1.cpp中内容
int x=2;
t2.cpp中内容
输出为:2
注意:
(1)t1.cpp中内容改为
extern int x = 2;
或
int x;
都可以正确运行(为int x时输出随机数);
但是改为extern int x;则不正确。
原因:
在t1.cpp中extern int x;是引用性说明,而在这之前x并没有定义,到哪去引用?更不用说t2.cpp中的引用了。
extern int x = 2;是定义性说明,因此再在t2.cpp中引用是正确的,而int 2;也是定义行说明。
因此,在定义性说明时,最好省略extern.