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

C語言可變參數函數實現指南:va_list/va_start/va_arg/va_end 完整詳解

     編輯:關於C語言

C語言可變參數函數實現指南:va_list/va_start/va_arg/va_end 完整詳解

C 語言通過棧傳遞參數(右至左入棧),<stdarg.h> 提供標準宏訪問可變參數列表。

核心宏與原理

示例 1:求 N 個數之和

int sum(int count, ...) {
    int s = 0; va_list ap;
    va_start(ap, count);
    for (int i = 0; i < count; ++i)
        s += va_arg(ap, int);
    va_end(ap);
    return sum;
}
// 調用:sum(5, 1,2,3,4,5) → 15

示例 2:標準庫可變參數函數族

void test(int count, ...) {
    va_list ap; va_start(ap, count);
    vprintf("%d,%d,%d\n", ap);           // 格式化輸出
    char buf[1024];
    vsprintf(buf, "a=%d,b=%d,c=%d\n", ap); // 格式化到緩衝區
    vfprintf(stdout, "a=%d,b=%d,c=%d\n", ap); // 輸出到流
    vsscanf("10,30,40", "%d,%d,%d", ap);   // 從字符串掃描到可變參數地址
    vsnprintf(buf, 30, "a=%d,b=%d,c=%d", ap); // 限長格式化
    va_end(ap);
}

關鍵注意點

  • **類型一致性**:va_arg 類型必須與實際參數類型完全匹配(含符號、寬度),否則 UB。
  • **參數個數**:需約定機制(如首參數計數、哨兵值、格式字符串)告知函數何時停止。
  • **棧帧佈局**:參數右至左入棧,va_start 以最後固定參數地址為基準計算偏移。
  • **可移植性**:va_list 在某些架構(如 x86_64)是結構體而非指針,不可假設為指針操作。

掌握 stdarg.h 是實現 printf、日志庫、腳本綁定等基礎設施的前提。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
宏作用參數
va_list聲明參數列表指針不透明類型(通常 char*)
va_start(ap, last)初始化 ap 指向第一個可變參數last 為最後一個固定參數名
va_arg(ap, type)取出當前參數並按 type 大小移動指針需知參數類型
va_end(ap)清理(某架構調整棧指針)必須成對調用