Functions
Outline
|
|
|
|
Function declarations |
|
Variables |
|
return values and void |
|
Event driven programming: |
|
winmain() and the message loop |
|
Winproc() and the message functions |
|
Design of functions and data structures
in the Windows environment |
Program
structure
Pascal C/C++
|
|
|
|
|
function f: integer; |
|
… |
|
procedure p; |
|
… |
|
|
|
|
|
x := f; |
|
p; |
|
|
|
int f() |
|
… |
|
void p() |
|
… |
|
|
|
|
|
x = f(); |
|
p(); |
|
|
Function
Example
|
|
|
#include <iostream.h> |
|
int mult(int x, int y); |
|
int main() { |
|
int x, y; |
|
cout<<"Please input two
numbers to be multiplied:"; |
|
cin>>x>>y; |
|
cout<<"The product of
your two numbers is "<<mult(x, y); |
|
return 0; |
|
} |
|
|
|
int mult(int x, int y) { return x*y; } |
Function
Things to remember
|
|
|
Functions may not be nested. |
|
Use void to specify functions that do
not return values. |
Call by
value
Pascal C/C++
|
|
|
ANSI C/C++: |
|
float f(int x, int y ,float z) |
|
{
int q; |
|
|
|
q = x*x +y; |
|
return (q – z); |
|
} |
|
function f(x, y: integer; |
|
z: real) : real; |
|
|
|
var |
|
q: integer; |
|
begin |
|
q := sqr(x) + y; |
|
f := q – z; |
|
end; |
Call by
value
Pascal C/C++
|
|
|
procedure p(x : integer); |
|
|
|
var |
|
temp: integer; |
|
begin |
|
…. |
|
end; |
|
TRADITIONAL C: |
|
void p(x) |
|
int x; |
|
{
int temp; |
|
…. |
|
return; |
|
} |
Call by
value
Pascal C/C++
|
|
|
procedure p(x : integer); |
|
|
|
var |
|
temp: integer; |
|
begin |
|
…. |
|
end; |
Call by
value
Pascal C/C++
|
|
|
|
function f(c: char) : integer; forward; |
|
TRADITIONAL C: |
|
int f(); |
|
ANSI C/C++: |
|
int f(char c); |
|
OR |
|
int f(char); |
Call by
value
Pascal C/C++
|
|
|
|
function f(c: char) : integer; |
|
forward; |
|
TRADITIONAL C: |
|
int f(); |
|
ANSI C/C++: |
|
int f(char c); |
|
OR |
|
int f(char); |
Call by reference
|
|
|
Call by reference means the address of
a variable is passed to the called function. |
|
Formal parameters called by reference
must be defined as pointers, and the calling function must be provided with
the addresses of the actual parameters (using & operator) unless the
actual parameter already is a pointer. |
Call by reference:
Memory allocation process
|
|
|
|
void swap(int *x, int *y) |
|
{
int temp; |
|
|
|
temp = *x; |
|
*x = *y; |
|
*y = temp; |
|
} |
|
|
|
int main(){ |
|
int i = 10, j=6; |
|
swap(&i, &j); |
|
} |
Call by reference:
Memory allocation process
|
|
|
|
void swap(int *x, int *y) |
|
{
int temp; |
|
|
|
temp = *x; |
|
*x = *y; |
|
*y = temp; |
|
} |
|
|
|
int main(){ |
|
int i = 10, j=6; |
|
swap(&i, &j); |
|
} |
Using reference variables
in functions
|
|
|
|
#include <iostream.h> |
|
void times2(int &x); // function
prototype |
|
void main() { |
|
int var; // declare var as integer
variable |
|
var = 10; // put value of 10 in var |
|
cout << "var is "
<< var << endl; |
|
times2(var); // call 'times2()'
with var as parameter |
|
cout << "var is now
" << var << endl; |
|
} |
|
void times2(int &x) { x = x * 2; } |
Using reference variables
in functions
Call by
reference
Pascal C/C++
|
|
|
procedure p(var x: integer); |
|
|
|
begin |
|
x := 17; |
|
end; |
|
|
|
|
|
p(i); |
|
TRADITIONAL C: |
|
void p(x) |
|
int *x; |
|
{ *x = 17; |
|
} |
|
|
|
|
|
p(&i); |
Call by
reference
Pascal C/C++
|
|
|
ANSI C/C++: |
|
void p( int *x) |
|
{ |
|
*x = 17; |
|
} |
|
|
|
|
|
p(&i); |
|
procedure p(var x: integer); |
|
|
|
begin |
|
x := 17; |
|
end; |
|
|
|
|
|
p(i); |
Call by
reference
Pascal C/C++
|
|
|
C++ only: |
|
void p( int &x) |
|
{ |
|
x = 17; |
|
} |
|
|
|
|
|
p(i); |
|
procedure p(var x: integer); |
|
|
|
begin |
|
x := 17; |
|
end; |
|
|
|
|
|
p(i); |
Call by reference and
arrays
Pascal C/C++
|
|
|
|
type |
|
realarray = array[0..9] of real; |
|
|
|
procedure p(var a: realarray); |
|
|
|
begin |
|
a[1] := a[2] + a[3] |
|
end; |
|
TRADITIONAL C: |
|
void p(a) |
|
float a[]; |
|
{ |
|
a[1] = a[2] + a[3]; |
|
} |
Call by
arrrays
Pascal C/C++
|
|
|
|
TRADITIONAL C: |
|
OR because of the equivalence of arrays
and pointers |
|
|
|
void p(a) |
|
float *a; |
|
{ |
|
a[1] = a[2] + a[3]; |
|
} |
|
type |
|
realarray = array[0..9] of real; |
|
|
|
procedure p(var a: realarray); |
|
|
|
begin |
|
a[1] := a[2] + a[3] |
|
end; |
Call by
arrays
Pascal C/C++
|
|
|
|
ANSI C: |
|
|
|
void p(float a[]) |
|
{ a[1] = a[2] + a[3]; |
|
} |
|
OR |
|
void p(float *a) |
|
{
a[1] = a[2] + a[3]; |
|
} |
|
type |
|
realarray = array[0..9] of real; |
|
|
|
procedure p(var a: realarray); |
|
|
|
begin |
|
a[1] := a[2] + a[3] |
|
end; |
Recursion
|
|
|
void recurse() { |
|
recurse(); //Function calls itself |
|
} |
|
int main() { |
|
recurse(); //Sets off the recursion |
|
return 0; //Rather pitiful, it will
never be reached |
|
} |
Recursion
An Example
|
|
|
void doll(int size) { |
|
if(size==0)//No doll can be smaller
than 1 atom
// (10^0==1) so doesn't call itself |
|
return; //Return does not have to return //something, it can be used to exit a
function |
|
doll(size-1); //Decrements the size variable so
// the next doll will be smaller. |
|
} |
|
int main() { |
|
doll(10); //Starts off with a large
doll (its a // logarithmic scale) |
|
return 0; //Finally, it will be
used |
|
} |
Example 2. Coding in
C/C++ from Pascal
|
|
|
program gcd_lcm(input, output); |
|
|
|
(*This program inputs a specified
number of pairs of integers, and for each prints the gcd and/or lcm as
specified by the user. *) |
|
|
|
var |
|
noPairs: integer; |
|
choice: char; |
|
oneA, oneB: integer; |
|
i: integer; |
Example: gcd
|
|
|
function gcd(a,b: integer): integer; |
|
(* Compute gcd of a, b *) |
|
var temp: integer; |
|
begin |
|
while b <> 0 do |
|
begin |
|
temp := a mod b; |
|
a := b; |
|
b := temp |
|
end; |
|
gcd := a |
|
end; |
Example: lcm
|
|
|
function lcm(a,b: integer): integer; |
|
(* Compute lcm of a, b *) |
|
var temp, prod: integer; |
|
begin prod := a * b; |
|
if (a=0) or (b=0) then |
|
lcm := 0 |
|
else begin |
|
repeat |
|
temp := a mod b; |
|
a := b; |
|
b := temp |
|
until b = 0; |
|
lcm := prod div a; |
|
end |
|
end; |
Example: doIt
|
|
|
procedure doIt( |
|
choice: char; |
|
A, B: integer); |
|
(* Does the requested computations for
one pair of numbers. *) |
|
begin |
Example: doIt (Cont.)
|
|
|
case choice of |
|
|
|
‘g’,‘G’: writeln(‘gcd=‘, gcd(A, B)); |
|
|
|
‘l’, ’L’: writeln(‘lcm= ‘,lcm(A, B); |
Example: doIt (Cont.)
|
|
|
‘b’,’B’: writeln(‘gcd, lcm =‘, gcd(A, B), ‘,’, lcm(A, B)); |
|
|
|
|
|
|
|
|
|
otherwise |
|
writeln(‘Unknown choice’); |
|
end |
|
end; |
Example: main ()
|
|
|
begin |
|
write(‘How many pairs?’); |
|
readln(noPairs); |
|
for i := 1 to noPairs do |
|
begin |
|
write(‘Enter first letter of’, |
|
‘choice (Gcd, Lcm, Both) ‘, |
|
‘then two numbers: ‘); |
|
readln(choice, oneA, oneB); |
|
doIt(choice, oneA, oneB) |
|
end |
|
end. |
WinMain()
|
|
|
If we are running our programs under
Windows, the startup code would have to be different. Here, instead of
calling main(), we have to call WinMain( ). In case of programs under
Windows, four members are put on the stack. Thus, the startup code has to be
different. |
|
|
|
|