為什么不建議使用無符號整型,無符號整型能產(chǎn)生哪些bug?
《C專家編程》有這么幾行代碼。
#include一個數(shù)組,一個宏定義,宏的作用就是計算數(shù)組的元素個數(shù)。int array[] = {23, 34, 12, 17, 204, 99, 16}; #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int main() { int d = -1, x; /* ... */ if (d <= TOTAL_ELEMENTS - 2) x = array[d + 1]; /* ... */ return 0; }
主函數(shù)里面d初始化成-1,判斷語句中用 d 跟 TOTAL_ELEMENTS - 2做比較,如果成立,則給 x 賦值。
代碼很簡單,乍一看,-1 確實小于 5,于是判斷語句肯定成立。
問題就出在了這邊。
d屬于有符號整型,TOTAL_ELEMENTS因為是sizeof的求值結果,所以它屬于無符號整型,把這兩個放在一起運算,很顯然屬于混合運算。
一個是有符號一個是無符號,編譯器默認把有符號數(shù)轉(zhuǎn)換成無符號數(shù),接下來我們可以算一下。
-1的二進制是這樣的:
10000000 00000000 00000000 00000001
因為負數(shù)在內(nèi)存中是以補碼的形式存放,所以先轉(zhuǎn)換成反碼,再轉(zhuǎn)換成補碼。
11111111 11111111 11111111 11111110 11111111 11111111 11111111 11111111
把它轉(zhuǎn)換成無符號數(shù)字,就是最高位不再表示符號位,全部用來表示實際大小。
借助下計算器,-1轉(zhuǎn)換成無符號數(shù)就是這么大:
4294967295
所以判斷語句肯定不成立。
只要編譯器的sizeof返回的是無符號整型,那么這個bug就一直存在。 ?
對無符號類型的建議:
盡量不要在你的代碼中使用無符號類型,以免增加不必要的復雜性。尤其是,不要僅僅因為無符號數(shù)不存在負值(如年齡、國債)而用它來表示數(shù)量。
盡量使用像 int 那樣的有符號類型,這樣在涉及升級混合類型的復雜細節(jié)時,不必擔心邊界情況(如 -1 被翻譯為非常大的正數(shù))。
只有在使用位段和二進制掩碼時,才可以用無符號數(shù)。應該在表達式中使用強制類型轉(zhuǎn)換,使操作數(shù)均為有符號數(shù)或者無符號數(shù),這樣就不必由編譯器來選擇結果的類型。
嵌入式開發(fā)中使用無符號的場景很多,操作地址、寄存器等等,尤其是做單片機等等一些底層開發(fā),隨處可見 unsigned 字樣,這也是由硬件特性決定。使用的時候多加注意,尤其是做一些基本運算的時候。
審核編輯:湯梓紅
-
嵌入式
+關注
關注
5094文章
19184瀏覽量
307856 -
寄存器
+關注
關注
31文章
5367瀏覽量
121221 -
編程
+關注
關注
88文章
3638瀏覽量
94012 -
代碼
+關注
關注
30文章
4830瀏覽量
69091
原文標題:為什么不建議使用無符號整型
文章出處:【微信號:學益得智能硬件,微信公眾號:學益得智能硬件】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論