C++ 预处理器
#define 预处理
#define 预处理指令用于创建符号常量。该符号常量通常称为宏,指令的一般形式是:#define macro-name replacement-text
当这一行代码出现在一个文件中时,在该文件中后续出现的所有宏都将会在程序编译之前被替换为 replacement-text。
# 和 ## 运算符
# 运算符会把 replacement-text 令牌转换为用引号引起来的字符串。
在 C 语言的预处理阶段,`#define` 指令用于定义宏。宏是一种符号常量,用于在代码中使用更具可读性的名称代替特定的值或代码段。`#define` 指令的一般形式如下:
```c
#define macro-name replacement-text
```
其中,`macro-name` 是宏的名称,`replacement-text` 是宏的替换文本。编译器在预处理阶段会用 `replacement-text` 替换所有出现的 `macro-name`。
### 理解 `#` 运算符
在宏定义中,`#` 运算符有一个特殊用途,它可以将宏参数转换为字符串文字。这个过程称为字符串化(stringizing)。使用 `#` 运算符可以将一个宏参数转换成带引号的字符串。
例如,考虑以下宏定义:
```c
#define TO_STRING(x) #x
```
这里,`#x` 将宏参数 `x` 转换为字符串。例如,如果我们使用 `TO_STRING(123)`, 宏将展开为 `"123"`。
### 示例代码
下面是一个简单的例子,演示如何使用 `#` 运算符将宏参数转换为字符串:
```c
#include <stdio.h>
#define TO_STRING(x) #x
int main() {
int number = 100;
// 使用 TO_STRING 宏将 number 转换为字符串 "number"
printf("The macro argument as a string: %s\n", TO_STRING(number));
// 使用 TO_STRING 宏将 123 转换为字符串 "123"
printf("The macro argument as a string: %s\n", TO_STRING(123));
return 0;
}
```
输出结果将是:
```
The macro argument as a string: number
The macro argument as a string: 123
```
在这个例子中,`TO_STRING(number)` 被展开为 `"number"`,而 `TO_STRING(123)` 被展开为 `"123"`。这表明 `#` 运算符将宏参数转换为用引号引起来的字符串。
### 应用场景
这种字符串化操作在很多场景中非常有用。例如:
1. **生成调试信息**:将变量名转换为字符串,以便在调试输出中使用。
2. **构建错误消息**:生成包含宏参数名称的错误信息。
3. **代码生成**:在宏中生成特定格式的代码字符串。
### 总结
`#` 运算符在宏定义中用于将宏参数转换为字符串文字。这种特性提供了强大的工具,可以在编写更具适应性的和可维护性的代码时灵活地生成字符串。
## 运算符用于连接两个令牌。下面是一个实例:
#define CONCAT( x, y ) x ## y
当 CONCAT 出现在程序中时,它的参数会被连接起来,并用来取代宏。例如,程序中 CONCAT(HELLO, C++) 会被替换为 "HELLO 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;

浙公网安备 33010602011771号