cse202: lecture 12the ohio state university1 function calling
TRANSCRIPT
CSE202: Lecture 12 The Ohio State University 1
Function Calling
CSE202: Lecture 12 The Ohio State University 2
Parameter Passing
• There are two ways (in C++) to pass parameters to functions.– Pass by Value (what we’ve seen so far)– Pass by Reference (we’ll see this later)
• In the functions we have seen so far, the input parameters are passed by value. In other words, the values of the parameters are copied.
CSE202: Lecture 12 The Ohio State University 3
Arguments and Parameters. . .
double dist(double x1, double y1, double x2, double y2);
. . .
// call function dist()
dist_pq = dist(px, py, qx, qy);
. . .
• px, py, qx and qy are arguments to the function dist().
• x1, y1, x2 and y2 are the function parameters.
CSE202: Lecture 12 The Ohio State University 4
Pass by Value
CSE202: Lecture 12 The Ohio State University 5
Function dist()
// function distdouble dist(double x1, double y1, double x2, double y2)// four input parameters: x1, y1, x2, y2// All parameters are PASSED BY VALUE{ double dx, dy, d;
dx = x1 - x2; dy = y1 - y2; d = sqrt(dx*dx + dy*dy);
// return the distance from (x1,y1) to (x2,y2) return(d);}
CSE202: Lecture 12 The Ohio State University 6
Pass By Value (pointDist3.cpp). . .double dist(double x1, double y1, double x2, double y2);. . . // call function dist() dist_pq = dist(px, py, qx, qy);. . .
• Pass by value: – Value px is copied to x1;– Value py is copied to y1;– Value qx is copied to x2;– Value qy is copied to y2.
• px, py, qx and qy are arguments to the function.• x1, y1, x2, y2 are the function parameters.
CSE202: Lecture 12 The Ohio State University 7
Function dist2()
// function dist2double dist2(double x1, double y1, double x2, double y2)// four input parameters: x1, y1, x2, y2// All parameters are PASSED BY VALUE{ double dx, dy, d;
dx = x1 - x2; dy = y1 - y2; d = sqrt(dx*dx + dy*dy);
x1 = 77; // What affect will this have on the program?
// return the distance from (x1,y1) to (x2,y2) return(d);}
CSE202: Lecture 12 The Ohio State University 8
Pass By Value (pointDist3.cpp). . .double dist2(double x1, double y1, double x2, double y2){ . . .
x1 = 77; // What affect will this have on the program? . . . return(d);}
. . . // call function dist2() dist_pq = dist2(px, py, qx, qy);
// What is the value of px?
dist_pr = dist2(px, py, rx, ry); dist_qr = dist2(qx, qy, rx, ry);
CSE202: Lecture 12 The Ohio State University 9
Pass by Value
• When a parameter is passed by value, any change to the parameter inside the function has absolutely no effect outside the function!
• If all the parameters are passed by value, the only effect the function has on the calling program is through the returned value.
CSE202: Lecture 12 The Ohio State University 10
Pass by Reference
CSE202: Lecture 12 The Ohio State University 11
Pass by Reference
• A C++ program can pass to a function the memory locations (references) of the variables used to make the function call, instead of copying their values.
• Any change to the value of parameters will change the value of the variables of the calling function.
CSE202: Lecture 12 The Ohio State University 12
Passing by Reference: Example
• The following function manipulates the parameters area and perimeter directly.
// prototype. // The & symbol represents the address of the variable.// It indicates pass by reference, not by value. void RectCalc(double l, double w, double & area, double & perim);
// definitionvoid RectCalc(double l, double w, double & area, double & perim){
area = l * w;perim = 2 * (l + w);
}
CSE202: Lecture 12 The Ohio State University 13
Breakdown of RectCalc() (1)
• The function takes 4 parameters. The first two, length and width, are passed by value as before.
• The last two, area and perimeter, are passed by reference (in other words, by their memory locations).
• The syntax for pass-by-reference parameters:data-type & reference-name
CSE202: Lecture 12 The Ohio State University 14
Breakdown of RectCalc() (2)
• Notice that because the function caller’s values are directly manipulated, this function does not have to return anything; the function is declared void
• Because of this, when calling the function, one need not assign a variable to its output (because it has none!)
CSE202: Lecture 12 The Ohio State University 15
Using RectCalc() (1)
//function prototypevoid RectCalc(double l, double w, double & area, double & perim); int main(){
double rectArea, rectPerim, rectlength = 2.0, rectwidth = 3.0;
//call the function. Do not use & modifier here!!//don’t assign it to anything! It has no return value!RectCalc(rectlength, rectwidth, rectArea, rectPerim);
//rectArea and rectPerim now hold modified values!cout << “The area is: “ << rectArea
<< “ and the perimeter is: “ << rectPerim << endl;
return 0;}
//Place Function Definition here
CSE202: Lecture 12 The Ohio State University 16
Using RectCalc() (2)
• Notice that because rectArea and rectPerim were passed by reference, their values were manipulated.
• So this simulates the effect of returning 2 values back to the caller!
CSE202: Lecture 12 The Ohio State University 17
pointDist3.cpp. . .// main functionint main(){ double px, py, qx, qy, rx, ry; double dx, dy, dist_pq, dist_pr, dist_qr;
// read input cout << "Enter point 1 (2 floats): "; cin >> px >> py; cout << "Enter point 2 (2 floats): "; cin >> qx >> qy; cout << "Enter point 3 (2 floats): "; cin >> rx >> ry;
CSE202: Lecture 12 The Ohio State University 18
Function inputCoord()
// function inputCoord()void inputCoord(int i, double & x, double & y)// three input parameters: i, x, y// Parameter i is passed by value// Parameters x and y are PASSED BY REFERENCE { // read input cout << "Enter point " << i << " (2 floats): "; cin >> x >> y;}
CSE202: Lecture 12 The Ohio State University 19
pointDist5.cpp. . .// main functionint main(){ double px, py, qx, qy, rx, ry; double dist_pq, dist_pr, dist_qr;
// read input inputCoord(1, px, py); inputCoord(2, qx, qy); inputCoord(3, rx, ry);. . .
CSE202: Lecture 12 The Ohio State University 20
pointDist5.cpp. . . // calculate distances dist_pq = dist(px, py, qx, qy); dist_pr = dist(px, py, rx, ry); dist_qr = dist(qx, qy, rx, ry);
// output distances output_distance(px, py, qx, qy, dist_pq); output_distance(px, py, rx, ry, dist_pr); output_distance(qx, qy, rx, ry, dist_qr);
return 0;}
// function definitions. . .
CSE202: Lecture 12 The Ohio State University 21
Notes on Pass by Reference (1)
• The argument to a reference parameter must be a variable, not a constant or an expression. (Why?)
• The following function calls are illegal:
void RectCalc(double l, double w, double & a, double & p);
double a = 3.0, b = 4.0, c = 5.0, d = 6.0, e = 7.0;
const double x = 5.0, y = 6.0;
RectCalc(3.0, 4.0, 5.0, 6.0);
RectCalc(a, b, 5.0, 6.0);
RectCalc(a, b, c*d, e);
RectCalc(a, b, x, y);
CSE202: Lecture 12 The Ohio State University 22
Notes on Pass by Reference (2)
• Note the function call gives no indication whether a parameter is passed by reference. You need to look at the function definition to make sure.
• If you do not pay attention to this, variables could be changed that you were not expecting to change! If a variable’s value is not supposed to change, then it should (usually) be passed by value.
CSE202: Lecture 12 The Ohio State University 23
A Closer Look at Pass-by-Reference
CSE202: Lecture 12 The Ohio State University 24
swap() Function Definition
// swap() function definitionvoid swap(double & num1, double & num2)// swap the values of num1 and num2{double temp;
temp = num1; // Why do we need temp?num1 = num2;num2 = temp;
}
CSE202: Lecture 12 The Ohio State University 25
swap() Function Usage
int main(){double oneNum, anotherNum;oneNum = 3.3;anotherNum = 5.6;
swap(oneNum, anotherNum); //swap!
//oneNum now holds 5.6//anotherNum now holds 3.3
}
CSE202: Lecture 12 The Ohio State University 26
A Closer Look at swap():From main()
• In main(), two variables are declared and defined:
oneNum = 3.3
anotherNum = 5.6
• Memory cells in the computer are allocated to hold these variables
CSE202: Lecture 12 The Ohio State University 27
A Closer Look at swap(): After calling swap()
• The main() function calls swap()
• Because swap defined num1 and num2 as reference parameters, the variables oneNum and anotherNum are now referred to as num1 and num2 respectively inside the function
• In other words, they are “aliased” or “linked”
CSE202: Lecture 12 The Ohio State University 28
A Closer Look at swap(): Inside swap()
• In swap(), a new variable, temp, is introduced to hold the value of num1
• Without temp, the first variable assignment would overwrite the other!
• We see how in the next slide.
CSE202: Lecture 12 The Ohio State University 29
A Closer Look at swap(): Making the Exchange
• Assign num2 to num1.
• Notice that num1 value is now lost. Fortunately, we saved its value inside temp
CSE202: Lecture 12 The Ohio State University 30
A Closer Look at swap(): Finishing up
• swap() has completed its routine. Its local variables vanish, and the calling variables have their values swapped.
• The main() function now continues execution beyond the function call.
• This was all done without actually “returning” any values
CSE202: Lecture 12 The Ohio State University 31
Another example using swap()int main(){
double a, b;
cout << “Enter two numbers: “;cin >> a >> b;
if (a > b) { swap(a,b); }
cout << a << “ <= “ << b << endl;
return 0; }
CSE202: Lecture 12 The Ohio State University 32
Standard Template Library: swap()
• swap() is such a useful function, that it is part of the standard template library.
...#include <algorithm>using namespace std;
int main(){ int a, b; double c, d;
. . . swap(a,b); swap(c,d);. . .
CSE202: Lecture 12 The Ohio State University 33
Standard Template Library: swap()
#include <algorithm>#include <iostream>using namespace std;
int main(){ double a, b; cout << “Enter two numbers: “;
cin >> a >> b;
if (a > b)
{ swap(a,b); }
cout << a << “ <= “ << b << endl;
return 0; }
CSE202: Lecture 12 The Ohio State University 34
Expressions as Arguments• Expressions can be arguments to function parameters
which are passed BY VALUE:
double circleArea(double radius); // Pass by valuedouble r(3.5);double area = circleArea(3*r+2.0); // valid
• Constants and expressions CANNOT be arguments to function parameters which are passed BY REFERENCE:
double circleArea(double & radius); // Pass by referencedouble r(3.5);double area1 = circleArea(3*r+2.0); // SYNTAX ERROR!double area2 = circleArea(3.5); // SYNTAX ERROR!
Pass by Value vs. Pass by Reference
• Use pass by reference when you want the function to change the value of an argument;
• Otherwise, use pass by value.
CSE202: Lecture 12 The Ohio State University 35
CSE202: Lecture 12 The Ohio State University 36
What’s the error?. . . void rect_calc(double & l, double & w, double & area, double & perim);
int main(){ double rectArea(0.0), rectPerim(0.0), rectLength(2.0), rectWidth(3.0);
rect_calc(rectLength, rectWidth, rectArea, rectPerim);
cout << "Area: " << rectArea << endl; cout << "Perimeter: " << rectPerim << endl;
return 0;}
void rect_calc(double l, double w, double & area, double & perim){ area = l * w; perim = 2 * (l + w);}
CSE202: Lecture 12 The Ohio State University 37
> g++ rectCalcError1.cpp
/tmp/ccJFlGrU.o: In function `main':
rectCalcError1.cpp:(.text+0x4e): undefined reference to `rect_calc(double&, double&, double&, double&)'
collect2: ld returned 1 exit status
>
void rect_calc(double & l, double & w, double & area, double & perim);
int main(){ double rectArea(0.0), rectPerim(0.0), rectLength(2.0), rectWidth(3.0);
rect_calc(rectLength, rectWidth, rectArea, rectPerim);...void rect_calc(double l, double w, double & area, double & perim){ area = l * w; perim = 2 * (l + w);}
CSE202: Lecture 12 The Ohio State University 38
Function Prototype
• The function prototype should look EXACTLY LIKE the function header (except that the prototype ends with a ‘;’.)
• Protoype:
void rect_calc(double l, double w, double & area, double & perim);
• Header:
void rect_calc(double l, double w, double & area, double & perim);
CSE202: Lecture 12 The Ohio State University 39
What’s the error?. . . void rect_calc(double l, double w, double & area, double & perim);
int main(){ int rectArea(0.0), rectPerim(0.0), rectLength(2.0), rectWidth(3.0);
rect_calc(rectLength, rectWidth, rectArea, rectPerim);
cout << "Area: " << rectArea << endl; cout << "Perimeter: " << rectPerim << endl;
return 0;}
void rect_calc(double l, double w, double & area, double & perim){ area = l * w; perim = 2 * (l + w);}
CSE202: Lecture 12 The Ohio State University 40
> g++ rectCalcError2.cpp
rectCalcError2.cpp: In function ‘int main()’:
rectCalcError2.cpp:16: error: invalid initialization of reference of type ‘double&’ from expression of type ‘int’
rectCalcError2.cpp:8: error: in passing argument 3 of ‘void rect_calc(double, double, double&, double&)’
>
8. void rect_calc(double l, double w, 9. double & area, double & perim);10. 11. int main()12. {13. int rectArea(0.0), rectPerim(0.0), 14. rectLength(2.0), rectWidth(3.0);15. 16. rect_calc(rectLength, rectWidth, rectArea, rectPerim);...28. void rect_calc(double l, double w, 29. double & area, double & perim)30. {31. area = l * w;32. perim = 2 * (l + w);33. }
CSE202: Lecture 12 The Ohio State University 41
What’s the error?. . . void rect_calc(int l, int w, int & area, int & perim);
int main(){ double rectArea(0.0), rectPerim(0.0), rectLength(2.0), rectWidth(3.0);
rect_calc(rectLength, rectWidth, rectArea, rectPerim);
cout << "Area: " << rectArea << endl; cout << "Perimeter: " << rectPerim << endl;
return 0;}
void rect_calc(int l, int w, int & area, int & perim){ area = l * w; perim = 2 * (l + w);}
CSE202: Lecture 12 The Ohio State University 42
> g++ rectCalcError2.cpp
rectCalcError2.cpp: In function ‘int main()’:
rectCalcError2.cpp:16: error: invalid initialization of reference of type ‘double&’ from expression of type ‘int’
rectCalcError2.cpp:8: error: in passing argument 3 of ‘void rect_calc(double, double, double&, double&)’
>
8. void rect_calc(int l, int w, 9. int & area, int & perim);10. 11. int main()12. {13. double rectArea(0.0), rectPerim(0.0), 14. rectLength(2.0), rectWidth(3.0);15. 16. rect_calc(rectLength, rectWidth, rectArea, rectPerim);...28. void rect_calc(int l, int w, 29. int & area, int & perim)30. {31. area = l * w;32. perim = 2 * (l + w);33. }
CSE202: Lecture 12 The Ohio State University 43
Pass by Reference
• When passing by reference:– Arguments of type int must be passed to
parameters of type int;– Arguments of type double must be passed to
parameters of type double;– Arguments of type string must be passed to
parameters of type string;– etc.
CSE202: Lecture 12 The Ohio State University 44
Other Notes on Functions
• If a calculation or process needs to execute repeatedly, then make that a function.
• Keep your functions from doing too much. If a function is long and complex, it is hard to debug.
• Split long and complex functions into more functions.
CSE202: Lecture 12 The Ohio State University 45
Return
CSE202: Lecture 12 The Ohio State University 46
The return Statement• All functions that have a return value must have
a return statement.
• A function may have more than one return statement.
• When a return is executed, it will immediately exit your function and return back to the calling procedure.
• At each function call, one and only one return statement is executed.
CSE202: Lecture 12 The Ohio State University 47
#include <iostream>using namespace std;
int maxInt(int a, int b);
int main(){
cout << maxInt(88, 102) << endl;
return 0;}
// function maxInt has two return statementsint maxInt(int a, int b){
if (a >= b) { return a; }else { return b; }
// Note: The program never reaches here!}
CSE202: Lecture 12 The Ohio State University 48
const Parameters
CSE202: Lecture 12 The Ohio State University 49
const Parameters
• Parameters can be declared constant.
• Example:
void rect_calc(const double l, const double w, double & area, double & perim);
CSE202: Lecture 12 The Ohio State University 50
rectCalc2.cpp. . .void rect_calc(const double l, const double w, double & area, double & perim);
int main(){ double rectArea(0.0), rectPerim(0.0), rectLength(2.0), rectWidth(3.0);
rect_calc(rectLength, rectWidth, rectArea, rectPerim);
cout << "Area: " << rectArea << endl; cout << "Perimeter: " << rectPerim << endl;. . .}
// function definitionvoid rect_calc(const double l, const double w, double & area, double & perim){ area = l * w; perim = 2 * (l + w);}
CSE202: Lecture 12 The Ohio State University 51
const Parameters
• Values of const parameters cannot be modified.
• Pass by reference parameters can be declared const!!
• Why would we this? Pass a “large” object by reference (to save memory) but ensure it is not modified, i.e., pass a C++ string.
CSE202: Lecture 12 The Ohio State University 52
Passing a const string#include <string>...void read_input(const string & prompt, double & l, double & w){ cout << prompt;
cin >> l; cin >> w;}
CSE202: Lecture 12 The Ohio State University 53
rectCalc3.cpp...#include <string>using namespace std; // Must come before using type string
void read_input(const string & prompt, double & l, double & w);void rect_calc(const double l, const double w, double & area, double & perim);
int main(){ double rectArea(0.0), rectPerim(0.0), rectLength(2.0), rectWidth(3.0); string prompt = "\nThis program computes the area and perimeter of a rectangle\nfrom
its length and width.\nThe formula for area is (length*width).\nThe formula for perimeter is 2*(length+width).\n\nEnter length and width: ";
read_input(prompt, rectLength, rectWidth); rect_calc(rectLength, rectWidth, rectArea, rectPerim);
cout << "Area: " << rectArea << endl; cout << "Perimeter: " << rectPerim << endl; return 0;}...
CSE202: Lecture 12 The Ohio State University 54
> rectCalc3.exe
This program computes the area and perimeter of a rectanglefrom its length and width.The formula for area is (length*width).The formula for perimeter is 2*(length+width).
Enter length and width: 3 5Area: 15Perimeter: 16
... double rectArea(0.0), rectPerim(0.0), rectLength(2.0), rectWidth(3.0); string prompt = "\nThis program computes the area and perimeter of a
rectangle\nfrom its length and width.\nThe formula for area is (length*width).\nThe formula for perimeter is 2*(length+width).\n\nEnter length and width: ";
read_input(prompt, rectLength, rectWidth);...
CSE202: Lecture 12 The Ohio State University 55
const Parameters
• Can pass strings by value, but then a new copy is made of the entire string.
• Both:void read_input(const string & prompt, double & l, double & w);
and
void read_input(const string prompt, double & l, double & w);
will have the same behavior but the second will use more memory.
CSE202: Lecture 12 The Ohio State University 56
Passing IO Streams
CSE202: Lecture 12 The Ohio State University 57
writeFile4.cpp. . .int main(){ ofstream fout; // declare an output file stream string file_name("outfile.txt");
fout.open(file_name.c_str(), ios::out); // open file file_name for output
if (!fout.is_open()) // check if file is opened for output { cerr << "Unable to open file " << file_name << endl; exit(10); }
fout << “x = “ << 3 << endl;fout << “y = “ << 7.5 << endl;
fout.close();return 0;
}
CSE202: Lecture 12 The Ohio State University 58
Function write_data()void write_data(ostream & out, int x, double y){ out << "x = " << x << endl; out << "y = " << y << endl;}
• Note: Pass string streams by reference.
CSE202: Lecture 12 The Ohio State University 59
writeFunc.cppvoid write_data(ostream & out, int x, double y);
int main(){ ofstream fout; // declare an output file stream string file_name("outfile.txt");
fout.open(file_name.c_str(), ios::out); // open file file_name for output
if (!fout.is_open()) // check if file is opened for output . . .
write_data(cout, 3, 7.5);write_data(fout, 3, 7.5);
fout.close();return 0;
}
CSE202: Lecture 12 The Ohio State University 60
Function read_data()int read_data(istream & in){ int x;
in >> x; x = abs(x);
return(x);}
• Note: Pass string streams by reference.
CSE202: Lecture 12 The Ohio State University 61
readFunc.cpp. . .int read_data(istream & in);
int main(){ ifstream fin; // declare an input file stream string file_name("infile.txt"); int x,y;
fin.open(file_name.c_str(), ios::in); if (!fin.is_open()) . . . // check if file is opened for input
x = read_data(fin); cout << "Enter integer: "; y = read_data(cin);
cout << "x = " << x << endl; cout << "y = " << y << endl;
fin.close(); // close file stream fin. . .
CSE202: Lecture 12 The Ohio State University 62
> readFunc.exeEnter integer: -17x = 23y = 17>
…
x = read_data(fin);
cout << "Enter integer: "; y = read_data(cin);
cout << "x = " << x << endl; cout << "y = " << y << endl;…
File: infile.txt
-23
int read_data(istream & in){ int x;
in >> x; x = abs(x);
return(x);}
Function Exercises
CSE202: Lecture 12 The Ohio State University 63
CSE202: Lecture 12 The Ohio State University 64
passExample1.cpp
...// function prototypevoid f(int a, int & b);
int main(){ int x(5), y(10);
f(x,y);
cout << "x = " << x << endl; cout << "y = " << y << endl;
return 0;}
// functionvoid f(int a, int & b){ a++; b = 2*b;
cout << "a = " << a << endl; cout << "b = " << b << endl;}
CSE202: Lecture 12 The Ohio State University 65
passExample2.cpp
...// function prototypesvoid f(int & a);void g(int & b);
int main(){ int x(4);
f(x);
cout << "x = " << x << endl;
return 0;}
// functionvoid f(int & a){ a++; g(a); cout << "a = " << a << endl;}
// functionvoid g(int & b){ b = 2*b; cout << "b = " << b << endl;}
CSE202: Lecture 12 The Ohio State University 66
What is the problem?
...// function prototypesvoid f(int & a);void g(int & b);
int main(){ int x(4);
f(x);
cout << "x = " << x << endl;
return 0;}
// functionvoid f(int & a){ a++; g(a); cout << "a = " << a << endl;}
// functionvoid g(int & b){ b = 2*b; f(b); cout << "b = " << b << endl;}
CSE202: Lecture 12 The Ohio State University 67
passExample3.cpp
...// function prototypevoid f(int & a);
int main(){ int a(3), x(8);
f(x);
cout << "a = " << a << endl; cout << "x = " << x << endl;
return 0;}
// functionvoid f(int & a){ int x;
a = 2*a; x = 7;
cout << "a = " << a << endl; cout << "x = " << x << endl;}
CSE202: Lecture 12 The Ohio State University 68
passExample4.cpp
...// function prototypevoid f(int a, int b);
int main(){ int x(5);
f(x, x);
cout << "x = " << x << endl;
return 0;}
// functionvoid f(int a, int b){ a++; b = 2*b;
cout << "a = " << a << endl; cout << "b = " << b << endl;}
CSE202: Lecture 12 The Ohio State University 69
passExample5.cpp
...// function prototypevoid f(int & a, int & b);
int main(){ int x(5);
f(x, x);
cout << "x = " << x << endl;
return 0;}
// functionvoid f(int & a, int & b){ a++; b = 2*b;
cout << "a = " << a << endl; cout << "b = " << b << endl;}