# CSE202: Lecture 12The Ohio State University1 Function Calling.

## Presentation on theme: "CSE202: Lecture 12The Ohio State University1 Function Calling."— Presentation transcript:

CSE202: Lecture 12The Ohio State University1 Function Calling

CSE202: Lecture 12The Ohio State University2 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 12The Ohio State University3 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 12The Ohio State University4 Pass by Value

CSE202: Lecture 12The Ohio State University5 Function dist() // function dist double 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 12The Ohio State University6 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 12The Ohio State University7 Function dist2() // function dist2 double 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 12The Ohio State University8 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 12The Ohio State University9 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 12The Ohio State University10 Pass by Reference

CSE202: Lecture 12The Ohio State University11 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 12The Ohio State University12 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); // definition void RectCalc(double l, double w, double & area, double & perim) { area = l * w; perim = 2 * (l + w); }

CSE202: Lecture 12The Ohio State University13 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 12The Ohio State University14 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 12The Ohio State University15 Using RectCalc() (1) //function prototype void 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 12The Ohio State University16 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 12The Ohio State University17 pointDist3.cpp... // main function int 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 12The Ohio State University18 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 12The Ohio State University19 pointDist5.cpp... // main function int 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 12The Ohio State University20 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 12The Ohio State University21 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 12The Ohio State University22 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 12The Ohio State University23 A Closer Look at Pass-by- Reference

CSE202: Lecture 12The Ohio State University24 swap() Function Definition // swap() function definition void 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 12The Ohio State University25 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 12The Ohio State University26 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 12The Ohio State University27 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 12The Ohio State University28 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 12The Ohio State University29 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 12The Ohio State University30 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 12The Ohio State University31 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 12The Ohio State University32 Standard Template Library: swap() swap() is such a useful function, that it is part of the standard template library.... #include using namespace std; int main() { int a, b; double c, d;... swap(a,b); swap(c,d);...

CSE202: Lecture 12The Ohio State University33 Standard Template Library: swap() #include 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 12The Ohio State University34 Expressions as Arguments Expressions can be arguments to function parameters which are passed BY VALUE: double circleArea(double radius); // Pass by value double 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 reference double 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 12The Ohio State University35

CSE202: Lecture 12The Ohio State University36 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 12The Ohio State University37 > 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 12The Ohio State University38 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 12The Ohio State University39 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 12The Ohio State University40 > 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 12The Ohio State University41 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 12The Ohio State University42 > 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 12The Ohio State University43 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 12The Ohio State University44 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 12The Ohio State University45 Return

CSE202: Lecture 12The Ohio State University46 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 12The Ohio State University47 #include using namespace std; int maxInt(int a, int b); int main() { cout << maxInt(88, 102) << endl; return 0; } // function maxInt has two return statements int maxInt(int a, int b) { if (a >= b) { return a; } else { return b; } // Note: The program never reaches here! }

CSE202: Lecture 12The Ohio State University48 const Parameters

CSE202: Lecture 12The Ohio State University49 const Parameters Parameters can be declared constant. Example: void rect_calc(const double l, const double w, double & area, double & perim);

CSE202: Lecture 12The Ohio State University50 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 definition void rect_calc(const double l, const double w, double & area, double & perim) { area = l * w; perim = 2 * (l + w); }

CSE202: Lecture 12The Ohio State University51 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 12The Ohio State University52 Passing a const string #include... void read_input(const string & prompt, double & l, double & w) { cout << prompt; cin >> l; cin >> w; }

CSE202: Lecture 12The Ohio State University53 rectCalc3.cpp... #include 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 12The Ohio State University54 > rectCalc3.exe This program computes the area and perimeter of a rectangle from its length and width. The formula for area is (length*width). The formula for perimeter is 2*(length+width). Enter length and width: 3 5 Area: 15 Perimeter: 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 12The Ohio State University55 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 12The Ohio State University56 Passing IO Streams

CSE202: Lecture 12The Ohio State University57 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 12The Ohio State University58 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 12The Ohio State University59 writeFunc.cpp void 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 12The Ohio State University60 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 12The Ohio State University61 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 12The Ohio State University62 > readFunc.exe Enter integer: -17 x = 23 y = 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 12The Ohio State University63

CSE202: Lecture 12The Ohio State University64 passExample1.cpp... // function prototype void 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; } // function void f(int a, int & b) { a++; b = 2*b; cout << "a = " << a << endl; cout << "b = " << b << endl; }

CSE202: Lecture 12The Ohio State University65 passExample2.cpp... // function prototypes void f(int & a); void g(int & b); int main() { int x(4); f(x); cout << "x = " << x << endl; return 0; } // function void f(int & a) { a++; g(a); cout << "a = " << a << endl; } // function void g(int & b) { b = 2*b; cout << "b = " << b << endl; }

CSE202: Lecture 12The Ohio State University66 What is the problem?... // function prototypes void f(int & a); void g(int & b); int main() { int x(4); f(x); cout << "x = " << x << endl; return 0; } // function void f(int & a) { a++; g(a); cout << "a = " << a << endl; } // function void g(int & b) { b = 2*b; f(b); cout << "b = " << b << endl; }

CSE202: Lecture 12The Ohio State University67 passExample3.cpp... // function prototype void f(int & a); int main() { int a(3), x(8); f(x); cout << "a = " << a << endl; cout << "x = " << x << endl; return 0; } // function void f(int & a) { int x; a = 2*a; x = 7; cout << "a = " << a << endl; cout << "x = " << x << endl; }

CSE202: Lecture 12The Ohio State University68 passExample4.cpp... // function prototype void f(int a, int b); int main() { int x(5); f(x, x); cout << "x = " << x << endl; return 0; } // function void f(int a, int b) { a++; b = 2*b; cout << "a = " << a << endl; cout << "b = " << b << endl; }

CSE202: Lecture 12The Ohio State University69 passExample5.cpp... // function prototype void f(int & a, int & b); int main() { int x(5); f(x, x); cout << "x = " << x << endl; return 0; } // function void f(int & a, int & b) { a++; b = 2*b; cout << "a = " << a << endl; cout << "b = " << b << endl; }