Sie sind auf Seite 1von 33

Chapter 9

Subprograms

ISBN 0-321-33025-0

Chapter 9 Topics

• Introduction
• Fundamentals of Subprograms
• Design Issues for Subprograms
• Local Referencing Environments
• Parameter-Passing Methods
• Parameters That Are Subprogram Names
• Overloaded Subprograms
• Generic Subprograms
• Design Issues for Functions
• User-Defined Overloaded Operators
• Coroutines

9-2

1
Introduction

• Two fundamental abstraction facilities


– Process abstraction
• Emphasized from early days
– Data abstraction
• Emphasized in the1980s

9-3

Fundamentals of Subprograms

• Each subprogram has a single entry point

• 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-4

2
Basic Definitions (1/3)

• A subprogram definition describes the


interface to and the actions of the
subprogram abstraction
• A subprogram call is an explicit request
that the subprogram be executed
• A subprogram header is the first part of the
definition, including the name, the kind of
subprogram, and the formal parameters

9-5

Basic Definitions (2/3)

• The parameter profile (aka signature) of a


subprogram is the number, order, and types of its
parameters
• The protocol is a subprogram’s parameter profile
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 often
called prototypes

9-6

3
Basic Definitions (3/3)

• 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 actual parameter

… formal
caller d = f1(a, b, c) parameter

