這個問題在這里已經有了答案: 遞回如何在 C 中作業 5 個答案 9 小時前關閉。
這篇文章在9 小時前被編輯并提交審核。
我試圖制作一個程式,使用遞回的概念找到我們數字的數字的立方和。
但是當我嘗試添加數字并更新變數時,會發生一些奇怪的事情sum。當我寫
sum = sum pow(sumCube(num), 3);
這些值不會添加并存盤在sum. 相反,in 的值sum會被覆寫,就好像 的值sum每次都重置為 0。
另一方面,當我寫
sum = pow(sumCube(num), 3);
該程式似乎運行完美。這是供您參考的程式。
#include <iostream>
#include<math.h>
using namespace std;
int num = 51, dgt = 0, sum = 0;
int sumCube(int)
{
int dgt = num % 10;
while (num > 10)
{
num = num / 10;
//sum = sum pow(sumCube(num), 3); //doesn't work properly
sum = pow(sumCube(num), 3); //works properly
}
cout << sum << endl;
return(dgt);
}
int main()
{
num = num * 10;
sumCube(num);
return 0;
}
我認為語法是導致問題的原因。但我也看過一些帖子,說這兩種語法的行為方式相同。我以前從未遇到過這樣的問題,兩個版本似乎都以相同的方式作業。
任何幫助表示贊賞。
uj5u.com熱心網友回復:
遞回的整體方法是完全錯誤的。
即使在最好的條件下,改變全域狀態也是一個壞主意。在使用遞回時避免這種情況尤為重要,因為它使正確推理代碼變得更加困難。
函式通常應該通過ing 來表示計算結果。
return這對于遞回函式尤其重要。這就是return. _在這里使用遞回的意義(誠然是一個簡單的例子)是它已經分解并簡化了每一步的問題:我們使用遞回來找到所有其他立方體的總和,然后為當前數字添加立方體。因此,正確的遞回代碼不應該有
while回圈。請確保您對呼叫函式的作業原理有充分的了解。寫作
int sumCube(int) {意味著該函式接受一個引數,但不能使用它,因為它沒有名稱。我們應該寫一個名字:int sumCube(int num) {. 然后,只有在 function 內部,是作為引數傳入num的任何內容的名稱。這不必是另一個名為;的變數。它根本不必是一個變數。我們不將變數傳遞給函式。我們將值傳遞給函式。num
您知道,就像您撰寫 時一樣pow(sumCube(num), 3),3根本不必是變數,也不必具有由pow函式指定的名稱。就像使用pow函式時的方式一樣,它return是一個可以在 右側使用的值 ,并且不會更改任何全域變數。
考慮到這個背景,我們可以重新處理這個問題。這樣想:想象你有別人的函式 ,sumCube2它以其他方式解決了同樣的問題。我們想用它來幫助解決問題。我們的一般做法是什么?
我們想給出
sumCube2一個比我們得到的更簡單的問題(否則我們可以直接使用它)。我們已經有一個分解步驟:我們使用除法和取模來提取最后一位數字。我們想將呼叫的結果
sumCube2與一些本地計算結合起來。很容易看出如何做到這一點:我們將最后一個數字立方,并將函式呼叫的結果添加到該立方值。然后我們可以return得到那個結果。我們需要提防簡化空間不足的問題。這很簡單:如果我們得到
0,那么我們就知道結果是0,我們就不必再做任何作業了。(還有其他方法可以實作這一步,但為什么要讓它變得更難呢?)
所以:我們需要一個接受名為的引數的函式num:
int sumCube(int num) {
int last, rest;
我們將首先檢查我們的特殊情況:
if (!num) return 0;
否則,我們提取最后一位數字,并將其余數字分開:
last = num % 10;
rest = num / 10;
我們return通過使用結果來計算和sumCube2結果:
return sumCube2(rest) pow(last, 3);
}
請注意,我們不需要修改任何全域變數、使用while回圈或類似的東西。
我們可以稍微壓縮一下代碼,因為我們并不真正需要那些中間計算結果的名稱(那只是為了能夠一步一步地討論邏輯):
int sumCube(int num) {
if (!num) return 0;
return sumCube2(num / 10) pow(num % 10, 3);
}
(或者我們可以使用?:條件運算式,或者我們可以顯式使用乘法而不是呼叫pow,你明白了。)
現在,我們如何使這種使用遞回,而不必依賴于sumCube2我們沒有寫的神話?
簡單:sumCube是一個旨在完全執行sumCube2將要執行的操作的功能。所以我們只是呼叫它 - 即,在那里進行遞回呼叫。
int sumCube(int num) {
if (!num) return 0;
return sumCube(num / 10) pow(num % 10, 3);
}
它之所以有效,是因為對函式的每次 呼叫都會獲取自己的引數和自己的區域變數,然后return回傳到呼叫它的位置——就像呼叫任何其他函式一樣。因為我們只期望遞回呼叫完成部分作業,并且因為我們只在有有效的“部分”作業遞回完成時才會遞回,所以我們避免了無限遞回。
請注意,我在此代碼中沒有任何cout邏輯。那是因為 的目的是計算sumCube立方體的總和。顯示該結果是一項完全獨立且不相關的任務。這是以下人員的責任:main
int main()
{
cout << sumCube(51) << endl;
return 0;
}
uj5u.com熱心網友回復:
基本問題是在這個運算式中:
sum pow(sumCube(num), 3)
的值sum可以在呼叫之前或之后讀取sumCube——這里沒有序列點,它們之間也沒有依賴關系。由于sumCube還修改sum(它是一個全域變數),你會得到不確定的行為。
當你使用 =運算子時,它的左運算元和它的右運算元之間存在依賴關系(就像任何賦值一樣),所以呼叫sumCube將在讀取值的加法之前出現sum,所以你總是會得到值修改sum 后sumCube
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/495646.html
上一篇:如何在日期范圍之間求和()價格?
