為什么不建議使用無符號(hào)整型,無符號(hào)整型能產(chǎn)生哪些bug?
《C專家編程》有這么幾行代碼。
#include一個(gè)數(shù)組,一個(gè)宏定義,宏的作用就是計(jì)算數(shù)組的元素個(gè)數(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 賦值。
代碼很簡(jiǎn)單,乍一看,-1 確實(shí)小于 5,于是判斷語句肯定成立。
問題就出在了這邊。
d屬于有符號(hào)整型,TOTAL_ELEMENTS因?yàn)槭莝izeof的求值結(jié)果,所以它屬于無符號(hào)整型,把這兩個(gè)放在一起運(yùn)算,很顯然屬于混合運(yùn)算。
一個(gè)是有符號(hào)一個(gè)是無符號(hào),編譯器默認(rèn)把有符號(hào)數(shù)轉(zhuǎn)換成無符號(hào)數(shù),接下來我們可以算一下。
-1的二進(jìn)制是這樣的:
10000000 00000000 00000000 00000001
因?yàn)樨?fù)數(shù)在內(nèi)存中是以補(bǔ)碼的形式存放,所以先轉(zhuǎn)換成反碼,再轉(zhuǎn)換成補(bǔ)碼。
11111111 11111111 11111111 11111110 11111111 11111111 11111111 11111111
把它轉(zhuǎn)換成無符號(hào)數(shù)字,就是最高位不再表示符號(hào)位,全部用來表示實(shí)際大小。
借助下計(jì)算器,-1轉(zhuǎn)換成無符號(hào)數(shù)就是這么大:
4294967295
所以判斷語句肯定不成立。
只要編譯器的sizeof返回的是無符號(hào)整型,那么這個(gè)bug就一直存在。

對(duì)無符號(hào)類型的建議:
盡量不要在你的代碼中使用無符號(hào)類型,以免增加不必要的復(fù)雜性。尤其是,不要僅僅因?yàn)闊o符號(hào)數(shù)不存在負(fù)值(如年齡、國債)而用它來表示數(shù)量。
盡量使用像 int 那樣的有符號(hào)類型,這樣在涉及升級(jí)混合類型的復(fù)雜細(xì)節(jié)時(shí),不必?fù)?dān)心邊界情況(如 -1 被翻譯為非常大的正數(shù))。
只有在使用位段和二進(jìn)制掩碼時(shí),才可以用無符號(hào)數(shù)。應(yīng)該在表達(dá)式中使用強(qiáng)制類型轉(zhuǎn)換,使操作數(shù)均為有符號(hào)數(shù)或者無符號(hào)數(shù),這樣就不必由編譯器來選擇結(jié)果的類型。
嵌入式開發(fā)中使用無符號(hào)的場(chǎng)景很多,操作地址、寄存器等等,尤其是做單片機(jī)等等一些底層開發(fā),隨處可見 unsigned 字樣,這也是由硬件特性決定。使用的時(shí)候多加注意,尤其是做一些基本運(yùn)算的時(shí)候。
審核編輯:湯梓紅
-
嵌入式
+關(guān)注
關(guān)注
5152文章
19676瀏覽量
317697 -
寄存器
+關(guān)注
關(guān)注
31文章
5434瀏覽量
124571 -
編程
+關(guān)注
關(guān)注
88文章
3689瀏覽量
95276 -
代碼
+關(guān)注
關(guān)注
30文章
4900瀏覽量
70769
原文標(biāo)題:為什么不建議使用無符號(hào)整型
文章出處:【微信號(hào):學(xué)益得智能硬件,微信公眾號(hào):學(xué)益得智能硬件】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
急急急!!!如何設(shè)定列表框的輸出為數(shù)組或無符號(hào)整型?
if不能判斷有符號(hào)數(shù)的大小?編譯器bug還是我bug了。。。
是否可以獲得兩個(gè)無符號(hào)數(shù)之差的無符號(hào)結(jié)果?
怎么通過FPGA向DSP發(fā)送有符號(hào)整型數(shù)據(jù)?
整型數(shù)據(jù)在C語言中的分類
無符號(hào)整形變量和一般整形變量的區(qū)別
IAR警告:無符號(hào)整數(shù)與零的無意義比較是否合理?
fpga 有符號(hào)數(shù)、無符號(hào)數(shù)

C++編程中整型數(shù)據(jù)在內(nèi)存中存儲(chǔ)是怎么樣的
常見的PLC系統(tǒng)BUG有哪些?如何減少這些BUG的產(chǎn)生?

評(píng)論