📜  C++预处理器

📅  最后修改于: 2020-12-17 05:16:21             🧑  作者: Mango


预处理程序是指令,它们向编译器提供指令,以在实际编译开始之前对信息进行预处理。

所有预处理程序指令均以#开头,并且一行上的预处理程序指令之前只能出现空格字符。预处理程序指令不是C++语句,因此它们不以分号(;)结尾。

您已经在所有示例中看到了#include指令。此宏用于将头文件包含到源文件中。

C++支持许多预处理器指令,例如#include,#define,#if,#else,#line等。让我们看看重要的指令-

#define预处理程序

#define预处理程序指令创建符号常量。符号常量称为,指令的一般形式为-

#define macro-name replacement-text 

当该行出现在文件中时,在编译程序之前,该文件中所有随后出现的宏都将由替换文本替换。例如-

#include 
using namespace std;

#define PI 3.14159

int main () {
   cout << "Value of PI :" << PI << endl; 

   return 0;
}

现在,假设我们拥有源代码文件,让我们对该代码进行预处理以查看结果。因此,让我们使用-E选项进行编译,并将结果重定向到test.p。现在,如果您检查test.p,它将有很多信息,在底部,您将找到替换为以下内容的值-

$gcc -E test.cpp > test.p

...
int main () {
   cout << "Value of PI :" << 3.14159 << endl; 
   return 0;
}

功能类宏

您可以使用#define定义将采用以下参数的宏-

#include 
using namespace std;

#define MIN(a,b) (((a)

如果我们编译并运行以上代码,这将产生以下结果-

The minimum is 30

条件编译

有几种指令,可用于编译程序源代码的选择性部分。此过程称为条件编译。

条件预处理器构造非常类似于“ if”选择结构。考虑以下预处理器代码-

#ifndef NULL
   #define NULL 0
#endif

您可以编译程序以进行调试。您还可以使用单个宏打开或关闭调试,如下所示:

#ifdef DEBUG
   cerr <

如果在指令#ifdef DEBUG之前定义了符号常量DEBUG,则cerr语句将在程序中编译。您可以使用#if 0语句来注释掉程序的一部分,如下所示-

#if 0
   code prevented from compiling
#endif

让我们尝试以下示例-

#include 
using namespace std;
#define DEBUG

#define MIN(a,b) (((a)

如果我们编译并运行以上代码,这将产生以下结果-

The minimum is 30
Trace: Inside main function
Trace: Coming out of main function

#和##运算符

#和##预处理程序运算符在C++和ANSI / ISO C中可用。#运算符使替换文本标记转换为带引号的字符串。

考虑以下宏定义-

#include 
using namespace std;

#define MKSTR( x ) #x

int main () {

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

   return 0;
}

如果我们编译并运行以上代码,这将产生以下结果-

HELLO C++

让我们看看它是如何工作的。很容易理解C++预处理器改变了思路-

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

上一行将变成下一行-

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

##运算符用于连接两个标记。这是一个例子-

#define CONCAT( x, y )  x ## y

当CONCAT出现在程序中时,其参数将串联起来并用于替换宏。例如,在程序中,将CONCAT(HELLO,C++)替换为“ HELLO C++”,如下所示。

#include 
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;

预定义的C++宏

C++提供了许多下面提到的预定义宏-

Sr.No Macro & Description
1

__LINE__

This contains the current line number of the program when it is being compiled.

2

__FILE__

This contains the current file name of the program when it is being compiled.

3

__DATE__

This contains a string of the form month/day/year that is the date of the translation of the source file into object code.

4

__TIME__

This contains a string of the form hour:minute:second that is the time at which the program was compiled.

让我们看一个上面所有宏的例子-

#include 
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;
}

如果我们编译并运行以上代码,这将产生以下结果-

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