[英]How can I fix the 'end of non-void function' for my minimum coins owed in change?
The problem is to find the minimum number of coins owed given an amount of dollars in change, assuming that available coins to give back are 25c, 10c, 5c and 1c. 问题是,假设找回的硬币数量为25c,10c,5c和1c,则找到找零给定金额的硬币的最小数量。
I implemented a solution with recursion in C, but somehow it kept throwing the "error: control may reach end of non-void function". 我用C递归实现了一个解决方案,但是不知何故它不断抛出“错误:控件可能到达非void函数的结尾”。 I'm fairly new to C so I couldn't quite figure out whats going on.
我是C语言的新手,所以我不太清楚发生了什么。 Any help is greatly appreciated!
任何帮助是极大的赞赏! Here's my code:
这是我的代码:
#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));
}
The code in the for
loop in processChange
does this: processChange
中for
循环中的processChange
执行以下操作:
remainder
is zero, do a calculation and return. remainder
为零,请进行计算并返回。 centsChange
is one, return. centsChange
为1,则返回。 centsChange
is at least arr[i]
, do a calculation and return. centsChange
至少为arr[i]
,则进行计算并返回。 for
loop and continue iterating. for
循环的末尾并继续进行迭代。 As far as the compiler can tell, the value of i
will reach four, and control will leave the for
loop. 据编译器所知,
i
的值将达到4,并且控制将离开for
循环。 At that point, control would flow to the end of the function, where there is no return
statement. 届时,控制权将流到该函数的末尾,那里没有
return
语句。 Thus, the compiler is warning you that control would reach the end of a non-void function. 因此,编译器警告您控件将到达非空函数的末尾。 (A “non-void function” is one with a return type that is not
void
. The return type of processChange
is int
.) (“非空函数”是具有不为
void
的返回类型的processChange
的返回类型为int
。)
One way to fix this is to insert a return
statement at the end of the function. 解决此问题的一种方法是在函数末尾插入
return
语句。
Another is to disable compiler warnings for this situation, which you can do with GCC and Clang using the -Wno-return-type
command-line switch. 另一个方法是针对这种情况禁用编译器警告,您可以使用
-Wno-return-type
命令行开关对GCC和Clang进行此操作。
We can see that control cannot actually leave the for
statement because, when i
is three, arr[i]
is one, so centsChange % arr[i]
necessarily produces zero, which is assigned to remainder
, causing code to flow into the first case above. 我们可以看到控件实际上不能离开
for
语句,因为当i
为3时, arr[i]
为1,因此centsChange % arr[i]
必然会产生零,并将其分配给remainder
,从而导致代码流入第一种情况以上。 With GCC and Clang, you can inform the compiler of this by inserting __builtin_unreachable();
使用GCC和Clang,您可以通过插入
__builtin_unreachable();
来通知编译器__builtin_unreachable();
as the last statement in the function. 作为函数中的最后一条语句。 That tells the compiler that that point in the code logically cannot be reached by any combination of circumstances within the program.
这告诉编译器,程序中各种情况的组合都无法在逻辑上达到代码中的这一点。 (Using this compiler feature when it is not true that control cannot reach the location will break your program.)
(如果不是真的,控件无法到达该位置,则使用此编译器功能将破坏程序。)
Note that the fact that control cannot leave the for
loop for the above reason implies the centsChange == 1
base case is unnecessary. 注意,由于上述原因,控件无法离开
for
循环这一事实意味着centsChange == 1
基本情况是不必要的。 The fact that remainder == 0
must be satisfied at some point means it serves as a base case. 必须在某些时候满足
remainder == 0
的事实,这意味着它可以作为基本情况。
Although this analysis discusses the code as it is, experienced programmers would restructure the code so that none of the above solutions are necessary. 尽管此分析按原样讨论了代码,但是经验丰富的程序员将对代码进行重组,以使上述解决方案都不是必需的。 There are times when various complications motivate us to use code where the compiler cannot deduce that a certain point is never reached in execution, but we know it is, and the above workarounds may be used in such cases.
有时,各种复杂性会促使我们使用代码,而编译器无法推断出执行中从未达到某个特定点,但我们知道确实如此,在这种情况下可以使用上述变通方法。 However, this is not one of them.
但是,这不是其中之一。 This code is fairly simple and can be restructured so that control flow is simpler and more apparent to the compiler.
该代码非常简单,可以进行重组,以使控制流对于编译器而言更加简单和明显。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.