Managing Compound Expressions

C++ Primer 4/e 在算式這裡還有一個忠告:『Beginning C and C++ programmers often have difficulties understanding order of evaluation and the rules of precedence and associativity. Misunderstanding how expressions and operands are evaluated is a rich source of bugs. Moreover, the resulting bugs are difficult to find because reading the program does not reveal the error unless the programmer already understands the rules.

Two rules of thumb can be helpful:

  1. When in doubt, parenthesize expressions to force the grouping that the logic of your program requires.

  2. If you change the value of an operand, don’t use that operand elsewhere in the same statement. If you need to use the changed value, then break the expression up into separate statements in which the operand is changed in one statement and then used in a subsequent statement.

An important exception to the second rule is that subexpressions that use the result of the subexpression that changes the operand are safe. For example, in *++iter the increment changes the value of iter, and the (changed) value of iter is then used as the operand to *. In this, and similar, expressions, order of evaluation of the operand isn’t an issue. To evaluate the larger expression, the subexpression that changes the operand must first be evaluated. Such usage poses no problems and is quite common.』

中文版的是這樣說:『C和C++新手常常很難瞭解「核定次序」以及優先序和結合律的規則。「誤解算式和運算元的核定方式」是臭蟲的豐富根源。更有甚者,其所導致的臭蟲很難被發現,因為除非程式員瞭解那些規則,否則閱讀程式碼無法找出錯誤。

兩個經驗法則可能會有幫助:

1.如果不甚肯定,請為算式加入小括號,強迫其運算元結合方式符合你的程式所需要的邏輯。
2.如果改變了運算元值,不要在相同述句內的任何其他地方使用同一個運算元。如果需要使用改變後的值,請把算式拆成分離述句,讓運算元在某個述句內被改變,再於後續述句內被使用。

第二規則有一個重要例外:任何子算式如果使用「改變運算元值」之子算式的運算結果,都是安全的。例如在*++iter中,遞增動作改變了iter的值,而iter改變後的值接著被當作*的運算元。在此算式及類似算式中,運算元核定次序不是問題。當核定較大算式時,算式內「改變運算元值」的子算式一定會先被球值。這個用法沒問題,而且滿常見的。』

恩,一個親身的經驗就是人要謙卑,不要自以為是的以為自己C和C++很行就拼命用簡潔語法,然後下錯了運算式還拼命地認為不可能是那裡錯,到頭來偵錯的時間會加長許多,在工廠常會被要求針對有可能做錯的事作查檢表,這裡的運算子優先序表及忠告可以列入寫C的查檢表,應該也不錯。

achi’s English Blog

感謝你看到這裡,很快就可以離開了,但最好的獎勵行動就是按一下幫我分享或留言,感恩喔~

點我分享到Facebook

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *