对不起,英语不好。
uint16_t a, c;
uint8_t b = 0xff;
a = b<<8;
c = b*10;
我们得到的
a
和c
的值是多少?任意整数类型的情况如何?
最佳答案
uint16_t a, c;
uint8_t b = 0xff;
a = b<<8;
首先,对
<<
的参数执行整数提升。常量8
是int
,因此不会转换。由于uint8_t
的转换等级小于int
的转换等级,并且uint8_t
的所有值都可以表示为int
,因此b
会被转换-保留其值-变为int
。然后将得到的int
值向左移八位。如果
int
仅16位宽,则值0xff * 2^8
不能表示为int
,然后该移位调用未定义的行为-n1570和C99中的6.5.7(4):如果E1具有带符号的类型和非负值,并且E1×2E2可表示为结果类型,则为结果值;否则,行为是不确定的。
否则,结果为
255*256 = 65280 = 0xFF00
。由于该值可以用a
类型表示,因此将int
转换结果转换为uint16_t
会保留该值。如果结果超出范围(例如,移位距离为9 [并且int
足够宽]),则将对2^16
取模,以得到0
到2^16 - 1
范围内的值, >。c = b*10;
通常的算术转换是对
uint16_t
的操作数执行的。两个操作数都具有整数类型,因此首先执行整数提升。由于*
是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
为模。如果(提升的)左操作数的类型是带符号的且值是非负的,则结果为value * 2^distance
(如果该类型可以表示该类型),否则行为未定义。如果在2中未发生未定义的行为,则结果将转换为存储在其中的变量的类型。
如果目标类型为
_Bool
(或其别名),则将非零结果转换为1,将零结果转换为0,否则如果结果可以目标类型表示,则保留其值,否则
如果目标类型是无符号的,则结果以模
2^width
的形式减少,否则结果以实现定义的方式转换,或者引发实现定义的信号。
对于
*
:执行通常的算术转换,以便两个(转换后的)操作数具有相同的类型。
以结果类型执行乘法;如果那是有符号整数类型并且乘法溢出,则该行为是不确定的。
以与上述相同的方式将结果转换为目标类型。
这就是定义抽象机的方式,如果实现可以通过另一种方式达到相同的结果(定义了行为),则它可以在按条件规则下随意执行。
关于c - 扩展标准C中的移位或算术运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13785955/