程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> C Primer Plus 02

C Primer Plus 02

編輯:關於C
[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.他們在計算機內部的二進制是一樣的。    
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved