简体   繁体   中英

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.

I implemented a solution with recursion in C, but somehow it kept throwing the "error: control may reach end of non-void function". I'm fairly new to C so I couldn't quite figure out whats going on. 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:

  • If remainder is zero, do a calculation and return.
  • If centsChange is one, return.
  • If centsChange is at least arr[i] , do a calculation and return.
  • Otherwise, reach the end of the for loop and continue iterating.

As far as the compiler can tell, the value of i will reach four, and control will leave the for loop. At that point, control would flow to the end of the function, where there is no return statement. 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 .)

One way to fix this is to insert a return statement at the end of the function.

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.

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. With GCC and Clang, you can inform the compiler of this by inserting __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. The fact that remainder == 0 must be satisfied at some point means it serves as a base case.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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