0

This is part of code from my greedy.c

The purpose of this do while loop is to get a valid input.

I'm having trouble, I tested it outside do while loop and it was working fine.

I think that mistake is really dumb but I really need help!!

I'm stuck here... :-(

void calc(int number, int change, int coins)
{
    int result = change / number;
    coins = coins + result;
    change = change % number;
}

int main(void)
{      
    int change;

    do
    {
        printf("How much I owe you: ");
        change = round(GetFloat() * 100);
    } 
    while (change < 0);

    int coins = 0;

    while (change > 0)
    {
        if (change >= 25)
        {
            calc(25, change, coins);    
        }

        if (change >= 10)
        {
            calc(10, change, coins);  
        }

        if (change >= 5)
        {
            calc(5, change, coins);
        }

        if (change >= 1)  
        {
            calc(1, change, coins);
        }
    }

    printf("Minimum number of coins needed is: %i \n", coins);
    return 0;
}
5
  • The only way that loop would repeat is if you entered a negative number. Why do you think it's an infinite loop? – curiouskiwi Aug 22 '14 at 22:49
  • @curiouskiwi I'm not sure, maybe I'm just hunting in the dark, but the program won't printf nothing after initilizing change(I already tryed). I really don't get it. – Valentino Skobljanec Aug 23 '14 at 8:53
  • @ValentinoSkobljanec what are other loops that you have in your code? – kzidane Aug 23 '14 at 10:02
  • @Kareem I have four for loops inside of a while loop. But I thought that the problem stands in line: change = round(GetFloat() * 100); 'cause if I try to print something in do while loop(and put that printf after initilazing change) it wouldn't work. – Valentino Skobljanec Aug 23 '14 at 10:36
  • @ValentinoSkobljanec probably the problem is caused by one or more of these loops. If you don't mind, you can update your question to see if we can help you identify the bug. – kzidane Aug 23 '14 at 10:38
1

The problem is that variables are in different scope. Scope refers to the rules in C which determine how variables are access. Variables can only be accessed in the scope in which they are defined.

In this case there are two different scopes, the main function, and the calc function. It is clear from the code in the calc function, that the intention is to update the coins and change variables. However, this will not work this way, because the variables are in two different scopes. So even though the variables have the same names, they are different variables.

To put this another way, the coins variable in the calc function is not the same as the coins variable in the main function, it is in fact just a copy. When you change one copy, the other copy does not change automatically.

There are at least two possible ways to solve this:

  1. Place the variables in global scope, so that both functions refer to the same variables.
  2. Pass a pointer to the variables, i.e. pass the variables by reference instead of by *value.

Global scope

To use global scope, declare the variables outside the main and calc functions:

int change;
int coins = 0;

void calc(int number)
{
    int result = change / number;
    coins = coins + result;
    change = change % number;
}

int main(void)
{      
    // get input from user

    while (change > 0)
    {
        if (change >= 25)
        {
            calc(25);    
        }

        // calculate 10s, 5s, and 1s
    }

    // print results
}

This tells C that the change and coins variables are accessible to all functions in the program. Note that it is no longer necessary to pass the values to calc, since calc can access the variables directly.

While this may work, it is not recommended, as there are many problems associated with using global variables, as discussed in the shorts and lectures. My advice would be to try this, observe the results, and then use something else.

Pointers

Pointers have not been covered at this point in the course (as far as I can recall), so if the following is confusing it may be useful to watch ahead in the course, and come back to this when pointers make more sense.

At the moment the code works by copying the values to the calc function. This is referred to as passing the variables by value, since it is the actual value of the variable which is transferred from one function to the other.

Another way to send the variables, is to instead pass the location of where the variable resides in memory. This location is indicated by a pointer, which allows both functions to modify the same data in memory. This is called passing by reference.

void calc(int number, int* change, int* coins)
{
    int result = *change / number;
    *coins = *coins + result;
    *change = *change % number;
}

int main(void)
{      
    int change;

    // get input

    int coins = 0;

    while (change > 0)
    {
        if (change >= 25)
        {
            calc(25, &change, &coins);    
        }

        // calculate 10s, 5s, and 1s
    }

    // print results
}

Here's what each of the new lines of code are doing:

void calc(int number, int* change, int* coins)

int* change and int* coins means that instead of taking int variables as before, the calc function will instead take as arguments the locations of where two int values are in memory.

int result = *change / number;
*coins = *coins + result;
*change = *change % number;

These lines are almost the same as before, with the exception of the * character. Since change and coins are pointers to memory locations, the * just means "update the int at this location".

calc(25, &change, &coins); 

The use of the & means that instead of passing int values to calc, it passes pointers to the locations of the variables. This allows calc to modify the exact same memory which main uses for change and coins.

2
  • Thanks Luke for helping in this mess. It was really giving me a headache. I found that mistake few hours ago(with testing the function calc), but I wasn't successful in solving the problem, so i give up from that implementation and jumped to another, which is done recently and is working perfectly fine(but this idea is more elegant). I met with pointers before but I thought that bad memory of it is reason for errors. Now I can see that pointers in C and C++ are different(if I'm not wrong again)?! Now I have two code for greedy and I learn something new. Thanks one more time!! :-) – Valentino Skobljanec Aug 23 '14 at 22:32
  • Great, glad to help. Pointers in C and C++ are mostly the same, for primitive types like int, but differ with more complex types such as arrays and structs (generally using new and delete instead of malloc and free). Pointers in either language can be tricky, and can lead to memory errors if not used with care. – Luke Van In Aug 24 '14 at 0:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .