[英]finding gcd: not all control paths return a value
int gcd(int a, int b) {
if (b == 0)
return a;
else {
gcd(b, a % b);
}
}
當我嘗試計算最大公約數時,我知道我必須調用return gcd(b,a%b)
而不是gcd(b,a%b)
。 但我不明白為什么。 b 不會在某個時候變成 0 嗎?
當你第一次調用該函數時。 如果b!=0
它將繼續執行else gcd(b, a % b);
但是你第一次調用的函數沒有返回值。
下面的代碼將幫助你理解遞歸:
int gcd(int a, int b) {
if (b == 0)
return a;
else {
return gcd(b, a % b);
}
}
int calc_gcd(int a, int b) {
if (b == 0)
return a;
else {
gcd(b, a % b);
// return ?
}
}
call function calc_gcd
相當於在你的代碼中調用gcd
。 缺少返回值。 正確的遞歸函數應該是這樣的:
gcd0 ... return value to user
gcd1 .... ↑
gcd2 .... ↑
gcd3 .... pass value to ↑
你真的不必做
return gcd(b,a%b)
但這是最簡單的方法。
您似乎明白在所有情況下都必須從具有類似頭的函數返回 int
int gcd(int a, int b)
在 if 的兩個分支中都這樣做是一種簡單的方法。
可以說,對於可讀性、可維護性、健壯性等輔助目標,返回 int 的函數的最后一條語句應該始終是return SomeInt;
. 但要做到這一點並不容易,而且許多靜態分析工具也不會抱怨“無法訪問代碼”。 一個局部變量int returnValue
,初始化為一個明智選擇的默認值並寫入所有分支可以讓你到達那里。
但是同樣,一些工具然后抱怨一個值被寫入一個變量,然后在使用之前總是被覆蓋......所以默認的init可能是a
,然后不會在“then”中被覆蓋。 讓分析工具開心有時是一個循環游戲......
順便說一下,您顯示的代碼可能(絕對不能保證)實際工作,因為編譯器有時默認返回最后計算的結果,即使它被忽略。 但是您絕對不應該依賴它,並且應該受到人類或工具的任何抱怨。 我們可以放心地認為這是一個壞主意(tm)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.