在我們使用函數時,一般大多數情況下里面的參數都是給定的,而且我們一般使用時並不會超過三個參數,可是這並不排除不會出現三個以上的參數,比如說求平均值,求和等等一些可能出現三個以上參數的函數運算,這時我們的參數不再是固定的,而是隨時會不斷變化的。因此我們就需要一種方法來實現它們,這種方法就是C語言給我們提供的一種叫做可變參數列表的函數方法。
首先,可變參數列表是通過宏來定義的,而這些宏又在<stdarg.h>的頭文件中,因此我們在使用時要先引用該頭文件,在引用後我們需要其下三個宏的函數:
void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_end(va_list ap);
上面這三個函數都是用宏定義的,下面是這些宏在標準ANSI形式下的定義:
typedef char * va_list; #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) #define va_end(ap) ( ap = (va_list)0 )
從上面的宏我們可以看出:
va_list實際上是一個字符類型的指針。
_INTSIZEOF()這個函數主要是把傳進來n的長度變成int長度的整數倍。
va_start主要作用是將va_list定義的指針指向v後面的地方,也就是可變參數第一個數的首地址,實際上就是對va_list進行初始化。
va_arg則是將當前參數取出並將va_list定義的指針變量指向下一個參數,t指的是參數類型。
va_end是對整個參數列表進行清理或者也可理解爲釋放。
下面通過一個簡單的例子看下具體的實現方法---通過可變參數列表實現求多個數的最大值
#include<stdarg.h> int MAX(int count,...) { int i=0; int max=0; int k=0; va_list arg; //定義一個va_list類型的變量 va_start(arg,count); //讓arg指向count後面第一個可變參數,進行初始化 max=va_arg(arg,int); //將第一個可變參數取出,並指向下一個可變參數 for(i=0;i<count-1;i++) { k=va_arg(arg,int); //通過count依次取出 if(k>max) //進行比較 max=k; } va_end(arg); //進行清理釋放 return max; }
這就是C中可變參數的用法,我們的printf,scanf等都是通過它們實現的,當然有一點要注意的是可變參數列表可接受多個參數,但至少需要一個參數。