我在以下课程中缺少什么?

时间:2009-11-05 20:39:44

标签: c sizeof

#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循环不会运行一次?

5 个答案:

答案 0 :(得分:18)

问题是sizeof()返回未签名的size_t-1TOTAL_ELEMENTS - 2的比较会产生警告,表明您已将unsigned与signed进行了比较。发生此比较时,-1将转换为无符号值MAX_UINT。在32位平台上,-1MAX_UINT都是0xFFFFFFFF

您的TOTAL_ELEMENTS()宏可以合并到(int),但这在技术上并不正确,因为size_t的值范围大于int。最好更改循环变量,使其声明为size_t,永远不会变为负数。

答案 1 :(得分:4)

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

答案 2 :(得分:2)

因为TOTAL_ELEMENTS是无符号值(类型size_t)而d是有符号值(类型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]);

这比你拥有的要清楚得多。

答案 3 :(得分:0)

你可以

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

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

答案 4 :(得分:-2)

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

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