Cplusplus 简明教程
C++ Preprocessor
预处理器是指令,可在实际编译开始之前向编译器提供对信息进行预处理的指令。
The preprocessors are the directives, which give instructions to the compiler to preprocess the information before actual compilation starts.
所有预处理器指令都以 # 开头,并且在一行的预处理器指令之前只能出现空白字符。预处理器指令不是 C++ 语句,因此它们不会以分号 (;) 结束。
All preprocessor directives begin with #, and only white-space characters may appear before a preprocessor directive on a line. Preprocessor directives are not C++ statements, so they do not end in a semicolon (;).
您已在所有示例中都看到了 #include 指令。此宏用于将头文件包含到源文件中。
You already have seen a #include directive in all the examples. This macro is used to include a header file into the source file.
C++ 支持多种预处理器指令,例如 #include、#define、#if、#else、#line 等。让我们看看重要的指令 −
There are number of preprocessor directives supported by C++ like #include, #define, #if, #else, #line, etc. Let us see important directives −
The
#define 预处理器指令创建符号常量。符号常量称为 macro ,指令的一般形式为 −
The #define preprocessor directive creates symbolic constants. The symbolic constant is called a macro and the general form of the directive is −
#define macro-name replacement-text
当此行出现在某个文件中时,在程序编译之前,该文件中宏的所有后续出现都会被 replacement-text 替换。例如 −
When this line appears in a file, all subsequent occurrences of macro in that file will be replaced by replacement-text before the program is compiled. For example −
#include <iostream>
using namespace std;
#define PI 3.14159
int main () {
cout << "Value of PI :" << PI << endl;
return 0;
}
现在,让我们对这段代码进行预处理,以查看结果(假设我们有源代码文件)。因此,让我们使用 -E 选项对其进行编译,并将结果重定向到 test.p。现在,如果您检查 test.p,它将包含大量信息,并且在底部,您会发现已将值替换为以下内容 −
Now, let us do the preprocessing of this code to see the result assuming we have the source code file. So let us compile it with -E option and redirect the result to test.p. Now, if you check test.p, it will have lots of information and at the bottom, you will find the value replaced as follows −
$gcc -E test.cpp > test.p
...
int main () {
cout << "Value of PI :" << 3.14159 << endl;
return 0;
}
Function-Like Macros
您可以使用 #define 来定义一个作为参数的宏,如下所示 −
You can use #define to define a macro which will take argument as follows −
#include <iostream>
using namespace std;
#define MIN(a,b) (((a)<(b)) ? a : b)
int main () {
int i, j;
i = 100;
j = 30;
cout <<"The minimum is " << MIN(i, j) << endl;
return 0;
}
如果我们编译并运行上述代码,这将产生以下结果:
If we compile and run above code, this would produce the following result −
The minimum is 30
Conditional Compilation
可以使用多个指令来编译程序源代码的某些部分。此过程称为条件编译。
There are several directives, which can be used to compile selective portions of your program’s source code. This process is called conditional compilation.
条件预处理结构非常像“if”选择结构。考虑以下预处理器代码 −
The conditional preprocessor construct is much like the ‘if’ selection structure. Consider the following preprocessor code −
#ifndef NULL
#define NULL 0
#endif
您可以出于调试目的编译程序。您还可以使用以下单个宏打开或关闭调试 −
You can compile a program for debugging purpose. You can also turn on or off the debugging using a single macro as follows −
#ifdef DEBUG
cerr <<"Variable x = " << x << endl;
#endif
如果在指令 #ifdef DEBUG 之前已定义了符号常量 DEBUG,则会导致 cerr 语句在程序中被编译。可以使用 #if 0 语句对程序的部分进行注释,如下所示 −
This causes the cerr statement to be compiled in the program if the symbolic constant DEBUG has been defined before directive #ifdef DEBUG. You can use #if 0 statment to comment out a portion of the program as follows −
#if 0
code prevented from compiling
#endif
我们尝试以下示例 −
Let us try the following example −
#include <iostream>
using namespace std;
#define DEBUG
#define MIN(a,b) (((a)<(b)) ? a : b)
int main () {
int i, j;
i = 100;
j = 30;
#ifdef DEBUG
cerr <<"Trace: Inside main function" << endl;
#endif
#if 0
/* This is commented part */
cout << MKSTR(HELLO C++) << endl;
#endif
cout <<"The minimum is " << MIN(i, j) << endl;
#ifdef DEBUG
cerr <<"Trace: Coming out of main function" << endl;
#endif
return 0;
}
如果我们编译并运行上述代码,这将产生以下结果:
If we compile and run above code, this would produce the following result −
The minimum is 30
Trace: Inside main function
Trace: Coming out of main function
和 # 预处理器运算符可在 C++ 和 ANSI/ISO C 中使用。 运算符会导致替换文本标记被转换为一个字符串(由引号包围)。
The # and ## preprocessor operators are available in C++ and ANSI/ISO C. The # operator causes a replacement-text token to be converted to a string surrounded by quotes.
考虑以下宏定义 −
Consider the following macro definition −
#include <iostream>
using namespace std;
#define MKSTR( x ) #x
int main () {
cout << MKSTR(HELLO C++) << endl;
return 0;
}
如果我们编译并运行上述代码,这将产生以下结果:
If we compile and run above code, this would produce the following result −
HELLO C++
我们来看看它如何工作的。很容易理解,C++ 预处理器会转换 −
Let us see how it worked. It is simple to understand that the C++ preprocessor turns the line −
cout << MKSTR(HELLO C++) << endl;
上述行将被转换成以下行 −
Above line will be turned into the following line −
cout << "HELLO C++" << endl;
运算符用于连接两个标记。这里有一个示例 −
The ## operator is used to concatenate two tokens. Here is an example −
#define CONCAT( x, y ) x ## y
当 CONCAT 出现在程序中时,它的自变量是连接起来的,并且用于替换宏。例如,在程序中,CONCAT(HELLO, C) 被替换为“HELLO C”,如下所示。
When CONCAT appears in the program, its arguments are concatenated and used to replace the macro. For example, CONCAT(HELLO, C) is replaced by "HELLO C" in the program as follows.
#include <iostream>
using namespace std;
#define concat(a, b) a ## b
int main() {
int xy = 100;
cout << concat(x, y);
return 0;
}
如果我们编译并运行上述代码,这将产生以下结果:
If we compile and run above code, this would produce the following result −
100
我们来看看它是如何工作的。很容易理解,C++ 预处理器会变换 −
Let us see how it worked. It is simple to understand that the C++ preprocessor transforms −
cout << concat(x, y);
上述行将被转换成本行 −
Above line will be transformed into the following line −
cout << xy;
Predefined C++ Macros
C++ 提供了许多预定义的宏,如下所示 −
C++ provides a number of predefined macros mentioned below −
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. |
我们来看一下上述所有宏的一个示例 −
Let us see an example for all the above macros −
#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;
}
如果我们编译并运行上述代码,这将产生以下结果:
If we compile and run above code, this would produce the following result −
Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48