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

C 語言可變參數列表:stdarg.h 宏機制與實戰案例

     編輯:關於C

核心宏與類型

  • 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;
}

關鍵注意點

  1. 類型安全:va_arg 不檢查類型,調用者必須保證實參類型與取參類型一致,否則未定義行為;
  2. 參數個數:需約定傳遞方式(如首參計數、哨兵值 NULL、格式字符串);
  3. 默認參數提升:float→double、char/short→int,取參時用提升後類型;
  4. 可移植性:嚴格遵循 va_start/arg/end 順序,不可在兩個 va_list 間跳轉。

原理簡析

參數在棧上連續分佈,va_start 計算首個可變參數地址,va_arg 按類型大小遞增指針並解引用。編譯器處理棧幀佈局差異(如寄存器傳參),故必須用標準宏。

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