可变参数列表
有的時候同一個函數核可能需要接收不同數量的參數,那么函數原型應該如何定義,不確定的參數應該如何訪問,下面將給出答案。
可變參數列表是通過宏來實現的,這些宏定義于stdarg.h的頭文件中,它聲明了一種類型 va_list(typedef __builtin_va_list __gnuc_va_list; 頭文件中是這樣定義的) 和三個宏 ---- va_start va_arg 和 va_end (
#define va_start(v,l)?? ?__builtin_va_start(v,l)
#define va_end(v)?? ?__builtin_va_end(v)
#define va_arg(v,l)?? ?__builtin_va_arg(v,l)
)。通過使用一個類型和三個宏配合我們就可以訪問到參數的值。
?
當然實際的程序這樣寫是沒有必要的,只要用數組就好了,但是在這里為了舉一個簡單的例子就使用了這種方法,假如我們要寫一個求和的代碼,但是不使用數組,那么我們就不一定向函數中傳遞多少參數,那么我們就需要這樣寫。
如下代碼:
#include<stdio.h> #include<stdarg.h> int sum(int n,...);int main() {int a;a=sum(4,1,2,3,4);printf("%d",a); }int sum(int n,...) {int i;int sum=0;va_list var_arg;va_start(var_arg,n);for( i = 0; i < n ; i++ ){sum+=va_arg( var_arg , int );}va_end(var_arg);return sum; }
所有的可變參數和函數在定義的時候不確定部分就用用 “...” 來補充他們的位置,那么函數原型就如int sum(int n,...);
當然實際使用的時候肯定不會只是這樣的簡單的參數,可變參數部分可能會接收int short char這些都會轉換成 int類型 , float 會轉換為 double 類型,編譯器和宏并不會幫你分析傳遞的參數的類型,這就需要你自己經過一些判斷來分析傳遞的參數類型并進行強制轉換。在函數接收了傳遞來的參數的時候我們并不知道這些參數的名稱,這個時候我們就需要用到頭文件stdarg.h 的一個類型和三個宏,那么首先在函數中你需要定義一個 va_list 類型的變量,如 va_list var_arg; ,這個var_arg變量就是用來訪問未確定的部分,同時這個變量需要通過 va_start 來進行初始化,va_start 有兩個參數第一個參數是va_list類型的變量的名稱,第二個參數是未確定參數之前的最后一個有名字的參數。初始化過程把var_arg變量設置為指向可變參數的部分的第一個參數。初始化后我們就需要進行訪問這些參數,這時需要使用 va_arg,這個宏也有兩個參數,va_list 類型的變量和參數的類型,如:sum+=va_arg( var_arg , int ); ,va_arg( var_arg , int )? 會返回一個未確定的參數并指向下一個未確定的參數,當然這些參數都是需要你進行一些判斷的,可能是前面的一些承參數提供給你的信息。就像在定義一個文件文件指針一樣,在對它操作結束后就需要對它進行釋放,因為C語言中沒有垃圾處理機制,這一切的工作都需要我們自己來完成,請一定要記住定義后就一定要有對應的釋放,不然這些沒有用的東西沒有得到釋放,那么及時你的內存再大也有不夠用的一天,同時即使i你的內存夠用這也是一種浪費的行為,當然可變參數列表也不會例外的,它使用 va_end 只有一個參數就是 va_list 類型的變量,如代碼中:va_end(var_arg);?
?
當然可變參數列表本身也存在一些問題,就行剛才的程序你就可以看出,如果你想中途停止訪問這些未知參數是可以的,但是如果你想不從頭訪問,直接訪問其中的某一個肯定是不可以的。
轉載于:https://www.cnblogs.com/foreverW/p/7242100.html
總結
- 上一篇: 最好听的公会名字大全
- 下一篇: WCF服务端返回:(413) Reque