抱歉英语不好。
uint16_t a, c;
uint8_t b = 0xff;
a = b<<8;
c = b*10;
我们获得的a
和c
的价值是多少?任意整数类型的情况是什么?
答案 0 :(得分:0)
uint16_t a, c;
uint8_t b = 0xff;
a = b<<8;
首先,对<<
的参数执行整数提升。常量8
是int
,因此不会被转换。由于uint8_t
的转化排名小于int
的转化排名,uint8_t
的所有值都可以表示为int
,因此转换b
- 保留其价值 - int
。然后,生成的int
值向左移动8位。
如果int
只有16位宽,则值0xff * 2^8
不能表示为int
,然后移位调用未定义的行为 - 在n1570中为6.5.7(4)并且C99:
如果E1具有带符号类型和非负值,并且E1×2 E2 在结果类型中可表示,那么这就是结果值;否则,行为未定义。
否则,结果为255*256 = 65280 = 0xFF00
。由于该值可在a
类型中表示,因此将int
转换结果转换为uint16_t
会保留该值;如果结果超出范围(例如,如果移位距离为9 [且int
足够宽]),则将以模2^16
为模,以获得0
范围内的值2^16 - 1
的{{1}}。
uint16_t
通常的算术转换是在c = b*10;
的操作数上执行的。两个操作数都具有整数类型,因此首先执行整数提升。由于*
是10
且所有int
类型的值都可以表示为b
,因此整数提升会为两个操作数提供相同的类型int
,通常的算术转换不需要任何进一步的转换。乘法在int
类型上完成,其结果int
再次可以在2550
类型中表示,因此在存储值之前转换为c
在uint16_t
中保留了值。
任意整数类型的情况是什么?
c
:
整数促销;转换等级小于或等于<<
(和int
)[宽度unsigned int
为<=
]的整数类型的整数类型的值/表达式,类型为(unsigned) int
,_Bool
,int
和signed int
的位域将转换为unsigned int
或int
(unsigned int
,如果可以的话表示原始类型的所有值,否则为int
。
如果(提升的)右操作数(移位距离)为负或大于或等于宽度(值位数加符号位;有一个符号位或无符号位)(已提升)左操作数,行为未定义。如果(提升的)左操作数的值为负,则行为未定义。如果(提升的)左操作数的类型是无符号的,则结果为unsigned int
,减少模value * 2^distance
。如果(提升的)左操作数的类型是有符号且值为非负,则结果为2^width
如果在类型中可表示,则行为未定义。
如果2.中没有出现未定义的行为,则结果将转换为存储它的变量的类型。
value * 2^distance
(或其别名),则非零结果将转换为1,零结果将转换为0,否则_Bool
为模,否则为 2^width
:
这就是如何定义抽象机器,如果实现可以以另一种方式实现相同的结果(定义行为),它可以在as-if规则下随心所欲地做。