11
main()  {   
  if ( -1 < (unsigned char) 1 )
    printf("less than");
  else        
    printf("NOT less than");
} 

打印less than。因为,(unsigned char) 1 被转换为 (signed char) 1然后: (signed) -1 < (signed) 1, 因此输出是less than.

但是如果我将上面的代码更改if ( (-1 < (unsigned int) 1 )

那么输出是NOT less than

所以很明显,当我将 unsigned char 更改为 unsigned int 时:

  • (有符号)-1 转换为无符号整数 [正好相反]
  • 因为 -1 存储为 2 对 1 的补码;位模式被评估为 255(可能)
  • 因此 255 < 1 将评估为 false,否则将执行。
  • 即使你用int a = -1;'-1'代替相同的结果

问题:

  1. 在有符号和无符号算术期间......如何确定是否将有符号转换为无符号,反之亦然。

  2. 为什么 unsigned char 和 char 之间的算术转换不同:显然 unsigned 被转换为有符号和无符号 int 和 int :显然有符号是转换器到无符号

PS:我知道这不依赖于编译器..所以不要说它是。

4

2 回答 2

10

规则如下:

6.3.1.8 常用算术转换

...

否则,对两个操作数都执行整数提升。然后将以下规则应用于提升的操作数:

  1. 如果两个操作数具有相同的类型,则不需要进一步转换。
  2. 否则,如果两个操作数都具有有符号整数类型或都具有无符号整数类型,则具有较小整数转换等级的类型的操作数将转换为具有较高等级的操作数的类型。
  3. 否则,如果无符号整数类型的操作数的等级大于或等于另一个操作数类型的等级,则将有符号整数类型的操作数转换为无符号整数类型的操作数的类型。
  4. 否则,如果有符号整数类型的操作数的类型可以表示无符号整数类型的操作数类型的所有值,则将无符号整数类型的操作数转换为有符号整数类型的操作数的类型。
  5. 否则,两个操作数都转换为与带符号整数类型的操作数类型对应的无符号整数类型。

然后规则如下工作:

  • -1 < (unsigned char) 1

首先,两个操作数都转换为整数(因为一个整数可以表示 unsigned char 的所有值)。然后对这些有符号类型进行比较。然后使用规则 1。比较成功。

  • -1 < (unsigned int) 1

int 不能表示 unsigned int 的所有值,因此使用规则 3 并将有符号整数转换为无符号整数 (UINT_MAX - 1)。现在比较失败了。

于 2010-10-10T13:08:09.130 回答
1

这是由于整数促销。两个参数都可以表示为 int,因此它们都转换为 int。

ISO C 6.3.1.1,第 2 段:

如果一个 int 可以表示原始类型的所有值,则将该值转换为 int;否则,它将转换为无符号整数。这些被称为整数提升。48) 所有其他类型都不受整数提升的影响。

于 2010-10-10T13:47:26.863 回答