可能重复:
Confused about C macro expansion and integer arithmetic
A riddle (in C)
以下C程序的输出是打印数组中的元素。但实际运行时,它不会这样做。
#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;
}
为什么?
答案 0 :(得分:5)
sizeof()
会返回unsigned int
,因此在&lt; =比较中,d
会转换为unsigned int
。 -1转换为unsigned int
时为0xffffff
。由于0xffffff > (7-2)
,for循环体不会被执行一次。
答案 1 :(得分:4)
此操作失败,因为sizeof
返回的值为size_t
的值为无符号。这导致比较将-1
提升为无符号,这通常是一个非常大的值,从而使比较失败。
您应该收到有关标志不匹配的警告。
答案 2 :(得分:3)
这一点是值sizeof
返回的类型。
这是一个
size_t
,它是一个无符号类型,因此将-1
转换为该类型进行比较会产生该类型的最大值,该值远大于5.
答案 3 :(得分:1)
for(d=-1;d <= ((int)TOTAL_ELEMENTS-2);d++)
答案 4 :(得分:1)
我想这更清楚:
for(d = 0; d < TOTAL_ELEMENTS; d++)
printf("%d\n",array[d]);
并且size_t
案件不再是问题。
答案 5 :(得分:0)
编写此循环的更标准方法是
for(d = 0; d < TOTAL_ELEMENTS; d++)
...
正如其他几位已正确指出的那样,问题在于比较有符号/无符号值。这种结构可以避免这个问题。
答案 6 :(得分:0)
当我执行以下操作时,您的原始问题有效:
#define TOTAL_ELEMENTS 7
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;
}
这与将负数d = -1与(TOTAL_ELEMENTS-2)进行比较有关。我相信它可能是尺寸,但我会留下找出为什么作为练习。
保留原来的#define原样 -
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
- 但使用从零开始的索引也有效。
我不确定为什么原来的TOTAL_ELEMENTS定义导致循环无法打印。