前些天偶然看到了一個收集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語言中隱式轉換數據類型遵循長度小的向長度大的轉換,有符號向無符號轉換,字符型轉換爲整形。只要咱們在編程中稍加留意,通常不會出現這樣的問題,何況在本題中,這種循環的寫法,恐怕也只是出題人故意爲之吧,但仍是當心應對爲妙。
以上只是我的觀點,不是之處,歡迎討論。