0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

無符號(hào)整型能產(chǎn)生哪些bug?

學(xué)益得智能硬件 ? 來源:學(xué)益得智能硬件 ? 2023-11-09 17:09 ? 次閱讀

為什么不建議使用無符號(hào)整型,無符號(hào)整型能產(chǎn)生哪些bug?

《C專家編程》有這么幾行代碼。

#include 


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;
}
一個(gè)數(shù)組,一個(gè)宏定義,宏的作用就是計(jì)算數(shù)組的元素個(gè)數(shù)。

主函數(shù)里面d初始化成-1,判斷語句中用 d 跟 TOTAL_ELEMENTS - 2做比較,如果成立,則給 x 賦值。

代碼很簡單,乍一看,-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就一直存在。 344f75b8-7edf-11ee-939d-92fbcf53809c.png ?

對無符號(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)的場景很多,操作地址、寄存器等等,尤其是做單片機(jī)等等一些底層開發(fā),隨處可見 unsigned 字樣,這也是由硬件特性決定。使用的時(shí)候多加注意,尤其是做一些基本運(yùn)算的時(shí)候。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5105

    文章

    19288

    瀏覽量

    310189
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5392

    瀏覽量

    121929
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3649

    瀏覽量

    94356
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4858

    瀏覽量

    69550

原文標(biāo)題:為什么不建議使用無符號(hào)整型

