C語言不定引數個數,可變引數函式使用學習
阿新 • • 發佈:2019-01-30
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; }
執行結果: