730 likes | 978 Views
Function Calling. 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)
E N D
Function Calling The Ohio State University
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. The Ohio State University
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. The Ohio State University
Pass by Value The Ohio State University
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); } The Ohio State University
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. The Ohio State University
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); } The Ohio State University
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); The Ohio State University
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. The Ohio State University
Pass by Reference The Ohio State University
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. The Ohio State University
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); } The Ohio State University
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 The Ohio State University
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!) The Ohio State University
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 The Ohio State University
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! The Ohio State University
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; The Ohio State University
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; } The Ohio State University
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); . . . The Ohio State University
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 . . . The Ohio State University
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); The Ohio State University
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. The Ohio State University
A Closer Look at Pass-by-Reference The Ohio State University
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; } The Ohio State University
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 } The Ohio State University
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 The Ohio State University
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” The Ohio State University
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. The Ohio State University
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 The Ohio State University
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 The Ohio State University
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; } The Ohio State University
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); . . . The Ohio State University
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; } The Ohio State University
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! The Ohio State University
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. The Ohio State University
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); } The Ohio State University
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); } > 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 > The Ohio State University
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); The Ohio State University
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); } The Ohio State University
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); ... void rect_calc(double l, double w, double & area, double & perim) { area = l * w; perim = 2 * (l + w); } > 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&)’ > The Ohio State University
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); } The Ohio State University
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); ... void rect_calc(int l, int w, int & area, int & perim) { area = l * w; perim = 2 * (l + w); } > 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&)’ > The Ohio State University
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. The Ohio State University
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. The Ohio State University
Return The Ohio State University
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. The Ohio State University
#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 statements int maxInt(int a, int b) { if (a >= b) { return a; } else { return b; } // Note: The program never reaches here! } The Ohio State University
const Parameters The Ohio State University
const Parameters • Parameters can be declared constant. • Example: void rect_calc(const double l, const double w, double& area, double & perim); The Ohio State University
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); } The Ohio State University