1. 程式人生 > >自我學習: C 標準庫 - stdarg.h

自我學習: C 標準庫 - stdarg.h

自我學習: C 標準庫 – <stdarg.h>

維基百科上對此標準庫的介紹是

stdarg.h is a header in the C standard library of the C programming language that allows functions to accept an indefinite number of arguments.

翻譯過來是該標準庫能允許函式接受數量不定的引數(accept an indefinite number of arguments.).

It provides facilities for stepping through a list of function arguments of unknown number and type.

它提供了執行未知數量和型別的函式引數列表的工具。

在 cplusplus.com 上是這麼解釋的,感覺解釋的很好。

This header defines macros to access the individual arguments of a list of unnamed arguments whose number and types are not known to the called function.

A function may accept a varying number of additional arguments without corresponding parameter declarations by including a comma and three dots (,...) after its regular named parameters:

return_type function_name ( parameter_declarations , ... ); 
To access these additional arguments the macros va_start, va_arg and va_end, declared in this header, can be used:
First, va_start initializes the list of variable arguments as a va_list.
Subsequent executions of va_arg yield the values of the additional arguments in the same order as passed to the function.
Finally, va_end shall be executed before the function returns.

翻譯過來是

該標頭檔案定義一系列的巨集來訪問未命名引數列表的各個引數,這些引數的數量和型別是被呼叫函式所不知道的。
函式可以接受不同數量的附加引數,而不需要相應的引數宣告,方法是在其常規命名引數之後加上逗號和三個點(,…):

返回型別 函式名(引數 , ...);

要訪問這些附加的引數,可以使用在此庫中宣告的巨集va_start、va_arg和va_end:
首先,va_start將變數引數列表初始化為一個va_list。
va_arg的後續執行產生附加引數的值,其順序與傳遞給函式的順序相同。
最後,在函式返回之前執行va_end。

怎麼理解呢,直接看一個例子。

#include<stdarg.h>          //該標準庫匯入.
#include<stdio.h>
//該函式計算(1, 2, 3)三個數的和
int sum(int number, ...){  //number為接受引數的數量,小數點表示接受不定量的引數.
    int temp = 1;
    va_list list_sum;  //即宣告一個儲存不定量引數的容器,用來儲存巨集va_arg與巨集va_end所需資訊,型別為庫變數va_list.
    va_start(list_sum, number);  //庫巨集va_start,使va_list指向第一個引數va_arg.
    for(int i = 0; i < number; i++){  //執行迴圈,把(1,2,3)三個數依次與temp相加.
        temp += va_arg(list_sum, int); //庫巨集va_arg,在容器裡檢索引數,每次迴圈都返回不同的值.
    }
    va_end(list_sum);  //庫巨集va_end,結束符,釋放裝有資料的容器va_list.
    return temp;
}
int main(){
    printf("%d",sum(3, 1, 2, 3)); //第一個引數是number,表明了後面引數的數量,後三個引數即傳入va_list的數值.
    return 0;
}

對於萌新來說,一開始 sum() 的 三個小數點( ... )就無法理解了。

引入概念:可變引數函式

引用 Healtheon-部落格園 的文章開頭,地址:http://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html

在C中,當我們無法列出傳遞函式的所有實參的型別和數目時,可以用省略號指定引數表

void foo(...);
void foo(parm_list,...);

這種方式和我們以前認識的不大一樣,但我們要記住這是C中一種傳參的形式,在後面我們就會用到它。

可變引數函式的引數數量是可變動的,它使用省略號來忽略之後的引數。例如printf函式一般。

printf函式的原型是 extern int printf(const char *format, ... );

就如同:

printf("hello,world!");
printf("%d %d", a, b);
printf("%c,%c,%c,%c,%c", c, d, e, f, g);

引號後面的引數不一定需要,引數數目也不定。

stdarg.h 庫成員


(圖源 wiki百科)


(圖源 百度百科)

ummmmmm,有事先放著,以後補充。