当前位置:嗨网首页>书籍在线阅读

09-变参宏_...和_ _VA_ARGS_ _

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

16.3.3 变参宏: ..._ _VA_ARGS_ _

一些函数(如 printf() )接受数量可变的参数。 stdvar.h 头文件(本章后面介绍)提供了工具,让用户自定义带可变参数的函数。C99/C11也对宏提供了这样的工具。虽然标准中未使用“可变”(variadic)这个词,但是它已成为描述这种工具的通用词(虽然,C标准的索引添加了字符串化(stringizing)词条,但是,标准并未把固定参数的函数或宏称为固定函数和不变宏)。

通过把宏参数列表中最后的参数写成省略号(即,3个点 ... )来实现这一功能。这样,预定义宏

_ _VA_ARGS_ _ 可用在替换部分中,表明省略号代表什么。例如,下面的定义:

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

假设稍后调用该宏:

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

对于第1次调用, _ _VA_ARGS_ _ 展开为1个参数: "Howdy"

对于第2次调用, _ _VA_ARGS_ _ 展开为3个参数: "weight = %d, shipping = $%.2f\n"wtsp

因此,展开后的代码是:

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

程序清单16.5演示了一个示例,该程序使用了字符串的串联功能和#运算符。

程序清单16.5  variadic.c 程序

// variadic.c -- 变参宏
#include <stdio.h>
#include <math.h>
#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;
}

第1个宏调用, X 的值是 1 ,所以 #X 变成 "1" 。展开后成为:

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

然后,串联4个字符,把调用简化为:

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

下面是该程序的输出:

Message 1: x = 48
Message 2: x = 48.00, y = 6.9282

记住,省略号只能代替最后的宏参数:

#define WRONG(X, ..., Y) #X #_ _VA_ARGS_ _ #y //不能这样做