[英]How can I fix the 'end of non-void function' for my minimum coins owed in change?
問題是,假設找回的硬幣數量為25c,10c,5c和1c,則找到找零給定金額的硬幣的最小數量。
我用C遞歸實現了一個解決方案,但是不知何故它不斷拋出“錯誤:控件可能到達非void函數的結尾”。 我是C語言的新手,所以我不太清楚發生了什么。 任何幫助是極大的贊賞! 這是我的代碼:
#include <cs50.h>
#include <stdio.h>
#include <math.h>
int processChange(float change){
int centsChange = round(change*100);
int arr[4] = {25,10,5,1};
for(int i=0;i<4;i++){
int numCoins =0;
int remainder = centsChange%arr[i];
if(remainder==0){
numCoins = (centsChange - remainder)/arr[i];
return numCoins;
}
if(centsChange ==1){return 1;}//base case
if(centsChange>=arr[i]){
numCoins = (centsChange - remainder)/arr[i]+ processChange(remainder/100);
return numCoins;
}
}
}
int main(){
float change;
do
{
change = get_float("Enter the changed owed\n");
}while (change<0);
printf("Minimum number of coins returned is %d\n", processChange(change));
}
processChange
中for
循環中的processChange
執行以下操作:
remainder
為零,請進行計算並返回。 centsChange
為1,則返回。 centsChange
至少為arr[i]
,則進行計算並返回。 for
循環的末尾並繼續進行迭代。 據編譯器所知, i
的值將達到4,並且控制將離開for
循環。 屆時,控制權將流到該函數的末尾,那里沒有return
語句。 因此,編譯器警告您控件將到達非空函數的末尾。 (“非空函數”是具有不為void
的返回類型的processChange
的返回類型為int
。)
解決此問題的一種方法是在函數末尾插入return
語句。
另一個方法是針對這種情況禁用編譯器警告,您可以使用-Wno-return-type
命令行開關對GCC和Clang進行此操作。
我們可以看到控件實際上不能離開for
語句,因為當i
為3時, arr[i]
為1,因此centsChange % arr[i]
必然會產生零,並將其分配給remainder
,從而導致代碼流入第一種情況以上。 使用GCC和Clang,您可以通過插入__builtin_unreachable();
來通知編譯器__builtin_unreachable();
作為函數中的最后一條語句。 這告訴編譯器,程序中各種情況的組合都無法在邏輯上達到代碼中的這一點。 (如果不是真的,控件無法到達該位置,則使用此編譯器功能將破壞程序。)
注意,由於上述原因,控件無法離開for
循環這一事實意味着centsChange == 1
基本情況是不必要的。 必須在某些時候滿足remainder == 0
的事實,這意味着它可以作為基本情況。
盡管此分析按原樣討論了代碼,但是經驗豐富的程序員將對代碼進行重組,以使上述解決方案都不是必需的。 有時,各種復雜性會促使我們使用代碼,而編譯器無法推斷出執行中從未達到某個特定點,但我們知道確實如此,在這種情況下可以使用上述變通方法。 但是,這不是其中之一。 該代碼非常簡單,可以進行重組,以使控制流對於編譯器而言更加簡單和明顯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.