文章出處:【微信號(hào):學(xué)益得智能硬件,微信公眾號(hào):學(xué)益得智能硬件】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    急急急?。?!如何設(shè)定列表框的輸出為數(shù)組或符號(hào)整型?

    各位大神,我在前面板上選定了列表框,用創(chuàng)建屬性節(jié)點(diǎn)的方法設(shè)置了列表框中的項(xiàng)目,然后設(shè)定選擇模式為2(0 or more),輸出應(yīng)該是一維數(shù)組可為什么我把鼠標(biāo)放在輸出端時(shí)及時(shí)幫助顯示還是有符號(hào)32位
    發(fā)表于 11-09 17:33

    if不能判斷有符號(hào)數(shù)的大小?編譯器bug還是我bug了。。。

    ,所以不發(fā)生0xff。我懷疑是if不能判斷正負(fù),于是單獨(dú)編寫了一個(gè)函數(shù)測試,然后是判斷正負(fù)的。所以,我目前的程序出了bug了嗎?有符號(hào)數(shù)的0xfe13絕對是個(gè)負(fù)數(shù)吧,那是哪里搞錯(cuò)了呢?求大神賜教,解決完這個(gè)問題好回家過中秋啊
    發(fā)表于 09-14 10:23

    脈沖波形的產(chǎn)生整型

    脈沖波形的產(chǎn)生整型
    發(fā)表于 01-21 20:33

    是否可以獲得兩個(gè)符號(hào)數(shù)之差的符號(hào)結(jié)果?

    嗨,可能是個(gè)愚蠢的問題。我有兩個(gè)像這樣的符號(hào)變量(XC32):當(dāng)在兩個(gè)變量之間求差時(shí),我得到一個(gè)有符號(hào)的結(jié)果(即,在某個(gè)點(diǎn)上可能有負(fù)值)。為了糾正這個(gè)問題,我得到了結(jié)果的絕對值。我的問題是:我
    發(fā)表于 03-24 07:50

    怎么通過FPGA向DSP發(fā)送有符號(hào)整型數(shù)據(jù)?

    我用的是TL138EVM-F的開發(fā)板,在用FPGA和DSP通信的時(shí)候遇到點(diǎn)問題。我看了創(chuàng)龍的例程有UPP的外部回環(huán)測試,上板也驗(yàn)證成功了。我現(xiàn)在需要做的是通過FPGA向DSP發(fā)送有符號(hào)整型數(shù)據(jù),再
    發(fā)表于 04-01 10:27

    整型數(shù)據(jù)在C語言中的分類

    整型數(shù)據(jù)在C語言中,數(shù)據(jù)包含整型和浮點(diǎn)型兩種數(shù)據(jù),而浮點(diǎn)型又可以轉(zhuǎn)換為二進(jìn)制,最終所有數(shù)據(jù)都會(huì)變成二進(jìn)制。補(bǔ)充:(不考慮有無符號(hào)整型數(shù)據(jù):int,short,long,long lo
    發(fā)表于 11-08 07:36

    符號(hào)整形變量和一般整形變量的區(qū)別

    1.在使用單片機(jī)的時(shí)候注意符號(hào)整形變量和一般整形變量的區(qū)別2.進(jìn)行比較的時(shí)候最好使用一般變量進(jìn)行比較,如果原來變量是符號(hào)變量最好將其進(jìn)行強(qiáng)制類型轉(zhuǎn)換,轉(zhuǎn)換成。一般類型變量進(jìn)行比較3
    發(fā)表于 01-24 06:08

    IAR警告:符號(hào)整數(shù)與零的無意義比較是否合理?

    ;#123;}}問題符號(hào)整型賦值為0啊,為什么會(huì)與0比較無意義?按照警告去消除的話,就變?yōu)閕f(0 < x && x <= 100)
    發(fā)表于 04-07 15:35

    fpga 有符號(hào)數(shù)、符號(hào)數(shù)

    ?在設(shè)計(jì)中,所有的算數(shù)運(yùn)算符都是按照符號(hào)數(shù)進(jìn)行的。如果要完成有符號(hào)數(shù)計(jì)算,對于加、減操作通過補(bǔ)碼處理即可用符號(hào)加法完成。對于乘法操作,
    的頭像 發(fā)表于 10-09 15:22 ?6186次閱讀
    fpga 有<b class='flag-5'>符號(hào)</b>數(shù)、<b class='flag-5'>無</b><b class='flag-5'>符號(hào)</b>數(shù)

    C++編程中整型數(shù)據(jù)在內(nèi)存中存儲(chǔ)是怎么樣的

    1.整型的歸類 char short int long 以上都分為有符號(hào)(signed)與符號(hào)(unsigned)的類型 2.原碼、反碼和補(bǔ)碼 2.1 定義 計(jì)算機(jī)在表示一個(gè)數(shù)字時(shí),
    的頭像 發(fā)表于 09-01 15:22 ?5742次閱讀

    如何取整求個(gè)符號(hào)整數(shù)的平均值

    取整求個(gè)符號(hào)整數(shù)的平均值,居然也整出花兒來?
    的頭像 發(fā)表于 03-18 10:24 ?2568次閱讀

    常見的PLC系統(tǒng)BUG有哪些?如何減少這些BUG產(chǎn)生

    PLC系統(tǒng)可能會(huì)遇到各種不同類型的BUG,以下是一些常見的PLC系統(tǒng)BUG以及如何減少這些BUG產(chǎn)生的建議: (1)邏輯錯(cuò)誤:邏輯錯(cuò)誤是最常見的PLC系統(tǒng)
    的頭像 發(fā)表于 10-31 11:30 ?1303次閱讀
    常見的PLC系統(tǒng)<b class='flag-5'>BUG</b>有哪些?如何減少這些<b class='flag-5'>BUG</b>的<b class='flag-5'>產(chǎn)生</b>?

    常見的PLC系統(tǒng)BUG有哪些?如何減少BUG產(chǎn)生呢?

    PLC系統(tǒng)可能會(huì)遇到各種不同類型的BUG,以下是一些常見的PLC系統(tǒng)BUG以及如何減少這些BUG產(chǎn)生的建議
    的頭像 發(fā)表于 10-31 11:29 ?1015次閱讀

    java中長整型怎么定義

    在Java中,長整型是一種數(shù)據(jù)類型,用于存儲(chǔ)整數(shù)值。它的取值范圍比整型要大,可以存儲(chǔ)更大的整數(shù)值。長整型的大小為8字節(jié),即64位。在Java中,長整型用關(guān)鍵字"long"進(jìn)行聲明和定義
    的頭像 發(fā)表于 11-30 11:29 ?3600次閱讀

    char是有符號(hào)類型還是符號(hào)類型?

    看一個(gè)C語言的筆試題,題目很簡單,問char是有符號(hào)類型還是符號(hào)類型?
    的頭像 發(fā)表于 03-17 10:15 ?1403次閱讀