Lab 9 -- Scope, Lifetime, and More on Functions

Click Here to CREATE ANSWER SHEET for LAB 9

Objectives:

Sections:

  1. Review
  2. Functions that Return a Single Value
  3. Local and global variables
  4. Scope
  5. Lifetime of a variable

Review
In previous labs, the following topics were covered:


Exercise 1:
Look at the program called cla9a.cpp. On the answer sheet, answer the following questions. Note that line numbers have been added to help you identify certain parts of this program.

a. Which lines of the program contain function prototypes?

b. Which lines of the program contain the function definition of the function PrintInfo?

c. Which line of the program activates (calls) the function PrintInfo?

d. Name all void functions with no parameters (if any).

e. Name all void functions with value parameters (if any).

f. Name all void functions with reference parameters (if any).

g. Name the library functions (if any) used in the program.


Functions that Return a Single Value
Until this lab, we have only written void functions. When we call (activate) a void function, the name of the function together with the parameters sent to the function appear as a C++ statement. We have also studied several library functions that return a single value such as sqrt() and pow(). When we studied these functions, we noticed that the function could be activated in an expression or in an output statement. For example, both of the following are perfectly legal in C++.
cout << "The square root of 5 is  " << sqrt(5.0) << endl;

y = sqrt(5.0);

The square root function shown above, returns a single value -- namely, the square root of its single argument. Often a function is needed to compute a single value and this value is returned back to the calling program. Therefore, we say that this particular function returns a single value.


RULE: If a function calculates a single value, this value should be returned to the calling function using the return statement.


Consider the following function:


    // Function:   Average()
    // Purpose:    This function calculates and returns the average 
    // of three floating point grades. 
    float Average (float test1, float test2, float test3)   //IN: test scores 
    { 
          float avg;                         //average of scores 
          avg = (test1 + test2 + test3)/3; 
          return avg; 
    } 
	

It is an example of a function that has input arguments and a single return value. This function computes the average of the three tests and returns the average using the return statement. The word "float" preceding the word "Average" in the function header indicates that the datatype of the value returned will be of type float.

We will now explore functions that receive value parameters and return a single value through the return statement. We will examine two mathematical problems that are related to the quadratic equation. The quadratic equation in mathematics is a function of the form f(x) = ax2+ bx + c. The first problem that we will explore is that of evaluating the function at a specific value for x. The second problem that we will explore is that of finding values of x that make the function have the value 0. In other words we will find roots of ax2+ bx + c = 0 using the quadratic formula.


Exercise 2:
Copy the file called cla9b.cpp to your account. This program contains a function called quadratic() that receives input arguments for a, b, c, and x and evaluates a quadratic equation of the form ax
2 + bx + c for a particular value of x.

By studying the code in cla9b.cpp, answer the following questions on the answer sheet:

a. Name the parameters (function heading) for the function quadratic().
b. Name the actual arguments (the arguments in the activation statement).
c. What is the return type of this function?

Exercise 3:
Compile and execute this C++ program to assure that it solves our first problem of evaluating a quadratic. Run the program with the the following values for a, b, c, and x. There is nothing to turn in as a result of this exercise.

 1   1   1    0
 0   2   3    1
 4   2   12   5 
Exercise 4:
Copy the file cla9c.cpp to your account. It is a modified version of the previous program. Write a function called discriminant() that will compute the value of the discriminant of a quadratic equation. In other words, given the values a, b, and c, this function finds and returns the value of b2 - 4ac. Add this function to the end of the cla9c.cpp program.

Exercise 5:
Add a function prototype for discriminant() to cla9c.cpp above main().

Exercise 6:
Add C++ statements to the function main() that will calculate the roots of the quadratic equation. To find the roots, use the discriminant function written in the previous exercises and the formulas below. Only compute the roots when the discriminant is not negative. When the discriminant is negative, print the message "No Real Roots".


Create a script log with the source program listing of the modified code, compilation results, and a run of the program using the following data:


 		1	1	1
		1	5	-6
		1	6	10
  
The following UNIX commands will let you create what is required:
            $ script lab9ex6.log
            $ pr -n -t -e4 cla9c.cpp
            $ c++ cla9c.cpp -o cla9c
            $ cla9c
            1  1  1
            1  5 -6
            1  6 10
            N
            $ exit
(Be sure to exit the script session before continuing!)


Local and Global variables
Now that we have begun to write programs containing more than one function, we can look more closely at the variables declared within a program. Consider the following:

NOTE: In general, it is not good practice to make use of global variables within individual functions. It is best for each function to be as self contained as possible. This can best be achieved if the function only uses variables passed as arguments or variables which are defined locally. Nonetheless, we will briefly study global variables in order to fully understand C++ scope.


Scope
Now lets discuss scope of a variable. The scope of a variable is the portion of the program where the variable is valid or "known". The following program will be used to study the concepts of scope of a variable. Line numbers have been added to help in our explanation.
(NOTE: A file containing scope.cpp is not available nor needed. Answer the exercise questions by inspecting and hand-tracing the program.)


