可變參函數的經典應用場景之一是不定數量同類型參數的聚合運算。本文實現一個通用的 add(int count, ...) 函數,接收第一個參數為後續參數個數,返回所有 int 參數的累加和。代碼簡潔,完美展示 stdarg.h 標準宏的使用範式。
#include#include int add(int count, ...) { va_list ap; va_start(ap, count); // 以 count 為定位參數 int sum = 0; for (int i = 0; i < count; i++) { sum += va_arg(ap, int); // 依次取出 int 參數並累加 } va_end(ap); // 必須調用,清理資源 return sum; } int main() { printf("%d\n", add(3, 5, 5, 6)); // 16 printf("%d\n", add(10, 1,2,3,4,5,6,7,8,9,10)); // 55 return 0; }
16 55
count 之後的第一個可變參。int 類型讀取並推進游標。注意:傳入 short/char 會提升為 int,取值仍用 int;傳入 float 提升為 double,取值需用 double。double add_double(int count, ...) {
va_list ap;
va_start(ap, count);
double sum = 0.0;
for (int i = 0; i < count; i++) {
sum += va_arg(ap, double); // float 會提升為 double
}
va_end(ap);
return sum;
}
log_printf(level, fmt, ...)max(count, ...), min(count, ...), avg(count, ...)set_multiple(obj, count, field1, val1, field2, val2, ...)assert_all(count, cond1, cond2, ...)| 錯誤寫法 | 後果 | 正確寫法 |
|---|---|---|
va_arg(ap, char) | 讀取錯誤位寬,後續參數錯位 | va_arg(ap, int) 後轉型 |
va_arg(ap, float) | 讀取 4 字節實為 8 字節 double | va_arg(ap, double) |
漏調 va_end | 部分平台棧損壞/內存洩漏 | 必須成對調用 |
count 與實際參數不符 | 越界讀取,未定義行為 | 調用端嚴格保證一致 |
add(count, ...) 是可變參函數最純粹的教學示例。掌握其「計數定位 + 循環取值 + 資源清理」三步範式,即可舉一反三實現各類聚合運算函數。