假设我有一台 32 位机器。
我知道在整数提升期间,表达式被转换为:
int
原始类型的所有值是否可以用 int 表示unsigned
否则
您能否解释一下以下表达式会发生什么? 一般来说,排名在这里是如何运作的?
第一个片段:
int16_t x, pt;
int32_t speed;
uint16_t length;
x = (speed*pt)/length;
第二个:
x = pt + length;
#EDIT:
我找到了以下链接,该链接非常清楚地描述了该问题: 隐式类型转换。
具体来说,阅读伦丁的答案,非常有帮助!
正确引用的整数提升规则 C11 6.3.1.1:
如果
int
可以表示原始类型的所有值(受限制 对于位字段的宽度),该值将转换为int
; 否则,它将转换为unsigned int
。这些被称为 整数促销。所有其他类型均由整数更改 促销。
其中"否则,将其转换为无符号 int"在实践中仅用于一种特定的特殊情况,即较小的整数类型unsigned short
具有与unsigned int
相同的大小。在这种情况下,它将保持未签名状态。
除了这种特殊情况之外,所有小整数类型都将始终提升为(有符号)int
,无论它们的符号性如何。
假设 32 位int
,则:
x = (speed*pt)/length;
speed
签了 32 名,它就不会得到晋升。pt
将整数提升为int
(有符号 32)。speed*pt
的结果将具有类型int
。
length
将整数提升为int
。除法将使用int
类型的操作数进行,结果类型将int
.
结果将转换为有符号的 16,因为它被分配给x
(分配期间的左值转换)。
x = pt + length;
类似,这里 + 的两个操作数将在加法之前提升为int
,之后结果将转换为符号 16。
有关详细信息,请参阅隐式类型升级规则。
整数提升规则在 6.3.1.8 常用算术转换中定义。
1. int16_t x, pt;
int32_t speed;
uint16_t length;
x = (speed*pt)/length;
2. x = pt + length;
排名实际上是指 CAM 在limits.h
中定义的类型的位数。 该标准对 CAM 中较低等级的类型施加了对应实施中较低等级的类型。
对于您的代码,
speed * pt
是 int32_t 和 int16_t 之间的乘法,这意味着,它被转换为
speed * (int16_t => int32_t) pt
结果tmp1
将是int32_t
.
接下来,它将继续
tmp1_int32 / length
长度将从uint16_t
转换为int32_t
,因此它将计算tmp2
:
tmp1_int32 / (uint16_t => int32_t) length
结果tmp2
将是int32_t
类型。
接下来,它将计算一个赋值表达式,左侧为 16 位,右侧为 32 位,因此它将剪切结果:
x = (int32_t => int16_t) tmp2_int32
您的第二个案例将被评估为
x = (int32_t => int16_t) ( (int16_t => int32_t) pt + (uint16_t => int32_t) length )
如果运算符的两个操作数的秩都小于 int 秩,则 CAM 允许在运算没有溢出时添加这两种类型,然后将结果转换为整数。
换句话说,可以在
INT16+INT16
或在
(int32_t => int16_t) ((int16_t => int32_t) INT16 + (int16_t => int32_t) INT16)
前提是添加可以在不溢出的情况下完成。