亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

利用C++怎么實現一個可變參數函數

發布時間:2020-12-07 15:07:32 來源:億速云 閱讀:448 作者:Leah 欄目:開發技術

利用C++怎么實現一個可變參數函數?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

1. 可變參數宏實現變參函數

可變參數宏實現可分為以下幾個步驟:

  1. 函數形參原型中給出省略符;
  2. 函數實現中聲明一個va_list可變參數列表變量;
  3. 開始初始化構造va_list變量;
  4. 訪問變參列表;
  5. 完成清理工作;
     

上述步驟的實現需要使用到四個宏:

  1. va_list
  2. void va_start(va_list ap, last_arg)
  3. type va_arg (va_list ap, type)
  4. void va_end(va_list ap)
     

va_list 是在C語言中解決變參問題的一組宏

void va_start(va_list ap, last_arg)

ap :是一個 va_list 類型的對象,它用來存儲通過 va_arg 獲取額外參數時所必需的信息。

last_arg :是最后一個傳遞給函數的已知的固定參數,即省略號之前的參數。

宏定義:type va_arg (va_list ap, type)

該宏用于變參數函數調用過程中,type是當前參數類型,調用該宏后,ap指向變參數列表中的下一個參數,返回ap指向的參數值,是一個類型為type的表達式。 ap是arg_ptr參數指針之意。

void va_end(va_list ap)

允許使用了 va_start 宏的帶有可變參數的函數返回。如果在從函數返回之前沒有調用 va_end,則結果為未定義。
這些宏在頭文件stdarg.h中聲明定義。因此使用時需要包含該頭文件。

下面給出用法示例:

#include <stdarg.h>

//可變參數函數sum(),求任意個數整數的和。

//Step1: 函數形參原型中給出省略符
int Sum(int count, ...);

int Sum(int count, ...) {
 //Step2: 函數實現中聲明一個va_list可變參數列表變量;
 va_list ap;
 //Step3: 開始初始化構造va_list變量, 第二個參數為最后一個確定的形參
 va_start(ap, count);
 int sum = 0;
 for(int i = 0; i < count; i++) {
  //讀取可變參數,的二個參數為可變參數的類型
  sum += va_arg(ap, int);
 }
 //清理工作
 va_end(ap);
 return sum;
}

實際中使用可變參數宏實現C++可變參數函數編程,還要注意一下幾點:

  • 函數原型中省略號必須在參數列表的末尾:也就是說,在函數原型中參數列表省略號的右邊不能再出現確定參數;
  • 試用完成是用va_end做清理工作步驟不可缺少,否則可能導致內存或資源泄漏;
  • va_list在一次訪問中不能后退,但可以多次構造va_list多次訪問;
     

2. 更安全的可變參數函數實現方法

對于上面示例代碼中count傳進的實參如果與后面...省略符對應的實際參數數量不一致時,可能導致函數風險。這一切完全依賴運行時的具體情況而定,很不安全。

另一種更安全的可變參數宏實現方法是利用C++的 attribute ((format()))特性來輔助可變參數的檢查。

最常見的形式是有如下兩個:

__attribute__((format(printf, m, n))) 
__attribute__((format(scanf, m, n)))

其中參數m與n的含義為:

m:第幾個參數為格式化字符串(format string);

n:參數集合中的第一個,即參數“…”里的第一個參數在函數參數總數排在第幾;

attributeformat屬性可以給被聲明的函數加上類似printf或者scanf的特征,它可以使編譯器檢查函數聲明和函數實際調用參數之間的格式化字符串是否匹配。format屬性告訴編譯器,按照printf, scanf等標準C函數參數格式規則對該函數的參數進行檢查。這在我們自己封裝調試信息的接口時非常的有用。

format的語法格式為:

format (archetype, string-index, first-to-check)
  其中,“archetype”指定是哪種風格;“string-index”指定傳入函數的第幾個參數是格式化字符串;“first-to-check”指定從函數的第幾個參數開始按上述規則進行檢查。

下面給出2個示例:

一般函數:

為自己定義的一個帶有可變參數的函數,其功能類似于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

類成員函數

需要特別注意的是,如果myprint是一個函數的成員函數,那么m和n的值可有點“懸乎”了,例如:

extern void myprint(int l,const char *format,...) attribute ((format(printf, 3,4 )));

其原因是,類成員函數的第一個參數實際上一個隱身的this指針。

關于利用C++怎么實現一個可變參數函數問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

龙南县| 阳曲县| 启东市| 石首市| 黑水县| 韶关市| 闻喜县| 德保县| 三原县| 正镶白旗| 垫江县| 南汇区| 荣昌县| 寿宁县| 聂荣县| 天祝| 喀什市| 建湖县| 柳江县| 仁怀市| 科尔| 乌审旗| 景德镇市| 枣庄市| 正蓝旗| 中超| 绥阳县| 商水县| 静安区| 陈巴尔虎旗| 泗洪县| 石河子市| 望谟县| 安吉县| 峨山| 濮阳县| 盘山县| 陆河县| 临夏县| 建平县| 武汉市|