以下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;
}
原因是什么?
最佳答案
进行比较时,将执行类型转换。d <= (TOTAL_ELEMENTS-2)
属于d
类型,signed int
属于(TOTAL_ELEMENTS-2)
类型,这是一种无符号类型。c的规则规定,当运算符有一个有符号和一个无符号参数,且无符号参数的大小大于或等于有符号参数时,则将有符号参数转换为无符号参数。
也就是说,比较结果是:
(size_t) d <= (TOTAL_ELEMENTS-2)
因为
size_t
是无符号的,size_t
是一个非常非常大的数字,不再是-1。对于32位(size_t) -1
来说,它是232-1=4294967295。要解决此问题,可以显式地将右侧强制转换为带符号的int:
d <= (int) (TOTAL_ELEMENTS-2)
或者,更好的是,摆脱怪异的负面索引等等。
为了以后的参考,打开所有编译器警告。例如,如果您打开
size_t
,gcc将打印一个警告:$ gcc -o arrayprint -Wall -Wextra -ansi arrayprint.c
arrayprint.c: In function ‘main’:
arrayprint.c:11: warning: comparison between signed and unsigned