2
#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;
}

为什么for循环一次都不运行?

4

5 回答 5

18

问题是sizeof()返回size_t的是未签名的。-1与with的比较TOTAL_ELEMENTS - 2应该会导致警告,表明您已将无符号与有符号进行了比较。发生这种比较时, 将-1转换为无符号值,即MAX_UINT。在 32 位平台上,-1MAX_UINT都是0xFFFFFFFF.

您的TOTAL_ELEMENTS()宏可以包含强制转换,(int)但这在技术上是不正确的,因为size_t它的值范围比int. 最好更改循环变量,使其声明为size_t并且永远不会变为负数。

于 2009-11-05T20:43:34.610 回答
4

您正在混合有符号和无符号算术。sizeof 产生一个 size_t (无符号类型)。当您执行时,d <= (TOTAL_ELEMENTS -2)d转换为无符号,然后进行比较。由于-1在转换为无符号时成为目标类型中的最大值,因此您的条件变为类似于0xffffffff <= 5,它始终为假,因此循环永远不会执行。

于 2009-11-05T20:45:02.047 回答
2

因为TOTAL_ELEMENTS是一个无符号值(type size_t)并且d是一个有符号值(type int,它很可能是在您的平台上签名的,您当然会假设它是即使不是)。在这种情况下,编译器正在转换d为无符号值,并且将 -1 转换为无符号值通常会导致SIZE_MAX或类似的结果,这肯定大于TOTAL_ELEMENTS - 2. 要正确执行此操作,请将无符号值转换为有符号值:(int)(TOTAL_ELEMENTS - 2)

出于好奇,您为什么要从 -1 开始索引,然后在循环中添加 1?为什么不这样做:

unsigned i;
for(i = 0; i < (TOTAL_ELEMENTS); i++)
    printf("%d\n", array[i]);

它会比你所拥有的要清楚得多。

于 2009-11-05T20:46:34.720 回答
0

你可以

#define TOTAL_ELEMENTS ((int)(sizeof(array) / sizeof(array[0])))

假设array总是足够小。毕竟,您使用的是整数来遍历数组的元素。

于 2009-11-05T20:49:08.867 回答
-2

我不确定。sizeof 是否像您认为的那样做?已经有一段时间了,但我认为您可能正在计算int*调用时的大小sizeof (array),即 1(1 个字节)。将它除以一个 int 的大小(通常是 4 个字节)肯定意味着你的循环永远不会运行。

编辑:似乎更有可能将 d 转换为无符号类型。其他海报可能是正确的。

于 2009-11-05T20:46:06.133 回答