2014-1 Ch 4. Parameters and Function Overloading March 19, 2014 Advanced Networking Technology Lab. (YU-ANTL) Dept. of Information & Comm. Eng, Graduate School, Yeungnam University, KOREA (Tel : +82-53-810-2497; Fax : +82-53-810-4742 http://antl.yu.ac.kr/; E-mail : ytkim@yu.ac.kr)
Parameters Call-by-value Call-by-reference Mixed parameter-lists Outline Overloading and Default Arguments Examples, Rules Testing and Debugging Functions assert Macro Stubs, Drivers ch 4-2
Parameters Two methods of passing arguments as parameters Call-by-value "copy" of value is passed Call-by-reference "address of" actual argument is passed ch 4-3
Call-by-Value Parameters Copy of actual argument passed Considered "local variable" inside function If modified, only "local copy" changes Function has no access to "actual argument" from caller This is the default method Used in all examples thus far ch 4-4
Memory Usage in Call-by-Value double average(int i, int j) { double avg; } avg = (i + j)/2.0; return avg; void main(int argc, char *argv[]) { int x, y; double d; x = 3; y = 5; d = average(x, y); cout << Average: << d <<endl; Function Call: Function average() Return Function Call: main() stack frame for average( ) - arguments: int i, int j - local variables: double avg copy copy stack frame for main( ) - arguments: int argc, char * argv[] - local variables: int x, int y, double d Memory Stack return copy } ch 4-5
Call-by-Value Example Formal Parameter Used as a Local Variable (1) ch 4-6
Formal Parameter Used as a Local Variable (2) ch 4-7
Formal Parameter Used as a Local Variable (3) ch 4-8
Call-by-Value Pitfall Common Mistake: Declaring parameter "again" inside function: double fee(int hoursworked, int minutesworked) { int quarterhours; int minutesworked // local variable // NO! } Compiler error results "Redefinition error " Value arguments ARE like "local variables" But function gets them "automatically" ch 4-9
Call-By-Reference Parameters Used to provide access to caller s actual argument Caller s data can be modified by called function! Typically used for input function To retrieve data for caller Data is then "given" to caller Specified by ampersand, &, after type in formal parameter list ch 4-10
Memory Usage in Call-by-Reference void average(int i, int j, int& sum, double& avg) { sum = i + j; avg = sum/2.0; } void main(int argc, char *argv[]) { int x, y, sum; double avg; x = 3; y = 5; average(x, y, sum, avg); cout << Sum: << sum; cout <<, Average: << avg; Function Call: Function average() Return Function Call: main() stack frame for average( ) - arguments: int i, j, sum, double avg - local variables: copy ref ref stack frame for main( ) - arguments: int argc, char * argv[] - local variables: int x, y, sum, double d Memory Stack } ch 4-11
Call-By-Reference Example Call-by-Reference Parameters (1) ch 4-12
Call-by-Reference Parameters (2) ch 4-13
Call-by-Reference Parameters (3) ch 4-14
Call-By-Reference Details What s really passed in? A "reference" back to caller s actual argument! Refers to memory location of actual argument Called "address", which is a unique number referring to distinct place in memory ch 4-15
Constant Reference Parameters Reference arguments inherently "dangerous" Caller s data can be changed Often this is desired, sometimes not To "protect" data, & still pass by reference: Use const keyword void sendconstref( const int &par1, const int &par2); Makes arguments "read-only" by function No changes allowed inside function body ch 4-16
Parameters ( 파라메터, 매개변수 ) and Arguments ( 인수 ) Confusing terms, often used interchangeably True meanings: Formal parameters In function declaration and function definition Arguments Used to "fill-in" a formal parameter In function call (argument list) Call-by-value & Call-by-reference Simply the "mechanism" used in plug-in process ch 4-17
Mixed Parameter Lists Can combine passing mechanisms Parameter lists can include pass-by-value and pass-by-reference parameters Order of arguments in list is critical: void mixedcall(int & par1, int par2, double & par3); Function call: mixedcall(arg1, arg2, arg3); arg1 must be integer type, is passed by reference arg2 must be integer type, is passed by value arg3 must be double type, is passed by reference ch 4-18
Choosing Formal Parameter Names Same rule as naming any identifier: Meaningful names! Functions as "self-contained modules" Designed separately from rest of program Assigned to teams of programmers All must "understand" proper function use OK if formal parameter names are same as argument names Choose function names with same rules ch 4-19
Passing Arguments to main() function You have used main() function as this: int main(void) {.. } Prototype of main() getting passed arguments int main(int argc, char *argv[]) {.. } ch 4-20
Passing Arguments to Main() function argc and argv argc (argument count): integer number of the count of arguments argv (argument vector): character pointers of the arguments C: \cprogram> mycopy src dst m y c c o o p y \0 \0 argv[0] s s r r c c \0 \0 argv[1] d s s t t \0 \0 3 3 argv[2] argc argv 배열 ch 4-21
main_arg.c #include <stdio.h> int main(int argc, char *argv[]) { int i = 0; for(i = 0;i < argc; i++) printf(" 명령어라인에서 %d 번째문자열 = %s\n", i, argv[i]); } return 0; Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. c:\cprogram\mainarg\debug>mainarg src dst 명령어라인에서 0 번째문자열 = mainarg 명령어라인에서 1 번째문자열 =src 명령어라인에서 2 번째문자열 =dst c:\cprogram\mainarg\debug> ch 4-22
Providing Arguments in Visual C++ Program 여기에프로그램인수들을넣으면된다. ch 4-23
Sample Program: mile2km.c #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { double mile, km; if( argc!= 2 ){ printf(" 사용방법 : mile2km 거리 \n"); return 1; } mile = atof(argv[1]); km = 1.609 * mile; printf(" 입력된거리 (%d mile) 는 %f km 입니다. \n", mile, km); } return 0; Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. c:\cprogram\mainarg\debug>mile2km 10 입력된거리 (10 mile) 는 16.090000 km 입니다. c:\cprogram\mainarg\debug> ch 4-24
Sample Program: /* * Test program for main function with argc and argv handling * Programmed by Young-Tak Kim, March 20, 2012 */ #include <iostream> using namespace std; int main(int argc, char *argv[]) { char mode ; double base, exponent; cout << "test program for main function with argc and argv" << endl; cout << "argc: " << argc << endl; for (int i=0; i<argc; i++) { cout << "argv[" << i << "]: " << argv[i] << endl; } if (argc < 4) { cout <<" Error in command format n"; cout <<" Usage> power mode(r or i) base exponent" << endl; return -1; } else { mode = *argv[1]; base = atof(argv[2]); exponent = atof(argv[3]); } cout <<"mode: " << mode; cout << ", base: " << base; cout << ", exponent: " << exponent << endl; } return 0; ch 4-25
Execution 1) test Execution 2) test r 1.015 2000 Execution 3) test i 1.015 2000 ch 4-26
Same function name Function Overloading double avg(double d1, double d2); double avg(double d1, double d2, double d3); double avg(int d1, int d2); double avg(int d1, int d2, int d3); Different parameter lists Separate function definitions Function "signature" Function name & parameter list Must be "unique" for each function definition Allows same task performed on different data ch 4-27
Overloading Example: average() Function computes average of 2 numbers: double average(double n1, double n2) { return ((n1 + n2) / 2.0); } Now compute average of 3 numbers: double average(double n1, double n2, double n3) { return ((n1 + n2) / 2.0); } Same name, two functions ch 4-28
Overloaded Average() Cont d Which function gets called? Depends on function call itself: avg = average(5.2, 6.7); Calls "two-parameter average()" avg = average(6.5, 8.5, 4.2); Calls "three-parameter average()" Compiler resolves invocation based on signature of function call "Matches" call with appropriate function Each considered separate function ch 4-29
Overloading Pitfall Only overload "same-task" functions A mpg() function should always perform same task, in all overloads Otherwise, unpredictable results C++ function call resolution: 1 st : looks for exact signature 2 nd : looks for "compatible" signature ch 4-30
1 st : Exact Match Overloading Resolution Looks for exact signature Where no argument conversion required 2 nd : Compatible Match Looks for "compatible" signature where automatic type conversion is possible: 1 st with promotion (e.g., int double) No loss of data 2 nd with demotion (e.g., double int) Possible loss of data ch 4-31
Overloading Resolution Example Given following functions: 1. void f(int n, double m); 2. void f(double n, int m); 3. void f(int n, int m); These calls: f(98, 99); Calls #3 f(5.3, 4); Calls #2 f(4.3, 5.2); Calls??? Avoid such confusing overloading ch 4-32
Automatic Type Conversion and Overloading Numeric formal parameters typically made "double" type Allows for "any" numeric type Any "subordinate" data automatically promoted int double float double char double *More on this later! Avoids overloading for different numeric types ch 4-33
Automatic Type Conversion and Overloading Example Miles-per-Gallon double mpg(double miles, double gallons) { return (miles/gallons); } Example function calls: mpgcomputed = mpg(5, 20); Converts 5 & 20 to doubles, then passes mpgcomputed = mpg(5.8, 20.2); No conversion necessary mpgcomputed = mpg(5, 2.4); Converts 5 to 5.0, then passes values to function ch 4-34
Default Arguments Allows omitting some arguments Specified in function declaration/prototype void showvolume(int length, int width = 1, int height = 1); Last 2 arguments are defaulted Possible calls: showvolume(2, 4, 6); //All arguments supplied showvolume(3, 5); //height defaulted to 1 showvolume(7); //width & height defaulted to 1 ch 4-35
Default Arguments Example: Default Arguments(1) ch 4-36
Default Arguments (2) ch 4-37
Testing and Debugging Functions Many methods: Lots of cout statements In calls and definitions Used to "trace" execution Compiler Debugger Environment-dependent : e.g.) Visual Studio debugging F5: go F9: break point F10: trace with step-over F11: trace with step-in assert Macro Early termination as needed Stubs and drivers Incremental development ch 4-38
Stubs and Drivers Separate compilation units Each function designed, coded, tested separately Ensures validity of each unit Divide & Conquer Transforms one big task smaller, manageable tasks But how to test independently? Driver programs ch 4-39
Driver Program Example: Driver Program (1) ch 4-40
Driver Program (2) ch 4-41
Driver Program (3) ch 4-42
Stubs Develop incrementally Write "big-picture" functions first Low-level functions last "Stub-out" functions until implementation Example: double unitprice(int diameter, double price) { return (9.99); // not valid, but noticeably // a "temporary" value } Calls to function will still "work" ch 4-43
Fundamental Testing Rule To write "correct" programs Minimize errors, "bugs" Ensure validity of data Test every function in a program where every other function has already been fully tested and debugged Avoids "error-cascading" & conflicting results ch 4-44
Test Driver Program to Measure the Elapsed Time of Program Executions Measurement of Execution Times In order to test a function as a module in a large scale system, a driver program is temporarily prepared and used. This driver program prepares the testing conditions (i.e., arrays to be sorted, input data file and output data files, etc.), and invokes the module to be tested. The measurement of the elapsed time taken to process some function, is usually performed with system clock readings. In Visual C++, QueryPerformanceCounter (LARGE_INTEGER & time) provides the current time in microsecond. So, reading the system time before and after the function call can provide the time taken for the function call. Example of time measurement is as follows: ch 4-45
Sample Test Driver for Visual C++ Program #include <Windows.h>... int function_to_be_tested(int array[], int size); // QueryPerformanceFrequency(LARGER_INTEGER *freq); // QueryPerformanceCounter(LARGER_INTEGER *time); int main() { LARGE_INTEGER freq, t_1, t_2 LONGLONG t_diff; double elapsed_time; CONST int MAX_SIZE 1000; int array[max_size], size; }... //Initialize array with size data elements // generated by rand()function QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&t_1); function_to_be_tested(array, size); QueryPerformanceCounter(&t_2); t_diff = t_2.quadpart - t_1.quadpart; elapsed_time = ((double) t_diff / freq.quadpart)*1000000; // in microsec printf( It took %f [micro-seconds] to perform the function with %d integer data array., elapsed_time, size);... ch 4-46
Summary 4-1 Formal parameter is placeholder, filled in with actual argument in function call Call-by-value parameters are "local copies" in receiving function body Actual argument cannot be modified Call-by-reference passes memory address of actual argument Actual argument can be modified Argument MUST be variable, not constant ch 4-47
Summary 4-2 Multiple definitions of same function name possible: called function overloading Default arguments allow function call to "omit" some or all arguments in list If not provided default values assigned Functions should be tested independently As separate compilation units, with drivers ch 4-48
Homework 4 4.1 Write C++ functions that calculate power(base, exponent) in i) recursive function calls, and ii) iterative computation. double powerrecur(double base, int exponent); double poweriter(double base, int exponent); Write a main() function that uses the argument passing for argc and argv[], that receives the mode ( r : recursive, i : iterative), base and exponent from the console command line, and invokes the corresponding function. Check the correct calculations of power for the given base and exponent. Note: Examples of program execution: c:>power r 1.015 1000 c:>power i 1.015 2000 4.2 Using a test driver to measure the elapsed time of program executions, measure the elapsed times (in micro-second) for powerrecur() and poweriter() for base = 1.015 and exponent= 4000. Explain why the recursive structure takes more execution time in this power calculation. ch 4-49