Title: Call by Value
1Call by Value Call by Reference Review The
contents of this particular lecture prepared by
the instructors at the University of Manitoba in
Canada and modified by Dr. Ahmad Reza Hadaegh
2Void and Non-Void Functions - Every function has
a type - Part of the header, tells C what type
of value the function will give back when we
call it - The first word of the header defines
the type of the function - The type void is
used to indicate that the function is not
returning anything - If you want to return a
value, simply supply the type you want instead
of void
3Non- Void Functions int mypower (int x, int y)
// raise x to power y (y gt 0) using a
count- controlled loop int count 1 // loop
counter int answer 1 // holds the answer
while (count lt y) // loop to print 1
char _at_ a time answer answer x
count // end while return
answer // send answer back to caller
Note gt1 parameter
Causes function to terminate and send back value
weve specified
4Calling Non-Void Functions - When we call this
function, just like most built-in functions, we
need to do something with the result - Store
it answer mypower(x,y) - Print it
cout ltlt mypower(2,3) - Pass it on to other
calculations x 2 mypower(7,14) y sqrt(
mypower(2,4)) - Remember that the order of
arguments matters!!!
5Prototypes for Non-Void Functions - For a
prototype of this function, we need to add the
type information (just as we needed to use
void in earlier examples) int mypower( int x,
int y) - Remember that you can actually put
the parameter names if you want, but theyre
irrelevant
6More on Return - Return may also be useful in
terminating a function prematurely - You can
use it anywhere in the function, and you can
use it without a value in a void function to
simply cause the function to terminate early -
Example while (1) cin gtgt x
if (x lt 0) return else //
lots of other code
7More on Return - Is also commonly used in the
main function - we usually give the main
function a type of int, and return some
integer indicating whether the program ran
correctly - e. g. return 0 for no error, higher
numbers for more severe problems int main
() // whatever main does return
0 - The text uses this feel free to use
it if you want
8Example int strange( int) int main() int
arg 7 cout ltlt strange(arg) cout ltlt endl ltlt
arg int strange( int y) y 6 return
0 lt See Example 1gt
We print the result of calling strange, which is
0 (the value returned by strange)
But whats happening here? We print arg, which is
7
Or is it? When we call strange, we change its
parameter to 6.
9Altering Parameter Values - According to what we
know happens with parameters, 7 should be
printed - Thats because - - the parameter y is
created when the function runs - the argument is
copied into it (the 7)... - and even though we
change y to 6, y itself is destroyed when the
function returns - So our original argument, arg
(with the value 7) is never touched and cant
be!
10Parameter Types - But it doesnt always have to
be this way! - We are making use of only one of
two types of parameters allowed by C - These
are called Value Parameters, because as the
name implies, the argument values are copied
into the parameter, and the original argument
can never be changed - Theres a second type
that DOES allow argument values to be changed
11Reference Parameters - This second type is
called a Reference Parameter - For the moment,
just assume that when you declare one, youre
allowed to actually make changes to the
argument being passed - We can and do use this
to return values from functions - Since we
can have as many parameters as we want, we can
return as many values as wed like in them by
altering the parameters!
12Reference Parameters - Very easy to declare -
just put an ampersand () at the end of the
data type of the parameter name int x - So,
when writing functions, just ask yourself if
you want the original argument to be changeable,
and if you do, add the ampersand! - Lets see
our strange example with reference
parameters...
13Example int strange( int) int main() int
arg 7 cout ltlt strange(arg) cout ltlt endl ltlt
arg int strange( int y) y
6 return 0 lt See Example 2gt
The parameter y is now a Reference Parameter -
this means that whatever we pass to y can be
altered!
14Example int strange( int) int main()
int arg 7 cout ltlt strange(arg) cout ltlt
endl ltlt arg int strange(int y) y
6 return 0
So arg is passed to strange
y will be 7 as before
y will be set to the value 6...
15Example int strange( int) int main() int
arg 7 cout ltlt strange( arg) cout ltlt endl ltlt
arg int strange( int y) y
6 int answer y2 return answer -
Obviously, we have to be careful with these!
arg, after the call to strange, will also have
the value 6!
16 - More importantly , considering the full
example int strange( int ) int main() int
arg 7 cout ltlt strange( arg) cout ltlt endl ltlt
arg int strange( int y) y 6 return
0
So when strange returns,arg has the value 6, and
that is what is printed!
17Returning Multiple Values - We can use
reference parameters to return as many values
as we want - See the next example
18Returning Multiple Values int main() float
l, w, h getvalues(l, w, h) cout ltlt volume
is ltlt lwh //----------------------------
-------------------- void getvalues(float len,
float wid, float height) cout ltlt enter
an integer length cin gtgt len cout ltlt
enter an integer width cin gtgt wid cout ltlt
enter an integer height cin gtgt height
19Returning Multiple Values - getvalues doesnt
return anything... - instead, it has three
reference parameters - when we input values, we
change these, and change the variables the caller
supplies! - Getvalues takes l, w, h as
arguments, and because each of its parameters is
a reference parameter, it actually modifies l, w,
and h, effectively allowing the function to give
back three values lt See Example 3gt
20Returning Multiple Values - But suppose I did
this! int main() int l, w,
h getvalues( 6, 2, 3) // other code after
this - It doesnt make sense does it? How
can the function change a 6, or a 2??? It can
only change whats stored in a variable!
21One Dimensional Arrays Structured data
types The contents of this particular lecture
prepared by the instructors at the University of
Manitoba in Canada and modified by Dr. Ahmad Reza
Hadaegh
22One Dimensional Arrays - Key observation -
arrays can be indexed with variables int main()
char line 80 int i for (i 0 ilt 80 i
i 1) cin gtgt line i for( i 0 ilt 80 i i
1) cout ltlt line i for( i 79 igt 0 i i-
1) cout ltlt line i
Loop runs i 0, i 1, i 2, ..., i 79
23One Dimensional Arrays - Arrays can be declared
of any data type - char, int, float, . -
General format of array declaration DataType
ArrayName ConstIntExpression - DataType is
the data type of the array elements - ArrayName
is the name of the array - ConstIntExpression is
a literal int or int constant
24One Dimensional Arrays - Examples of Array
Declaration - float cmplx2 // entries
cmplx0, cmplx1 - int ivec2000 //
entries ivec0, ..., ivec1999 - const int
arraylen 1000 - char biglinarraylen //
array biglin has entries biglin0,...,
biglin999
25One Dimensional Arrays - Accessing Array
Components - General form of array access
is ArrayNameIndexExpression - ArrayName is
the name of the array - IndexExpression is any
integer expression - When evaluated, an array
access is just like any other accessed
variable - treat it like you would any value of
the array type
26One Dimensional Arrays - Array Entry
Assignment ivec0 17 // ivec entry 0
assigned 17 ivec0 ivec0 3 2 // ivec
entry 0 assigned 53 ivecivec0-2 5 // ivec
entry 51 assigned 5 cout ltlt cmplx0 // print
out cmplx entry 0 cin gtgt biglin5 // read
biglin entry 5 foo( ivec0) // call
function foo with value 53
27One Dimensional Arrays - Array Storage - array
entries are stored one after another in memory -
the index is just the offset from the beginning
of the array
ivec0
Memory Layout of int ivec2000
ivec1
Each location holds a single integer
ivec2
.
ivec1999
28One Dimensional Arrays // E. G find the largest
element in array of integers int main() int
ValueArray500 ... // somehow move data into
ValueArray int maxval, i maxval
ValueArray0 for (i 1 ilt 500 i) if
(ValueArray igt maxval) maxval
ValueArrayi cout ltlt "Maximum value in array
is " ltlt maxval
start out assuming ValueArray 0 is largest
Update maxval if a larger value found
29One Dimensional Arrays - Out of Bounds Array
Indices - What does the following code do?
char line80 line80 'X' - Code
accesses element 80, but the last defined
element in the array is line79 - result is
undetermined - it may even modify other
variables - C does not check this - your
program may do weird things - this is invalid
code!
30One Dimensional Arrays Initializing arrays -
Like variables of type char, float and int,
arrays can be initialized when declared int
littlearray52,4,6,8, 10 float
wintertemp3 -40, -45, -50 - This is
especially important for const arrays const int
IntsMod5 5 0,1,2,3,4 const float
FunConstants 23.14, 2.71 // arrays of
constants cannot be modified
31Array Operations - C does not provide
"Aggregate" array operations - Operations
which act on entire array - Example int
x100, y100, z100 // two arrays of 100
ints x y // this does not assign contents of
y to x x yz // this does not assign contents
of yz to x
32Array Operations - To assign the contents of
array y to x, you need a loop int i int
x100, y100 for (i 0 ilt 100 i) xi
yi // assign entry yi to value xi
33Array Operations - Also cannot - Output
arrays int arr3 1,2,3 cout ltlt arr -
Return arrays return arr - Operations can
be defined (by user functions) - Not defined by
automatically for most types
34Arrays as Parameters
35Introduction - Arrays can be passed as
parameters to functions - some important (and
annoying!) differences with passing other
types of parameters - Main difference -
Arrays are always passed by reference - don't
need (and don't use) an - this is the only
way to return an array - Modify a parameter
36Arrays as Parameters // Example copy one array
of chars to another const int arrsize 50 void
CopyArray(char, char) int main() char
aarrsize, barrsize int i for (i 0 ilt
arrsize i) b i 'Z' CopyArray( a, b)
// copy contents of b to a
Prototype array parameters do not include size
37Arrays as Parameters // Copy array y to x void
CopyArray( char x, char y) int i for (i
0 ilt arrsize i) xi yi
No necessary x, y are always reference
parameters
Don't include array size in function header
either Size is not passed!!!
Modifications to x are propagated to actual
parameter of caller
Using the global constant arrsize
38Arrays as Parameters - Often compute with arrays
of different sizes - don't want to use a global
constant for size - Solution - Pass the size as
an additional parameter // Copy array y to
x void CopyArray( char x, char y, int sz)
int i for (i 0 ilt sz i) x i y
i
sz is the size of the arrays x, y
39Arrays as Parameters - To call the new
CopyArray CopyArray( a, b, arrsize) - arrsize
can be local to main instead of global - The
fact that 1) arrays are always passed by
reference 2) size information is not passed is
an annoying limitation of C arrays
40Constant Parameters - Useful to note explicitly
that a parameter is not modified by a
function - tells any person reading the code
that they can expect parameter to be
constant - tells compiler that it can assume
parameter to be constant - Value parameters
do this in some sense - changes not propagated
to actual parameters - For arrays we can't call
by value...
41Constant Parameters - Declare that a parameter
is constant with the const keyword void
CopyArray(char x, const char y, int sz)
int i for (i 0 ilt sz i) x i y
i lt See Example 4gt
42Array Example Comparing arrays bool
CompareArray(const int x, const int
y) int i for (i 0 ilt sz i) if
(x i ! y i) // compare xi, yi return
false // return false if difference
found return true
both array parameters are declared constLook,
but don't touch!
43Passing the Size of an Array - Consider the sz
parameter in our copying function void
CopyArray( char x, const char y, int sz)
. . . - What happens if what is
passed to sz is bigger than the actual size of
the array?
44Passing the Size of an Array - Big problems, as
we already know - the loop runs off the end of
the array - But what happens if the value of sz
is smaller than the actual size of the
array? - Nothing really - we just dont use
part of it...
45Passing the Size of an Array - Why would you
ever want to do this? - Suppose we want to read
integers into an array until end-of-file, then
call a copy function (like that used earlier
but for integers) to copy to another array -
We dont know how big the file is, so how can
we declare a big enough array to hold it all?
46Using only Part of an Array - We cant have
arrays that grow on the fly (there are data
types like this that we will see later) - We
have no choice at the moment other than setting
an arbitrary bound that will be bigger than we
need - e. g. say that we will handle any set
of values up to 500, and declare our arrays
that size.
47Using only Part of an Array - Now suppose we
write some code to read in the data values...
we dont know how many items there will be in a
given file, but we can count them as we read
48Using only Part of an Array const int arrsize
500 int listarrsize // the array will hold up
to 500 values int count 0 // counter to keep
track of the number // of slots
filled up in the array ifstream myfile int item
// item from the file myfile. open(eg1.
txt) myfile gtgt item while (myfile count lt
arrsize) // stop _at_ end of file or no
room list count item // stick the item in
the array count myfile gtgt item When
loop quits count-1 contains last slot used in
array
49Using only Part of an Array So if we wanted to
call our copy array function void CopyArray(
int x, const int y, int sz) int i for
(i 0 ilt sz i) xi yi
Note the modification - we copy up to and
including slot sz because its a real slot and
not just the absolute size of the array (this
also uses integer arrays now)
50Using only Part of an Array - So if we wanted to
call our copy array function void CopyArray(
int x, const int y, int sz) int i for
(i 0 iltsz i) x i y i - We could
pass count (250) to its size parameter, and the
loop would run up to and including 249
(count-1), copying only the part we used
51Using only Part of an Array - That is, if after
reading the data in, we used the following
statements int list2arrsize // copied
array CopyArray( list2,list, count) - Only
the first 249 items would be copied - the
remainder of list2 would be whatever junk was
there before - Similarly, we could print only the
used portion, or sort only the used portion - we
just have to remember where the used portion ends!
52Using only Part of an Array - This is commonly
done - The only downside is that there will
usually be wasted space - we always declare the
full array even if we use all of it only
rarely - Also a problem where we dont know how
big to make the array - We will discuss how to
solve these problems later