简体   繁体   English

如何为找零的最低硬币固定“非无效功能的末端”?

[英]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: processChangefor循环中的processChange执行以下操作:

  • If remainder is zero, do a calculation and return. 如果remainder为零,请进行计算并返回。
  • If centsChange is one, return. 如果centsChange为1,则返回。
  • If centsChange is at least arr[i] , do a calculation and return. 如果centsChange至少为arr[i] ,则进行计算并返回。
  • Otherwise, reach the end of the 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.

相关问题 如何修复“错误:控制到达非空函数结束”? - How to fix "error: control reaches end of non-void function"? 如何修复 HackerRank 的“错误:控制到达非空函数 [-Werror=return-type] 的末尾”? - How to fix "error: control reaches end of non-void function [-Werror=return-type]" at HackerRank? 我的代码需要帮助,它给我一个错误控制,可能会到达非void函数的结尾 - I need help on my code, it gives me an error control may reach end of non-void function 控制到达非空 function 的末尾。 如何解决这个问题? - control reaches end of non-void function. How to solve this? 控制如何到达这个非void function的结尾? - How does control reach the end of this non-void function? 如何解决“控件到达非void函数结束”警告? - How to solve the “control reaches end of non-void function” warning? 如何使用atexit()注册非空函数? - How to register a non-void function with atexit()? 测试我的排序算法错误:控制到达非无效 function 的结尾 - Testing my sorting algorithm Error: control reaches end of non-void function 我收到一条警告,说我已达到非空函数的结尾 - I am getting a warning saying I have reached end of non-void function 为什么即使保证返回,我也会收到警告“控制到达非空函数的结尾” - Why do I get the warning 'control reaches end of non-void function' even when the return is guaranteed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM