【轉】C/C++中可變參數的詳細介紹(va_list,va_start,va_arg,va_end)

可變參數的函數原理其實很簡單,而va系列是以宏定義來定義的,實現跟堆棧相關.我們寫一個可變函數的C函數時,有利也有弊,所以在不必要的場合,我們無需用到可變參數。如果在C++裏,我們應該利用C++的多態性來實現可變參數的功能,儘量避免用C語言的方式來實現。

  由於在C語言中沒有函數重載,解決不定數目函數參數問題變得比較麻煩,即使採用C++,如果參數個數不能確定,也很難採用函數重載。對這種情況,提出了指針參數來解決問題。

如printf()函數,其原型爲:
int   printf(   const   char*   format,   ...);

它除了有一個參數format固定以外,後面跟的參數的個數和類型是可變的,例如我們可以有以下不同的調用方法:   
printf( "%d ",i);   
printf( "%s ",s);   
printf( "the   number   is   %d   ,string   is:%s ",   i,   s);

如何實現其功能?

我們需要以下幾個宏定義:

1)va_list 
定義了一個指針arg_ptr, 用於指示可選的參數.

(2)va_start(arg_ptr, argN)
使 參數列表指針arg_ptr指向函數參數列表中的第一個可選參數,argN是位於第一個可選參數之前的固定參數, 或者說最後一個固定參數.如有一va函數的聲明是void va_test(char a, char b, char c, ...), 則它的固定參數依次是a,b,c, 最後一個固定參數argN爲c, 因此就是va_start(arg_ptr, c).

(3)va_arg(arg_ptr, type)
返回參數列表中指針arg_ptr所指的參數, 返回類型爲type. 並使指針arg_ptr指向參數列表中下一個參數.返回的是可選參數, 不包括固定參數.

(4)va_end(arg_ptr)
清空參數列表, 並置參數指針arg_ptr無效.

(注:va在這裏是variable-argument(可變參數)的意思.   這些宏定義在stdarg.h中,所以用到可變參數的程序應該包含這個頭文件)

也需你現在還是不能理解,彆着急,現在從一個實例着手.定義這麼一個函數,函數的第一個參數是固定的,其餘參數是可變的。定義爲:
void   simple_va_fun(int i,...); 其代碼爲:

#include <iostream>
#include <string>
#include <iostream>
using namespace std;
#include <stdarg.h>
void simple_va_fun(int i, ...)
{
    va_list arg_ptr;       /// 定義可變參數指針
    va_start(arg_ptr, i);  /// i爲最後一個固定參數
    int j = va_arg(arg_ptr, int); //返回第一個可變參數,類型爲int
    char c = va_arg(arg_ptr, char); ///返回第二個可變參數,類型爲char
    va_end(arg_ptr);  ///清空參數指針
    printf("%d %d %c", i, j, c);
    return;
}

int main()
{
    simple_va_fun(100);
    cout << endl;
    simple_va_fun(100, 200);
    cout << endl;
    simple_va_fun(100, 200, 'a');
    cout << endl;
    system("pause");
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章