Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c语言中的整数提升_C_Integer Overflow_Integer Promotion - Fatal编程技术网

c语言中的整数提升

c语言中的整数提升,c,integer-overflow,integer-promotion,C,Integer Overflow,Integer Promotion,假设我有一台32位机器。 我知道在整数升级期间,表达式转换为:\ int如果原始类型的所有值都可以用int表示 未签名否则 你能解释一下下面的表达式会发生什么吗?总的来说,排名是如何运作的 第一段: si16 x, pt; si32 speed; u16 length; x = (speed*pt)/length; 第二个: x = pt + length; 编辑: si16表示signed short(大小16位),si32位表示signed int(大小32位)和u16表示uns

假设我有一台32位机器。

我知道在整数升级期间,表达式转换为:\

  • int
    如果原始类型的所有值都可以用int表示
  • 未签名
    否则
你能解释一下下面的表达式会发生什么吗?总的来说,排名是如何运作的

第一段:

si16  x, pt;
si32  speed;
u16 length;
x = (speed*pt)/length;
第二个:

x = pt + length;
编辑:
si16
表示
signed short
(大小16位),
si32
位表示
signed int
(大小32位)和
u16
表示
unsigned short
(大小16)

我发现以下链接非常清楚地描述了这个问题: .


具体来说,请阅读Lundin的答案,非常有帮助

整数提升规则,正确引用C116.3.1.1:

如果
int
可以表示原始类型的所有值(受限制 根据宽度(对于位字段),值转换为
int
; 否则,它将转换为
无符号int
。这些被称为 整数促销。所有其他类型均由整数保持不变 晋升

其中,“否则,它将转换为无符号整数”实际上仅用于一种特殊情况,即较小的整数类型
无符号短
的大小与
无符号整数
相同。在这种情况下,它将保持未签名状态

除了这种特殊情况之外,所有小整数类型都将被提升为(有符号)
int
,而不管它们的有符号性如何


假设32位
int
,则:

 x = (speed*pt)/length;
速度
已签名为32,将不会升级
ptr
将整数提升为
int
(带符号32)。
speed*ptr
的结果将具有类型
int

length
将整数提升为
int
。除法将使用类型为
int
的操作数执行,结果类型为
int

当结果被分配到
x
(分配期间的左值转换)时,它将被转换为有符号16


x=pt+长度
类似,这里+的两个操作数在加法之前都将升级为int,之后结果将转换为有符号16。

中定义了整数升级规则

排名有效地表示CAM在
limits.h
中定义的类型的位数。该标准规定CAM中较低等级的类型与实施中较低等级的类型相对应

对于您的代码

speed*pt
是int32和Int16之间的乘法,也就是说,它在

speed*(int16=>int32)pt
结果
tmp1
将是
int32

下一步,它将继续

tmp1_int32 / length
长度将从uint16转换为int32,因此它将计算
tmp2
so:

tmp1_int32 / (uint16=>int32) length
并且结果
tmp2
将为int32类型

接下来,它将计算赋值表达式,左侧为16位,右侧为32位,因此它将剪切结果,以便:

x = (int32=>int16) tmp2_int32
您的第二个案例将被评估为

x = (int32=>int16) ( (int16=>int32) pt + (uint16=>int32) length )
如果一个运算符的两个操作数的秩都小于int的秩,则CAM允许在运算不溢出的情况下添加这两种类型,然后将结果转换为整数

换言之,可以在以下两种情况下转换INT16+INT16

 INT16+INT16
或者

 (int32=>int16) ((int16=>int32) INT16 + (int16=>int32)INT16)

如果添加操作可以在没有溢出的情况下完成。

什么是
si16
si32
u16
?如果不知道
sizeof(int)
相对于
sizeof(si16)
和其他问题,这个问题是不可能回答的。“假设我有32位机器。”根本不相关。我们需要知道您的
int
@David Bowling的详细信息,si16表示有符号的短字符(大小16位),si32位表示有符号的int字符(大小32位),u16表示无符号的短字符(大小16位)。为什么
si16
u16
,而不是
ui16
?请您解释一下这句话:“所有其他类型都不会因整数而改变。”@Monir还有一些上下文,这意味着所有不属于“小整数类型”的类型都不受规则的影响。小整数类型有:bool、char、short(以及它们的stdint.h等价物)。允许在不首先将运算符转换为int的情况下应用运算符,前提是您可以证明它不会溢出。@alinsoar编译器可以优化此类表达式,但确实不允许优化升级引起的副作用,包括符号的隐式变化。“排名”,即转换排名,在6.3.1.1中正式规定。“CAM”应该是什么意思?c抽象机器我说的是关于我的参考的整数提升,而不是排名。更准确地说,CAM指的是标准定义的抽象语义。
 (int32=>int16) ((int16=>int32) INT16 + (int16=>int32)INT16)