C++傳遞不定參函數


定義不定參數函數,要用到下面這些宏:

  • va_start(ap, farg): 初始化一個va_list變量ap,farg是第一個形參
  • va_arg(ap, type): 獲取(下)一個type類型的參數
  • va_end(ap): 結束使用ap

C語言里編寫不定參數函數的形式是這樣的:

#include <stdarg.h>
int sum(int cnt,...) {
    int sum = 0;
    int i;
    va_list ap;
    va_start(ap, cnt);
    for(i = 0; i < cnt; ++i)
        sum += va_arg(ap, int);
    va_end(ap);
    return sum;
}

定義不定參數函數,要用到下面這些宏:

  • va_start(ap, farg): 初始化一個va_list變量ap,farg是第一個形參
  • va_arg(ap, type): 獲取(下)一個type類型的參數
  • va_copy(ap): 用於復制參數列表
  • va_end(ap): 結束使用ap
    這些宏定義一般在stdarg.h里。
typedef char * va_list;
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1)  )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v)  )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))  )
#define va_end(ap) ( ap = (va_list)0 )

注意: 上面這些宏定義會因不同的系統和不同的處理器架構而不同

_INTSIZEOF宏

_INTSIZEOF這個宏的位運算意義比較難理解,乍一看以為是表示多少個int型的長度,其實它運算出來的結果是按照int型對齊后的長度。比如int型為4個字節,_INTSIZEOF(1)、_INTSIZEOF(2)、_INTSIZEOF(3)、_INTSIZEOF(4)的結果都是4,_INTSIZEOF(5)、_INTSIZEOF(6)、_INTSIZEOF(7)、_INTSIZEOF(8)的結果都是8,這正是x86架構CPU下的參數傳遞方式,32位即4字節對齊。

幾個注意事項

  • 不定參數的函數至少要有一個固定的參數,因為要用它來初始化va_list,比如上面代碼中sum函數的cnt參數,同時它也表明了傳遞的參數的個數。

常用方式

不定參數函數最常用來格式化字符串,一個比較常見的場景是我們想輸出一些log消息,但又不能直接在控制台輸出,需要自己寫一個log函數來格式化log消息並輸出。這時我們可以用vsprintf函數:

void log(const char *format, ...) {
    char buf[MAX_BUF_SIZE];
    va_list ap;
    va_start(ap, format);
    vsprintf(buf, format, ap);
    OUTPUT(buf);
}

vsprintf函數的前兩個參數和sprintf的前兩個參數意義相同,只不過后面的不定參換成了va_list類型的參數列表,這正是讓我們用來定義自己的格式化函數的。

附:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM