前言html
在C++中使用可變參數可沒C#中那麼方便,使用起來也很麻煩,想盡辦法搜了不少資料仍然無果,可是確有一些心得。
網絡
文章
ide
1. http://www.programmer-club.com.tw/ShowSameTitleN/vc/13915.html函數
2. va_list、va_start、va_arg、va_end的原理與使用spa
正文.net
一. 遍歷可變參數code
1.1 傳入的時候指定參數個數orm
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);
htm
}
blog
調用方法:「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
(...)
{
bResult
=
FALSE;
}
va_end(ap);
return
bResult;
}
代碼說明:
這段代碼是在使用Sqlite時封裝的一段代碼,儘可能保持了C#的命名比較習慣一點,這段代碼只是編譯經過了,這裏僅用於說明這個道理和用法,是否是和Format很像 :)
i. 使用:ExecuteNonQuery("update test set c1 = ? where id = ? ","abc","1")
結束
正文一段內容中代碼均來自網絡,多爲轉載,不知原始出處,仍謝之!