C語言迷題:有符號數與無符號數的問題

前些天偶然看到了一個收集C語言迷題的網站,非常感興趣。本人對C/C++語言自己非常感興趣,曾經作過幾年相應的開發,也算是相對比較熟悉的了,但也被其中的一些問題給難住了,畢竟這些問題都是涉及到很是細節的知識,可能在開發中,常常會無心地碰到,雖然百思不得其解,但也會無心地就被咱們本身給繞過去了。 html

出於對技術細節的瞭解,接下來將會摘錄一些問題,進行分析。 編程

先來看看今天這個問題的代碼吧。 數組


#include<stdio.h>

  #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
  int array[] = {23,34,12,17,204,99,16};

  int main()
  {
      int d;

      for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
          printf("%d\n",array[d+1]);

      return 0;
  }
很是完美的代碼,不是嗎?但是不管你是否相信,你就是看不到須要的結果。


問題就出在了for循環中的數字的比較中。 網站

首先,咱們看到,d是int型,是有符號數;而後再看看宏定義呢,宏裏邊使用了sizeof來計算數組的容量,根據C語言標準,sizeof應該返回的是size_t數據類型,而size_t定義爲以下類型: spa


typedef unsigned long size_t;
說明宏返回的結果應該是一個 un signed long 類型的值。


那麼這兩個類型的數字進行比較,會出現什麼結果呢? code

對了,int型的d會被隱式轉換成unsigned long類型,讓咱們來試試轉換吧。 htm

在的值是-1,其在機器內的補碼錶示爲: 開發

    1111111111111111,即爲:0xFFFF get

而後在轉換的時候,系統會根據轉換的狀況,因爲int型的長度沒有unsigned long長,所以會根據int型數字的高位進行擴展,擴展後的結果,便得d變成了以下數字: io

    11111111111111111111111111111111,即:0xFFFFFFFF

好了如今你應該明白爲何輸出不告終果了吧。

最後讓咱們來作個總結,通常狀況下,在C語言中隱式轉換數據類型遵循長度小的向長度大的轉換,有符號向無符號轉換,字符型轉換爲整形。只要咱們在編程中稍加留意,通常不會出現這樣的問題,何況在本題中,這種循環的寫法,恐怕也只是出題人故意爲之吧,但仍是當心應對爲妙。

以上只是我的觀點,不是之處,歡迎討論。

相關文章
相關標籤/搜索