關於c 可變引數的理解

2021-06-27 10:20:32 字數 1653 閱讀 3341

最近在看cocos2dx的原始碼,發現有很多地方用到了可變引數,就是三個點,然後查了查資料,把自己的思路整理一下,希望能對看到的人有幫助。

首先三個點的值傳到了巨集__va_args__中__va_args__只能在巨集中替換可變引數,,下面舉個例子(該例子**於http://具體是那篇我忘了)

#include #include #define writeline(...) printf(__va_args__);

int main()

然後在這上面看了可變引數用的幾個低階的函式va_start、va_arg、va_copy(c++11)、va_end和va_list。在vs2013中va_list在vadefs.h就是typedef char *  va_list;這樣定義的,下面列出函式的實現

#define _crt_va_start(ap,v)  ( ap = (va_list)_addressof(v) + _intsizeof(v) )

#define _crt_va_arg(ap,t) ( *(t *)((ap += _intsizeof(t)) - _intsizeof(t)) )

#define _crt_va_end(ap) ( ap = (va_list)0 )

#define va_start _crt_va_start

#define va_arg _crt_va_arg

#define va_end _crt_va_end

然後下面上例子**(****於)

#include #include void ******_printf(const char* fmt...)

else if (*fmt == 'c') else if (*fmt == 'f')

++fmt;

}va_end(args);}

int main()

然後說說我在cocos2dx中看到的應用,例如在cocos2dx中sequence建立多個動作的時候最後乙個引數要填nullptr,原因就是可變引數作為臨時變數壓入棧中是從左往右的,然後最後乙個空指標(nullptr)就在棧底,關於sequence具體的實現我沒有看,大家有興趣自己看一下,去引數的時候可以直接用va_arg取出函式的指標,通過判斷是否為nullptr來判斷時候結束呼叫,在cocos2dx的api中我們可以看到

static sequence * 	create (m m1, std::nullptr_t listend)

static sequence * create (m m1, m m2, std::nullptr_t listend)

static sequence * create (m m1, m m2, m m3, std::nullptr_t listend)

static sequence * create (m m1, m m2, m m3, m m4, std::nullptr_t listend)

static sequence * create (m m1, m m2, m m3, m m4, m m5, std::nullptr_t listend)

然後關於可變引數就說到這裡了



可變引數的理解

c中的printf中的引數就是典型的可變引數,引數不固定,那怎麼獲取呢 正常情況下c的函式引數入棧規則為 stdcall,它是從右到左的,即函式中的最右邊的引數最先入棧 include include define va rounded size type sizeof type sizeof in...

關於C之可變引數

之前的文章有提到過變參巨集,即該巨集可以接受可變數量的引數。stdarg.h 標頭檔案為函式提供了乙個類似的功能,但是用法比較複雜。必須按如下步驟進行 1.提供乙個使用省略號 一定是最後的引數 的函式原型 2.在函式定義中建立乙個va list型別的變數 3.用巨集把該變數初始化為乙個引數列表 4....

關於函式的可變引數

關於函式的可變引數 前提 一般我們程式設計的時候,函式中形式引數的數目通常是確定的,在呼叫時要依次給出與形式引數對應的實際引數。但在某些情況下我們希望函式的引數個數可以根據需要確定,因此c語言引入可變引數函式。一 什麼是可變引數 函式中引數的個數和型別是可變的,這就是可變引數 例如 printf 這...