1
(-1L<1U) ? printf("A"):printf("B");    
(-1L<1UL) ? printf("C"):printf("D");    
((short int)-1<1U) ? printf("E"):printf("F");    
((short int)-1<1UL) ? printf("G"):printf("H");    

这段代码在 gcc 编译器中运行后返回 BDEH ....我无法理解为什么会这样。请有人指导。

4

1 回答 1

6

这被标准称为“通常的算术转换”,当两个不同的整数类型作为同一运算符的操作数出现时适用。

本质上是做什么的

  • 如果类型具有不同的宽度(更准确地说是标准所说的转换等级),那么它将转换为更宽的类型
  • 如果两种类型的宽度相同,除了非常奇怪的架构之外,它们中的无符号获胜

具有任何类型的值的有符号到无符号转换-1始终会导致无符号类型的最高可表示值。

对于第 (1) 行,结果取决于宽度longint范围。如果int比 窄long,则所有unsigned值都适合long,因此 RHS 的转换停止long。结果是“A”。unsigned long如果它们具有相同的宽度,则两边的转换继续进行,结果为“B”。

对于您的特殊情况,short还有一个称为“整数提升”的功能,它提升所有比intto更窄的类型int。在您的第 3 行和第 4 行中,您将首先将 LHS 上的表达式转换为int,这使值保持不变,然后将 (3) 转换为 (3)unsigned int并将 (4) 转换为unsigned long

据此,我的平台(linux、gcc)使用您的代码正确打印“ADFH”。

结果“BDEH”将出现在首先具有longint具有相同宽度并且范围为 的范围所unsigned覆盖的平台上int,即unsigned忽略 的符号位int。我不知道这样的平台仍然存在。

几年来,我写了一篇关于整数类型剖析的博文,它应该仍然有效。

于 2013-10-17T06:45:42.090 回答