The Scope of Identifiers
1. A variable which is accessible to a subprogram without having
to be explicitly declared in that subprogram is called a
GLOBAL variable with respect to the subprogram. Variables
declared within subprograms are called LOCAL variables with
respect to the subprogram.
2. A variable could be local to one module (the calling module)
at the same time that it is global to another (the module
being called).
3. The scope of a variable (or more generally an identifier) is
the extent to which it is available to various subprograms in
a given program.
4. RECOMMENDATION: make all variables as local as possible. If
a subprogram needs to interact with a variable, then that
variable should be passed to it as a parameter.
5. The rule of determining the scope of an identifier is:
The scope of an identifier extends from the program unit in
which it is defined to all subunits which do not themselves
redefine that identifier.
6. The rule for procedure calls is:
A procedure can be referenced only in blocks that CONTAIN the
procedure. Procedures within the same block may only
reference those which physically precede it.
--------------------------------------------------------
| |
| MAIN PROGRAM |
| Var A, B, C, D, E, F, G, H, I |
| |
| ----------------------------------------- |
| | Subprogram #1 | |
| | Var A, C, E, X, Y, Z | |
| | | |
| | -------------------------- | |
| | | Subprogram #1a | | |
| | | Var C, Y, U, V | | |
| | | | | |
| | | A := 5; | | |
| | -------------------------- | |
| ----------------------------------------- |
| |
| ----------------------------------------- |
| | Subprogram #2 | |
| | Var A, B, D, X, V | |
| | | |
| ----------------------------------------- |
| |
| |
--------------------------------------------------------
In the previous program structure:
MAIN can call subprograms 1 and 2
MAIN cannot call subprogram 1a
Subprogram 1 can call subprogram 1a
Subprogram 2 cannot call subprogram 1a
Subprogram 2 can call subprogram 1
Subprogram 1 cannot call subprogram 2
7. VALUE PARAMETERS are used only for INPUT to procedures.
VARIABLE PARAMETERS are used for both input to and output from
procedures
8. When an identifier is used in a procedure, the Pascal compiler
(a) first looks to see if the identifier is local to the
procedure
(b) THEN it looks to see if the identifier is a formal
parameter
(c) FINALLY it looks to see if the identifier is known outside
the procedure at some level containing the procedure; if
so, the FIRST occurrence of the identifier is used.
9. A global variable can be redefined at each new procedure level,
at which time it is local to that level.
SCOPE RULES DEMO PROGRAM
Program Scope_rules;
{ This program illustrates the various scope rules for identifiers
in Pascal. Just what can be referenced within procedures and at
what levels? }
Uses
Crt;
Var
A, B, X, Y: Integer; { LOCAL TO MAIN CODE; GLOBAL TO ALL
PROCEDURES WHICH DO NOT REDEFINE THEM! }
{ ============== 1ST PROCEDURE ================================ }
Procedure FIRST;
Begin { FIRST }
Writeln('Writing from within procedure #1...');
Writeln('A = ', A);
Writeln('B = ', B); { The main code variables }
A := -6;
B := 0;
Writeln('Leaving procedure #1...')
End; { FIRST }
{ ============== 2ND PROCEDURE =============================== }
Procedure SECOND;
Var
A, C: Integer;
Begin
Writeln('Writing from within procedure #2...');
A := 15;
B := -1;
C := 10;
Writeln('A = ', A);
Writeln('B = ', B);
Writeln('C = ', C);
Writeln('Leaving procedure #2...')
End; { SECOND }
{ ============== 3RD PROCEDURE =============================== }
Procedure Third(Var X, Y: Integer);
Begin
Writeln('Writing from within procedure #3...');
Writeln('X = ', X);
Writeln('Y = ', Y);
X := -25; { X and the parameter referenced by it are the same }
Y := 123 { Y and the parameter referenced by it are the same }
End; { THIRD }
{ ============== 4TH PROCEDURE ================================== }
Procedure Fourth(X, Y: Integer);
Var
A, F: Integer;
{ ============== 5TH PROCEDURE: NESTED WITHIN 4th ============ }
Procedure Fifth(Var M, N: Integer);
Var
C, F: Integer;
Begin { FIFTH }
Writeln;
Writeln('Now inside FIFTH procedure declared within FOURTH...');
A := 16; { A is global to #4 }
B := 976; { B is the global variable in the main program }
M := -65; { M is linked to the parameter referenced by it }
N := 100; { ditto for N }
F := -99; { F is local to #5 }
Writeln('A' :5, 'B' :5, 'F' :5, 'M' :5, 'N' :5, 'X' :5, 'Y' :5);
Writeln(A :5, B :5, F :5, M :5, N :5, X :5, Y :5);
Writeln('Leaving procedure FIFTH...');
Writeln
End; { FIFTH }
Begin { FOURTH }
Writeln;
Writeln('Writing from within procedure #4...');
Writeln('X = ', X);
Writeln('Y = ', Y);
X := -55;
Y := 125; { Both X and Y are local to Procedure #4 }
A := 2500; { A and F are local to procedure #4 }
F := -512;
Writeln('X = ', X);
Writeln('Y = ', Y);
Writeln('A = ', A);
Writeln('F = ', F);
FIFTH(X, Y);
Writeln('Back in 4th again...');
Writeln('A' :5, 'B' :5, 'F' :5, 'X' :5, 'Y' :5);
Writeln(A :5, B :5, F :5, X :5, Y :5);
Writeln('Leaving procedure #4...')
End;
BEGIN { MAIN }
Clrscr;
A := 1;
B := 2;
Writeln('In Main.');
Writeln('A = ', A);
Writeln('B = ', B);
Writeln('Calling First Procedure');
FIRST;
Writeln('Returned from FIRST... now A = ', A, ' and B = ', B);
Readln;
A := 1;
B := 2;
Writeln('In Main..');
Writeln('A = ', A);
Writeln('B = ', B);
Writeln('Calling Second Procedure');
SECOND;
Writeln('Returned from SECOND... now A = ', A, ' and B = ', B);
Readln;
A := 1;
B := 2;
X := 81;
Y := -95;
Writeln('In Main...');
Writeln('Calling Third Procedure');
THIRD(A, B);
Writeln('Returned from THIRD... ');
Writeln('now A = ', A, ' , B = ', B, ' , X = ', X, ' and Y = ', Y);
Readln;
A := 1;
B := 2;
Writeln('In Main....');
Writeln('Calling Fourth Procedure');
FOURTH(A, B);
Writeln;
Writeln('Returned from FOURTH... ');
Writeln('now A = ', A, ' , B = ', B, ' , X = ', X, ' and Y = ', Y);
Readln
END.
=====================================================================
PROGRAM RUN:
=====================================================================
In Main.
A = 1
B = 2
Calling First Procedure
Writing from within procedure #1...
A = 1
B = 2
Leaving procedure #1...
Returned from FIRST... now A = -6 and B = 0
In Main..
A = 1
B = 2
Calling Second Procedure
Writing from within procedure #2...
A = 15
B = -1
C = 10
Leaving procedure #2...
Returned from SECOND... now A = 1 and B = -1
In Main...
Calling Third Procedure
Writing from within procedure #3...
X = 1
Y = 2
Returned from THIRD...
now A = -25 , B = 123 , X = 81 and Y = -95
In Main....
Calling Fourth Procedure
Writing from within procedure #4...
X = 1
Y = 2
X = -55
Y = 125
A = 2500
F = -512
Now inside FIFTH procedure declared within FOURTH...
A B F M N X Y
16 976 -99 -65 100 -65 100
Leaving procedure FIFTH...
Back in 4th again...
A B F X Y
16 976 -512 -65 100
Leaving procedure #4...
Returned from FOURTH...
now A = 1 , B = 976 , X = 81 and Y = -95