以下代码片段的输出是什么?为什么?
What would be the output of the following code snippet and why?
#include <stdio.h>
#include <stdlib.h>
typedef unsigned int U32;
int main() {
U32 var = -1;
printf("var = %u\n", var);
if(var != -1)
{
printf("\n I'm not -1\n");
}
else
{
printf("I'm -1 and Var :%u\n", var);
}
}
此处“-1”应转换为unsigned
int
,并赋值给var
。然后在 if
条件下它不应该等于 -1。但它会进入 else
语句。
在此声明中
if(var != -1)
编译器需要判断操作数的公共类型。这个过程称为通常的算术转换。
来自 C 标准(6.5.9 相等运算符)
4 If both of the operands have arithmetic type, the usual arithmetic
conversions are performed....
相对于通常的算术转换(C标准,6.3.1.8通常的算术转换)
Otherwise, if the operand that has unsigned integer type has rank
greater or equal to the rank of the type of the other operand, then
the operand with signed integer type is converted to the type of the
operand with unsigned integer type.
所以根据 if 语句表达式中的引号,具有 int 类型的整数常量 -1
被转换为 unsigned int 类型,即变量 var
的类型,因为int 和 unsigned int 类型具有相同的等级,变量 var
具有 unsigned int.
类型
结果条件为假。
一个int
,无论是有符号的还是unsigned
都由一系列位表示,如
B1B2...Bn
其中
Bi ∈ {0; 1}
现在最大的代表unsigned
int
看起来像
1111...1
然而,作为有符号值,-1 表示为
1111...1
还有
所以,1111...1 == 1111...1 是正确的。转换为 unsigned
并没有改变任何值,它改变了给定值的感知方式。就记忆表示而言,2^(32-1) 和 -1 实际上是同一个人,穿着不同的衣服。
请注意,所有整型常量(例如 1
)都有一个类型。鉴于 U32
是 unsigned int
,那么:
在U32 var = -1;
(赋值)的情况下,int
类型的右操作数被转换为左操作数的类型。
在 if(var != -1)
的情况下,-1
操作数根据 从类型 int
转换为 unsigned int
通常的算术转换,详情在这里:
在这两种情况下,都会发生有符号到无符号的转换,并且根据 6.3.1.3 明确定义了这种转换:
Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or
subtracting one more than the maximum value that can be represented in the new type
until the value is in the range of the new type.
意味着在上面两种情况下,都会生成相同的无符号值0xFFFFFFFF
。
#include <stdio.h>
#include <stdlib.h>
typedef unsigned int U32;
int main() {
U32 var = -1;
printf("var = %u\n", var);
if(var != -1)
{
printf("\n I'm not -1\n");
}
else
{
printf("I'm -1 and Var :%u\n", var);
}
}
此处“-1”应转换为unsigned
int
,并赋值给var
。然后在 if
条件下它不应该等于 -1。但它会进入 else
语句。
在此声明中
if(var != -1)
编译器需要判断操作数的公共类型。这个过程称为通常的算术转换。 来自 C 标准(6.5.9 相等运算符)
4 If both of the operands have arithmetic type, the usual arithmetic conversions are performed....
相对于通常的算术转换(C标准,6.3.1.8通常的算术转换)
Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
所以根据 if 语句表达式中的引号,具有 int 类型的整数常量 -1
被转换为 unsigned int 类型,即变量 var
的类型,因为int 和 unsigned int 类型具有相同的等级,变量 var
具有 unsigned int.
结果条件为假。
一个int
,无论是有符号的还是unsigned
都由一系列位表示,如
B1B2...Bn
其中
Bi ∈ {0; 1}
现在最大的代表unsigned
int
看起来像
1111...1
然而,作为有符号值,-1 表示为
1111...1
还有
所以,1111...1 == 1111...1 是正确的。转换为 unsigned
并没有改变任何值,它改变了给定值的感知方式。就记忆表示而言,2^(32-1) 和 -1 实际上是同一个人,穿着不同的衣服。
请注意,所有整型常量(例如 1
)都有一个类型。鉴于 U32
是 unsigned int
,那么:
在
U32 var = -1;
(赋值)的情况下,int
类型的右操作数被转换为左操作数的类型。在
if(var != -1)
的情况下,-1
操作数根据 从类型int
转换为unsigned int
通常的算术转换,详情在这里:
在这两种情况下,都会发生有符号到无符号的转换,并且根据 6.3.1.3 明确定义了这种转换:
Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.
意味着在上面两种情况下,都会生成相同的无符号值0xFFFFFFFF
。