subprogram int f1(int x, float y, int z) {


definition …
9-7

Actual/Formal Parameter
Correspondence (Positional)
• Positional
– The binding of actual parameters to formal
parameters is by position
– the first actual parameter is bound to the first
formal parameter and so forth
– Safe and effective

caller d = f1(a, b, c)

int f1(int x, float y, int z) {



9-8

4
Actual/Formal Parameter
Correspondence (Keyword)
• Keyword
– The name of the formal parameter to which an
actual parameter is to be bound is specified
with the actual parameter
In Ada
Sumer (Length => My_Length,
List => My_Array,
Sum => My_Sum);

– Advantage: Parameters can appear in any order


– Disadvantage: user must know the formal
parameter’s names

9-9

Mixed Mode

• In Ada Positional

Sumer (My_Length,
Sum => My_Sum
List => My_Array,
);

Keyword

9-10

5
Formal Parameter Default Values

• In certain languages (e.g., C++, Ada),


formal parameters can have default values
(if no actual parameter is passed)
definition
function Compute_Pay(Income : Float;
Exemptions : Integer := 1;
Tax_Rate : Float) return Float;
call
Pay := Compute_Pay(20000.0, Tax_Rate => 0.15);

then Exemptions has its default value 1


9-11

Default Parameters in C++

• In C++, default parameters must appear


last because parameters are positionally
associated
definition
float compute_pay(float income, float tax_rate,
int exemptions = 1)

call
pay = compute_Pay(20000.0, 0.15);

then exemptions has its default value 1


9-12

6
Variable Number of Parameters in C#

• C# methods can accept a variable number


of parameters as long as they are of the
same type

9-13

Procedures and Functions


• There are two categories of subprograms
– Procedures are collection of statements that
define parameterized computations
– Functions structurally resemble procedures but
are semantically modeled on mathematical
functions
• They are expected to produce no side effects
• In practice, program functions have side
effects

9-14

7
Design Issues for Subprograms

• What parameter passing methods are


provided?
• Are parameter types checked?
• Are local variables static or dynamic?
• Can subprogram definitions appear in other
subprogram definitions?
• Can subprograms be overloaded?
• Can subprogram be generic?

9-15

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

9-16

8
Local Referencing Environments

• Local variables
#include <stdio.h>
can be static
static
– More efficient int sum; stack-dynamic
(no indirection)
– No run-time int fun1(int a, float b)
overhead {
static int cnt;
– Cannot support int i, j;
recursion … static
} stack-dynamic

9-17

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-18

9
Semantics Models of Parameter Passing

In Mode

Out Mode

Inout
Mode

9-19

Pass-by-Value (In Mode)

• The value of the actual parameter is used to


initialize the corresponding formal
parameter
– Normally implemented by copying
– Can be implemented by transmitting an access
path but not recommended (enforcing write
protection is not easy)
– When copies are used, additional storage is
required
– Storage and copy operations can be costly

9-20

10
Illustrating Pass-by-Value

caller
… int f1(int x, float y, int z) {
d = f1(a, b, c) …

push(c) x
a
push(b)
b y
push(a) c z
stack

9-21

Pass-by-Result (Out Mode)


• An implementation model for out-mode
parameters
• the corresponding 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
• Potential problem: sub(p1, p1);
whichever formal parameter is copied back
will represent the current value of p1

9-22

11
Pass-by-Result: C# Examples

void DoIt(out int x, int index) {


x = 17;
index = 42;
}

sub = 21;
f.DoIt(out list[sub], sub);

If the address to which to return the value is computed


on entry to the method, 17 will be returned to list[21]
If the address is computed just before return, 17 will be
returned to list[42]
9-23

Pass-by-Value-Result (Inout Mode)

• A combination of pass-by-value and


pass-by-result
• Sometimes called pass-by-copy
• Formal parameters have local storage
• Disadvantages:
– Those of pass-by-result
– Those of pass-by-value

9-24

12
Pass-by-Reference (for Inout Mode)

• Pass an access path (usually an address)


• Also called pass-by-sharing
• Passing process is efficient (no copying and
no duplicated storage)
• Disadvantages
– Slower accesses (compared to pass-by-value) to
formal parameters
– Potentials for un-wanted side effects
– Un-wanted aliases (access broadened)

9-25

Creating Alias With Pass-By-Reference

definition

void fun(int &first, int &second)

call

fun(total, total)

call (if i == j)

fun(list[i], list[j])

9-26

13
Example of Creating Alias in C

int * global;
void main() {

sub(global);

}
void sub(int * param) {

} global and
param are aliases

9-27

Pass-by-Name (Inout Mode)

• By textual substitution
• Formals are bound to an access method at
the time of the call, but actual binding to a
value or address takes place at the time of
a reference or assignment
• Allows flexibility in late binding

9-28

14
Pass-by-Name: Resulting Semantics

• If actual is a scalar variable, it is pass-by-reference


• If actual is a constant expression, it is pass-by-
value
• If actual is an array element, it is like nothing else
procedure sub1(x: int; y: int);
begin
x := 1;
y := 2;
x := 2;
y := 3;
end;

sub1(i, a[i]); 補充教材


9-29

Pass-by-Name: Resulting Semantics

• If actual is an expression with a reference


to a variable that is also accessible in the
program, it is also like nothing else
e.g. (assume k is a global variable)
procedure sub1(x: int; y: int; z: int);
begin
k := 1;
y := x;
k := 5;
z := x;
end;

sub1(k+1, j, i);
補充教材
9-30

15
Implementing Parameter-Passing
Methods

• In most language parameter communication


takes place through the run-time stack
• Pass-by-value parameters have their values
copied into stack locations, which then serve
as storage for corresponding formal
parameters
• Pass-by-result parameters are implemented as
the opposite of pass-by-value
• Pass-by-reference is the simplest to
implement; only an address is placed in the
stack
9-31

One Possible Stack Implementation

Passed by value

Passed by result
Passed by value-result

Passed by reference

9-32

16
Parameter Passing Methods of Major
Languages (Fortran and C)
• Fortran
– Always used the inout semantics model
– Before Fortran 77: pass-by-reference
– Fortran 77 and later: scalar variables are often
passed by value-result
•C
– Pass-by-value
– Pass-by-reference is achieved by using pointers
as parameters

9-33

Parameter Passing Methods of Major


Languages (C++ and Java)

• C++
– A special pointer type called reference type for
pass-by-reference
• Java
– All parameters are passed by value
– Object parameters are passed by reference

9-34

17
Parameter Passing Methods of Major
Languages (Ada)

• Ada
– Three semantics modes of parameter
transmission: in, out, in out; in is the
default mode
– Formal parameters declared out can be
assigned but not referenced
– those declared in can be referenced but not
assigned
– in out parameters can be referenced and
assigned

9-35

Parameter Passing Methods of Major


Languages (C# and Others)

• C#
– Default method: pass-by-value
– Pass-by-reference is specified by preceding
both a formal parameter and its actual
parameter with ref
• PHP: very similar to C#
• Perl: all actual parameters are implicitly
placed in a predefined array named @_

9-36

18
Type Checking Parameters

• Considered very important for reliability


• FORTRAN 77 and original C: none
• Pascal, FORTRAN 90, Java, and Ada: it is
always required
• ANSI C and C++: choice is made by the
user
– Prototypes
• Relatively new languages Perl, JavaScript,
and PHP do not require type checking

9-37

In C89, functions can be defined…


in the original C with prototype method
double sin(x)
double sin(double x)
double x;
{ … }
{ … }

avoid type checking type checking performed

double value; double value;


int count; int count;
… …
value = sin(count) value = sin(count)

legal but incorrect legal yet correct


9-38

19
In C99 and C++

• All functions must have their formal


parameters in prototype format
• Type checking can be avoided for some of
the parameters
– By replacing the last part of the
parameter list with an ellipsis

int printf(cost char* format_string, …)

9-39

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
void fun(int matrix[][]) {

a = matrix[i][j] + 1; Where is matrix[i][j]?

}

9-40

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

void fun(int matrix[][10]) {


… }

void main() {
int mat[5][10]; for the storage
… mapping function
fun(mat); Note: C array is row-major

} 9-41

Multidimensional Arrays as Parameters:


C and C++ (Continued)

• Disallows writing flexible subprograms


• Programmer’s solution:
– pass a pointer to the array and the sizes of the
dimensions as other parameters
void fun(float *mat_ptr, int num_rows,
int num_cols);
– the user must include the storage mapping
function in terms of the size parameters

*(mat_ptr +(row * num_cols) + col) = x;


(programmer自己寫的)
9-42

21
Multidimensional Arrays as Parameters:
Ada
• Constrained arrays: Not a problem;
declared size is part of the array’s type
• Unconstrained arrays
– index ranges are not given in the array type
definition.
– can be formal parameters ⇒ cause problems?
type Mat_Type is array (Integer range <>,
unconstrained Integer range <>) of Float;
array type

function Sumer(Mat : in Mat_Type) return Float

9-43

Ada’s Solution
• Definitions of variables of unconstrained array
types must include index ranges.
– Subprogram can obtain the index range
information of the actual parameter
type Mat_Type is array (Integer range <>,
Integer range <>) of Float;
Mat_1 : Mat_Type(1..100, 1..20);
index range
function Sumer(Mat : in Mat_Type) return Float
is
begin
for Row in Mat’range(1) loop
for Col in Mat’range(2) loop get ranges
… 9-44

22
Multidimensional Arrays as Parameters:
Fortran
• Formal parameter that are arrays have
a declaration after the header
– For single-dimension arrays, subscripts
in the declaration are irrelevant
– For multi-dimensional arrays, the
subscripts allow the compiler to build the
storage-mapping function

9-45

Fortran Example

Subroutine Sub(Matrix, Rows, Cols, Result)


傳入參數
Integer, Intent(In) :: Rows, Cols
Real, Dimension(Rows, Cols), Intent(In) :: Matrix
Real, Intent(In) :: Result
陣列的大小

End Subroutine Sub

array declaration

9-46

23
Multidimensional Arrays as Parameters:
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-47

Example in Java

row的大小
float sumer(float mat[ ][ ]) {
float sum = 0.0f;
for (int row = 0; row < mat.length, row++) {
for (int col = 0; col < mat[row].length; col++ {
sum += mat[row][col];
}
} column的大小
return sum;
}

9-48

24
Design Considerations for Parameter
Passing

• Two important considerations


– Efficiency
– One-way or two-way data transfer
• But the above considerations are in conflict
– Good programming suggest limited access to
variables, which means one-way whenever
possible
– But pass-by-reference is more efficient to pass
structures of significant size (like an array)
9.5.8 請自行閱讀
9-49

Parameters that are Subprogram


Names
• It is sometimes convenient to pass
subprogram names as parameters
• Issues:
1. Are parameter types (of the passed subprogram)
checked?
2. What is the correct referencing environment for
a subprogram that was sent as a parameter?
(the problem arises only with languages that
allow nested subprograms)

9-50

25
Parameters that are Subprogram Names:
Parameter Type Checking
• C and C++
– functions cannot be passed as parameters, but
pointers to functions can be passed
– The type of the pointer is the function’s
protocol accepting a
pointer to function
– So parameters can be type checked
int fun1(int x, float y);
… int fun2(int (*fc)(int, float))
{
int (*p)(int,float); fc(7, 12.3);
p is a pointer return 0;
p = fun1;
fun2(p); to function }
passing p as a parameter 9-51

Parameters that are Subprogram Names:


Parameter Type Checking

• FORTRAN 95 type checks


• Ada does not allow subprogram parameters;
a similar alternative is provided via Ada’s
generic facility

9-52

26
Parameters that are Subprogram
Names: Referencing Environment
• What is the referencing environment of the
subprogram that is passed as a parameter?
• Shallow binding: The environment of the
call statement that enacts the passed
subprogram
• Deep binding: The environment of the
definition of the passed subprogram
• Ad hoc binding: The environment of the call
statement that passed the subprogram

9-53

Referencing Environment Example


function sub1() {
var x;
function sub2() { sub2 中的x是哪裏的?
alert(x);
};
function sub3() { Shallow binding:
var x; sub2 中的x是sub4的
x = 3;
sub4(sub2);
}; Deep binding:
function sub4(subx) { sub2 中的x是sub1的
var x;
x = 4;
subx(); Ad hoc binding:
};
x = 1; sub2 中的x是sub3的
sub3();
}; 9-54

27
Overloaded Subprograms

• An overloaded subprogram is one that has


the same name as another subprogram in
the same referencing environment
– Every version of an overloaded subprogram has
a unique protocol
double pow(double, double)
double pow(int, double) overloaded
double pow(float, double)

• C++, Java, C#, and Ada include predefined


overloaded subprograms
9-55

Overloaded Subprograms (Continued)

• In Ada, the return type of an overloaded function


can be used to disambiguate calls (thus two
overloaded functions can have the same parameter
profile and differ only in their return types)
function f1(p1: in Integer) return Float;
function f1(p1: in Integer) return Integer;
• Because Java, C++, and C# allow mixed-mode
expressions, the return type is irrelevant to the
disambiguation (因為有coercion)
int fun(int p1); Which one should be called in
float fun(int p1); 5.0 + fun(3)?

9-56

28
Generic Subprograms

• A generic or polymorphic subprogram takes


parameters of different types on different
activations
• Overloaded subprograms provide ad hoc
polymorphism (they need not behave similarly)
• parametric polymorphism is provided by a
subprogram that takes generic parameters that
are used in type expressions that describes the
types of the parameters of the subprogram

9-57

Examples of parametric
polymorphism: C++
template <class Type>
Type max(Type first, Type second) {
return first > second ? first : second;
}
• The above template can be instantiated for any
type for which operator > is defined. For example

int max (int first, int second) {


return first > second? first : second;
}
只寫一次程式碼,產生對應不同參數型態的版本
9-58

29
Design Issues for Functions

• Are side effects allowed?


– Parameters should always be in-mode to
reduce side effect (like Ada)
• 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-59

User-Defined Overloaded
Operators

• Operators can be overloaded in Ada and C++


• An Ada example
Function “*”(A,B: in Vec_Type): return Integer is
Sum: Integer := 0;
begin
for Index in A’range loop
Sum := Sum + A(Index) * B(Index)
end loop
return sum;
end “*”; 將*定義成內積運算

c = a * b; -- a and b are of type Vec_Type

9-60

30
Coroutines
• A coroutine is a subprogram that has multiple
entries and controls them itself
• Also called symmetric control: caller and called
coroutines are on a more equal basis
• A coroutine call is named a resume
• The first resume of a coroutine is to its beginning,
but subsequent calls enter at the point just after
the last executed statement in the coroutine
• Coroutines repeatedly resume each other, possibly
forever
• Coroutines provide quasi-concurrent execution of
program units (the coroutines); their execution is
interleaved, but not overlapped
9-61

Coroutines Illustrated: Possible


Execution Controls

9-62

31
Coroutines Illustrated: Possible
Execution Controls

9-63

Coroutines Illustrated: Possible


Execution Controls with Loops

9-64

32
Summary

• A subprogram definition describes the actions


represented by the subprogram
• Subprograms can be either functions or
procedures
• Local variables in subprograms can be stack-
dynamic or static
• Three models of parameter passing: in mode, out
mode, and inout mode
• Some languages allow operator overloading
• Subprograms can be generic
• A coroutine is a special subprogram with multiple
entries

9-65

33

Das könnte Ihnen auch gefallen