可变参数的使用之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_start()來初始化列表為傳入的可變長參數。
然后,通過用va_arg()函數來依次讀取參數列表中的參數。這里va_arg(ap,type)中,ap指參數列表,type指轉換類型。
注意!注意!注意!
type絕對不能為以下類型:
一個float坑了我半個小時!血的教訓啊!
最后,不要忘記用va_end()來釋放參數列表。
在調試這個參數列表的時候,可能在一行報錯,但是其實真正的錯誤在于上一次va_arg()讀取參數的時候。
比如:
從前面的警告可以看出,這里使用了float的類型轉換,是不允許的。但是,那時候我沒發現這個問題。而這個float導致讀取參數出錯。然而,編譯器真正報錯的地方不在此處,而是在下一個類型為(char *)參數讀取使用的時候。害得我找了好久關于指針地址的問題,結果最后發現是前一個float參數的讀取錯誤導致之后的(char *)參數的錯誤讀取,最后導致了bug的出現。
所以,對于可變長參數的使用要非常小心,要考慮更加周全一點點,才能減少bug的出現。
總結
以上是生活随笔為你收集整理的可变参数的使用之va_arg的陷阱s的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【博客】博客资源汇总
- 下一篇: Orangepi Zero播放声音报错的