有符号和无符号整数的整数转换等级

例如,如果我有,

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

对于这个陈述, int c = a + b; 是第一个转换为unsigned int还是b将转换为signed intunsigned intsigned都具有相同的转换级别,那么我们如何知道哪一个将被转换? 有标准规则吗?

简答:根据C99 6.3.1.8-p1,s值将被转换为无符号整数,按照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有符号和无符号整数

  1. 当具有整数类型的值转换为除_Bool之外的另一个整数类型时,如果该值可以由新类型表示,则它将保持不变。

  2. 否则,如果新类型是无符号的,则通过重复地添加或减去一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内.60)

  3. 否则,新类型将被签名,并且值无法在其中表示; 结果是实现定义的,或者引发实现定义的信号。

C99 6.3.1.8通常的算术转换

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

首先,如果任一操作数的相应实数类型是long double,则另一个操作数在不改变类型域的情况下被转换为其对应的实类型为long double的类型。

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

否则,如果任一操作数的相应实数类型为float,则另一个操作数在不更改类型域的情况下转换为对应的实类型为float的类型.62)

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

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

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

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

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

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