C++面向对象程序设计
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.11 预处理器

C++预处理器(也叫预编译器)提供了一些预处理命令,如#define、#else、#elif、#endif、#error、#if、#ifdef、#ifndef、#include、#line、#pragma、#undef等。这些命令在正式编译之前执行,所有的预处理命令都以“#”开头,独占一行,语句结束时不需要分号。

1.#define和#undef

#define常用于定义一个标识符常量或带参数的宏。例如:

#define pi 3.14159
#define MAX(a,b) ((a)>(b)?(a):(b))

在对程序进行预编译时,C++会用#define定义的标识符常量的值替代常量标识符,用宏的代码替代宏名。例如,若对上述定义存在下面的引用:

x=pi+5;
int y=MAX(9,3);

在编译相应程序之前,上面的两条语句将被预处理为下面的形式:

x=3.14159+5;
int y=((9))>(3)?(9):(3));

#undef用于删除由#define定义的宏,使之不再起作用。例如:

#undef MAX

此命令之后,MAX就不再有意义了。

2.条件编译

条件编译指示编译器只对满足条件的语句或语句块进行编译,使同一程序在不同的编译条件下,能够得到不同的目标代码。常用的条件编译有以下两种形式。

(1)第1种形式

#ifdef 标识符
  语句组1
[#else
   语句组2
]
#endif

[ ]中的内容是可选项,即可以有#else部分,也可以没有#else部分。意思是,如果已经用#define定义了某标识符,就编译语句组1;否则就编译语句组2,当然前提是存在#else部分。

(2)第2种形式

#ifndef 标识符
   语句组1
[#else
   语句组2
]
#endif

如果没有用#define定义某标识符,就编译语句组1;否则就编译语句组2。

例2-19】 #ifdef条件编译的应用例子。

//Eg2-19.cpp
#include <iostream>
using namespace std;
#define DK
#ifdef DK
   void f1(){ cout<<"Dk is defined!"<<endl; }
#else
   void f1(){ cout<<"DK not defined!"<<endl; }
#endif
void main(){
   f1();
}

由于“#ifdef DK”为真,所以本程序相当于下面的程序:

#include <iostream>
using namespace std;
void f1(){ cout<<"Dk is defined!"<<endl; }
void main(){
   f1();
}

请大家思考一下,如果去掉语句“#define DK”,又会是什么情况呢?