return1在c語言中是什么意思 1在c語言中是什么意思( 二 )


有符號數到無符號數的隱式強制類型轉換導致了某些非直觀的行為 。而這些非直觀的特性經常導致程序錯誤,并且這種包含隱式強制類型轉換的細微差別的錯誤很難被發現 。
4 擴展一個整型數字的位表示一個常見的運算是在不同字長的整數之間轉換,同時又保持數值不變 。
對于有符號整數和無符號整數,兩者在擴展時,高位的符號擴展有所區別:
short sx = val; /* -12345 */unsigned short usx = sx; /* 53191 */int x = sx; /* -12345 */unsigned ux = usx; /* 53191 */在采用補碼表示的32 位大端法機器上的內存布局:

return1在c語言中是什么意思  1在c語言中是什么意思

文章插圖
有符號整型使用1來做符號擴展 。
無符號整型使用0來做符號擴展 。
return1在c語言中是什么意思  1在c語言中是什么意思

文章插圖
有符號整數在做右移運算時,也會存在符號擴展的問題 。
5 截斷數字假設我們不用額外的位來擴展一個數值,而是減少表示一個數字的位數 。例如下面代碼中這種情況:
int x = 53191;short sx = (short) x;/* -12345 */int y = sx;/* -12345 */當我們把x 強制類型轉換為short 時,我們就將 32 位的int 截斷為了 16 位的short int 。
return1在c語言中是什么意思  1在c語言中是什么意思

文章插圖
當將一個w位的整型數截斷為一個k位整型數字時,我們會丟棄高w-k位 。
無符號整數取模:
有符號整數的補碼取模后要做轉換 :
6 整數運算與溢出C語言的整型數字是一個有限字長的表示,當在計算時存在溢出時,會做模運算處理 。
當兩個w位的無符號整型相加時,其結果可能是一個w+1位的無符號數 。
return1在c語言中是什么意思  1在c語言中是什么意思

文章插圖
當兩個w位的無符號整型相加時其和等于或超過時,就會發生溢出,其結果為和與的模運算:
return1在c語言中是什么意思  1在c語言中是什么意思

文章插圖
補碼加法存在正溢出與負溢出:
return1在c語言中是什么意思  1在c語言中是什么意思

文章插圖
首先要明白,一個正數和一個負數相加,結果一定不會溢出(因為結果的絕對值一定小于兩個加數的絕對值,兩個加數都表達出來了,結果一定能表達出來 。)
所以,發生溢出的情況一定是符號相同的兩個數相加 。
分情況討論:
① 正整數pa + 正整數pb = r
符號位0,數位相加,如果結果的符號位變成1了,那一定是兩個加數的更高位相加進上來的 。
假設將一個長度 w=4 的0、1 串映射到有符號整數,其更大的正數只能是0111,也就是7 。
0111+0001 = 1000 // 7 + 1 = 8-2^4 = -8,向下溢出
0111+0011 = 1010 // 7+ 3 = 10-2^4 = -6,向下溢出
發生向下溢出,判斷的方式之一是:r<pa || r<pb 。
② 負整數na + 負整數nb = r
符號位都是1,所以符號位一定會進位 。數位相加,如果最后符號位是0,說明結果變成正的了,那一定是發生溢出了(負+負!=正) 。
假設將一個長度 w=4 的0、1 串映射到有符號整數,其最小的負數只能是1000,也就是-8 。
1000+1111 = 11000 ->0110 // -8+(-1) = -9+2^4 = 7,向上溢出
1011+1011 = 10110 ->0110 // -5+(-5) = -10+2^4 = 6,向上溢出
另外一種情況,沒有改變符號位的溢出,屬正常溢出,正如有符號位擴展、算術移位一樣:
1100+1100 = 10000 ->0000 // -4+(-4)= -8,正常溢出
1111+1111 = 11110 ->1110 // -1+(-1)=-2,正常溢出
發生向上溢出,判斷的方式之一是:r<pa || r<pb 。

return1在c語言中是什么意思  1在c語言中是什么意思

文章插圖
CPU的標志寄存器有一個溢出標志位,反映有符號數加減運算是否溢出 。如果運算結果超過了8位或者16位有符號數的表示范圍,則OF置1,否則置0 。
7 整數的乘除① 兩整數乘除的結果還是一個整數類型(類型一致),如果是除法,可能存在舍入(舍入到零,向上舍入,向下舍入)的情況;
② 兩整數乘法要考慮溢出的情況 。
③ 位運算也是一種特殊的整數乘除,乘數與除數是2的不同的整數冪(當一個整數乘除一個常數時,這個常數如果不是某個整數次冪,可以拆解成不同的冪次的加減) 。
8 代碼示例8.1 帶符號數產生意外結果的例子 。這個例子會造成無限循環,因為sizeof會返回unsigned int 類型,由此帶來的結果是,i - sizeof(char)這個表達式的求值結果將會是 unsigned int (隱式轉換 !!),i 會隱式轉換為unsigned,i從 0 減 1 后變成-1,其二進制編碼是 0xFFFFFFFF,轉換成無符號數是2^32-1,從而產生無限循環,有時候你需要特別留心這種不經意的錯誤 !

推薦閱讀