下面,我們來看一下,如果在c++的函數中接收數量不定的函數參數。這種形式如同在C#的函數參數列表中使用params 類型的參數。
我們可以將函數定義成能夠接受任意數量的實參。通過將省略號(3個句點...)寫在函數定義中形參列表的最後,即可表示調用該函數時可以提供數量可變的實參。例如:
int sumValues(int first,...)
{
//Code for the function
}
函數定義中必須至少有一個普通形參,但也可以有多個。省略號必須總是放在形參列表的最後。
顯然,定義中沒有關於可變列表中實參的類型或數量的任何信息,因此我們的函數代碼必須弄清楚自己被調用時接收的是什麼。本地C++庫在stdarg.h頭文件中定義了va_start、va_arg、和va_end宏,以幫助我們做這件事。用示例來說明其用法是最容易的。
#include <iostream>
#include "stdarg.h"
using namespace std;
int sum(int count,...)
{
if(count<=0)
return 0;
va_list arg_ptr;
va_start(arg_ptr,count);
int sum = 0;
for (int i=0;i<count;i++)
{
sum+=va_arg(arg_ptr,int);
}
va_end(arg_ptr);
return sum;
}
int main()
{
cout<<sum(2,4,6,8,10,12)<<endl;
cout<<sum(2,22,33,44,55,66,77,88,99)<<endl;
return 0;
}
本例結果:
10
55
按任意鍵繼續。。。
示例說明
main()函數函數在兩條輸出語句中調用了sum()函數,第一次有6個實參,第二次有9個實參。
sum()函數有一個int類型的普通形參,它表示後面跟着的實參的數量。形參列表中的省略號表明可以傳遞任意數量的實參。基本上,我們有兩種方法來確定調用該函數時有多少實參:第一是像sum()函數一樣,用某個固定的形參指定實參的數量;第二是要求最後一個實參具有特殊的標記值,以便我們進行檢查和確認。
爲了開始處理可變的實參列表,我們首先聲明一個va_list類型的指針:
va_list arg_ptr;
va_list 類型是在stdarg.h頭文件中定義的,該指針用來依次指向各個實參。
va_start宏用來初始化arg_ptr,使其指向列表中的第一個實參:
va_start宏用來初始化arg_ptr,使其指向列表中的第一個實參:
va_start(arg_ptr,count);
這個宏的第二個實參是函數形參列表中活力號前面固定形參的名稱,用來確定第一個可變實參的位置。
我們在for循環中取出列表中各個實參的值:
for (int i=0;i<count;i++)
{
sum+=va_arg(arg_ptr,int);
}
var_arg宏返回arg_ptr指向的位置存儲的實參值,並使arg_ptr遞增,以指向下一個實參值。va_arg宏的第二個實參是第一個實參的類型,決定着我們得到的數值以及va_arg遞增的方式,因此如果該實參不正確,將造成混亂。程序也許會執行,但我們得到的數值將是無用數據,而且arg_ptr將被錯誤地遞增,從而指向另外的無用數據。
當結束檢索實參值之後,我們用下面這條語句使arg_ptr復位:
va_end(arg_ptr);
va_end宏將我們傳遞給它的實參--va_list類型的指針復位成空值。始終這樣做是個好主意,因爲在處理過實參之後,arg_ptr將指向某個不包含有效數據的存儲單元。