為什么不建議使用無符號整型,無符號整型能產(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的求值結(jié)果,所以它屬于無符號整型,把這兩個放在一起運算,很顯然屬于混合運算。
一個是有符號一個是無符號,編譯器默認把有符號數(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就一直存在。
?對無符號類型的建議:
盡量不要在你的代碼中使用無符號類型,以免增加不必要的復(fù)雜性。尤其是,不要僅僅因為無符號數(shù)不存在負值(如年齡、國債)而用它來表示數(shù)量。
盡量使用像 int 那樣的有符號類型,這樣在涉及升級混合類型的復(fù)雜細節(jié)時,不必擔心邊界情況(如 -1 被翻譯為非常大的正數(shù))。
只有在使用位段和二進制掩碼時,才可以用無符號數(shù)。應(yīng)該在表達式中使用強制類型轉(zhuǎn)換,使操作數(shù)均為有符號數(shù)或者無符號數(shù),這樣就不必由編譯器來選擇結(jié)果的類型。
嵌入式開發(fā)中使用無符號的場景很多,操作地址、寄存器等等,尤其是做單片機等等一些底層開發(fā),隨處可見 unsigned 字樣,這也是由硬件特性決定。使用的時候多加注意,尤其是做一些基本運算的時候。
審核編輯:湯梓紅
-
嵌入式
+關(guān)注
關(guān)注
5210文章
20680瀏覽量
337374 -
寄存器
+關(guān)注
關(guān)注
31文章
5620瀏覽量
130455 -
編程
+關(guān)注
關(guān)注
90文章
3724瀏覽量
97458 -
代碼
+關(guān)注
關(guān)注
30文章
4977瀏覽量
74419
原文標題:為什么不建議使用無符號整型
文章出處:【微信號:學益得智能硬件,微信公眾號:學益得智能硬件】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
傳遞一個無符號的 long 型指針給函數(shù)
急急急?。。∪绾卧O(shè)定列表框的輸出為數(shù)組或無符號整型?
if不能判斷有符號數(shù)的大小?編譯器bug還是我bug了。。。
是否可以獲得兩個無符號數(shù)之差的無符號結(jié)果?
怎么通過FPGA向DSP發(fā)送有符號整型數(shù)據(jù)?
整型數(shù)據(jù)在C語言中的分類
IAR警告:無符號整數(shù)與零的無意義比較是否合理?
fpga 有符號數(shù)、無符號數(shù)
C++編程中整型數(shù)據(jù)在內(nèi)存中存儲是怎么樣的
常見的PLC系統(tǒng)BUG有哪些?如何減少這些BUG的產(chǎn)生?
無符號整型能產(chǎn)生哪些bug?
評論