Lab 8: Parameter Passing and Scope


Introduction

This lab's exercise investigates some of the features and restrictions of C++ functions that we haven't considered up to now.

  1. Parameter-Passing Mechanisms. The six experiments in this part deal with a function's parameters:
     

  2. Scope in C++. The six experiments in this part examine some of the scope rules that govern the relationship between items that are in different functions.

Each experiment starts out with an issue and a hypothesis about the issue. Your work will be to prove or disprove the hypothesis by answering various questions. You should write out these answers for future reference and/or to hand in if your instructor asks you to do so.

You will begin with the following program

params.cpp
and modify it in various ways to test the hypotheses. Download it and add to the opening documentation whatever information your instructor specifies.

Part I: Parameter-Passing Mechanisms

The general form of a C++ function heading is:

    ReturnType Name( ParameterDeclarationList )
where ParameterDeclarationList is a sequence of zero or more parameter declarations, separated by commas, each of which has the form:
    Type ParameterName
where Type is a valid type, and ParameterName is a valid identifier.

We've used identical parameter lists in both the prototype and the definition of our functions. This is not necessary, however. The prototype may use different parameter names than those in the definition — in fact, the prototype need only have the parameter types listed. We will, however, make the headings of both the same because this serves as additional documentation (and we can copy and paste it from one to the other.)

Terminology

  1. A value parameter is a parameter whose Type is not followed by an ampersand (&). A value parameter is a variable that is local to the function; when the function is called, it receives a copy of the value of the corresponding argument.
  2. A reference parameter is parameter whose Type is followed by an ampersand (&). (Technically, the ampersand is part of the type.) A reference parameter is an alias (e.g., another name) for its corresponding argument — they share the same memory locations.

Question #8.1: We have used parameters in several of our programs. In every case, which kind did we use?

Now look over the program in params.cpp. Note that its behavior consists of 3 steps:

  1. Initialize a set of variables to some initial value (-1 in this case).
  2. Call function change() that tries to modify the values of those variables.
  3. Output the values of those variables to view the effects of function change().

The key word above is "tries." change() tries to alter the variables in main() through its parameters, but it's not always successful.

This function change() will be the "laboratory" that we will use to conduct experiments with parameters.

The Parameter Experiments

Experiment #1: Changing Value Parameters

Experiment #2: Value Parameters and Their Arguments

Experiment #3: Naming Parameters and Arguments

Experiment #4: Differing Numbers of Parameters and Arguments

Experiment #5: Reference Parameters

Experiment #6: Constant Reference Parameters


Part II: Scope in C++

Declaring a name in a C++ program can be thought of as providing the compiler with a meaning for that name. However, as we have seen, the same name can be declared in different parts of a program and thus may mean something different in one part than it does in another part.

To illustrate, the name arg1 was declared twice in Experiment #3 — once as an integer variable in the main program and a second time as an integer value parameter in the function change(). We also saw that when arg1 is a value parameter, altering it in change() leaves the value of arg1 in the main program unchanged.

We might conclude from this that arg1 in main() and arg1 in change() are two different variables. Stated differently, the same name can have different meanings in different parts of a program. For example, nothing prevents us from declaring a variable as an integer in main() and then redeclaring a variable with the same name as a real number in the function change(). The same name will have one meaning when execution is in main() and a different meaning when execution is in change().

Definition: The set of all places in a program where a name has a particular meaning is called the scope of that name.

The (Simplified) C++ Rules of Scope

The basic rules governing the scope of C++ names can be summarized as follows:

  1. Local block scope. A block of code is a section of code enclosed within "curly" braces { and }. The scope of any variable or constant declared within a block starts at its declaration and extends to the end of that block. This means that this variable or constant is defined only in the code (which may include nested compound statements) from its declaration to the end of the block. They are thus said to be "local" to that block.
  2. Local parameter scope. The scope of a parameter starts at its declaration and ends at the function's closing brace. Parameters are thus also local because their scope covers only a local area of the code.
  3. for-loop scope. A variable declared in the initialization expression of a for loop is local to the for loop.
  4. Non-local scope. There are several other types of scope that we'll simple refer to as "non-local." In particular, the scope of an item declared outside all curly-brace blocks extends from it's declaration to the end of the file. For example, anything declared in a library that we #include at the beginning of a program has meaning throughout the entire program.

(Also, C++ classes have their own rules of scope, which we will examine in a later exercise.)

The scope of a variable or constant determines where it is valid — that is, where it may be used. If we try to access a variable or constant outside its scope, that access is invalid, and the compiler will generate an error message.

The Scope Experiments

Experiment #7: Same Identifier Declared Twice in Same Local Scope

Experiment #8: Same Identifier Declared in Nested Blocks

Experiment #9: Using an Twice-Declared Identifier in Inner Block

Experiment #10: Using an Twice-Declared Identifier in Outer Block

Experiment #11: Non-local Scope

Experiment #12: Keywords, Locals, and Non-Locals  

Submit

Hand in the answers to the questions of the experiments that your instructor asks you to do. You may also be required to turn in a copy of your program after each of those experiments.


Lab Home Page


Report errors to Larry Nyhoff (nyhl@cs.calvin.edu)