CSCI 201 Study Aid: Variable Scope

What is ``Scope''

Resolving naming conflicts

An Example

Examine the program below and determine the scope of its identifiers. These scoping principals are designed to make sure that the different functions do not inadvertently change variables in the other's memory space simply because the variables are accidentally or even purposefully given the same name. An added benefit is that a programmer can work on a particular function and make changes without having to worry about how those changes will affect the variables in other functions.

 
// Complete program to calculate population doubling time
#include <iostream.h>
float doublingTime(float bacterialGrowthRate);  // Prototype - notice,
                                                //it is defined before main
int main ()
{
        float twiceTime, rateEColi;             // variable declaration
        rateEColi = 0.84;       // Unit is bacteria per hour. Rates vary
                                // with the environment.
        twiceTime = doublingTime(rateEColi);    // Calling statement
                                                // rateEColi is known as an
                                                // actual arugment
        cout << "Doubling time for Escherichia coli is: "
             <<  twiceTime  << endl;
        return 0;
}

float doublingTime(float bacterialGrowthRate)   // Function definition -
                                                 // bacterialGrowthRate is
                                                 // known as a
                                                 // formal parameter
{
        float natLogOf2 = 0.6931, time2Double;  // Data declarations for
                                                   // doublingTime function
        time2Double = natLogOf2 / bacterialGrowthRate;
        return time2Double;
}
Scope of the Identifiers
IDENTIFIER SCOPE FUNCTION
twiceTime Function Scope main
rateEColi Function Scope main
natLogOf2 Function Scope doublingTime
time2Double Function Scope doublingTime
bacterialGrowthRate Function Scope doublingTime

Note that the calling statement

   twiceTime = doublingTime(rateEColi)
passes the value of rateEColi to the function doublingTime which makes a copy of the value of rateEColi and stores it as bacterialGrowthRate. The called function, doubleTime, CANNOT alter the value of rateEcoli in the main function; it doesn't even know there is a variable named rateEColi. This is because the identifiers rateEColi and bacterialGrowthRate are stored in different places in memory (the identifiers have different storage locations even if they have the same name).

Exercises

  1. Is this program valid, and if so what does it do?
       #include 
       const   int x = 3;
       float y;
    
       int  foo(float &x) 
       {
          int y;
          y = int(x - (int(x) % 2));
          x = 13;
          return y;
       }
    
       int main()
       {
          int y = 3;
          float x = 3.14;
          y = y + foo(x);
          cout << x << " " << y << "\n";
       }
    

    solution

  2. What does this program print?
    #include 
    
    void a(void);   // function prototype
    void c(void);   // function prototype
    
    int x = 1;      // global variable
    
    main()
    {
       int x = 5;   // local variable to main
    
       cout << "local x in outer scope of main is " << x << endl;
    
       {            // start new scope
          int x = 7;
    
          cout << "local x in inner scope of main is " << x << endl;
       }            // end new scope
    
       cout << "local x in outer scope of main is " << x << endl;
    
       a();         // a has local x
       c();         // c uses global x
       a();         // a reinitializes local x
       c();         // global x also retains its value
    
       cout << "local x in main is " << x << endl;
    
       return 0;
    }
    
    void a(void)
    {
       int x = 25;  // initialized each time a is called
    
       cout << endl << "local x in a is " << x 
            << " after entering a" << endl;
       ++x;
       cout << "local x in a is " << x 
            << " before exiting a" << endl;
    }
    
    void c(void)
    {
       cout << endl << "global x is " << x 
            << " on entering c" << endl;
       x *= 10;
       cout << "global x is " << x << " on exiting c" << endl;
    }
    

    solution