6

例如,如果我有,

 int a = 42;
 unsigned b = 10;
 int c = a + b;

对于此语句,将首先转换为 a还是将其转换为 a int c = a + b;?两者都具有相同的转换等级,那么我们如何知道哪一个会被转换?有标准规则吗?aunsigned intbsigned intunsigned intsigned

4

1 回答 1

10

简短回答:根据 C99 6.3.1.8-p1,as 值将被转换为无符号整数,根据 C99 6.3.1.3-p2,将 UINT_MAX+1 添加到它,直到它落在允许的范围内unsigned int。由于它已经在该范围内,因此不会执行添加。int c在 C99 6.3.1.3-p3 中,如果 (p1) 和 (p2) 不适用,则分配回的结果将是实现定义的。但在这种情况下,请注意 6.3.1.3-p1 的“值”子句。在这种情况下,值 (52)可以用 表示int,因此它没有改变,而是被定义了。

C99 6.3.1.3 有符号和无符号整数

  1. 当整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新类型表示,则保持不变。

  2. 否则,如果新类型是无符号的,则在新类型中可以表示的最大值的基础上重复加减一,直到该值在新类型的范围内。60)

  3. 否则,新类型是有符号的,值不能在其中表示;结果是实现定义的,或者引发了实现定义的信号。

C99 6.3.1.8 常用算术转换

许多期望算术类型的操作数的运算符会以类似的方式导致转换和产生结果类型。目的是确定操作数和结果的通用实数类型。对于指定的操作数,每个操作数都在不改变类型域的情况下转换为对应的实数类型是公共实数类型的类型。除非另有明确说明,否则公共实数类型也是结果的对应实数类型,如果它们相同,则其类型域是操作数的类型域,否则为复数。这种模式称为通常的算术转换

首先,如果任一操作数的对应实数类型为 long double,则将另一个操作数转换为对应实数类型为 long double 的类型,而不改变类型域。

否则,如果任一操作数的对应实数类型为双精度,则将另一个操作数转换为对应实数类型为双精度的类型,而不改变类型域。

否则,如果任一操作数的对应实数类型为浮点数,则将另一个操作数转换为对应实数类型为浮点数的类型,而不改变类型域。62)

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

  • 如果两个操作数具有相同的类型,则不需要进一步转换。

  • 否则,如果两个操作数都具有有符号整数类型或都具有无符号整数类型,则具有较小整数转换等级的类型的操作数将转换为具有较高等级的操作数的类型。

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

  • 否则,如果有符号整数类型的操作数的类型可以表示无符号整数类型的操作数类型的所有值,则将无符号整数类型的操作数转换为有符号整数类型的操作数的类型。

  • 否则,两个操作数都转换为与带符号整数类型的操作数类型对应的无符号整数类型。

于 2012-11-30T04:54:58.610 回答