表达式的求值顺序

twtfufitx 2010-04-24 08:35:59
书中说如果表达式X+Y的结果大于整型所能容纳的值,它就会产生溢出.在有些机器上,下面这个测试if(x+y+1>0)的结果将取决于先计算x+y还是y+1,因为在两种情况下溢出的地点不同.
如,signed int值为-32768---32767 X(32767)+Y(1)的值为32768,即-32768再加1,得-32767
和先运算Y+1=2,在加X得-32767 两个溢出点不是一样的.为什么会有两个不同的溢出点.
如何理解,不管是先运行哪个,不是只有一个溢出点吗
...全文
119 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
twtfufitx 2010-04-26
  • 打赏
  • 举报
回复
非常感谢
2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 twtfufitx 的回复:]

楼上你说的情况是在两个不同的平台中.有两个不同的溢出点.
在同一个平台中有可能会有两个溢出点吗?
[/Quote]
如果某平台对溢出作封顶处理,即 32767 + 1 = 32767,
那么对于 x + y + 1,若 x = 32767, y = 1,计算 x + y = 32767 时发生溢出,计算 32767 + 1 时再次发生溢出,总共两次溢出。

不过这个和你在顶楼的问题似乎已经没有关系了。
x + y + 1 一定会先算 x + y,所以顶楼那个测试的依据就是错的。

至于他说的“两个溢出”,可能是认为一个在第一次加法里面就溢出了,另一个在第二次加法才溢出。这纯粹是个措辞问题,不必深究,关键是知道程序的行为。

最后罗嗦一句:依赖溢出行为写程序,多数时候是极其恶劣的事情……
twtfufitx 2010-04-25
  • 打赏
  • 举报
回复
楼上你说的情况是在两个不同的平台中.有两个不同的溢出点.
在同一个平台中有可能会有两个溢出点吗?
2010-04-24
  • 打赏
  • 举报
回复
如果真的出现了 x + ( y + 1 ) 的情况,某些平台下结果和 ( x + y ) + 1 的确有可能不同,毕竟溢出的后果是未定义的。
有些系统就约定溢出的结果是封顶,而不是截断,这种情况下 32767 + 1 就还是 32767。
2010-04-24
  • 打赏
  • 举报
回复
根据运算符的结合性, x + y + 1 只会被解析成 ( x + y ) + 1,如果编译器足够标准,可以不用担心这个。不管优化过后的实际计算过程是什么样,最后的结果必须和这个一致,否则这个优化就是不严格的。
yyg990441 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 bigcarrot 的回复:]
1. x+y+1, 确实无法确定先算x+y 还是 y+1, 甚至还有可能先算 x+1
2. 无论什么顺序 对于整形的(x+y+1) 结果总是一样的
[/Quote]
那运算符的"结合性"是什么意思?说+是"左结合"的是什么意思?
BigCarrot 2010-04-24
  • 打赏
  • 举报
回复
1. x+y+1, 确实无法确定先算x+y 还是 y+1, 甚至还有可能先算 x+1
2. 无论什么顺序 对于整形的(x+y+1) 结果总是一样的
向立天 2010-04-24
  • 打赏
  • 举报
回复
你第二个算错了
Y+1=2
X+2=32769
对应的二进制数为
1000000000000001
所以结果为-1
yyg990441 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 cy330206 的回复:]
这个要去看编译器的,有编译器来决定的
[/Quote]
x+y+1>0必定先算x+y,不可能先算y+1,这是+号的结合性保证的
cy330206 2010-04-24
  • 打赏
  • 举报
回复
这个要去看编译器的,有编译器来决定的

69,380

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