#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循环不会运行一次?
答案 0 :(得分:18)
问题是sizeof()
返回未签名的size_t
。 -1
与TOTAL_ELEMENTS - 2
的比较会产生警告,表明您已将unsigned与signed进行了比较。发生此比较时,-1
将转换为无符号值MAX_UINT
。在32位平台上,-1
和MAX_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转换为无符号类型。其他海报可能是正确的。