Re: [問題] 什麼情況下會從後往前做運算?

看板C_and_CPP (C/C++)作者 (Rish)時間6年前 (2019/05/11 13:03), 編輯推噓6(6012)
留言18則, 5人參與, 6年前最新討論串2/2 (看更多)
前兩樓有提到這個問題與第八誡相關 不過第八誡可能有些不夠清楚 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/--x/x++/x--/function(&x)(能改變x的函式) - 如果Standard沒有特別去定義某段敘述中哪個部份必須被先執行, 那結果會是undefined behavior(結果未知)。 - 如果Standard有特別去定義執行順序,那結果就根據執行順序決定。 個人臆測: 不定義執行順序是為了保持與數學運算邏輯的相容性 讓C語言優雅又好入門的方法 其實把敘述一行行寫出來,並不會遜於用一行完成 追求程式邏輯清晰比短小可能來的重要 *結合方向http://codepad.org/hR8UFMOb 我想這個例子應該可以說明,乘除法向左結合的特性 結合方向遇上非獨立的求值還是會有問題的 最後送給原Po: '凡物皆數'----畢達哥拉斯 C語言裡大家都是傳值,不要分這麼細 很少發文,請鞭小力一點 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.237.199.112 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1557551006.A.060.html

05/11 13:55, 6年前 , 1F
05/11 13:55, 1F

05/11 15:45, 6年前 , 2F
05/11 15:45, 2F

05/11 16:35, 6年前 , 3F
編譯器可以檢查Wsequence-point
05/11 16:35, 3F

05/11 16:38, 6年前 , 4F
編譯-Wall起來,八誡不會難
05/11 16:38, 4F

05/11 16:51, 6年前 , 5F
感謝大大耐心解惑 雖然還是不太懂 決定先跳過這個點了
05/11 16:51, 5F

05/11 16:53, 6年前 , 6F
"以上四個求值地位相同,不會有哪個求值一定會先做"
05/11 16:53, 6F

05/11 16:54, 6年前 , 7F
編譯結果那四個參數的取值順序是 4,3,2,1
05/11 16:54, 7F

05/11 16:54, 6年前 , 8F
那為何不能是 4,2,3,1呢 不禁有這樣子的疑惑
05/11 16:54, 8F

05/11 16:56, 6年前 , 9F
因為第一條式子也是"後面的結果先做有可能改動到前面"
05/11 16:56, 9F

05/11 16:56, 6年前 , 10F
的情況 可是卻可以是從左邊開始算
05/11 16:56, 10F

05/11 17:00, 6年前 , 11F
若是第二條用"因為後面先做會影響到前面的結果,所以先
05/11 17:00, 11F

05/11 17:01, 6年前 , 12F
做後面" 那麼又跟第一條式子矛盾了 主要是卡在這裡
05/11 17:01, 12F

05/11 17:06, 6年前 , 13F
原本做題目好好的,自從遇到case2那條奇怪的式子後
05/11 17:06, 13F

05/11 17:07, 6年前 , 14F
反而導致往後做時,一直會冒出一個念頭 是不是該後往前
05/11 17:07, 14F

05/11 17:09, 6年前 , 15F
有種一知半解最危險的感覺,反而會顧慮太多
05/11 17:09, 15F

05/11 17:20, 6年前 , 16F
「不要在一個運算式中,寫出變數會互相影響的程式碼」
05/11 17:20, 16F

05/11 18:11, 6年前 , 17F
在這個問題上不用擔心會有一知半解的情形
05/11 18:11, 17F

05/11 18:18, 6年前 , 18F
art1所言是整篇重點,沒有這種疑義才是良好的程式碼
05/11 18:18, 18F
文章代碼(AID): #1SrbUU1W (C_and_CPP)
文章代碼(AID): #1SrbUU1W (C_and_CPP)