[英]Why code is implemented differently on changing order in the assignment statement?
我通過引用調用以下方式定義的階乘函數。
int factorial(int &n) {
n--;
if (n>0) return factorial(n)*(n+1);
else return 1;
}
當我傳遞值5時,它返回值1,正如我所期望的那樣。 但是當我以下面的方式定義階乘函數時,它返回5的階乘,即120。
int factorial(int &n) {
n--;
if (n>0) return (n+1)*factorial(n);
else return 1;
}
我推測表達式是按線性順序計算的,當在表達式中調用一個函數時,存儲局部變量的所有值和到目前為止在原始表達式中已經計算過的組件表達式,並且當函數將控制權返回給調用者這些保留的值用於計算表達式而不是它們的修改值。
我的假設是否正確? 請賜教。
我推測表達式是按線性順序評估的[...]
是的,不是。 評估順序通常以線性順序(從第一個到最后一個或從最后一個到第一個)完成,但未指定。 當您編寫factorial(n)*(n+1)
,允許編譯器首先計算(n+1)
first或factorial(n)
。 不同的編譯器將采用不同的方式。 而且,同一編譯器的不同版本甚至可以改變排序,因此這不是你應該依賴的東西。 標准是[intro.execution] :
除非另有說明,否則對單個運算符的操作數和單個表達式的子表達式的評估是不確定的。 [...]如果對標量對象的副作用相對於同一標量對象的另一個副作用或使用相同標量對象的值進行的值計算未被排序,並且它們不可能並發(1.10), 則行為未定義。
(唯一的例外是一樣的東西&&
, ||
, ,
,和?:
)
在這種情況下,只需刪除引用即可輕松完全依賴於順序依賴:
int factorial(int n) {
if (n>0) return factorial(n-1)*(n);
else return 1;
}
現在, factorial(n-1) * n
和n * factorial(n-1)
,無論它們在哪個階段進行評估,都能正常工作並給出相同的正確答案。 這也有額外的好處,沒有人會期望factorial
因實際修改它的論點:
int i = 6;
int f = factorial(i);
// now i is 1??
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.