linux C 可變引數型別va_list
阿新 • • 發佈:2022-04-02
目錄
可變函式引數,會用到va_list系列巨集,在C中用於定義可變引數列表,包含可變引數資訊。
常用的va_list系列巨集
包含:
- va_start(ap, last)巨集:初始化可變引數列表;
- va_arg(ap, type)巨集:返回下一個引數;
- va_copy(dest, src)巨集:複製引數列表指標,將dest初始化為src;
- va_end(ap)巨集:結束使用可變引數列表,會清空引數列表,置引數ap無效;
其宣告如下:
#include <stdarg.h> void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_end(va_list ap); void va_copy(va_list dest, va_list src);
例如,我們常用的C庫函式printf,就用到了可變引數列表
#include <stdio.h>
int printf(const char *format, ...);
形參列表裡的 "..."代表0個或多個引數。
將可變引數由“...”轉換為va_list型別形式,
#include <stdarg.h>
int vprintf(const char *format, va_list ap);
va_list系列巨集使用模式
對於自定義可變引數列表的函式,可用va_list系列巨集,按如下模式對可變引數進行解析:
void func(type v, ...) { va_list(ap, v); // 定義一個指向個數可變的引數列表指標 va_start(ap, v); // 使指標ap指向函式引數列表的第一個可選引數,v是第一個可選引數之前的固定引數 while () { type tmp = va_arg(ap, type); // 返回引數列表中指標ap所指的引數,返回型別為type,並使指標ap指向下一個引數 } va_end(ap); // 清空引數列表,並置引數列表指標ap無效 }
例1:定義一個可變引數的求和函式
int sum(int v, ...) { int i = v; int s = 0; va_list ap; va_start(ap, v); while (i > 0) { s += va_arg(ap, int); i--; } // { volatile int tmp = va_arg(ap, int); // tmp是未知值 printf("tmp = %d\n", tmp); // } 用於測試 va_end(ap); return s; }
呼叫:
int main()
{
int s = sum(3,2,3,4);
printf("sum = %d\n", s);
return 0;
}
執行結果:
tmp = -1392657952
sum = 9
例2:定義一個自定義列印字串函式
void my_print(const char *fmt, ...)
{
char *s = fmt;
va_list ap;
va_start(ap, fmt);
while (s != NULL) {
printf("%s\n", s);
s = va_arg(ap, char *);
}
va_end(ap);
}
呼叫:
int main()
{
my_print("hello", "yes", "no");
return 0;
}
執行結果:
hello
yes
no