日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

可变参数的使用之va_arg的陷阱s

發布時間:2024/4/24 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 可变参数的使用之va_arg的陷阱s 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在寫程序的時候用到了可變參數,但是在調試程序的時候發現,當可變參數為float類型的時候竟然是出了莫名其妙的一些錯誤,搞得一頭霧水一臉懵逼,上網查查去,看到了這樣的帖子:

轉載自:https://rickyhao.com/?p=37

C 可變長參數va_arg的一些總結和陷阱

?2015-09-14 ?0 Comments??197 Views??0 Times

今天嘗試著使用va_arg來寫一個my_printf()函數,目的就是做到像printf()那樣可以格式化輸出。
首先,想到的就是通過可變長參數來傳遞參數。之所以這樣做是因為我們不能確定每次調用my_printf()的時候,會使用幾個實參。
stdarg.h就是這個可變長參數的頭文件,里面定義了以下幾個函數:

va_start() //使va_list指向起始的參數 va_list() //用來保存宏va_arg與宏va_end所需信息 va_arg() //檢索參數 va_end() //釋放va_list va_copy() //拷貝va_list的內容

大致就是這樣。
我們在定義函數的時候,就可以這樣定義:

void fun(int i,...);

這里的三個點就是代表著可變長參數
然后,我們可以在這個函數內這樣獲得參數:

void fun(int i,...) {va_list var_arg; //定義叫var_arg的參數列表va_start(var_arg,i); //使得var_arg指向可變長參數的位置(也就是...的位置),這里的i變量是用來定位...位置的int num=va_arg(var_arg,int) //將var_arg參數列表中的第一位參數讀取為int類型。va_end(var_arg); //釋放參數列表var_arg }

從上面的示范可以知道,函數定義的時候,可變長參數(…)不能放在形參的第一個必須有一個參數來使得va_start()來定位可變長參數(…)的位置。類型基本隨意。
然后,用va_list()來創建參數列表。并且用va_start()來初始化列表為傳入的可變長參數。
然后,通過用va_arg()函數來依次讀取參數列表中的參數。這里va_arg(ap,type)中,ap指參數列表,type指轉換類型。
注意!注意!注意!
type絕對不能為以下類型:

——char、signed char、unsigned char ——short、unsigned short ——signed short、short int、signed short int、unsigned short int ——float

一個float坑了我半個小時!血的教訓啊!
最后,不要忘記用va_end()來釋放參數列表。

在調試這個參數列表的時候,可能在一行報錯,但是其實真正的錯誤在于上一次va_arg()讀取參數的時候
比如:

va_arg(var_arg,float);

從前面的警告可以看出,這里使用了float的類型轉換,是不允許的。但是,那時候我沒發現這個問題。而這個float導致讀取參數出錯。然而,編譯器真正報錯的地方不在此處,而是在下一個類型為(char *)參數讀取使用的時候。害得我找了好久關于指針地址的問題,結果最后發現是前一個float參數的讀取錯誤導致之后的(char *)參數的錯誤讀取,最后導致了bug的出現。
所以,對于可變長參數的使用要非常小心,要考慮更加周全一點點,才能減少bug的出現。


總結

以上是生活随笔為你收集整理的可变参数的使用之va_arg的陷阱s的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。