0

抱歉英语不好。

uint16_t a, c;
uint8_t b = 0xff;

a = b<<8;
c = b*10;

什么是价值,a我们c得到了什么?任意整数类型的情况如何?

4

1 回答 1

0
uint16_t a, c;
uint8_t b = 0xff;

a = b<<8;

首先,整数提升是在 的参数上执行的<<。常数8是一个int,因此不被转换。由于 的转换等级uint8_t小于 的int,并且 的所有值uint8_t都可以表示为ints,b因此将其转换为 - 保留其值 - 为int。然后将结果int值左移八位。

如果int仅 16 位宽,则该值0xff * 2^8不能表示为int,然后移位调用未定义的行为 - n1570 和 C99 中的 6.5.7 (4):

如果 E1 有带符号类型和非负值,并且 E1 × 2 E2在结果类型中是可表示的,那么这就是结果值;否则,行为未定义。

否则,结果为255*256 = 65280 = 0xFF00。由于该值可以以 的类型表示aint因此将移位结果转换为uint16_t保留该值;如果结果超出范围(例如,如果移位距离为 9 [并且int足够宽]),则将对其进行模数减少2^16以获得范围02^16 - 1的值uint16_t

c = b*10;

通常的算术转换是在 的操作数上执行的*。两个操作数都具有整数类型,因此首先执行整数提升。由于10is an和's 类型的int所有值都可以表示为 an ,因此整数提升使两个操作数具有相同的类型,,并且通常的算术转换不需要任何进一步的转换。乘法是在 type 处完成的,其结果 ,再次可以在 的类型中表示,因此在将值存储到保留值之前完成到该值的转换。bintintint2550cuint16_tc

任意整数类型的情况如何?

对于<<

  1. 整数促销;整数类型的值/表达式,其转换等级小于或等于int(and unsigned int) [宽度<=为] 的整数类型,类型为,和(unsigned) int的位域转换为or (如果可以表示原始类型,否则)。_Boolintsigned intunsigned intintunsigned intintunsigned int

  2. 如果(提升的)右操作数(移位距离)为负数或大于或等于(提升的)左操作数的宽度(值位加符号位的数量;有一个符号位或没有),则行为是不明确的。如果(提升的)左操作数的值为负数,则行为未定义。如果(提升的)左操作数的类型是无符号的,则结果是value * 2^distance,减少模2^width。如果(提升的)左操作数的类型是有符号的且值为非负数,则结果是value * 2^distance如果该类型可表示,否则行为未定义。

  3. 如果 2. 中没有发生未定义的行为,则将结果转换为存储它的变量的类型。

    • 如果目标类型是_Bool(或其别名),则将非零结果转换为 1,将零结果转换为 0,否则
    • 如果结果可以用目标类型表示,则保留其值,否则
    • 如果目标类型是无符号的,则结果是减少模2^width,否则
    • 结果以实现定义的方式转换或引发实现定义的信号。

对于*

  1. 执行通常的算术转换,以便两个(转换后的)操作数具有相同的类型。
  2. 乘法是在结果类型上执行的;如果那是有符号整数类型并且乘法溢出,则行为未定义。
  3. 结果以与上述相同的方式转换为目标类型。

这就是抽象机的定义方式,如果实现可以以另一种方式实现相同的结果(定义行为的地方),它可以在 as-if 规则下为所欲为。

于 2012-12-09T13:36:11.893 回答