Skip to content

预处理器

预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。

所有的预处理器指令都是以井号#开头,只有空格字符可以出现在预处理指令之前。预处理指令不是 C++ 语句,所以它们不会以分号;结尾。

我们已经看到,之前所有的实例中都有 #include 指令。这个宏用于把头文件包含到源文件中。

C++ 还支持很多预处理指令,比如 #include、#define、#if、#else、#line 等,让我们一起看看这些重要指令。

1.宏定义

使用#define预处理指令用于创建符号常量,宏定义声明的内容不可以被更改,为了便于区分,一般用全大写来定义标识符

1.1 基本语法

程序总遇到宏定义的标识符,会直接替换成后面的内容

c++
#define 标识符 内容

例子

c++
#include<iostream>  
#define SUCCESS 1
#define NAME "张三"

int main()
{
    std::cout << SUCCESS << std::endl;		// 打印1
    std::cout << NAME << std::endl;			// 打印"张三"
    return 0;
}

注意

在程序中用到宏定义的时候,会直接替换成宏定义描述的语句

c++
#include<iostream>  
#define EXPR 2+2
int main()
{
    std::cout << EXPR << std::endl;				// 4
    std::cout << EXPR * EXPR << std::endl;		// 8
    return 0;
}

按照往常的数学常识来说,上面第二个打印语句应该打印16,但并不是这样,因为上述第二个打印语句会被转化成如下语句

c++
std::cout << 2 + 2 * 2 + 2 << std::endl;

由此可见,2+2的两边并没有括号,正是因为EXPR被完全替换成了2+2,先乘除后加减,所以是8

若想实现上述语句等于16,可有这样做

c++
#include<iostream>  
#define EXPR (2+2)
int main()
{
    std::cout << EXPR * EXPR << std::endl;		// 16
    return 0;
}

如此,2+2两边被加了括号,则变成4*4=16

1.2 参数宏

#define 可以定义一个带有参数的宏

c++
#define ADD(a,b) a + b

若有特殊符号影响编译,需要给内容加上括号

c++
#include <iostream>
using namespace std;

#define MIN(a,b) (a < b ? a : b)

int main()
{
    int i, j;
    i = 100;
    j = 30;
    cout << "较小的值为:" << MIN(i, j) << endl;

    return 0;
}

2.条件编译

条件编译就是给定一个条件,符合条件就编译范围内的内容,否则就不编译

c++
#ifdef 条件
// 条件编译内容
#endef

可以使用 #if 0 语句注释掉程序的一部分

c++
#if 0
   不进行编译的代码
#endif

3.#运算符

# 运算符会把宏标识符括号中的内容,换成#后的内容

c++
#include <iostream>
using namespace std;
 
#define MKSTR( x ) #x
 
int main ()
{
    cout << MKSTR(HELLO C++) << endl;
 
    return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

c++
HELLO C++

不难理解,C++ 预处理器把下面这行:

c++
cout << MKSTR(HELLO C++) << endl;

转换成了:

c++
cout << "HELLO C++" << endl;

4.##运算符

## 运算符会把宏标识符括号中的内容拼接起来

c++
#include <iostream>
using namespace std;
 
#define concat(a, b) a ## b
int main()
{
   int xy = 100;
   
   cout << concat(x, y);
   return 0;
}

// 打印结果为 100

转换如下

c++
cout << concat(x, y);
// 转换成
cout << xy;

5.预定义宏

C++ 提供了下表所示的一些预定义宏:

描述
__LINE__这会在程序编译时包含当前行号。
__FILE__这会在程序编译时包含当前文件名。
__DATE__这会包含一个形式为 month/day/year 的字符串,它表示把源文件转换为目标代码的日期。
__TIME__这会包含一个形式为 hour:minute:second 的字符串,它表示程序被编译的时间。
c++
#include <iostream>
using namespace std;
 
int main ()
{
    cout << "Value of __LINE__ : " << __LINE__ << endl;
    cout << "Value of __FILE__ : " << __FILE__ << endl;
    cout << "Value of __DATE__ : " << __DATE__ << endl;
    cout << "Value of __TIME__ : " << __TIME__ << endl;
 
    return 0;
}

执行结果

c++
Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48

MIT Licensed