C语言中函数可变参数解析
大多數時候,函數中形式參數的數目通常是確定的,在調用時要依次給出與形式參數對應的所有實際參數。但在某些情況下希望函數的參數個數可以根據需要確定。典型的例子有
大家熟悉的函數printf()、scanf()
可變參數的實現:
C語言頭文件stdarg.h提供了一個數據類型va-list和三個宏(va-start、va-arg和va-end),va—start使vp指向第一個可選參數。va—arg返回參數列表中的當前參數并使vp指向參數列表中的下一個參數。va
?
—end把vp指針清為NULL。函數體內可以多次遍歷這些參數,但是都必須以va—start開始,并以va—end結尾。用它們在被調用函數不知道參數個數和類型時對可變參數表進行測試,從而為訪問可變參數提供
?
了方便且有效的方法。va-list是一個char類型的指針,當被調用函數使用一個可變參數時,它聲明一個類型為va-list的變量,該變量用來指向va-arg和va-end所需信息的位置。
?
下面給出va_list在C中的源碼:
?typedef char * va_list;?
采用ANSI標準形式時,參數個數可變的函數的原型聲明是:
? type funcname(type para1, type para2, ...)?
這種形式至少需要一個普通的形式參數,后面的省略號不表示省略,而是函數原型的一部分,type是函數返回值和形式參數的類型。
?
調用者在實際調用參數個數可變的函數時,要通過一定的方法指明實際參數的個數,例如把最后一個參數置為空字符串。
下面給出一個具體的例子:
求n個數的和:
int Sum(int n,...) {int i = 0,sum = 0;va_list vp; va_start(vp,n); //va—start使vp指向第一個可選參數for (i=0; i<n; i++){sum +=va_arg(vp,int); }va_end(vp); //va—end把vp指針清為NULL。return sum; }printf函數實現:(此處只實現了基本類型的打印)
1 void my_print(const char *format,...)2 {3 char c = 0;4 va_list vp; 5 va_start(vp,format); //vp指向第一個可選參數6 while (*format)7 {8 c = *format;9 switch (c) 10 { 11 case '%': 12 { 13 char cc = *(++format); 14 switch (cc) 15 { 16 case 'd': 17 { 18 char str[50]; 19 int n = va_arg(vp,int); //va—arg返回參數列表中的當前參數并使vp指向參數列表中的下一個參數。 20 char *string = _itoa(n,str,10); //把整數轉為字符串 21 print_str(string); 22 } 23 break; 24 case 'f': 25 { 26 char str[50]; 27 double f = va_arg(vp,double);//va—arg返回參數列表中的當前參數并使vp指向參數列表中的下一個參數 28 char *string = _gcvt(f,10,str);//將浮點型數轉換為字符串,取四舍五入 29 print_str(string); 30 } 31 break; 32 case 'c': 33 putchar(va_arg(vp,char)); 34 break; 35 case 's': 36 { 37 char *string = va_arg(vp,char*); 38 print_str(string); 39 } 40 break; 41 default: 42 break; 43 } 44 } 45 break; 46 default: 47 putchar(c); 48 break; 49 } 50 format++; 51 } 52 va_end(vp); 53 }理解可變參數很重要的是要理解函數棧幀的創建與銷毀,里面涉及到參數是如何壓棧,這方面內容在前面的博客:http://www.cnblogs.com/zhonglongbo/p/8392026.html
總結
以上是生活随笔為你收集整理的C语言中函数可变参数解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下unlink函数的使用
- 下一篇: 回调函数到底是怎么一回事呢