關於有無符號數

2021-06-19 00:10:05 字數 1080 閱讀 5712

《c專家程式設計》中對在使用有無符號數有的使用以下三點建議:

1.盡量不要在你的**中使用無符號數,以免增加不必需要的複雜性。尤其是,不要僅僅因為無符號數不存在負值(如年齡,國債)而用它來表示數量。

2.盡量使用像int那樣的有符號型別,這樣在涉及公升級混合型別的複雜細節時,不必擔心邊界情況(如-1被翻譯為非常大的正數)。

3.只有在使用位段和二進位制掩碼時,才可以用無符號數。應該在表示式中使用強制型別轉換,使運算元均為有符號或無符號數,這樣就不必由編譯器來選擇結果的型別。

1,2點可以合成一點,說的其實就是盡量不要使用無符號數,多使用有符號數,而第三點說明了無符號數的適用範圍。並強調了在處理表示式的時候是運算元型別一致的原則(同為有符號或無符號),這樣可以減少一些麻煩和錯誤。

另外,ansi c在對有符號數和無符號數進行運算時也給出了乙個標準(我在這裡就不談k&r c中的說法了):

當執行算術運算的時候,運算元的型別如果不同,就會發生轉換。資料型別一般朝著浮點精度更高、長度更長的方向轉換,整型數如果轉換為signed不會丟失資訊,就轉換為signed,否則轉換為unsigned。

下面有幾個例子: 1.

#include

#include

int main()

結果應該是 -1 但是卻得到:2147483647 。為什麼?因為strlen的返回值,型別是size_t,也就是unsigned int ,與 int 混合計算時型別被自動轉換了,結果自然出乎意料。。。

觀察編譯後的**,除法指令為 div ,意味無符號除法,即將-2看做無符號數了。

解決辦法就是強制轉換,變成 int y = (int)(x - strlen(str) ) / 2; 強制向有符號方向轉換(編譯器預設正好相反),這樣一來,除法指令編譯成 idiv 了。

2.void foo(void)

這個問題測試你是否懂得c語言中的整數自動轉換原則,我發現有些開發者懂得極少這些東西。不管如何,這無符號整型問題的答案是輸出是 」>6」。原因是當表示式中存在有符號型別和無符號型別時所有的運算元都自動轉換為無符號型別。因此-20變成了乙個非常大的正整數,所以該表示式計算出的結果大於6。這一點對於應當頻繁用到無符號資料型別的嵌入式系統來說是丰常重要的。

C語言有無符號資料運算錯誤

例如 c語言中在帶符號資料的運算過程中,若同時存在有符號和無符號變數,則會隱式的將有符號數轉換為無符號數進行運算。其中典型的程式 include float sum float a,unsigned length return result int main float result result ...

C 有 無符號數字型別之間的比較

在kmp.cpp中的迴圈,迴圈判斷下標 int型別 與std string size type型別比較發生了迴圈只執行一部分的問題。int i j 0 while i s.size j p.size 在這段 當中,出現了j p.size 但是卻不執行迴圈的情況。原因是當j為 1的時候,j p.siz...

有符號數與無符號數

關於有符號數和無符號數的一些重要知識點,包括它們在記憶體中的儲存方式 互相轉換 越界計算等。大家肯定都知道,對於有符號數,資料型別的最高位用於標示資料的符號,最高位為1表示負數,最高位為0表示正數,那麼今天我們主要就此討論乙個問題 在計算機內部具體是如何表示有符號數呢?在計算機內部是通過補碼的方式來...