繁体   English   中英

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

[英]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));

}

processChangefor循环中的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM