社区
C语言
帖子详情
表达式的求值顺序
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 两个溢出点不是一样的.为什么会有两个不同的溢出点.
如何理解,不管是先运行哪个,不是只有一个溢出点吗
...全文
160
10
打赏
收藏
表达式的求值顺序
书中说如果表达式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 两个溢出点不是一样的.为什么会有两个不同的溢出点. 如何理解,不管是先运行哪个,不是只有一个溢出点吗
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用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
打赏
举报
回复
这个要去看编译器的,有编译器来决定的
C++ -
表达式
求值
顺序
本文介绍了C++11中关于
表达式
求值
顺序
的规定,涵盖副作用、完整
表达式
、未定义行为等概念。C++11放弃了序列点,采用新的方式定义
求值
顺序
,如自增自减、逻辑运算符、赋值运算符等的
求值
规则。此外,还强调了函数调用、初始化
顺序
等场景下的
求值
顺序
。
顺序
栈使用——
表达式
求值
本文介绍如何利用
顺序
栈实现算术
表达式
的
求值
,包括加减乘除及括号处理。通过两个栈分别存储运算符和操作数,利用算符优先关系进行运算。
C语言&Python:
表达式
的
求值
顺序
(evaluation order)的差异
本文深入比较C语言和Python在
表达式
求值
顺序
上的根本差异:C语言除逻辑与、逻辑或、三元及逗号运算符外,多数操作符的子
表达式
求值
顺序
未定义,依赖序列点约束;而Python严格规定所有
表达式
及
表达式
列表均按从左到右、后序遍历语法树的方式
求值
,确保确定性。重点涵盖副作用、函数调用
顺序
及实际编程影响。
C++运算
表达式
求值
顺序
本文深入探讨C++中
表达式
的
求值
顺序
及其可能导致的未定义行为,解析逻辑与、逻辑或、条件和逗号运算符如何规定运算对象的
求值
顺序
,给出处理复合
表达式
的建议。
Go语言
表达式
的
求值
顺序
本文系统阐述Go语言中各类
表达式
的
求值
顺序
规则:包级变量初始化遵循依赖驱动的'ready for initialization'逐步推进机制;普通
表达式
(含函数、方法、channel操作)严格按从左到右
顺序
求值
;赋值语句分两阶段——先整体
求值
右侧操作数,再从左到右赋值;switch/select支持惰性
求值
,其中select对recv操作符左侧
表达式
延迟至实际选中时才
求值
。这些规则共同构成Go确定性执行行为的基础。
C语言
70,038
社区成员
243,245
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章