打印数组元素

jos*_*osh 3 c arrays

以下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)

是什么原因 ?

zvr*_*rba 6

TOTAL_ELEMENTS没有签名.-1,当转换为unsigned时,是一个非常大的数字,它不小于6.因此,你的循环永远不会运行.


Joh*_*ica 5

进行比较时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)