Presentation is loading. Please wait.

Presentation is loading. Please wait.

Call by Value Call by Reference Review

Similar presentations


Presentation on theme: "Call by Value Call by Reference Review"— Presentation transcript:

1 Call by Value Call by Reference Review
The contents of this particular lecture prepared by the instructors at the University of Manitoba in Canada

2 Void 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

3 Non- Void Functions int mypower (int x, int y)
{ // raise x to power y (y >= 0) using a count- controlled loop int count= 1; // loop counter int answer= 1; // holds the answer while (count <= y) { // loop to print 1 a time answer = answer * x; count++; } // end while return answer; } // send answer back to caller Note >1 parameter Causes function to terminate and send back value we’ve specified

4 Calling 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 << 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!!!

5 Prototypes 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 they’re irrelevant

6 More 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 >> x; if (x < 0) return; else // lots of other code }

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

8 Example int strange( int); int main() { int arg = 7;
cout << strange(arg); cout << endl << arg ; } int strange( int y) y = 6; return 0; < See Example 1> We print the result of calling strange, which is 0 (the value returned by strange) But what’s happening here? We print arg, which is 7 Or is it? When we call strange, we change it’s parameter to 6….

9 Altering Parameter Values
- According to what we know happens with parameters, 7 should be printed - That’s 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 can’t be!

10 Parameter Types - But it doesn’t 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 - There’s a second type that DOES allow argument values to be changed

11 Reference Parameters - This second type is called a Reference Parameter - For the moment, just assume that when you declare one, you’re 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 we’d like in them by altering the parameters!

12 Reference 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! - Let’s see our strange example with reference parameters...

13 Example int strange( int&); int main() { int arg = 7;
cout << strange(arg); cout << endl << arg ; } int strange( int& y) y = 6; return 0; < See: Example 2> The parameter y is now a Reference Parameter - this means that whatever we pass to y can be altered!

14 Example int strange( int&); int main() { int arg = 7;
cout << strange(arg); cout << endl << 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...

15 Example int strange( int&); int main() { int arg = 7;
cout << strange( arg); cout << endl << arg ; } int strange( int& y) y = 6; int answer = y*2; 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 << strange( arg); cout << endl << arg ; } int strange( int& y) { y = 6; return 0; So when strange returns,arg has the value 6, and that is what is printed!

17 Returning Multiple Values
- We can use reference parameters to return as many values as we want - See the next example

18 Returning Multiple Values
int main() { float l, w, h; getvalues(l, w, h); cout << “volume is “ << l*w*h; } // void getvalues(float& len, float& wid, float& height) cout << “enter an integer length: ”; cin >> len; cout << “enter an integer width: ”; cin >> wid; cout << “enter an integer height: ”; cin >> height;

19 Returning Multiple Values
- getvalues doesn’t 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 < See: Example 3>

20 Returning Multiple Values
- But suppose I did this! int main() { int l, w, h; getvalues( 6, 2, 3); // other code after this } - It doesn’t make sense does it? How can the function change a 6, or a 2??? It can only change what’s stored in a variable!

21 One 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

22 One Dimensional Arrays
- Key observation: - arrays can be indexed with variables int main() { char line[ 80]; int i; for (i= 0; i< 80; i= i+ 1) cin >> line[ i]; for( i= 0; i< 80; i= i+ 1) cout << line[ i]; for( i= 79; i>= 0; i= i- 1) } Loop runs i= 0, i= 1, i= 2, ..., i= 79

23 One 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

24 One Dimensional Arrays
- Examples of Array Declaration - float cmplx[2]; // entries: cmplx[0], cmplx[1] - int ivec[2000]; // entries: ivec[0], ..., ivec[1999] - const int arraylen= 1000; - char biglin[arraylen]; // array biglin has entries biglin[0],..., biglin[999];

25 One Dimensional Arrays
- Accessing Array Components - General form of array access is: ArrayName[IndexExpression] - 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

26 One Dimensional Arrays
- Array Entry Assignment ivec[0]= 17; // ivec entry 0 assigned 17 ivec[0]= ivec[0]* 3+ 2; // ivec entry 0 assigned 53 ivec[ivec[0]-2]= 5; // ivec entry 51 assigned 5 cout << cmplx[0]; // print out cmplx entry 0 cin >> biglin[5]; // read biglin entry 5; foo( ivec[0]); // call function foo with value 53

27 One 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 ivec[0] Memory Layout of int ivec[2000] ivec[1] Each location holds a single integer ivec[2] ……. ivec[1999]

28 One Dimensional Arrays
// E. G: find the largest element in array of integers int main() { int ValueArray[500]; ...; // somehow move data into ValueArray int maxval, i; maxval= ValueArray[0]; for (i= 1; i< 500; i++) if (ValueArray[ i]> maxval) maxval= ValueArray[i]; cout << "Maximum value in array is " << maxval; } start out assuming ValueArray[ 0] is largest Update maxval if a larger value found

29 One Dimensional Arrays
- Out of Bounds Array Indices - What does the following code do? char line[80]; line[80]= 'X'; - Code accesses element 80, but the last defined element in the array is line[79] - result is undetermined - it may even modify other variables - C++ does not check this - your program may do weird things - this is invalid code!

30 One Dimensional Arrays
Initializing arrays - Like variables of type char, float and int, arrays can be initialized when declared: int littlearray[5]={2,4,6,8, 10}; float wintertemp[3] = {-40, -45, -50}; - This is especially important for const arrays const int IntsMod5[ 5]={ 0,1,2,3,4}; const float FunConstants[ 2]={3.14, 2.71}; // arrays of constants cannot be modified

31 Array Operations - C++ does not provide "Aggregate" array operations
- Operations which act on entire array - Example: int x[100], y[100], z[100]; // two arrays of 100 ints x= y; // this does not assign contents of y to x x= y+z; // this does not assign contents of y+z to x

32 Array Operations - To assign the contents of array y to x, you
need a loop: int i; int x[100], y[100]; for (i= 0; i< 100; i++) x[i]= y[i]; // assign entry y[i] to value x[i]

33 Array Operations - Also cannot - Output arrays: int arr[3]={ 1,2,3};
cout << arr; - Return arrays: return arr; - Operations can be defined (by user functions) - Not defined by automatically for most types

34 Arrays as Parameters

35 Introduction - 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

36 Arrays as Parameters const int arrsize= 50;
// Example: copy one array of chars to another const int arrsize= 50; void CopyArray(char[], char[]); int main() { char a[arrsize], b[arrsize]; int i; for (i= 0; i< arrsize; i++) b[ i]= 'Z'; CopyArray( a, b); // copy contents of b to a } Prototype: array parameters do not include size

37 Arrays as Parameters void CopyArray( char x[], char y[]) { int i;
// Copy array y to x void CopyArray( char x[], char y[]) { int i; for (i= 0; i< arrsize; i++) x[i]= y[i]; } 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

38 Arrays 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; i< sz; i++) x[ i]= y[ i]; } sz is the size of the arrays x, y

39 Arrays 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

40 Constant 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...

41 Constant 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; i< sz; i++) x[ i]= y[ i]; } < See: Example 4>

