C++的va_start()va_end()函數(shù)應(yīng)用

字號(hào):

1:當(dāng)無(wú)法列出傳遞函數(shù)的所有實(shí)參的類(lèi)型和數(shù)目時(shí),可用省略號(hào)指定參數(shù)表
    void foo(...);
    void foo(parm_list,...);
    2:函數(shù)參數(shù)的傳遞原理
    函數(shù)參數(shù)是以數(shù)據(jù)結(jié)構(gòu):棧的形式存取,從右至左入棧.eg:
    #include
    void fun(int a, ...)
    {
    int *temp = &a;
    temp++;
    for (int i = 0; i < a; ++i)
    {
    cout << *temp << endl;
    temp++;
    }
    }
    int main()
    {
    int a = 1;
    int b = 2;
    int c = 3;
    int d = 4;
    fun(4, a, b, c, d);
    system("pause");
    return 0;
    }
    Output::
    1
    2
    3
    4
    3:獲取省略號(hào)指定的參數(shù)
    在函數(shù)體中聲明一個(gè)va_list,然后用va_start函數(shù)來(lái)獲取參數(shù)列表中的參數(shù),使用完畢后調(diào)用va_end()結(jié)束。像這段代碼:
    void TestFun(char* pszDest, int DestLen, const char* pszFormat, ...)
    {
    va_list args;
    va_start(args, pszFormat);
    _vsnprintf(pszDest, DestLen, pszFormat, args);
    va_end(args);
    }
    4.va_start使argp指向第一個(gè)可選參數(shù)。va_arg返回參數(shù)列表中的當(dāng)前參數(shù)并使argp指向參數(shù)列表中的下一個(gè)參數(shù)。va_end把a(bǔ)rgp指針清為NULL。函數(shù)體內(nèi)可以多次遍歷這些參數(shù),但是都必須以va_start開(kāi)始,并以va_end結(jié)尾。
    1).演示如何使用參數(shù)個(gè)數(shù)可變的函數(shù),采用ANSI標(biāo)準(zhǔn)形式
    #include 〈stdio.h〉
    #include 〈string.h〉
    #include 〈stdarg.h〉
    /*函數(shù)原型聲明,至少需要一個(gè)確定的參數(shù),注意括號(hào)內(nèi)的省略號(hào)*/
    int demo( char, ... );
    void main( void )
    {
     demo("DEMO", "This", "is", "a", "demo!", "");
    }
    /*ANSI標(biāo)準(zhǔn)形式的聲明方式,括號(hào)內(nèi)的省略號(hào)表示可選參數(shù)*/
    int demo( char msg, ... )
    {
     /*定義保存函數(shù)參數(shù)的結(jié)構(gòu)*/
     va_list argp;
     int argno = 0;
     char para;
     /*argp指向傳入的第一個(gè)可選參數(shù),msg是最后一個(gè)確定的參數(shù)*/
     va_start( argp, msg );
     while (1)
     {
     para = va_arg( argp, char);
     if ( strcmp( para, "") == 0 )
     break;
     printf("Parameter #%d is: %s\n", argno, para);
     argno++;
     }
     va_end( argp );
     /*將argp置為NULL*/
    return 0;
    }
    2)//示例代碼1:可變參數(shù)函數(shù)的使用
    #include "stdio.h"
    #include "stdarg.h"
    void simple_va_fun(int start, ...)
    {
     va_list arg_ptr;
     int nArgValue =start;
     int nArgCout=0; //可變參數(shù)的數(shù)目
     va_start(arg_ptr,start); //以固定參數(shù)的地址為起點(diǎn)確定變參的內(nèi)存起始地址。
     do
     {
     ++nArgCout;
     printf("the %d th arg: %d\n",nArgCout,nArgValue); //輸出各參數(shù)的值
     nArgValue = va_arg(arg_ptr,int); //得到下一個(gè)可變參數(shù)的值
     } while(nArgValue != -1);
     return;
    }
    int main(int argc, char* argv[])
    {
     simple_va_fun(100,-1);
     simple_va_fun(100,200,-1);
     return 0;
    }
    3)//示例代碼2:擴(kuò)展——自己實(shí)現(xiàn)簡(jiǎn)單的可變參數(shù)的函數(shù)。
    下面是一個(gè)簡(jiǎn)單的printf函數(shù)的實(shí)現(xiàn),參考了中的例子
    #include "stdio.h"
    #include "stdlib.h"
    void myprintf(char* fmt, ...) //一個(gè)簡(jiǎn)單的類(lèi)似于printf的實(shí)現(xiàn),//參數(shù)必須都是int 類(lèi)型
    {
     char* pArg=NULL; //等價(jià)于原來(lái)的va_list
     char c;
     pArg = (char*) &fmt; //注意不要寫(xiě)成p = fmt !!因?yàn)檫@里要對(duì)//參數(shù)取址,而不是取值
     pArg += sizeof(fmt); //等價(jià)于原來(lái)的va_start