sizeof
返回一個無符號整數,所以TOTAL_ELEMENTS
也是無符號的。
d
已簽名。起初,d
是-1
。但是,這樣做比較時,d
被隱式類型強制轉換爲無符號,因此它不再-1
被比較TOTAL_ELEMENTS
時,它實際上是UINT_MAX
(這是4294967295
我的機器上,但可能會爲其他人的不同)。
此外,
如果要解決這個問題,強制轉換TOTAL_ELEMENTS
到int
:
for(d = -1; d <= (int)(TOTAL_ELEMENTS - 2); d++)
這將打印:
23
34
12
17
204
99
16
正如你所期望。您可能還想查看Comparison operation on unsigned and signed integers以獲取有關signed-unsigned比較主題的更多信息。
值得注意的是開啓編譯器警告就已經幫助你弄清楚發生了什麼事情(如海德在他comment觀察):
$ gcc -Wall -Wextra test.c
test.c:7:17: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
for(d = 0; d < TOTAL_ELEMENTS; d++)
~^~~~~~~~~~~~~~~
1 warning generated.
或者,爲什麼不開始d
在0
並運行到TOTAL_ELEMENTS - 1
而不是?您甚至可以刪除類型轉換,僅在d = -1
的情況下才需要。
for(d = 0; d < TOTAL_ELEMENTS; d++)
printf("%d\n", array[d]);
作爲一個註腳,這裏有相關的C99標準摘錄:
6.3.1.8p2從符號到無符號類型定義的轉換。
如果具有無符號整數類型的操作數的秩大於或等於另一個操作數的類型的秩,然後 用符號整型操作數被轉換爲 操作數與無符號整數的類型類型。
6.3.1.3p2定義轉換是如何完成的:通過添加UINT_MAX + 1
的符號表示。
如果新類型是無符號的,則該值是通過重複地加上或減去小於能夠在新的類型來表示,直到該值是在 範圍的新類型的最大值 多一個轉換。
所以-1
=>-1 + (UINT_MAX + 1)
= UINT_MAX
,對於這種情況。
用硬編碼的變量名宏是自找麻煩。 – jackarms
更改字符'D = 0'做輸出的東西雖然 –
@TonyTannous但它沒有解釋什麼是在OP – CIsForCookies