1    //File:        scope.cpp
2    //Authors:   
3    //Purpose:     This program demonstrates scope.
4
5    //include files...
6    #include <iostream>
7
8    using namespace std;
9                                       
10   //function prototype(s)...   
11   void ShowScope(int& , int );       
12                                    
13   //global variables...       
14   int a,b;                           
15                                      
16   int main ()                    
17   {                                  
18        a = 10;                       
19        b = 20;                                           
20        cout << "Before activating ShowScope a= " << a << " and b= " << b << endl;
21        ShowScope (a,b);
22        cout << "\nAfter ShowScope a= " << a << " b= " << b << endl;
23
24        //end of main...
25        return 0;
26   }
27
28   //Function:    ShowScope()
29   //Purpose:     Further demonstrate scope
30
31   void ShowScope(int& x, int y)
32   {
33
34        //local declarations...
35        int a,c;
36
37        a = 100;
38        c = 200;
39        x = 300;
40        y = 400;
41        cout << "Inside ShowScope, a = " << a <<  " b = " << b <<  endl;
42        cout << "x = " << x << " and y = " << y << endl;
43        return;
44   }


We can see from line 14 that a and b are global variables since their definition occurs outside of all curly braces. In ShowScope(), a, c, x and y are local variables since these variables are defined in the function header or after the function header. Notice that there is a global variable and a local variable with the same name. When this happens, any reference to this name results in action being taken as locally as possible. Thus the assignment a = 100 in the function called ShowScope() only effects the local a and not the global a. Since a and b are global variables, their scope is the entire program including the ShowScope() function. Since the local variables a, c, x and y are defined in ShowScope(), their scope is the function ShowScope() and they are not known outside of that function. ShowScope() has two arguments x and y. The x argument is a pass-by-reference argument and the y argument is a pass-by-value argument.

Execution of the program is as follows:


Exercise 7:
What is the output generated by line 20 in the program? Place your answer on the answer sheet.


Exercise 8:
Show the output generated by statements 41 and 42 in the function ShowScope(). Note that ShowScope() does not have a local variable called b, thus when a reference to b is made in the cout statement, all local variables are checked first and when b is not found, global variables are searched to see if there is a global variable called b.


Exercise 9:
Show the output generated by line 22 when control is returned to the main function. Note that the value of a has changed because it corresponded to the variable parameter x in the function. The value of b did not change since it corresponded to the value argument y in the function.


Exercise 10:
Copy the C++ program called
cla9d.cpp to your account:

a. Identify (make a list) all global variables.

b. Identify all local variables in subOne.

c. Identify all local variables in subTwo.

d. Identify all formal arguments in subOne.

e. Identify all actual arguments in the call to subOne.



Exercise 11:
Show the output generated by the program cla9d.cpp.


Lifetime of a Variable
A variable's lifetime is the period of time during which that variable exists during execution. Some variables exist briefly. Some are repeatedly created and destroyed. Others exist for the entire execution of a program. In this section we will discuss two storage classes of variables: automatic variables and static variables.

An automatic variable's memory location is created when the block in which it is declared is entered. An automatic variable exists while the block is active, and then it is destroyed when the block is exited. Since a local variable is created when the block in which it is declared is entered and is destroyed when the block is left, one can see that a local variable is an automatic variable.

A static variable is a variable that exists from the point at which the program begins execution and continues to exist during the duration of the program. Storage for a static variable is allocated and initialized once when the program begins execution. A global variable is similar to a static variable since a global variable exists during the duration of the program. Storage for the global variable is allocated and is initialized once when the declaration for the global variable is encountered during execution. Thus both the global variable and the static variable have a history preserving feature -- they continue to exist and their contents are preserved throughout the lifetime of the program.

A programmer can also declare a local variable to be static by using the keyword static in the variable's declaration as in the following example:

           static int num=0;

For most applications, the use of automatic variables works just fine. Sometimes, however, we want a function to remember values between function calls. This is the purpose of a static variable. A local variable that is declared as static causes the program to keep the variable and its latest value even when the function that declared it is through executing. It is usually better to declare a local variable as static than to use a global variable. A static variable is similar to a global variable in that its memory remains for the lifetime of the entire program. However, a static variable is different from a global variable because a static variable's scope is local to the function in which it is defined. Thus other functions in the program can not modify a static variable's value because only the function in which it is declared can access the variable.


Exercise 12:
Copy the files cla9e.cpp and cla9f.cpp to your account. These programs are very similar. Describe the difference between the two.

Exercise 13:
Run the two programs and describe the difference in the output and why it occurs.


Exercise 14:

Submit the log file you have created in Lab 9 typing

          $ handin lab9log lab9ex6.log
Exercise 15:

From the PC you are working on, you must also submit the answer sheet (AnswerSheet9.pdf) using the following directions:


Congratulations! You have finished Lab 9.



Once you are done, you will need to log off ranger. Enter   $ exit   to exit the (sakura) terminal window. Depending on how you logged in to ranger you will need to enter $ exit one or more times to get completely logged off the system.