1.有關整數溢出,直接上代碼
#include<stdio.h>int main(void){int i = 2147483647;unsigned int j = 4294967295;printf("%d*%d**%d\n",i,i+1,i+2);printf("%u*%u**%u\n",i,i+1,i+2);printf("%d*%d**%d\n",j,j+1,j+2);printf("%u*%u**%u\n",j,j+1,j+2);getchar();return 0;}
運行結果如下
2147483647*-2147483648**-2147483647
2147483647*2147483648**2147483649
-1*0**1
4294967295*0**1
知識點講解如下:
當一個整數超過他所能表示的最大值以後,就會迴圈回去繼續從開頭開始,就像是一個環一樣。所以,對於第一個printf和第四個printf不用講解了吧。
那麼對於第二個和第三個printf語句呢?沒錯,還是涉及到資料的儲存管理。可以看我的上一篇文章,當然有興趣的可以這麼理解。如下
對於第二個,我沒什麼說的,很明顯,u的正數範圍比較大,所以,i會一直加一。
對於第三個,因為超出範圍了,所以變為-1。至於為什麼變為-1,也很簡單,
為了協助大家理解,先舉個相同範圍輸出,正常的例子,比如說範圍是0-9,那麼我現在數字是10,那麼迴圈一圈過去,相當於是0。實際上,同樣的,對於不同的資料類型的輸出,也是遵循這種規律的。
針對上面的輸出的第三個為什麼是-1呢,那你也可以這麼想,實際上是4294967295,電腦編譯的時候,發現不是%d類型,比較大,那麼就迴圈幾圈吧,先迴圈一圈吧(這裡所說的全就是指的是資料可表示的長度範圍,對於4294967295,一圈就是4294967296),減小到-1,發現-1在%d的範圍內,所以就是-1了,除以的得到的餘數,不同意的可以自己去驗證,本人已經驗證過了。
總之一句話,如果編譯運行沒錯誤,那麼你就需要按照電腦的思想去理解,他不會出錯,因為他也只是程式而已,既然可以運行,那麼就肯定有可以啟動並執行規則。上面我說的就是一個規則,當然只是理解而已,實際上,電腦只是取位不同,%d取得是低位16個1(注意,我機子32位系統,int型佔32個位元組),然後低位中的最高一位0代表正,1代表-,然後電腦內部計算,取得都是補碼-1,所以值變成-1嘍。(注意,一個是無符號,一個是有符號,補碼值按照不同的公式算)(注意,跟我剛才說的,減一圈,實際上減的就是高位的資料,一直到減為0,實際上電腦根本沒有減為0,直接就捨去了,但是我們可以這樣理解,比較方便)有興趣的可以看上篇文章,比較詳細。還有這篇文章http://bbs.csdn.net/topics/340253678還有這篇文章http://blog.csdn.net/wang6279026/article/details/8114805大部分都是這樣的,都看一遍估計就明白了。
再舉個例子:
printf函數不管你的變數類型,只管按照格式符的含義來解釋資料
例如:
int i=-1;
printf("%u\n",i);
32位平台會輸出4294967295,因為-1的源碼是32個1(在32平台上)
16位的輸出65535
個人理解,歡迎大家批評指正。可能有些地方轉不過去,歡迎交流。
2.格式化輸出
#include<stdio.h>int main(void){unsigned int un = 3000000000;short end = 200;long big = 65537;long long verybig = 12345678908642;printf("%u,%d\n",un,un);printf("%hd,%d\n",end,end);printf("%ld,%hd\n",big,big);printf("%lld,%ld\n",verybig,verybig);getchar();return 0;}
這個程式也可以按照我的自創的那種方法理解。注意:h代表short(16位),l代表long輸出結果是:3000000000,-1294967296
200,200
65537,1
12345678908642,19428999383.顯示八進位和十六進位
#include<stdio.h>int main(void){int x = 100;printf("%d*%o**%x\n",x,x,x);printf("%d*%#o**%#x\n",x,x,x);getchar();return 0;}輸出結果:100*144**64
100*0144**0x644.好了,那我總結一下精髓吧無符號與有符號資料都是迴圈的,但是如果兩個類型不符輸出,實際上是沒有問題的,因為,一個電腦內部的位元,既可以是有符號數,也可以是無符號數,僅此而已。這才是真正的核心。最後舉個小例子:假設平台是8位的,11111111的無符號數是127,有符號數是-1.他們在電腦內部的二進位是一樣的。