宏定义中的##操作符和... and _ _VA_ARGS_ _

本文详细介绍了C语言中预处理宏的两个重要特性:##操作符用于连接两个符号成为一个新的标识符,以及...and__VA_ARGS__用于创建变参宏的方法。通过具体的代码示例展示了如何利用这些特性实现字符串拼接及变量参数列表的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

宏定义中的##操作符和... and _ _VA_ARGS_ _

1.Preprocessor Glue: The ## Operator

预处理连接符:##操作符

Like the # operator, the ## operator can be used in the replacement section of a function-like macro.Additionally, it can be used in the replacement section of an object-like macro. The ## operator combines two tokens into a single token.

##将两个符号连接成一个。

For example, you could do this:

#define XNAME(n) x ## n

Then the macro

XNAME(4)

would expand to the following:

x4

Listing 1 uses this and another macro using ## to do a bit of token gluing.


// glue.c -- use the ## operator

#include

#define XNAME(n) x ## n

#define PRINT_XN(n) printf("x" #n " = %d\n", x ## n);

int main(void)

{

int XNAME(1) = 14; // becomes int x1 = 14;

int XNAME(2) = 20; // becomes int x2 = 20;

PRINT_XN(1);        // becomes printf("x1 = %d\n", x1);

PRINT_XN(2);        // becomes printf("x2 = %d\n", x2);

    return 0;

}

Here's the output:

x1 = 14

x2 = 20

Note how the PRINT_XN() macro uses the # operator to combine strings and the ## operator to combine tokens into a new identifier.


2.Variadic Macros: ... and _ _VA_ARGS_ _

Some functions, such as printf(), accept a variable number of arguments. The stdvar.h header file,provides tools for creating user-defined functions with a variable number of arguments. And C99 does the same thing for macros.Although not used in the standard, the word variadic has come into currency to label this facility. (However, the process that has added stringizing and variadic to the C vocabulary has not yet led to labeling functions or macros with a fixed number of arguments as fixadic functions and normadic macros.)

The idea is that the final argument in an argument list for a macro definition can be ellipses (that is, three periods)(省略号). If so, the predefined macro _ _VA_ARGS_ _ can be used in the substitution part to indicate what will be substituted for the ellipses. For example, consider this definition:

#define PR(...) printf(_ _VA_ARGS_ _)

Suppose you later invoke the macro like this:

PR("Howdy");

PR("weight = %d, shipping = $%.2f\n", wt, sp);

For the first invocation, _ _VA_ARGS_ _ expands to one argument:

"Howdy"

For the second invocation, it expands to three arguments:

"weight = %d, shipping = $%.2f\n", wt, sp

Thus, the resulting code is this:

printf("Howdy");

printf("weight = %d, shipping = $%.2f\n", wt, sp);

Listing 2 shows a slightly more ambitious example that uses string concatenation and the # operator:


// variadic.c -- variadic macros

#include

#include

#define PR(X, ...) printf("Message" #X ": " _ _VA_ARGS_ _)

int main(void)

{

    double x = 48;

    double y;

    y = sqrt(x);

    PR(1, "x = %g\n", x);

    PR(2, "x = %.2f, y = %.4f\n", x, y);

    return 0;

}

In the first macro call, X has the value 1, so #X becomes "1". That makes the expansion look like this:

(#为参数加双引号。)

print("Message " "1" ": " "x = %g\n", x);

Then the four strings are concatenated, reducing the call to this:

print("Message 1: x = %g\n", x);

Here's the output:

Message 1: x = 48

Message 2: x = 48.00, y = 6.9282

Don't forget, the ellipses have to be the last macro argument:

#define WRONG(X, ..., Y) #X #_ _VA_ARGS_ _ #y(这个是错误的例子。)

阅读(416) | 评论(0) | 转发(0) |
评论热议
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值