例如,如果我有,
int a = 42;
unsigned b = 10;
int c = a + b;
对于此声明,int c = a + b;
a
会先将unsigned int
转换为b
,还是将signed int
转换为unsigned int
? signed
和{{1}}都具有相同的转换排名,那么我们如何知道哪一个将被转换?有标准规则吗?
答案 0 :(得分:9)
简短回答:根据C99 6.3.1.8-p1,a
的值将被转换为无符号整数,按照C99 6.3.1.3-p2,加入UINT_MAX + 1直到它落入unsigned int
允许的范围。由于它已经在该范围内,因此不会进行任何添加。根据C99 6.3.1.3-p3,如果(p1)和(p2)不适用,则分配回int c
的结果将是实施定义。但在这种情况下请注意6.3.1.3-p1的“值”子句。在这种情况下,的值(52)可以由int
表示,因此不会更改,并且是定义的。
C99 6.3.1.3有符号和无符号整数
当整数类型的值转换为_Bool以外的另一个整数类型时,如果该值可以用新类型表示,则它将保持不变。
否则,如果新类型是无符号的,则通过重复地添加或减去一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内。 60)
- 醇>
否则,新类型已签名且值无法在其中表示;结果是实现定义的,或者引发实现定义的信号。
C99 6.3.1.8常规算术转换
许多期望算术类型操作数的运算符会以类似的方式导致转换并产生结果类型。目的是确定操作数和结果的通用实数类型。对于指定的操作数,每个操作数在不更改类型域的情况下转换为其对应的实类型是公共实类型的类型。除非另有明确说明,否则公共实类型也是结果的对应实数类型,如果它们相同则其类型域是操作数的类型域,否则是复数。此模式称为通常的算术转换:
首先,如果任一操作数的相应实数类型为long double,则另一个操作数在不更改类型域的情况下转换为对应实数类型为long double的类型。
否则,如果任一操作数的相应实数类型为double,则另一个操作数在不更改类型域的情况下转换为对应实数类型为double的类型。
否则,如果任一操作数的相应实数类型为float,则另一个操作数在不更改类型域的情况下转换为相应实数类型为float的类型.62)
否则,将对两个操作数执行整数提升。然后将以下规则应用于提升的操作数:
如果两个操作数具有相同的类型,则无需进一步转换。
否则,如果两个操作数都有有符号整数类型或两者都有无符号整数类型,则具有较小整数转换等级类型的操作数将转换为具有更高等级的操作数类型。
否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的等级,则带有符号整数类型的操作数将转换为具有无符号整数的操作数的类型类型。
否则,如果带有符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数类型的所有值,则具有无符号整数类型的操作数将转换为操作数的类型带有符号整数类型。
否则,两个操作数都将转换为无符号整数类型,对应于带有符号整数类型的操作数类型。