C語言可變引數列表 1

2021-07-06 01:13:13 字數 1146 閱讀 8153

嘗試使用c語言可變引數列表

對於一些函式有的時候,我們不希望它只能傳遞固定引數,例如如果我們想計算2個整數數之和寫乙個int sum(int ,int );的函式,但是如果想計算3個數之和呢?n個數之和呢?不可能去定義無限多個函式,也不能讓函式的引數太多,形如int sum(int ,int ,int ,int ,int ,int ,int ,int ,int ,int );10個數求和,這樣的編碼既不方便也不優雅,我們希望定義乙個函式,實現引數個數可以任意變化而不影響程式功能的函式。這就需要c語言定義的可變引數列表來實現了。

可變引數列表的使用必須使用標頭檔案  stdarg.h  該標頭檔案包含有可變引數列表的巨集定義和變數定義,包括va_list可變引數列表型別  va_arg()  va_start()  va_end()  3個巨集定義

下面展示求和函式源**:

#include

#include//包含有可變引數列表的巨集定義

sum(int length,...)

va_end(va);  //使指標指向空防止未定義指標錯誤

return sum;   

}int main()

原理可變引數列表實際上是利用了c語言函式引數傳遞時的入棧順序實現的,函式執行時,分配好的棧區的棧底在高位址,入棧向低位址擴充套件,位址減小(--),出棧則位址增加(++),呼叫函式時函式引數講從右至左依次入棧,在本例中length就是最後乙個入棧的位址最低,所以,只需要對length的位址進行自增運算,在保證所有引數型別一致的情況下即可把所有引數都訪問到。

如本例:

va_list 定義乙個可變引數列表的結構梯變數va_arg。

,然後使用va_start()這個帶參巨集來使va_arg結構體中的位址指向length之後的第乙個引數的位址,在本例中就是引數2的位址。

然後我們就可以根據迴圈來迭代計算(棧空間是連續的)每次使用va_arg()這個帶參巨集來訪問該元素,引數int是為了確定每次指標指向跳過的位元組數。

最後,我們使用va_end()這個帶參巨集來使va結構體中的位址為null,防止為定義的行為發生。

所以,可變引數列表的原理就是簡單的函式呼叫時引數在記憶體中存放規則(入棧規則)。

至於更複雜的printf(const char * format,...)可以接受不同型別的引數,是可變引數列表的經典例項。

未完待續!

C語言可變引數列表

c語言中類似於printf這種型別的函式,在呼叫它們時我們傳入的引數的型別和數量都不是固定的,這就需要可變引數列表,要使用可變引數列表,要用到以下幾種巨集。include void va start va list ap,last type va arg va list ap,type void v...

(C語言)可變引數列表

c函式要在程式中用到以下這些巨集 void va start va list arg ptr,prev param type va arg va list arg ptr,type void va end va list arg ptr va list 用來儲存巨集va start va arg和v...

可變引數 函式 可變引數列表 1

我們在c語言程式設計中有時會遇到一些引數個數可變的函式,即函式的入參個數和型別是不確定的,例如printf 函式,其函式原型為 int printf char format,它除了有乙個引數format固定以外,後面跟的引數的個數和型別是可變的 用三個點 做引數佔位符 實際呼叫時可以有以下的形式 p...