1. 程式人生 > >怎樣讓一個函式有不定長的引數列表?(附程式碼例項)

怎樣讓一個函式有不定長的引數列表?(附程式碼例項)

一、什麼是可變引數列表?

       我相信只要學過C語言,就一定用過 scanf() 和 printf() 兩個標準庫函式。用過的朋友都知道,這兩個函式功能強大無比,能輸入輸出各種各樣型別的東西!scanf() 能支援整型、浮點型、字元型等等型別的輸入,而且與之對應的輸出函式printf() 也能支援整型、浮點型、字元型等等型別的輸出 !它是怎麼實現的呢?是不是有什麼厲害的法寶、大殺器?  對!這個法寶就是使用可變引數列表

       可變引數列表,顧名思義,即讓一個函式在不同的時候接受不同數目的引數!

二、那有可變引數列表的函式都長什麼樣啊?

       所謂有大能力者,必骨骼驚奇,面相奇葩!^_^ 開個玩笑,它確實長得和普通的函式不太一樣。

       我在C語言的標準輸入輸出標頭檔案<stdio.h>中給大家扒出來幾個給大夥瞧瞧:

        

三、那我們怎麼來寫這樣擁有可變引數列表的函式呢?

       可變引數列表是通過系統提供的幾個巨集來實現的,這些巨集聲明於<stdarg.h>標頭檔案中,總共用到一個型別、三個巨集:

       <1>、va_list  :  可變引數型別,用來宣告一個va_list型別的變數。可以用它來和其他兩個巨集配合使用

       <2>、va_start:用來初始化va_list型別變數。

                 可接受兩個引數:引數1:va_list 型別變數 ; 引數2:省略號前最後一個有名字的引數

                 執行結果:  把va_list型別變數設定為指向可變引數部分的第一個引數。

       <3>、va_arg:用來訪問可變引數。

                 可接受兩個引數:引數1:va_list型別變數; 引數2:可變引數列表中下一個引數的型別

                 執行結果:返回當前可變引數的值,並使va_list型別變數指向下一個可變引數

       <4>、va_end:完成處理可變引數(訪問完最後一個可變引數之後,即可呼叫va_end)

下來,我們用一個求平均數的例項來看看可變引數列表具體怎麼使用:

原始碼:

/*
**函式功能: 求任意多個整數的平均值
**引數說明:
**@n_len : 參與計算平均值的整數的個數
**@(...) : 可變引數列表宣告
**返回值 : 求得的平均值
*/
float average(int n_len, ...)
{
	va_list varArgList;  //可變引數列表變數
	int count;           //可變引數個數計數器
	float sum = 0;       //所有參與平均數計算的引數的和

	va_start(varArgList, n_len);  //初始化varArgList變數,把它設定為指向可變引數部分的第一個引數


	for (count = 0; count < n_len; count++)
	{

		/*第一個引數varAraList為va_list型別變數,
		**第二個引數是可變引數列表中下一個引數的型別,我們用的是int
		**操作結果 : 返回當前可變引數的值,並使varArgList指向下一個可變引數
		*/
		sum += va_arg(varArgList, int);    
	}

	va_end(varArgList);   //完成處理可變引數(訪問完最後一個可變引數之後,就可呼叫va_end)

	return sum / n_len;
}

int main(void)
{
	printf("1, 2, 3, 4 的平均值為 %.1f \n", average(4, 1, 2, 3, 4));
	return 0;
}
執行截圖:                     大家有興趣可以自己實現簡單的printf函式^_^。