關於sprintf,printf,這些函式,引數都是不固定的。而這樣程式設計方式,也可以自己來搞定。c語言提供了幾個巨集就是做這個的。
va_list //乙個很特殊的型別
type va_arg(va_list ap, type);
void va_start(va_list ap, last_arg);
void va_end(va_list ap);
void va_copy(va_list dest,va_list src);
這個va_list是乙個完整的物件型別,適用於儲存巨集va_start,va_copy,va_arg和va_end所需的資訊。
如果建立了乙個va_list例項,傳遞給另乙個函式,並通過該函式中的va_arg使用,則在呼叫函式中的任何後續使用都應該在呼叫va_end之前進行。
先看乙個最簡單的例子
#include int sum(int n, ...)
va_end(mark);
//va_end(sub);
return sum;
}int main()
可以簡單理解va_start就是初始化,其第二個引數 last_arg在本例中可發現就是「n」,這個就是最後接收到的固定引數。為什麼是最後接收到,是因為引數的壓棧順序,這個可自行google。
另外,我把va_copy的注釋起來了,這個就是簡單的拷貝。然後va_end看標頭檔案就是定義為((void)(ap = (va_list)0))。也沒什麼好說的。
但是這樣簡單應用看起來也沒啥用。下面的寫法便會讓人一目了然。
#include #include char buffer[80];
int vspfunc(char* format, ...)
int main()
這就好像sprintf一樣,使用vsprintf,我把這3部分黏貼到了buffer中。這對於像做日誌系統等的還是有些用處的。
需要注意的是,我在vspfunc裡三個printf,我本來看va_arg菜鳥驛站的解釋(這個巨集檢索函式引數列表中型別為type的下乙個引數),還以為順序不重要,對這個例子,因為只有乙個char*,所以怎麼都可以列印出來,而int有兩個,所以那倆int才有順序。
試了下發現,先列印char*還是會報錯的。還是要按照順序來的。看了下標頭檔案的定義,發現原來並沒有搞什麼快取之類的,所以我這個例子,char*和int所佔空間的不同,由於讀取順序的錯誤必然出錯。還是不能想當然啊。
c 語言可變引數
1 當無法列出傳遞函式的所有實參的型別和數目時,可用省略號指定參數列 void foo void foo parm list,2 函式引數的傳遞原理 函式引數是以資料結構 棧的形式訪問,從右至左入棧.eg include void fun int a,int main output 12 343 獲...
c語言可變引數
ifdef debug print info x printk x,else print info x endif 一 什麼是可變引數 我們在c語言程式設計中有時會遇到一些引數個數可變的函式,例如printf 函式,其函式原型為 int printf const char format,它除了有乙個...
C語言可變引數
在gnu c中,巨集可以接受可變數目的引數,就象函式一樣,例如 1 2 define pr debug fmt,arg.printk kern debug fmt,arg 用可變引數巨集 variadic macros 傳遞可變參數列 你可能很熟悉在函式中使用可變參數列,如 1 voidprintf...