Variable Scope and Function Prototypes

Variable Scope

As you have been experimenting with functions, and passing variables back and forth many of you have questioned whether the name of the variable inside of a function has to be the same name as the associated variable in main. The answer to this question is no. In addition, just because you call a variable the same name inside a function and inside main does not mean that they contain the same value. An example of this is shown in the following case:

#include <iostream.h>
void add(void)
{
    int numberone;
    int numbertwo;
    cout<<"The sum is"<<numberone+numbertwo<<endl;
}
 
int main(void)
{
    int numberone;
    int numbertwo;
    cout<<"Input number one: ";
    cin>>numberone;
    cout<<"Input number two: ";
    cin>>numbertwo;
    add();
    return 0;
}

What do you think this program does? Try it out. You'll notice that it prints that the sum is zero no matter what numbers you type in. This is because no numbers are passed between main and the add function even though the variables have the same name. You can tell that this is the case because the add function has no parameters. This can be fixed by moving the int declarations for numberone and numbertwo inside of the add function declaration so that it reads void add(int numberone, int numbertwo). Make sure that your variables are separated by commas.

This demonstrates that matching the names of the variables does not help you out. Note that the names do not even need to match. The add function would work just the same if it instead was written

void add (int firstnumber, int secondnumber)
{
    cout<<firstnumber+secondnumber;
}

The issue of where a certain variable name corresponds to a certain value (as we are discussing here) is called variable scope. The issues discussed above can be summarized in the statement that the scope of variables, as they have been defined here, is limited to the functions in which they are defined.

Global Variables

C++ does allow you to define variables outside of any function. This is called defining global variables and these definitions occur at the same level as the #include statements that we have used. Once a variable is defined globally, all functions can access that variable. Therefore we could rewrite the add program using global variables as follows.

#include <iostream.h>
int numberone;
int numbertwo;
 
void add(void)
{
    cout<<numberone+numbertwo;
}
 
int main(void)
{
    cout<<"Input number one: ";
    cin>>numberone;
    cout<<"Input number two: ";
    cin>>numbertwo;
    add();
    return 0;
}

Global variables can be quite useful, but they can also make things quite confusing. They make it less clear where information is coming from. In general you should only define variables globally when there is no other way around it. That will definitely hold true for this class. Global variables also raise the question as to what will happen in the following situation

#include <iostream.h>
int number;
 
void square(void)
{
    int number;
    cout<<number*number;
}
 
int main(void)
{
    cout<<"Enter a number: ";
    cin>>number;
    return 0;
}

What do you think will happen in this situation where number is defined in two places? Note that a variable takes on the value 0 as soon as it is defined and does not change unless the program or the user changes it. Which value takes precedence (takes over), the global value or the value from within the function?

Function Prototypes

When we have used functions so far, we have put them at the top of our programs before main. This works for what we have done, but it is not the best style. Additionally, it can create problems if one function needs to call another function. In general, functions only know about other functions that have appeared before them. This is why main can call the functions that appear before it.

A better way to do this is to put function prototypes at the top of the program. Then the rest of the functions can appear either before or after main (depending on your style).  A function prototype is just the first line of a function that has its name along with its parameters and return type, and an extra semicolon at the end. For example the prototype for the function

void add(void)
{
    cout<<numberone+numbertwo;
}
would be
void add(void);
 
and the prototype for the function
void add(int numberone, int numbertwo)
{
    cout<<numberone+numbertwo;
}
would be
void add(int numberone, int numbertwo);

These lines should immediately follow the #include statements, and before any global variables. The actual functions can follow. This serves several purposes. One purpose is to have a list of all the functions at the top of the program which is easy to read. Additionally, it allows functions to call each other without problems. We will make other uses of prototypes later.

Back to Home Page House3.wmf (25540 bytes)