1. 程式人生 > >今天學習了關於C++ 中可變引數個數函式的使用!

今天學習了關於C++ 中可變引數個數函式的使用!

VA_LIST 是在C語言中解決變參問題的一組巨集

 他有這麼幾個成員

1) va_list型變數:

#ifdef _M_ALPHA

typedef struct {

       char *a0;       /* pointer tofirst homed integer argument */

       int offset;     /* byte offset ofnext parameter */

} va_list;

#else

typedef char *  va_list;

#endif

2)_INTSIZEOF 巨集,獲取型別佔用的空間長度,最小佔用長度為int的整數倍:

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) &~(sizeof(int) - 1) )

3)VA_START巨集,獲取可變引數列表的第一個引數的地址(ap是型別為va_list的指標,v是可變引數最左邊的引數):

#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )

4)VA_ARG巨集,獲取可變引數的當前引數,返回指定型別並將指標指向下一引數(t引數描述了當前引數的型別):

#defineva_arg(ap,t)    ( *(t *)((ap +=_INTSIZEOF(t)) - _INTSIZEOF(t)) )

5)VA_END巨集,清空va_list可變引數列表:

#defineva_end(ap)      ( ap = (va_list)0 )

VA_LIST的用法:     

      (1)首先在函式裡定義一具VA_LIST型的變數,這個變數是指向引數的指標;

       (2)然後用VA_START巨集初始化變數剛定義的VA_LIST變數;

      (3)然後用VA_ARG返回可變的引數,VA_ARG的第二個引數是你要返回的引數的型別(如果函式有多個可變引數的,依次呼叫VA_ARG獲取各個引數);

      (4)最後用VA_END巨集結束可變引數的獲取。

使用VA_LIST應該注意的問題:

   (1)可變引數的型別和個數完全由程式程式碼控制,它並不能智慧地識別不同引數的個數和型別;

   (2)如果我們不需要一一詳解每個引數,只需要將可變列表拷貝至某個緩衝,可用vsprintf函式;

   (3)因為編譯器對可變引數的函式的原型檢查不夠嚴格,對程式設計查錯不利.不利於我們寫出高質量的程式碼;


#include<iostream.h>
#include<stdarg.h>

int max(int n, ...)
{                // 定參 n 表示後面變引數量,定界用,輸入時切勿搞錯
 va_list ap;                         // 定義一個 va_list 指標來訪問引數表
    va_start(ap, n);                       // 初始化 ap,讓它指向第一個變參,n之後的引數
    int maximum = -0x7FFFFFFF;          // 這是一個最小的整數
    int temp;
     for(int i = 0; i < n; i++) {
    temp = va_arg(ap, int);          // 獲取一個 int 型引數,並且 ap 指向下一個引數
    if(maximum < temp) maximum = temp;
     }
    va_end(ap);                         // 善後工作,關閉 ap
    return maximum;
}
int main()
{
   cout << max(3, 10, 20, 30) << endl;
   cout << max(6, 20, 40, 10, 50, 30, 40) << endl;
}