C++ 预处理器和宏

顾名思义,C++ 预处理器是在代码编译之前转换(预处理)我们的程序。

预处理器使用预处理器指令来控制代码转换。例如,

#include <iostream>

这里,#include 是一个预处理器指令,它在编译程序之前将 <iostream> 头文件的内容插入到我们的程序中。

Working of C++ preprocessor in the compilation process
C++ 预处理器的工作原理

预处理器指令

在 C++ 中,所有预处理器指令都以 # 符号开头。例如,#include#define#if 等。

C++ 预处理器的常见应用包括:

  • #include - 用于包含头文件
  • #define - 用于定义宏
  • #if - 用于提供条件编译

现在,让我们详细了解这些预处理器指令。


#include 预处理器指令

#include 指令用于在我们的程序中包含头文件。例如,

#include <cmath>

这里,cmath 是一个头文件。#include 指令指示预处理器将上面的代码行替换为 cmath 头文件的内容。

这就是为什么我们需要使用 #include <cmath> 来使用 pow()sqrt() 等函数的原因。

我们也可以创建自己的自定义头文件,并使用 #include 指令在程序中使用它们。例如,

#include "path_to_file/my_header.h"

这里,我们在程序中包含了名为 my_header.h 的自定义头文件。

通过这种方式,我们可以将一个大型程序分成多个文件。


#define 预处理器指令

#define 指令用于“定义”可以在程序中使用的预处理器变量。例如,

#define PI 3.1415   // value of pi

现在,当我们在程序中使用 PI 时,它会被替换为 3.1415

这里,PI 被称为 **宏**。宏是已被命名的代码片段。


示例 1:C++ #define

#include <iostream>

// create a macro named PI // with the value 3.1415 #define PI 3.1415
using namespace std; int main() { double radius, area; cout << "Enter the radius: "; cin >> radius;
// use PI to calculate area of a circle area = PI * radius * radius; cout << "Area = " << area;
return 0; }

输出

Enter the radius: 4
Area = 50.264

类函数宏

我们还可以使用 #define 来创建像函数一样的宏。例如,

#define circleArea(r) (3.1415 * r * r)

让我们看一个实际示例

#include <iostream>
#define PI 3.1415 // macro that calculates area of circle // and takes parameter 'r' #define circle_area(r) (PI * r * r)
using namespace std; int main() { double radius = 2.5;
// call the circle_area() macro // pass radius as an argument cout << "Area = " << circle_area(radius);
return 0; }

输出

Area = 19.6344

在这里,代码 circleArea(radius); 会展开为 3.1415 * 2.5 * 2.5

注意: 使用函数比类函数宏更好,因为宏更容易出错。


#if 预处理器指令

#if 指令用于指示预处理器根据特定条件是否包含代码块。

在存在多个条件的情况下,它也可以与 #else#elif 指令结合使用。

因此,#if#else#elif 指令与 C++ 中的 if...else 语句非常相似,但有一个主要区别。

if...else 语句在执行时进行测试,以检查是否应执行代码块。

另一方面,条件指令在编译之前由预处理器测试,以决定是否在程序中包含代码块。

这是一个简单的例子,

#include <iostream>  

// create NUMBER macro with a value of 3
#define NUMBER 3 

using namespace std;

int main() {
// use #if directive to check // if NUMBER is greater than 0 #if (NUMBER > 0) cout << NUMBER << " is greater than 0."; #else cout << NUMBER << " is less than 0."; #endif
return 0; }

输出

3 is greater than 0.

在这里,#endif 指令用于指示 #if#else 指令的完成。

但是,在运行时决定执行哪部分代码时,if...else 语句比预处理器指令更受青睐。

尽管如此,在某些情况下 #if 指令更适用

  • 根据操作系统使用不同的代码(平台特定代码)。
  • 包含仅在调试版本中运行的调试代码(例如打印调试消息)。
  • 根据特定条件打开或关闭功能。
  • 包含特定于软件的特定版本或发行版的代码(版本特定代码)。

示例 2:平台特定 C++ 代码

#include <iostream>
using namespace std;

int main() {
    
// include if running on windows #ifdef _WIN32 cout << "Hello from Windows!" << endl; // include if running on linux #elif __linux__ cout << "Hello from Linux!" << endl; // include if running on some other system #else cout << "Hello from an unknown platform!" << endl; #endif
return 0; }

输出

Hello from Linux!

这是使用条件编译的平台特定代码示例。

这里,

  • _WIN32 - Microsoft Visual C++ 编译器在 Windows 平台上定义的宏
  • __linux__ - GNU C Compiler 在 Linux 系统上定义的宏
  • #ifdef - #if 的一个变体,它检查宏是否已被定义

_WIN32__linux__ 用于确定程序运行的系统。


预定义宏

以下是一些 C++ 编程中常用的预定义宏。

__DATE__ 包含当前日期的字符串。
__FILE__ 包含当前执行程序的文件的字符串。
__LINE__ 表示当前行号的整数。
__TIME__ 包含当前时间 (GMT) 的字符串。

注意: 由于这些是 **预定义** 宏,因此我们无需使用 #define 指令即可使用它们。


示例 3:预定义宏

#include <iostream>
using namespace std;

int main() {

// print the current time cout << "Current time: " << __TIME__;
return 0; }

输出

Current time: 04:23:31

此程序使用 __TIME__ 宏打印当前时间 (GMT)。


你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战