您好,登錄后才能下訂單哦!
利用C++怎么實(shí)現(xiàn)一個(gè)可變參數(shù)函數(shù)?針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。
1. 可變參數(shù)宏實(shí)現(xiàn)變參函數(shù)
可變參數(shù)宏實(shí)現(xiàn)可分為以下幾個(gè)步驟:
上述步驟的實(shí)現(xiàn)需要使用到四個(gè)宏:
va_list 是在C語言中解決變參問題的一組宏
void va_start(va_list ap, last_arg)
ap :是一個(gè) va_list 類型的對(duì)象,它用來存儲(chǔ)通過 va_arg 獲取額外參數(shù)時(shí)所必需的信息。
last_arg :是最后一個(gè)傳遞給函數(shù)的已知的固定參數(shù),即省略號(hào)之前的參數(shù)。
宏定義:type va_arg (va_list ap, type)
該宏用于變參數(shù)函數(shù)調(diào)用過程中,type是當(dāng)前參數(shù)類型,調(diào)用該宏后,ap指向變參數(shù)列表中的下一個(gè)參數(shù),返回ap指向的參數(shù)值,是一個(gè)類型為type的表達(dá)式。 ap是arg_ptr參數(shù)指針之意。
void va_end(va_list ap)
允許使用了 va_start 宏的帶有可變參數(shù)的函數(shù)返回。如果在從函數(shù)返回之前沒有調(diào)用 va_end,則結(jié)果為未定義。
這些宏在頭文件stdarg.h中聲明定義。因此使用時(shí)需要包含該頭文件。
下面給出用法示例:
#include <stdarg.h> //可變參數(shù)函數(shù)sum(),求任意個(gè)數(shù)整數(shù)的和。 //Step1: 函數(shù)形參原型中給出省略符 int Sum(int count, ...); int Sum(int count, ...) { //Step2: 函數(shù)實(shí)現(xiàn)中聲明一個(gè)va_list可變參數(shù)列表變量; va_list ap; //Step3: 開始初始化構(gòu)造va_list變量, 第二個(gè)參數(shù)為最后一個(gè)確定的形參 va_start(ap, count); int sum = 0; for(int i = 0; i < count; i++) { //讀取可變參數(shù),的二個(gè)參數(shù)為可變參數(shù)的類型 sum += va_arg(ap, int); } //清理工作 va_end(ap); return sum; }
實(shí)際中使用可變參數(shù)宏實(shí)現(xiàn)C++可變參數(shù)函數(shù)編程,還要注意一下幾點(diǎn):
2. 更安全的可變參數(shù)函數(shù)實(shí)現(xiàn)方法
對(duì)于上面示例代碼中count傳進(jìn)的實(shí)參如果與后面...省略符對(duì)應(yīng)的實(shí)際參數(shù)數(shù)量不一致時(shí),可能導(dǎo)致函數(shù)風(fēng)險(xiǎn)。這一切完全依賴運(yùn)行時(shí)的具體情況而定,很不安全。
另一種更安全的可變參數(shù)宏實(shí)現(xiàn)方法是利用C++的 attribute ((format()))特性來輔助可變參數(shù)的檢查。
最常見的形式是有如下兩個(gè):
__attribute__((format(printf, m, n))) __attribute__((format(scanf, m, n)))
其中參數(shù)m與n的含義為:
m:第幾個(gè)參數(shù)為格式化字符串(format string);
n:參數(shù)集合中的第一個(gè),即參數(shù)“…”里的第一個(gè)參數(shù)在函數(shù)參數(shù)總數(shù)排在第幾;
attributeformat屬性可以給被聲明的函數(shù)加上類似printf或者scanf的特征,它可以使編譯器檢查函數(shù)聲明和函數(shù)實(shí)際調(diào)用參數(shù)之間的格式化字符串是否匹配。format屬性告訴編譯器,按照printf, scanf等標(biāo)準(zhǔn)C函數(shù)參數(shù)格式規(guī)則對(duì)該函數(shù)的參數(shù)進(jìn)行檢查。這在我們自己封裝調(diào)試信息的接口時(shí)非常的有用。
format的語法格式為:
format (archetype, string-index, first-to-check)
其中,“archetype”指定是哪種風(fēng)格;“string-index”指定傳入函數(shù)的第幾個(gè)參數(shù)是格式化字符串;“first-to-check”指定從函數(shù)的第幾個(gè)參數(shù)開始按上述規(guī)則進(jìn)行檢查。
下面給出2個(gè)示例:
一般函數(shù):
為自己定義的一個(gè)帶有可變參數(shù)的函數(shù),其功能類似于printf:
extern void myprint(const char *format,...) attribute ((format(printf,1,2))); //m=1;n=2 extern void myprint(int l,const char *format,...) attribute ((format(printf,2,3))); //m=2;n=3
類成員函數(shù)
需要特別注意的是,如果myprint是一個(gè)函數(shù)的成員函數(shù),那么m和n的值可有點(diǎn)“懸乎”了,例如:
extern void myprint(int l,const char *format,...) attribute ((format(printf, 3,4 )));
其原因是,類成員函數(shù)的第一個(gè)參數(shù)實(shí)際上一個(gè)隱身的this指針。
關(guān)于利用C++怎么實(shí)現(xiàn)一個(gè)可變參數(shù)函數(shù)問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。