宏概述
-
在编程中,宏(Macro)是一种预处理器指令
-
宏可以让程序员在源代码中定义一段值或代码的别名,在编译程序之前,预处理器会查找这些宏,并将其替换为相应的值或代码
C++ 宏
-
在 C++ 中,宏可以通过预处理器指令
#define
来定义 -
宏可以是简单的常量替换,也可以函数样式的宏(函数样式的宏并不是真正的函数)
-
宏通常全大写以区别于变量
-
可以使用反斜杠(
\
)实现多行宏
一、简单常量替换宏
#include <iostream>
using namespace std;
#define PI 3.14159
int main() {
cout << PI << endl;
double radius = 5.0;
double area = PI * radius * radius;
cout << area << endl;
return 0;
}
- 输出结果
3.14159
78.5397
二、函数样式的宏
#include <iostream>
using namespace std;
// 使用反斜杠(\)实现多行宏
#define CALCULATE_MAXIMUM_1(firstNumber, secondNumber) \
((firstNumber > secondNumber) ? firstNumber : secondNumber)
#define CALCULATE_MAXIMUM_2(firstNumber, secondNumber) ((firstNumber > secondNumber) ? firstNumber : secondNumber)
int main() {
int a = 5, b = 10;
int result1 = CALCULATE_MAXIMUM_1(a, b);
int result2 = CALCULATE_MAXIMUM_2(a, b);
cout << result1 << endl;
cout << result2 << endl;
return 0;
}
- 输出结果
10
10
三、多行宏
#include <stdio.h>
// 使用反斜杠(\)实现多行宏
#define PRINT_SUM(a, b) \
printf("%d + %d = ", (a), (b)); \
printf("%d\n", (a)+(b))
int main() {
PRINT_SUM(3, 5);
return 0;
}
四、预定义宏
#include <stdio.h>
int main() {
printf("File: %s\n", __FILE__); // 当前文件名
printf("Line: %d\n", __LINE__); // 当前行号
printf("Date: %s\n", __DATE__); // 编译日期
printf("Time: %s\n", __TIME__); // 编译时间
return 0;
}
五、宏的特殊用法
1、字符串化宏
(1)基本介绍
#define STRINGIFY(x) #x
- 将宏参数 x 直接转换为字符串常量(在编译期展开)
(2)演示
#include <iostream>
using namespace std;
#define STRINGIFY(x) #x
int main() {
// 将变量名转为字符串
int someVar = 42;
cout << "变量名: " << STRINGIFY(someVar) << endl;
// 将表达式转为字符串
cout << "表达式: " << STRINGIFY(3 + 5 * 2) << endl;
return 0;
}
- 输出结果
变量名: someVar
表达式: 3 + 5 * 2
2、连接宏
(1)基本介绍
#define STRINGIFY(x) #x
- 将两个宏参数 a 和 b 直接拼接成一个符号(在编译期展开)
(2)演示
#include <iostream>
using namespace std;
#define CONCAT(a, b) a##b
void print_hello()
{
cout << "Hello World" << endl;
}
int main() {
// 拼接变量名
int xy = 100;
cout << CONCAT(x, y) << endl;
// 拼接函数名
CONCAT(print_, hello)();
return 0;
}
- 输出结果
100
Hello World
3、可变参数日志宏
(1)基本介绍
#define LOG(fmt, ...) printf("[LOG] " fmt "\n", ##__VA_ARGS__)
- 可变参数日志输出,支持格式化字符串
(2)关键语法解析
- 字符串字面量的自动拼接
"[LOG] " fmt "\n"
// 等价于
"[LOG] " "your_format" "\n"
// 合并后
"[LOG] your_format\n"
##__VA_ARGS__
是传入的可变参数,##
前缀用于当可变参数为空时,自动删除前面的逗号
LOG("No args");
// 展开为
printf("[LOG] " "No args" "\n",);
// 使用 ## 前缀后
printf("[LOG] " "No args" "\n");
(3)演示
#include <cstdio>
#define LOG(fmt, ...) printf("[LOG] " fmt "\n", ##__VA_ARGS__)
int main() {
int error_code = 404;
const char* path = "/index.html";
LOG("程序启动");
LOG("文件 %s 未找到,错误码: %d", path, error_code);
return 0;
}
- 输出结果
[LOG] 程序启动
[LOG] 文件 /index.html 未找到,错误码: 404