42 Array Example: Comparing arrays
bool CompareArray(const int x[], const int y[]) { int i; for (i= 0; i< sz; i++) if (x[ i] != y[ i]) // compare x[i], y[i] return false; // return false if difference found } return true; both array parameters are declared const:Look, but don't touch!

43 Passing 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?

44 Passing 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 don’t use part of it...

45 Passing 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 don’t know how big the file is, so how can we declare a big enough array to hold it all?

46 Using only Part of an Array
- We can’t 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.

47 Using only Part of an Array
- Now suppose we write some code to read in the data values... we don’t know how many items there will be in a given file, but we can count them as we read

48 Using only Part of an Array
const int arrsize= 500; int list[arrsize]; // 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 >> item; while (myfile && count < arrsize) { // end of file or no room list[ count] = item; // stick the item in the array count++; } When loop quits count-1 contains last slot used in array

49 Using 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; i< sz; i++) x[i]= y[i]; } Note the modification - we copy up to and including slot sz because it’s a real slot and not just the absolute size of the array (this also uses integer arrays now)

50 Using 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; i<sz; i++) x[ i]= y[ i]; } - We could pass count (250) to it’s size parameter, and the loop would run up to and including 249 (count-1), copying only the part we used

51 Using only Part of an Array
- That is, if after reading the data in, we used the following statements: int list2[arrsize]; // 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!

52 Using 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 don’t know how big to make the array - We will discuss how to solve these problems later


Download ppt "Call by Value Call by Reference Review"

Similar presentations


Ads by Google