標籤:
廢話不說,先來一段程式,諸位童鞋們猜猜這段程式的輸出:
#include<stdio.h>
#define MAX 255
int main(int argc, char **argv) {
unsigned char i, a[MAX];
for(i = 0; i <= MAX; i++) {
a[i] = i;
}
for(i = 0; i <= MAX; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
童鞋們可以在你們的電腦上跑一下上面代碼,有驚喜奧
還在等待輸出嗎?不用等了,永遠不會有輸出了,因為這是個死迴圈。話說哪來的死迴圈呢?這便要談一談電腦整型資料的表示範圍和資料溢出啦
看到這裡,我們要思考:對於unsigned char i = 255;i + 1 = ?
電腦中的加減乘除並不像我們平常數學中那樣,因為在數學中你已經假設了資料範圍為無窮大。但在電腦中,資源是有限的,為了充分利用資源,我們規定了佔有不同位的資料類型。如unsigned char,它和char一樣是8位,區別是首位不用做符號位,於是有:0000 0000 - 1111 1111 ,二進位轉化為十進位就是0 - 255.現在再討論上述程式:
1111 1111
+ 1
--------------------
1 0000 0000
上面我們說了,對於各種資料類型,用於表示表示的位元是固定的,那麼結果中的首位的1便會由於沒地方儲存而捨棄,於是你驚奇的發現 255 + 1 = 0
其實再思考上面的計算過程溢出位,我們發現按權值計算溢出位的表示大小相當於:溢出位*2^8.例如上面捨棄的1表示的實際大小為 1*2^8 = 256,
分析上面捨棄的行為,你會發現數學上有相對應的操作,它就是模數
好了,經過上面的分析,你應該會發現什麼,總結一下不帶正負號的整數的計算,再類推到有符號整數
對於溢出問題,提出如下問題以供思考:
1.有符號數和無符號數之間的轉化(不同資料類型之間轉化)
2.無符號加法,無符號乘法
3.有符號加法,有符號乘法
電腦與數學之資料範圍