本文為個人學習筆記,僅供個人學習、復習使用。
參考鏈接:鏈接1、鏈接2
在c語言中,我們可以定義這樣的函數,函數帶有可變數量的參數。
int func(int num,...){
.
.
.
}
int main(){func(2,2,3);
}
1、要注意定義函數時函數的形式;
c語言中的printf()函數其實也是一個可變參數函數,它的原型如下:
int printf(const char *format,...);
c語言之所以可以支持可變參數函數,一個重要的原因是c調用規范中規定c語言函數調用時,參數是從右向左壓入棧的;這樣一個函數實現的時候,就無需關心調用他的函數會傳遞幾個參數過來,而只要關心自己用到幾個。如printf()函數:
printf("%d%s\n",i,s);
printf()函數在定義的時候,不知道函數調用的時候回傳遞幾個參數,在實現上,printf()函數只關心第一個參數,即字符串"%d"s\n",當讀到%d的時候,printf()知道自己需要第二個參數,這時只需要去棧上尋找即可,當讀到%s的時候,再去棧上尋找一個參數即可,也就是說printf()函數不關心棧上到底壓了多少參數,只關心自己需要多少。
如何實現可變參數函數呢?
2、要包含頭文件<stdarg.h>,并注意釋放內存。
1、定義一個函數,最后一個參數為省略號,省略號前面可以設置自定義參數。
2、在函數定義中創建一個va_list類型變量,該類型是在stdrag.h頭文件中定義
3、使用int參數和va_start宏來初始化va_list變量為一個參數列表,宏va_start是在stdarg.h頭文件中定義的。
4、使用va_arg宏和va_list變量來訪問參數列表中的每個項。
5、使用宏va_end來清理va_list變量的內存。
eg:
#include<stdio.h>
#include<stdarg.h>double average(int num,...){va_list valist;double sum=0.0;int i;va_start(valist,num);for(i=0;i<num;i++){sum+=va_arg(valist,int);}va_end(valist);return sum/num;
}int main(){printf("Average of 2,3,4,5=%f\n",average(4,2,3,4,5));printf("Average of 5,10,15=%f\n",average(3,5,10,15));return 0;
}
宏va_list、va_arg、va_end定義在stdarg.h中,原型如下:
void va_start(va_list ap,last);
//取第一個可變參數的指針給ap,last是函數聲明中的最后一個固定參數
type va_arg(va_list ap,type);
//返回當前ap指向的可變參數的值,然后ap指向下一個可變參數;type表示當前可變參數的類型,支持的類型為int和double
void va_end(va_list ap);
//將ap置為null
這里要注意一點va_arg()函數的第二個參數不能被指定為char、short、或float。
char、short會被提升為int,而float會被提升為double。(這里涉及到整數提升的問題,可百度整數提升四個字了解)。