標籤:c 可變參數
(8)開發可變參數函數
在c語言中,可變參數的函數極其常見,如常用的printf()。可變參數函數的一般形式如下:
傳回值類型 函數名(類型1 參數1,類型2 參數2,...類型n 參數n,...);
如上所示,這是一個典型的可變參數樣式,它共有n個確定的參數,最後的...表示可變參數的含義。必須指出...必須位於最後,並且它至少要有一個確定的參數,原因後面陳述。
為了開發可變參數的函數,需用到標頭檔stdarg.h。下面共給出兩個執行個體,在執行個體中詳細解釋用法。一是求可變個整數的和;二是模仿printf函數。
執行個體一:求可變個整數的和
#include<stdio.h>#include<stdlib.h>#include<stdarg.h>/*對可變個參數求和count是可變個參數的個數*/int sum(int count, ...){int sum = 0;if (count > 0){va_list pData; //typedef char* va_list;va_start(pData, count); //使pData指向count的下一個參數int i;for (i = 0; i < count; i++)sum += va_arg(pData, int); //以int類型解析pData所指向的記憶體地區,解析之後,使pData指向下一個位置//va_end()與va_start()配套使用va_end(pData);}return sum;}int main(){printf("%d\n", sum(5, 1, 2, 3, 4, 5));return 0;}
運行 15
在sum中共用到了va_list類型,va_start()、va_arg()和va_end()宏。
其中,va_list就是char*類型,故直接使用char*,也是可以的。但推薦使用va_list,這樣更能表達含義。va_start()、va_arg()和va_end()都是在stdarg.h中定義的宏。va_start()的作用是使va_list型的變數指向第一個可變參數,故需要使用到離...最近的一個固定的確定的參數,這就是在設計可變參數函數時至少需要一個確定參數的原因。它的真實原因與函數的參數在記憶體中的分布有關:
顯然,由最後一個參數的地址,可以確定第一個可變參數的地址。接著使用va_arg(pData, int),不斷解析pData指向記憶體地區,且要指明用何種方式解析,這是va_arg()第二個參數的作用,解析完後,pData指向下一個可變參數的地址。由此即可得到所有的可變參數的值。
執行個體二,類比printf()函數
#include<stdio.h>#include<stdlib.h>#include<stdarg.h>/*簡單類比printf()函數format是輸出格式字串*/int iprintf(char *format,...){//count統計輸出資料個數int count;count = 0;va_list p;va_start(p, format);char ch;while (ch = format[count]){switch (ch){case 'd':printf("%d\n", va_arg(p, int)); break;case 'f':printf("%f\n", va_arg(p, double)); break;case 's':puts(va_arg(p, char*)); break;}count++;}va_end(p);return count;}int main(){int count = iprintf("sdf", "mvp", 4, 3.5);printf("共輸出 %d 個資料\n", count);system("pause");return 0;}
運行
在上面的類比printf()函數中我們實際上還是靠庫函數printf()來實現輸出,類比的只是原理。
專欄目錄,c指標