Re: [问题] 什么情况下会从后往前做运算?

楼主: RishYang (Rish)   2019-05-11 13:03:24
前两楼有提到这个问题与第八诫相关
不过第八诫可能有些不够清楚
https://reurl.cc/0nZmk
https://reurl.cc/YQ0D4
这两篇看完就可以解开你心中的疑惑
时间有限,让我为你简单整理一下部分内容
先从简单的四则运算开始
int ans = 1+2+3+4;
ans是10
原因是加法的结合方向(associativity)
加法的结合方向是向左,可得到:
(((1+2)+3)+4)
*下方有结合方向的补充
再来复杂一点的
int ans = 1*2+6/3;
ans是4
因为((1*2)+(6/3))而不是(1*(2+6)/3)
是由于乘法(*)运算子优先权(precedence)较加法(+)高
国小四则运算口号:
先乘除,后加减,括号要先算
根据口号,但是要先算(1*2)还是(6/3)?
两个括号的结果互相'独立',其中一个先算不影响答案
1 * 2 = 2不影响后面的(6/3),这就是我指的独立
回到你问的两个例子
c = sub1(a,&b)+sub2(&a,b);
是加号左边先还是右边先算(先求值)
'先算'涉及求值顺序(Order of evaluation)
求值顺序没有'左到右'或'右到左'的顺序
printf("%d\n%d\n%d\n%d\n",a+b+c+d,(b*=a),(a+=d),(d++));
a+b+c+d, (b*=a), (a+=d), (d++)
以上四个求值地位相同,不会有哪个求值一定会先做
由于一个向左,一个向右,加上国小口号
让你误会存在'执行顺序方向',实际上执行顺序是假议题
没有一个执行顺序方向,各自表述的空间
是因为你的求值并非'独立',所以你才被电脑(可能是编译或是执行时期)误导
希望你看完,更能体会第八诫字句的含意(以下为第八诫节录)
当一段程式码中,某个变量的值用某种方式被改变一次以上,
例如++x/
作者: Schottky (顺风相送)   2019-05-11 13:55:00
作者: ohmylove347 (米特巴爾)   2019-05-11 15:45:00
楼主: RishYang (Rish)   2019-05-11 16:35:00
编译器可以检查Wsequence-point编译-Wall起来,八诫不会难
作者: cuttheshit (科特落雪)   2019-05-11 16:51:00
感谢大大耐心解惑 虽然还是不太懂 决定先跳过这个点了"以上四个求值地位相同,不会有哪个求值一定会先做"编译结果那四个参数的取值顺序是 4,3,2,1那为何不能是 4,2,3,1呢 不禁有这样子的疑惑因为第一条式子也是"后面的结果先做有可能改动到前面"的情况 可是却可以是从左边开始算若是第二条用"因为后面先做会影响到前面的结果,所以先做后面" 那么又跟第一条式子矛盾了 主要是卡在这里原本做题目好好的,自从遇到case2那条奇怪的式子后反而导致往后做时,一直会冒出一个念头 是不是该后往前有种一知半解最危险的感觉,反而会顾虑太多
作者: art1 (人,原来不是人)   2019-05-11 17:20:00
“不要在一个运算式中,写出变量会互相影响的程式码”
楼主: RishYang (Rish)   2019-05-11 18:11:00
在这个问题上不用担心会有一知半解的情形art1所言是整篇重点,没有这种疑义才是良好的程式码

Links booklink

Contact Us: admin [ a t ] ucptt.com