Possible Duplicate:
Confused about C macro expansion and integer arithmetic
A riddle (in C)可能重复:对C宏展开和整数算法感到困惑
The output of the following C program is to print the elements in the array. But when actually run, it doesn't do so.
下面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;
}
Why is that?
这是为什么呢?
7 个解决方案
#1
4
This fails because sizeof
is returning a value of type size_t
, which is unsigned. This causes the comparison to promote the -1
to unsigned, which is generally a very large value and thus make the comparison fail.
这之所以失败,是因为sizeof返回的是一个类型size_t的值,它是无符号的。这导致比较将-1提升为无符号,这通常是一个很大的值,从而使比较失败。
You should receive warnings for the sign mismatch.
您应该收到符号不匹配的警告。
#2
5
sizeof()
returns unsigned int
and so in the <= comparison, d
gets converted to unsigned int
. -1 when converted to unsigned int
is 0xffffff
. Since 0xffffff > (7-2)
, for-loop body won't be executed even once.
sizeof()返回无符号整型,因此在<=比较中,d被转换为无符号整型。由于0xffffff > (7-2), for循环体甚至不会执行一次。
#3
3
The point is the type of value sizeof
returns.
关键是返回值sizeof的类型。
It's a
size_t
, which is an unsigned type, so converting-1
to that type for the comparison produces the maximal value of the type, which is far larger than 5.它是一个size_t,它是一个未签名的类型,所以将-1转换为该类型的比较会产生类型的最大值,这比5大得多。
#4
1
for(d=-1;d <= ((int)TOTAL_ELEMENTS-2);d++)
#5
1
I guess this is more clear:
我想这更清楚了:
for(d = 0; d < TOTAL_ELEMENTS; d++)
printf("%d\n",array[d]);
And size_t
case should not be a problem anymore.
size_t应该不再是个问题了。
#6
0
Your original problem works, when I do the following:
当我做以下工作时,你的原始问题是有效的:
#define TOTAL_ELEMENTS 7
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;
}
This has something to do with comparing a negative number d=-1 with (TOTAL_ELEMENTS-2). I believe it might be sizeof, butI will leave finding out why as an exercise.
这与将负数d=-1与(TOTAL_ELEMENTS-2)进行比较有关。我相信它可能是尺寸的,但我将把它作为一种练习。
Leaving your original #define as it was --
保留原来的#define
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
#定义TOTAL_ELEMENTS (sizeof(数组)/ sizeof(数组[0]))
-- but using zero-based indexing also worked.
——但是使用基于零的索引也是有效的。
I'm not sure why your original TOTAL_ELEMENTS definition caused the loop not to print.
我不确定为什么原始的TOTAL_ELEMENTS定义导致循环不打印。
#7
0
A more standard way to write this loop which works would be
一个更标准的方法来写这个循环,它是可行的
for(d = 0; d < TOTAL_ELEMENTS; d++)
...
as was pointed out by correctly by several others here already, the problem lies with signed/unsigned values being compared. This construct would have avoided the problem.
正如这里的其他几个人已经正确地指出的那样,问题在于比较有符号/无符号的值。这个构造可以避免这个问题。
#1
4
This fails because sizeof
is returning a value of type size_t
, which is unsigned. This causes the comparison to promote the -1
to unsigned, which is generally a very large value and thus make the comparison fail.
这之所以失败,是因为sizeof返回的是一个类型size_t的值,它是无符号的。这导致比较将-1提升为无符号,这通常是一个很大的值,从而使比较失败。
You should receive warnings for the sign mismatch.
您应该收到符号不匹配的警告。
#2
5
sizeof()
returns unsigned int
and so in the <= comparison, d
gets converted to unsigned int
. -1 when converted to unsigned int
is 0xffffff
. Since 0xffffff > (7-2)
, for-loop body won't be executed even once.
sizeof()返回无符号整型,因此在<=比较中,d被转换为无符号整型。由于0xffffff > (7-2), for循环体甚至不会执行一次。
#3
3
The point is the type of value sizeof
returns.
关键是返回值sizeof的类型。
It's a
size_t
, which is an unsigned type, so converting-1
to that type for the comparison produces the maximal value of the type, which is far larger than 5.它是一个size_t,它是一个未签名的类型,所以将-1转换为该类型的比较会产生类型的最大值,这比5大得多。
#4
1
for(d=-1;d <= ((int)TOTAL_ELEMENTS-2);d++)
#5
1
I guess this is more clear:
我想这更清楚了:
for(d = 0; d < TOTAL_ELEMENTS; d++)
printf("%d\n",array[d]);
And size_t
case should not be a problem anymore.
size_t应该不再是个问题了。
#6
0
Your original problem works, when I do the following:
当我做以下工作时,你的原始问题是有效的:
#define TOTAL_ELEMENTS 7
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;
}
This has something to do with comparing a negative number d=-1 with (TOTAL_ELEMENTS-2). I believe it might be sizeof, butI will leave finding out why as an exercise.
这与将负数d=-1与(TOTAL_ELEMENTS-2)进行比较有关。我相信它可能是尺寸的,但我将把它作为一种练习。
Leaving your original #define as it was --
保留原来的#define
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
#定义TOTAL_ELEMENTS (sizeof(数组)/ sizeof(数组[0]))
-- but using zero-based indexing also worked.
——但是使用基于零的索引也是有效的。
I'm not sure why your original TOTAL_ELEMENTS definition caused the loop not to print.
我不确定为什么原始的TOTAL_ELEMENTS定义导致循环不打印。
#7
0
A more standard way to write this loop which works would be
一个更标准的方法来写这个循环,它是可行的
for(d = 0; d < TOTAL_ELEMENTS; d++)
...
as was pointed out by correctly by several others here already, the problem lies with signed/unsigned values being compared. This construct would have avoided the problem.
正如这里的其他几个人已经正确地指出的那样,问题在于比较有符号/无符号的值。这个构造可以避免这个问题。