天天看點

[C++]周遊可變參數 (va_list)

正文

  一.  周遊可變參數

    1.1  傳入的時候指定參數個數

void arg_cnt(int cnt, ...)

{

    int value=0;

    int i=0;

    int arg_cnt=cnt;

    va_list arg_ptr; 

    va_start(arg_ptr, cnt); 

    for(i = 0; i < cnt; i++)

    {

        value = va_arg(arg_ptr,int);

        printf("value%d=%d\n", i+1, value);

    }

    va_end(arg_ptr);

      調用方法:“arg_cnt(4,1,2,3,4);”,第一個參數為傳入參數個數。

    1.2  傳入的時候指定特殊的字元以标示為結

int demo( char msg, ... )

    va_list argp;

    int argno = 0;

    char para;

    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 );

    return 0;

      調用方法:“demo("DEMO", "This", "is", "a", "demo!", "");”,最後一個參數标示結束。

  二.  探讨CString的Format方法

    在學可變參數這節的時候一直很向往能達到這種效果,即不用多傳一個參數來指定結束。我臆斷有兩種情況來實作:

    a).  編譯器做了手腳

      編譯之後有可能改變了函數多傳入了一個參數的個數,有幾個參數編譯的時候是能夠知道的。

    b).  使用"%"作為特殊符号

      實踐中發現如果有%字元出現在Format中的話是會報錯的,所有我推斷他統計了"%"出現的次數,然後解析"%"後面的參數,比如"%d"、"%s",通過統計"%"出現的次數就能夠解決參數個數的難度,也就不用我們傳入參數個數來實作周遊了。

    c).  類似實作代碼

int FindCharCount(CString csStr,char c)

    int iCount = 0;

    for(int i=0;i<csStr.GetLength();i++)

       i = csStr.Find(c ,i + 1 );

       iCount++;

    return iCount;

}

BOOL CppSQLite3Helper::ExecuteNonQuery(char * commandText,const char *params...)

    BOOL bResult = TRUE;

    va_list ap;

    try

        va_start(ap,params);

        CppSQLite3Statement stmt = m_db.compileStatement(commandText);

        for(int i = 0 , j = FindCharCount(CString(commandText),'?')  ; i < j ; i ++)

        {

            stmt.bind(i,va_arg(ap,char *));

        }

        stmt.execDML();

    catch(CppSQLite3Exception e)

        bResult = FALSE;

    catch(...)

    va_end(ap);

    return bResult;

      代碼說明:

        這段代碼是在使用Sqlite時封裝的一段代碼,盡量保持了C#的命名比較習慣一點,這段代碼隻是編譯通過了,這裡僅用于說明這個道理和用法,是不是和Format很像 :)

        i.  使用:ExecuteNonQuery("update test set c1 = ? where id = ? ","abc","1")

本文轉自over140 51CTO部落格,原文連結:http://blog.51cto.com/over140/583022,如需轉載請自行聯系原作者