[cpp]
#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.格式化輸出
[cpp]
#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,1942899938
3.顯示八進制和十六進制
[cpp]
#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**0x64
4.好了,那我總結一下精髓吧
無符號與有符號數據都是循環的,但是如果兩個類型不匹配輸出,實際上是沒有問題的,因為,一個計算機內部的二進制數,既可以是有符號數,也可以是無符號數,僅此而已。這才是真正的核心。
最後舉個小例子:假設平台是8位的,11111111的無符號數是127,有符號數是-1.他們在計算機內部的二進制是一樣的。