变长参数的函数及宏
函数
#include <string.h>
#include<stdarg.h>
int max(int num, int b...)
{
va_list ap; //A
int maxf,temp;
va_start(ap,b);//B
maxf=b;
cout <<b <<endl;
for(int i=1;i<num;i++) {
temp=va_arg(ap,int); //C
cout<<temp<<'\n';
if(maxf<temp)
maxf=temp;
}
va_end(ap); //D
return maxf;
}
void string_var(char * str, ...) {
strcmp("1", "2");
va_list vargs;
char *strValue = str;
int nArgCount = 0;
va_start(vargs, str);
do {
cout << "Count:" << nArgCount << " strValue:" << strValue << endl;
strValue = va_arg(vargs, char *);
strcmp("1", "2");
if (sizeof(strValue) == 0)
break;
++nArgCount;
} while (1);
va_end(vargs);
}
宏
#define MAX(num,...)\
max(num,__VA_ARGS__);
调用
cout << max(3, 11, 22, 44) << endl;
cout << MAX(3, 11, 22, 44);
string_var("abd", "dffd", "xxx");
相关宏
void va_start ( va_list arg_ptr, prev_param ); /* ANSI version */
type va_arg ( va_list arg_ptr, type );
void va_end ( va_list arg_ptr );
在这些宏中,va就是variable argument(可变参数)的意思;arg_ptr是指向可变参数表的指针;prev_param则指可变参数表的前一个固定参数;type为可变参数的类型。va_list也是一个宏,其定义为typedef char * va_list,实质上是一char型指针。char型指针的特点是++、--操作对其作用的结果是增1和减1(因为sizeof(char)为1),与之不同的是int等其它类型指针的++、--操作对其作用的结果是增sizeof(type)或减sizeof(type),而且sizeof(type)大于1。
通过va_start宏我们可以取得可变参数表的首指针,这个宏的定义为:
#define va_start ( ap, v ) ( ap = (va_list)&v + _INTSIZEOF(v) ) |
显而易见,其含义为将最后那个固定参数的地址加上可变参数对其的偏移后赋值给ap,这样ap就是可变参数表的首地址。其中的_INTSIZEOF宏定义为:
#define _INTSIZEOF(n) ((sizeof ( n ) + sizeof ( int ) - 1 ) & ~( sizeof( int ) - 1 ) ) |
va_arg宏的意思则指取出当前arg_ptr所指的可变参数并将ap指针指向下一可变参数,其原型为:
#define va_arg(list, mode) ((mode *)(list =\ (char *) ((((int)list + (__builtin_alignof(mode)<=4?3:7)) &\ (__builtin_alignof(mode)<=4?-4:-8))+sizeof(mode))))[-1] |
而va_end宏被用来结束可变参数的获取,其定义为:
#define va_end ( list ) |
可以看出,va_end ( list )实际上被定义为空,没有任何真实对应的代码,用于代码对称,与va_start对应;另外,它还可能发挥代码的"自注释"作用。所谓代码的"自注释",指的是代码能自己注释自己。