define#
可变参数宏#
含义:
__VA_ARGS__
是一个在宏中用来表示可变参数的标识符。它允许在宏中使用可变数量的参数。用法:
__VA_ARGS__
被用在宏定义中,用于表示可变参数的位置。示例:
#include <cstdio>
#define PRINT_VALUES(...) printf(__VA_ARGS__)
int main() {
PRINT_VALUES("Sum: %d\n", 10 + 20);
PRINT_VALUES("Product: %d\n", 5 * 6);
return 0;
}
含义:
#__VA_ARGS__
是字符串化运算符,用于将可变参数转换为字符串。用法:
#
运算符用于将宏参数转换为字符串。示例:
#include <cstdio>
#define SHOW_VALUES(...) puts(#__VA_ARGS__)
int main() {
SHOW_VALUES(1, "x", int); // 展开成 puts("1, \"x\", int")
return 0;
}
含义:
##
运算符用于在宏中连接两个标识符。##__VA_ARGS__
用于处理可变参数的连接问题。用法:
##
用于在宏中连接可变参数和其他标识符。示例:
#include <cstdio>
#define CONCATENATE(a, b) a##b
int main() {
int xy = CONCATENATE(10, 20); // 展开成 int xy = 1020;
printf("%d", xy);
return 0;
}
含义:
__VA_OPT__
是一个在可变参数宏中用于处理可选参数的特殊宏。用法:
__VA_OPT__(...)
表示可选参数,若__VA_ARGS__
非空,则插入括号内的内容;否则,将其忽略。示例:
#include <cstdio>
#define LOG_MSG(fmt, ...) printf(fmt __VA_OPT__(, ) __VA_ARGS__)
int main() {
LOG_MSG("Sum: %d, %d\n", 10 + 20, 40); // 展开成 printf("Sum: %d, %d\n", 10 + 20, 40);
LOG_MSG("Hello, World!\n"); // 展开成 printf("Hello, World!\n");
return 0;
}
#include <iostream>
// 制造函数工厂并使用它
#define FUNCTION(name, a) \
int fun_##name() { \
return a; \
}
FUNCTION(, 100)
FUNCTION(abcd, 12)
FUNCTION(fff, 2)
FUNCTION(qqq, 23)
#undef FUNCTION
#define FUNCTION 34
#define OUTPUT(a) std::cout << "output: " #a << '\n'
// 在后面的宏定义中使用之前的宏
#define WORD "Hello "
#define OUTER(...) WORD #__VA_ARGS__
int main() {
std::cout << "" << fun_() << '\n';
std::cout << "abcd: " << fun_abcd() << '\n';
std::cout << "fff: " << fun_fff() << '\n';
std::cout << "qqq: " << fun_qqq() << '\n';
std::cout << FUNCTION << '\n';
OUTPUT(million); // 注意这里没有引号
std::cout << OUTER(World) << '\n';
std::cout << OUTER(WORD World) << '\n';
}
/**
* 100
* abcd: 12
* fff: 2
* qqq: 23
* 34
* output: million
* Hello World
* Hello WORD World
*/
定义一个函数#
如果我们想要定义一个函数,比如 MAX(a, b)
,直接使用 #define
会出现问题。因为 #define
只是简单的文本替换,它不能理解 C 语言的语法。例如,下面的代码会导致编译错误:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
这是因为预处理器会把这段代码替换为:
((a) > (b) ? (a) : (b))
这显然不是一个有效的 C 语言函数定义。
为了解决这个问题,C 语言引入了 do { ... } while(0)
结构。这个结构的意思是执行 { ... }
中的代码,然后检查 while(0)
的条件是否成立。由于 while(0)
的条件永远不成立,所以这个结构可以用来定义一个多行的宏。这样,我们就可以定义一个函数了:
#define MAX(a, b) \
do { \
if ((a) > (b)) \
return (a); \
else \
return (b); \
} while (0)
这样,预处理器就会把这段代码替换为:
if ((a) > (b))
return (a);
else
return (b);
这就是一个有效的 C 语言函数定义了。