以下代码段的输出是什么,为什么?

时间:2019-10-17 10:11:42

标签: c implicit-conversion arithmetic-expressions

#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语句。

3 个答案:

答案 0 :(得分:3)

请注意,所有整数常量,例如1都有一个类型。假设U32unsigned int,则:

  • 对于U32 var = -1;(分配),类型为int的右操作数将转换为左操作数的类型。

  • if(var != -1)的情况下,按照通常的算术转换-1操作数从类型int转换为unsigned int >,详细信息在这里:Implicit type promotion rules

在两种情况下,都会发生有符号到无符号的转换,并且根据6.3.1.3很好地定义了这种转换:

  

否则,如果新类型是无符号的,则通过重复加或   比新类型可以表示的最大值多减去一个   直到该值在新类型的范围内。

意味着在以上两种情况下,都会生成相同的无符号值0xFFFFFFFF

答案 1 :(得分:2)

在此声明中

if(var != -1)

编译器需要确定操作数的通用类型。此过程称为常规算术转换。 来自C标准(6.5.9相等运算符)

  

4如果两个操作数都具有算术类型,则为常规算术   进行转换。...

相对于常规算术转换(C标准6.3.1.8常规算术转换)

  

否则,如果具有无符号整数类型的操作数具有等级   大于或等于另一个操作数类型的等级,然后   带符号整数类型的操作数将转换为   无符号整数类型的操作数。

因此,根据if语句表达式中的引号,将类型为int的整数常量-1转换为类型为unsigned int的类型,即变量var的类型,因为类型int和unsigned int具有相同的等级,变量var的类型为unsigned int。

结果是条件产生错误。

答案 2 :(得分:-2)

int(无论是带符号还是unsigned)由一系列位表示,例如

  

B1B2 ... Bn

其中

  

Bi∈{0; 1}

现在,最大可表示的unsigned int看起来像

1111...1

但是,作为有符号值,-1表示为

1111...1

也是

因此1111 ... 1 == 1111 ... 1为真。转换为unsigned并没有改变任何值,它改变了感知给定值的方式。就内存表示而言,2 ^(32-1)和-1实际上是同一个家伙,穿着不同的衣服。