va_list:參數列表指針類型;va_start(ap, last_fixed):初始化,last_fixed 為最後一個固定參數;va_arg(ap, type):按類型取出下一個參數,移動指針;va_end(ap):清理,必須成對調用。#include <stdio.h>
#include <stdarg.h>
float average(int n, ...) {
va_list ap;
va_start(ap, n);
float sum = 0;
for (int i = 0; i < n; ++i)
sum += va_arg(ap, int); // 假設均為 int
va_end(ap);
return sum / n;
}
int main() {
printf("%.2f\n", average(6, 1,2,3,4,5,6)); // 3.50
return 0;
}
void nstrcpy(char *dest, ...) {
va_list ap;
va_start(ap, dest);
char *p;
while ((p = va_arg(ap, char*)) != NULL) { // 以 NULL 結束
strcpy(dest, p);
dest += strlen(p);
}
va_end(ap);
}
int main() {
char buf[100];
nstrcpy(buf, "Hello", " ", "World", "!", NULL);
puts(buf); // Hello World!
return 0;
}
va_arg 不檢查類型,調用者必須保證實參類型與取參類型一致,否則未定義行為;float→double、char/short→int,取參時用提升後類型;va_start/arg/end 順序,不可在兩個 va_list 間跳轉。參數在棧上連續分佈,va_start 計算首個可變參數地址,va_arg 按類型大小遞增指針並解引用。編譯器處理棧幀佈局差異(如寄存器傳參),故必須用標準宏。