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