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