首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言可變參數列表 實作:va_list、va_start、va_arg、va_end 完整教學

     編輯:關於C

核心 API (<stdarg.h>)

  • va_list ap;:參數列表游標。
  • va_start(ap, last_fixed_param);:初始化,從最後一個固定參數開始。
  • va_arg(ap, type);:提取下一個參數,**必須知道型別**。
  • va_end(ap);:清理 (某些平台需釋放棧空間)。

範例一:計算平均值

#include 
double average(int count, ...) {
    va_list ap;
    va_start(ap, count);
    double sum = 0;
    for (int i = 0; i < count; i++)
        sum += va_arg(ap, int); // 假設皆為 int
    va_end(ap);
    return sum / count;
}
int main() {
    printf("%.2f\n", average(6, 1,2,3,4,5,6)); // 3.50
    return 0;
}

範例二:多字串連接 (類 strcat 多參數版)

void nstrcat(char *dest, ...) {
    va_list ap;
    va_start(ap, dest);
    const char *s;
    while ((s = va_arg(ap, const char *)) != NULL) { // 以 NULL 結束
        while (*dest) dest++; // 移到末尾
        while ((*dest++ = *s++)); // 複製含 \0
        dest--; // 退回 \0 位置,供下一輪接續
    }
    va_end(ap);
}
int main() {
    char buf[100] = "";
    nstrcat(buf, "Hello", " ", "World", "!", NULL);
    puts(buf); // Hello World!
    return 0;
}

關鍵注意事項

  1. 型別安全全靠程式設計師:va_arg(ap, int) 傳 double → UB。
  2. 無法獲知參數個數/型別:需約定 (如首參數 count、格式字串、哨兵 NULL)。
  3. 預設引數提升:float → double,char/short → int。提取時用提升後型別。
  4. C23 va_copy:複製 va_list 供二次遍歷。

printf 族函數原理

解析格式字串 %d %s %f 決定 va_arg 型別與次數,這是可變參數的標準用法模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved