stdarg.h提供了三個宏,書寫可變參數函數可以用到
void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
上面宏的字首va表示variable argument,即可變參數的意思。變量ap專門用來記錄擷取可變參數。下面依次介紹三個宏的意義和用法。
void va_start( va_list ap, last)
last為函數形參中"..."前的最後一個形參名字,宏va_start用于根據last的位置(或指針)來初始化變量ap,以供宏ar_arg來依次獲得可變參數的值。變量ap在被va_arg或va_end使用前,必須使用va_start初始化。
type va_arg(va_list ap, type)
va_arg宏用來獲得下一個參數的值,type為該參數的類型,它的參數ap必須被va_start初始化,通過該宏後,傳回參數值并使用ap指向下一個參數,以供va_arg再次使用。如果沒有下一個參數時調用va_arg或arg指定的類型不相容時,會産生可知的錯誤。
void va_end(va_list ap)
宏va_end與va_start必須要同一函數裡面對稱使用,調用va_start(ap,last)後ap得到初始化,在完成參數處理後,需要調用va_end(ap)來“釋放”ap。
簡單示例:
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
void mySprintf(char *str, const char *p, ...)
{
char *s;
int i,count=0;
char number[129]={0};
va_list valist;//申請參數清單變量
va_start(valist, p);//設定開始變量為傳過來的參數p
str[0] = 0;
while(*p != '\0')
{
switch(*p)
{
case 's':
s = va_arg(valist, char*);//假設一進入就遇到s,va_arg(valist, char*)擷取下一個參數是沒有問題的,因為需要的就是下一個,而不是目前的參數
strcat(str, s);
break;
case 'd':
i = va_arg(valist, int);//擷取下一個參數,變量類型在這裡是确定的(自己指定的)
strcat(str, itoa(i, number, 10));
break;
default:
while(str[count] != '\0')count++;
str[count] = *p;
count = 0;
break;
}
p++;
}
va_end(valist);//“釋放”valist
}
int main()
{
int a=12345;
char *p = "abcdef";
char str[100]={0};
mySprintf(str, "p+a=sd", p, a);
printf("%s\n", str);
return 0;
}
運作結果:
更多内容,參考資料:http://blog.csdn.net/hanchaoman/article/details/4153731