一. 周遊可變參數
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);
}
<a></a>
調用方法:“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")