可能重复:
A riddle (in C)
请参阅此代码
#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;
}
现在这个循环不会运行。 sizeof()将返回无符号值,因此TOTAL_ELEMENTS具有无符号值。 现在,进入for循环,请告诉我,如果一元运算符' - '在signed int 2上工作或隐式转换发生在unsigned中,然后' - '运算符工作。
答案 0 :(得分:8)
在您的示例中, d 在比较中转换为 unsigned int 。但-1不能表示为 unsigned int 值,因此它被转换为UINT_ MAX。要避免此行为,您可以通过预先添加(int)将比较的右侧转换为带符号的 int 。
有关C中整数转换的详细信息,请参阅Understand integer conversion rules。
答案 1 :(得分:2)
d&lt; = TOTAL_ELEMENTS-2中没有一元运算符。
TOTAL_ELEMENTS-2缩减为二进制运算符为 - 的表达式。然后该表达式变为无符号,因为其操作数之一是无符号的。
在d&lt; = TOTAL_ELEMENTS-2的情况下,由于同样的原因,d's类型也被转换为unsigned int。
标准的相关部分是第6.3.1.8#1节(ISO / IEC 9899:1999),其中说:
“否则,如果具有无符号整数类型的操作数的等级大于或等于 等于另一个操作数的类型的等级,然后是操作数 有符号整数类型转换为带有unsigned的操作数的类型 整数类型。“
答案 2 :(得分:2)
是的,d
在该表达式中也有一个无符号类型,因为促销,这就是循环失败的原因。
然而,问题是C编译器是否“认为”:
(unsigned) ((unsigned) 5 - (unsigned) 2)
即。将2提升为无符号,或者:
(unsigned) ((unsigned) 5 - (signed) 2)
即。减法取两种类型的操作数。当然,这没关系,因为两者的操作都是一样的。但是,重点是减法将返回一种类型的值,因此理论上它只能接受该类型的参数。所以它是第一个(unsigned int 2)。
P.S。 (-2)是一元的,而(5 - 2)是二元的。
答案 3 :(得分:0)
我怀疑无符号类型的sizeof()
传播到表达式TOTAL_ELEMENTS-2
,然后传播到d <= TOTAL_ELEMENTS-2
的两个操作数。在(int)
之前插入TOTAL_ELEMENTS
juste可以解决问题。
答案 4 :(得分:0)
看,' - '运算符是一元的是一个愚蠢的事情。忘了它。它是二进制' - ',我意识到。
当2转换为无符号整数时,它变为无符号2,因此TOTAL_ELEMENTS-2的值等于无符号5,然后当d转换为无符号整数时,它得到一个大的正值,并且 所以循环失败了。
发生在这里吗?
是的,我没有写这个代码,这是我在网上找到的一些谜题。 谢谢你们。