實現原理和理論依據:
函式引數傳遞的時候,引數是線性的儲存在記憶體中的,因此,如果知道引數存放的起始位置和結束位置,和引數的型別,那麼就可以得到需要的所有引數.
關於不定引數標頭檔案stdarg.h中的幾個巨集定義(每乙個顏色板塊為乙個巨集定義及其解釋):
va_list:
#ifndef _va_list_defined
#ifdef _m_alpha
typedef struct va_list;
#else
typedef char * va_list;
#endif
#define _va_list_defined
#endif
其中a0或者va_list是第乙個引數的位址,offset是從第乙個引數到第二個引數的記憶體位址偏移量,由引數的型別占用記憶體的空間決定.
#define _intsizeof(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
得到引數n的尺寸,相當與sizeof(n),為了相容性寫成了如上的表示式.
#define va_start(ap,v) ( ap = (va_list)&v + _intsizeof(v) )
其中ap是乙個va_list型的引數列表指標變數,v是參數列中的第乙個引數的名字.作用是初始化參數列,並讓參數列指標ap指向引數列表的第二個引數開始位址(根據以上巨集定義的表示式得知).
#define va_arg(ap,t) ( *(t *)((ap += _intsizeof(t)) - _intsizeof(t)) )
根據引數型別移動參數列指標ap,使之返回下乙個引數的值,引數的型別由第二個引數t指定(分析以上巨集定義表示式).
#define va_end(ap) ( ap = (va_list)0 )
結束引數傳遞,做清理工作,即讓參數列指標清空.
#include < stdio.h>
#include < string.h>
#include < stdarg.h>
#include int sum(int first,...)///* 函式原型宣告,至少需要乙個確定的引數,注意括號內的省略號 */
va_end(ap);
return sum;
}int main()
運用優劣參考 鏈結
不定長引數函式的實現
原始碼如下 int sum int num,return ret int main int argc,char argv 所謂不定長引數,就是函式的形參數量不定,型別也可能是不定的。我們把像上面的函式sum中如 int num 這樣的引數叫做 有名引數 後面用 代表的都是 匿名引數 有名引數是可以在...
不定引數函式
引數的儲存位置 實參在傳遞值時,給形參申請空間並賦值,其形參在位址上形參的位址是相鄰的 根據編譯器和系統環境可能會有所不同 a b 4 sizeof int 乙個int位元組 int func int a,int b 正如上文所說,如果每次通過p 定址,程式的不具有良好的可移植性。c語言有乙個標頭檔...
函式不定引數
函式引數是以資料結構 棧的形式訪問,從右至左入棧.1.va list用於宣告乙個變數,我們知道函式的可變引數列表其實就是乙個字串,所以va list才被宣告為字元型指標,這個型別用於宣告乙個指向引數列表的字元型指標變數,例如 va list ap ap arguement pointer 2.va ...