文章目錄
- 如何發現這個bug的
- 解決方法
- 用原生型別
- if哪怕只有一句話時也加上括號
- 把所要用的變數定義在函式塊的最前面
- 總結
如何發現這個bug的
在前幾天在寫一個問題的代碼:找二叉樹中值為x的結點,并回傳,下面來看看當時寫的代碼,
BT* BinaryTreeFind(BT* root,BTDataType x)
{
if (root == NULL)
return NULL;
if (root->x == x)
return root;
BT* ansleft = BinaryTreeFind(root->left, x);
if (ansleft)
{
return ansleft;
}
BT* ansright = BinaryTreeFind(root->right, x);
if (ansright)
{
return ansright;
}
return NULL;
}
可能很多人看這段代碼并沒有什么問題,甚至在有些編譯器上還能編譯過去,確實,這段代碼我一開始寫完也覺得沒什么問題,可是運行之后總是會報這個錯誤,

這就讓人感覺很疑惑了,我不是定義了ansleft了嗎,為什么會說我沒有定義了?而且為什么會報錯誤1了,BT將此型別用作運算式非法,然后到csdn上去查了下,其實錯誤1是由于c的編譯器要求將變數的申明放在一個函式塊的頭部,
那意思就是我的ansleft沒有定義在函式塊的開頭?這時你又要疑惑了,前面的是if陳述句啊,其實也就相當于把ansleft定義在域的開頭了,為了驗證這個,我還特地測驗了一下
那么問題出哪兒了?其實這是編譯器的一個bug,在某些情況下,編譯器無法識別typedef定義的識別符號,下面我們來看看例子,
此時編譯器可以識別出typedef定義的識別符號,
觸發編譯器無法識別typedef的條件
這里有個注意點:要觸發這個報錯,那個if千萬不能加{},雖說if后面只有一句代碼,可加可不加,但是如果你想要編譯器無法識別出的話,就不要加{},因為你不加{},編譯器就不會把if后面的那塊當成域的開始,如果你加{}的話,編譯器就會把它后面的那塊當成域的開始,這其實也就是一開始那個問題為什么會報錯的原因,
解決方法
用原生型別
既然此時typedef無法識別出你typedef出來的量,那我們不防用它的原生型別,這樣總能識別出來吧,
果真不出我們所料,編譯器此時是可以識別出來的,
if哪怕只有一句話時也加上括號
這種方法其實就是之前提到的,if如果不加{}的話,編譯器在某些情況下不會把后面那塊當成域的開始,那我們就加上{}唄,畢竟這也是一個書寫的好習慣,
可以看到,此時也很順利的編譯過去了,
把所要用的變數定義在函式塊的最前面
既然if沒有加{}在某些情況下,后面的那塊不會被當時域的開始,那我們不防就寫在函式塊的最前面,這樣肯定就是域的開始了吧,
這樣也可以編譯過去,
總結
其實這個問題也不能完全歸納為:有些編譯器可能在某些情況下無法識別typedef定義的識別符號,這里面其實也有:c編譯器的變數必須定義在域的開始的問題,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/298695.html
標籤:其他






