Transcript Chapter 1

Chapter 9: Subprograms
•
•
•
•
•
•
Introduction
Fundamentals of Subprograms
Local Referencing Environments
Parameter-Passing Methods
Type Checking Parameters
Design Issues for Functions
9-1
Introduction
• Two fundamental abstraction facilities
– Process abstraction
• Emphasized from early days->subprogram
– Data abstraction
• Emphasized in the1980s-> Class (ch 11 & 12)
• Benefits of subprogram
– Process abstraction:
• The procedure name like “sort” conveys the intent of
the procedure.
• focus on what;
– implementation hiding:
• Only procedures needs to be modified.
• easy to modify;
– modular program: easy to manage a large program;
– libraries: extending a language
9-2
Fundamentals of Subprograms
• Each subprogram has a single entry point
• A subprogram call is an explicit request
that the subprogram be executed
• The calling program is suspended during
execution of the called subprogram
• Control always returns to the caller when
the called subprogram’s execution
terminates
9-3
Procedures and Functions
• There are two categories of subprograms
– Procedures are collection of statements that
define parameterized computations
• treated as atomic statements, e.g., read (ch).
– Functions structurally resemble procedures but
are semantically modeled on mathematical
functions
• like operators, which return a result.
• called from within expressions, e.g., r*sin(angle).
9-4
Basic Definitions
• A subprogram definition describes the interface to
and the actions of the subprogram abstraction
• A subprogram header is the first part of the
definition, including the name, the kind of
subprogram, and the formal parameters
– Ada:
– C:
Procedure Adder (parameters)
void adder (parameters)
• The protocol is a subprogram’s parameter profile
(including the number, order, and types of its
parameters), and, if it is a function, its return type
• A subprogram declaration provides the protocol,
but not the body, of the subprogram
• Function declarations in C and C++ are called
prototypes, and often placed in header files.
9-5
Actual/Formal Parameter
• A formal parameter is a dummy variable listed in
the subprogram header and used in the
subprogram
• An actual parameter represents a value or address
used in the subprogram call statement
• Positional correspondence
– the first actual parameter is bound to the first formal
parameter, and so forth
– Safe and effective
• Keyword correspondence
– The name of the formal parameter to which an actual
parameter is to be bound, is specified with the actual
parameter
– Parameters can appear in any order
– Python example: sumer(length = my_len, list = my_array)
9-6
Formal Parameter Default Values
• In certain languages (e.g., C++, Ada),
formal parameters can have default values
(if not actual parameter is passed)
– In C++, default parameters must appear last
because parameters are positionally associated
– Example:
float compute_pay(float income, float tax_rate,
int exemptions = 1)
pay = compute_pay(20000.0, 0.15);
9-7
Local Referencing Environments
• Local variables can be stack-dynamic (bound to
storage)
– Advantages
• Support for recursion
• Storage for locals is shared among some subprograms
– Disadvantages
• Allocation/de-allocation, initialization time
• Indirect addressing
• Subprograms cannot be history sensitive
• Local variables can be static
– retain their values between activations (Ch 10); the
lifetime of a static variable is the entire computation.
– Storage for them is allocated statically at compile time; No
run-time overhead
– More efficient (no indirection)
– Cannot support recursion
– declared by the keyword static in C.
9-8
Example of static variables
• Consider the following
declaration:
•
int f(int n) {
static int count = 0;
int result;
count = count + 1;
if (n == 0) result = 1;
else result = n * f(n-1);
return result;
}
A trace showing the values of
variables for the call f(3)
-> f: n=3; count = 0
-> f: n=2; count = 1
-> f: n=1; count = 2
-> f: n=0; count = 3
<- f: n=0; count = 4; result =
<- f: n=1; count = 4; result =
<- f: n=2; count = 4; result =
<- f: n=3; count = 4; result =
1
1
2
6
9-9
Parameter Passing Methods
• Ways in which parameters are transmitted
to and/or from called subprograms
– Pass-by-value
– Pass-by-result
– Pass-by-value-result
– Pass-by-reference
– Pass-by-name
9-10
Models of Parameter Passing
9-11
Pass-by-Value (In Mode)
• The value of the actual parameter is used to
initialize the corresponding formal parameter.
• This method is normally used in Pascal, C, and C#.
• Example: In the call square (2+3) ->
x := 2+3; square := x*x; return 25
• Implementation
– Normally implemented by copying
– Require additional storage
– Storage and copy operations can be costly
• This method cannot change the value of the actual
parameters
9-12
Pass-by-Result (Out Mode)
• passed by result:
– no value is transmitted to the subprogram
– the formal parameter acts as a local variable; its value is
transmitted to caller’s actual parameter when control is
returned to the caller
– Require extra storage location and copy operation
– in C#: “out” is specified in formal and actual parameters
• Example
void Fixer(out int x, out int y) {x = 17; y=35;}
…
f.Fixer(out a, out b);
• Potential problem: sub(p1, p1); whichever
formal parameter is copied back last will represent
the current value of p1
9-13
Pass-by-Value-Result (inout Mode)
• A combination of pass-by-value and pass-byresult
• The actual are initially copied into the formals, and
the formals are eventually copied back out to the
actuals.
• Formal parameters have local storage
• Sometimes called pass-by-copy
• In Ada 95, all scalars are passed-by-copy
– Support three parameters: In, out, in out
• Disadvantages:
– Those of pass-by-result
– Those of pass-by-value
9-14
Pass-by-Reference (Inout Mode)
• Pass an access path
– A formal parameter becomes a synonym for the location
of an actual parameter;
• In C#
– Pass-by-reference is specified by preceding both a formal
parameter and its actual parameter with ref
– In Pascal, using “var” with formals (see the next page)
• achieved in C using pointers.
– The function is defined as follows:
void swapc(int *px, int *py)
{int z; z = *px; *px = *py; *py = z; }
– The procedure call should pass the pointer such as
swapc(&a, &b).
9-15
Pass-by-Reference
(cont)
• It is achieved in Pascal using the keyword “var”.
• Example:
procedure swap (var x: integer; var y: integer);
var z: integer;
begin
z := x; x := y; y := z;
end;
• A call swap (i, A[i]) does the following:
make the location of x the same as that of i;
make the location of y the same as that of A[i];
z :=x; x:=y; y:=z;
• If i is 2 and A[2] = 99; the effect of the call will be:
z: = 2; i:=99; A[2] := z => changed
9-16
Pass-by-Reference
(cont)
• Advantage
– Passing process is efficient (no copying and no
duplicated storage)
• Disadvantages
– Slower accesses (compared to pass-by-value) to
formal parameters, due to indirect addressing
– Potentials for un-wanted side effects, which
changes the actual parameters
– Un-wanted aliases
• Example (in C++)
void fun(int &first, int &second)
The call: fun(total, total)
9-17
Pass-by-Name (Inout Mode)
• By textual substitution
• Allows flexibility in late binding
– Not at the time of the subprogram call, but when the
formal is assigned or referenced
• Example (in Pascal):
Consider the procedure swap in page 16 without “var”.
• A call swap(i, A[i]) yields:
z :=i; i:=A[i]; A[i]:=z;
• If i is 2 and A[2] = 99, the effect of the call will be:
z: = 2; i:=99; A[i] := z
=> A[99] is affected, not A[2]
-> dynamic binding
• It is used in Algol 60 and achieves lexical scope by renaming
locals.
9-18
Type Checking Parameters
• Considered very important for reliability
• Pascal, FORTRAN 90, Java, and Ada: it is always
required
• ANSI C and C++: choice is made by the user
– Example of avoiding type checking:
double sin(x) double x; {…..}
• Relatively new languages Perl, JavaScript, and PHP
do not require type checking, since variables (and
formal parameters) are typeless.
9-19
Multidimensional Arrays as Parameters
• If a multidimensional array is passed to a
subprogram and the subprogram is
separately compiled, the compiler needs to
know the declared size of that array to
build the storage mapping function
9-20
Multidimensional Arrays as Parameters:
C and C++
• Programmer is required to include the declared sizes of
all but the first subscript in the actual parameter, to
compute the address
• Example:
void fun(int matrix[][10]) {…}
• Disallows writing flexible subprograms
• Solution: pass a pointer to the array and the sizes of
the dimensions as other parameters; the user must
include the storage mapping function in terms of the
size parameters
• Example:
void fun(float * mat_ptr, int num_row, int num_col);
..
*(mat_ptr + (row *num_col) + col) = x;
9-21
Multidimensional Arrays as Parameters:
Pascal and Ada
• Pascal
– Not a problem; declared size is part of the array’s type
• Ada
– Constrained arrays - like Pascal
– Unconstrained arrays - declared size is part of the object
declaration
• Java and C#
– Similar to Ada
– Arrays are objects; they are all single-dimensioned, but
the elements can be arrays
– Each array inherits a named constant (length in Java,
Length in C#) that is set to the length of the array when
the array object is created
9-22
Design Issues for Functions
• Are side effects allowed?
– Ada: Parameters should always be in-mode to
reduce side effect
• What types of return values are allowed?
– Most imperative languages restrict the return
types
– C allows any type except arrays and functions
– C++ is like C but also allows user-defined
types
– Ada allows any type
– Java and C# do not have functions but methods
can have any type
9-23