宏的可变参数(variadic macros)
#include <stdarg.h>
#define yourmacro(...) aa(__VA_ARGS__);
在调试程序的时候,通常会添加
#ifdef _DEBUG
//Debug_printf(参数);
#endif
在每一处调试的地方都需要添加这种宏会很麻烦,为了使系统更加简单,此时可以考虑使用可变参数的宏对其进行简化。如下所示:
在调试程序中,可以使用如下:
#ifdef _DEBUG
#define DEBUG(...) Debug_print(__VA_ARGS__);
#else
#define DEBUG(...)
#endif
此时在需要调试的地方直接添加如下语句即可。
DEBUG(参数);
函数的可变参数使用的步骤:
1. 在函数的原型中采用“...";
2. 函数的定义中采用va_list类型的变量;
3. 利用宏初始化参数列表va_start(va_list ap, parmN);
4. 利用宏访问参数列表va_arg(va_list ap, type);
5. 利用宏清除va_end(va_list ap)。
使用的数据有如下几类:
1. va_list: 用于存放可变参数的信息
2. void va_start(va_list ap, parmN);
//这个宏用在va_arg()以及va_end()之前用于初始化va_list ap;parmN是可变参数函数的参数表中“..."前的第一个参数。
3. void va_copy(va_list dest, va_list src);
//this macro initializes dest as a copy of the current state of src. (C99).由于va_arg对参数表的访问是单向的,不能返回。所以当需要返回的时候,此时可以采用复制va_list的方法。
4. type va_arg(va_list ap, type);
3. void va_copy(va_list dest, va_list src);
//this macro initializes dest as a copy of the current state of src. (C99).由于va_arg对参数表的访问是单向的,不能返回。所以当需要返回的时候,此时可以采用复制va_list的方法。
4. type va_arg(va_list ap, type);
//这宏用于获取va_list中的参数。type是这个参数的类型。每次调用后,都指向了va_list ap中下一个参数的值。
5. void va_end(va_list ap);
5. void va_end(va_list ap);
//这个宏关闭了这个过程,并使得ap不能再被使用了。
这些数据在stdargs.h中有定义,以_builtin开头的参数是编译器可以识别的数据或函数。
函数的原型:
这些数据在stdargs.h中有定义,以_builtin开头的参数是编译器可以识别的数据或函数。
//stdargs.h-------va_list/va_start/va_end/va_arg/va_copy的定义。 typedef __builtin_va_list __gnuc_va_list; #ifndef __va_list__ typedef __gnuc_va_list va_list; #endif /* not __va_list__ */ #ifdef _STDARG_H #define va_start(v,l) __builtin_va_start(v,l) #define va_end(v) __builtin_va_end(v) #define va_arg(v,l) __builtin_va_arg(v,l) #if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L || defined(__GXX_EXPERIMENTAL_CXX0X__) #define va_copy(d,s) __builtin_va_copy(d,s) #endif #define __va_copy(d,s) __builtin_va_copy(d,s) |
函数的原型:
1. 用“..."表示可变参数;
2. “..."必须位于参数表的最后;
3. "..."前至少有一个参数,最靠近“..."的参数称为parmN.
函数的原型举例:
void f1(int n, ...);
int f2(const char *s, int k, ...);
char f3(char c1, ..., char c2); // invalid
double f3(...); // invalid
函数的实现举例定义
int
__printf (const char *format, ...)
{
va_list arg;
int done;
va_start (arg, format); // 两个参数; 一个为va_start;另一个为 parmN;
done = vfprintf (stdout, format, arg);
va_end (arg);
return done;
}
函数的原型举例:
void f1(int n, ...);
int f2(const char *s, int k, ...);
char f3(char c1, ..., char c2); // invalid
double f3(...); // invalid
函数的实现举例定义
int
__printf (const char *format, ...)
{
va_list arg;
int done;
va_start (arg, format); // 两个参数; 一个为va_start;另一个为 parmN;
done = vfprintf (stdout, format, arg);
va_end (arg);
return done;
}
举例2
#include <stdio.h>
#include <stdarg.h>
double sum(int, ...);
int main(void)
{
double s,t;
s = sum(3, 1.1, 2.5, 13.3);
return 0;
}
double sum(int lim, ...)
{
va_list ap;
double tot = 0;
int i;
va_start(ap, lim);
for(i=0; i < lim, i++)
tot += va_arg(ap,double);
va_end(ap);
}
|