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:
- Place the variables in global scope, so that both functions refer to the same variables.
- 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
.