**引言:**
可變參數函數指可以接受可變數量參數的函數。比如printf函數就是一個可變參數函數。
**編寫:**
要完成可變參數函數的編寫,需要用到定義于stdarg.h頭文件中的一個類型va_list和三個宏va_start、va_arg、va_end。
**注意:**
1、可變參數必須從頭到尾按照順序逐個訪問。如果在訪問幾個可變參數后想半途中止,這是可以的。但是,如果想一開始就訪問列表中的參數,那是不行的。
2、由于參數列表中的可變參數部分并沒有原型,所以,所有作為可變參數傳遞給函數的值都將執行缺省參數類型提升。
3、參數列表中的省略號,它提示此處可能傳遞數量和類型未確定的參數。省略號只能出現參數表的尾部。
變長參數函數的關鍵在于如何處理一個甚至連名字都沒有的參數表。標準頭文件<starg.h>中包含一組宏定義,它們對如何遍歷參數表進行了定義。
va_list類型用于聲明一個變量,該變量將依次引用各參數。
va_start宏將va_list聲明的變量初始化為指向第一個無名參數的指針。在使用變量之前,該宏必須被調用一次。參數表必須至少包括一個有名參數,va_start將最后一個有名參數作為起點。
va_arg宏,調用該宏,該函數都將返回一個參數,并將聲明的變量指向下一個參數。va_arg使用一個類型名來決定返回的對象類型、指針移動的步長。
va_end宏,該宏必須在函數返回之前調用,以完成一些必要的清理工作。
**程序示例:**
~~~
#include <stdarg.h>
#include <stdio.h>
/*
*計算平均值
*/
float
average(int n_values, ...)
{
va_list var_arg;
int count;
float sum = 0;
va_start(var_arg, n_values); /*準備訪問可變參數? */
for(count = 0; count < n_values; count+=1){
sum += va_arg(var_arg, int);/*添加取自可變參數列表的值 ?*/
}
va_end(var_arg); /*完成處理可變參數 */
return sum/n_values;
}
void
main(int argc, char **argv)
{
printf("the average of 3 and 8 is %f\n", average(2, 3, 8));
printf("the average of 3 and 8 and 11 is %f\n", average(3, 3, 8, 11));
return;}
~~~
**注意:**
? ? ?C語言中的可變參數函數沒有長度檢查和類型檢查,可能會被利用為攻擊目標。設計函數時應先考慮替補方案。
- 前言
- (四)回調函數
- (一)while(1)死循環與for(;;)死循環的區別
- (二)static關鍵字
- (三)函數
- (四)可變參數函數
- (五)setjmp和longjmp
- (六)指針
- (七)回調函數
- (八)字符串
- (九)動態內存分配
- (十)結構體
- (十一)深入理解指針
- (十二)命令行參數
- (十三)printf、fprintf、sprintf和snprintf函數
- (十四)const關鍵字詳解
- (十五)字符串輸入函數fgets、gets和scanf
- (十六)字符串輸出函數puts、fputs和printf
- (十七)字符/字符串輸出函數fputc、fputs、putc、putchar和puts
- (十八)字符/字符串輸入函數fgetc、fgets、getc、getchar和gets
- (十九)restrict關鍵詞
- (二十)scanf函數詳解
- (二一)內聯函數
- (二二)位操作
- (二三)errno變量
- (二四)內存分配