FUNCTIONS IN C++
Topics Introduction to user-defined function and its requirements. Defining a function; Function prototype, Invoking/calling a function, Passing arguments to function, specifying argument data types, Default argument, Constant argument, Call by value, Call by reference, Returning values from a function, Calling functions with arrays, Scope rules of functions and variables local and global variables. Relating to Parameters and return type concepts in built-in functions
Introduction to user-defined function and its requirements. Functions Modularization of a program Software reusability Call function multiple times
C++ FUNCTIONS Definition: A function is a named, independent section of C/C++ code that performs a specific task and optionally returns a value to the calling program or/and receives values(s) from the calling program. Basically there are two categories of function: Predefined functions: available in C / C++ standard library such as stdio.h, math.h, string.h etc. User-defined functions: functions that programmers create for specialized tasks such as graphic and multimedia libraries, implementation extensions or dependent etc.
Example of User-defined C++ Function Function header Function body double computeTax(double income) { if (income < 5000.0) return 0.0; double taxes = 0.07 * (income-5000.0) return taxes; }
Requirement of Using Functions To help make the program more understandable To modularize the tasks of the program building blocks of the program Write a module once those lines of source code are called multiple times in the program
Requirement of Using Functions While working on one function, you can focus on just that part of the program construct it, debug it, perfect it. 5. Different people can work on different functions simultaneously. 6. If a function is needed in more than one place in a program, or in different programs, you can write it once and use it many times
Codes
Defining a function;
Function Definitions Function prototype Calling/invoking a function Tells compiler argument type and return type of function int square( int ); Function takes an int and returns an int Calling/invoking a function square(x); Parentheses an operator used to call function Pass argument x Function gets its own copy of arguments After finished, passes back result
Function Definitions Format for function definition return-value-type function-name( parameter-list ) { declarations and statements } Parameter list Comma separated list of arguments Data type needed for each argument If no arguments, use void or leave blank Return-value-type Data type of result returned (use void if nothing returned)
Function Definitions Example function return keyword int square( int y ) { return y * y; } return keyword Returns data, and control goes to function’s caller If no data to return, use return; Function ends when reaches right brace Control goes to caller Functions cannot be defined inside other functions Next: program examples
Function prototype,
Function Prototype Recall that the compiler must know certain things about your function When it finds a function call in your source code Must know information in heading Your program must have at least the heading of a function before it is invoked Usually listed before function main ( )
Function Prototypes Function prototype contains Function name Parameters (number and data type) Return type (void if returns nothing) Only needed if function definition after function call Prototype must match function definition Function prototype double maximum( double, double, double ); Definition double maximum( double x, double y, double z ) { … }
Function Prototypes Function signature Argument Conversion Part of prototype with name and parameters double maximum( double, double, double ); Argument Conversion Force arguments to be of proper type Converting int (4) to double (4.0) cout << sqrt(4) Conversion rules Arguments usually converted automatically Changing from double to int can truncate data 3.4 to 3 Mixed type goes to highest type (promotion) Int * double Function signature
Function Prototypes Data types Long double double Float long int int char
Invoking/calling a function,
Invoking/calling a function, #include <iostream.h> i void fun(); void main() { fun(); cout << x << endl; } void fun() cout <<“\n Hello Friends “ << endl;
Session 2
Passing arguments to function,
Parameters Function definition syntax: functionType functionName (formal parameter list) { statements } Call (invocation of the function) cout << "Enter radius for circle area -> "; cin >> radius; area = circleArea (radius); Parameters in the declaration : formal parameters Parameters in the call: actual parameters
Functions with Empty Parameter Lists void or leave parameter list empty Indicates function takes no arguments Function print takes no arguments and returns no value void print(); void print( void );
Passing arguments using call by value , References and Reference Parameters Copy of data passed to function Changes to copy do not change original Prevent unwanted side effects Call by reference Function can directly access data Changes affect original
Reference Reference Parameters Alias for argument in function call Passes parameter by reference Use & after data type in prototype void myFunction( int &data ) Read “data is a reference to an int” Function call format the same However, original can now be changed
Specifying argument data types,
Function arguments and its data types The function signature is actually similar to the function header except in two aspects: The parameters’ names may not be specified in the function signature The function signature must be ended by a semicolon Example double computeTaxes(double) ; Unnamed Parameter Semicolon ;
Why Do We Need Function Signature? For Information Hiding If you want to create your own library and share it with your customers without letting them know the implementation details, you should declare all the function signatures in a header (.h) file and distribute the binary code of the implementation file For Function Abstraction By only sharing the function signatures, we have the liberty to change the implementation details from time to time to Improve function performance make the customers focus on the purpose of the function, not its implementation
Example double computeTaxes(double income) { if (income<5000) return 0.0; return 0.07*(income-5000.0); } double getIncome(string prompt) cout << prompt; double income; cin >> income; return income; void printTaxes(double taxes) cout << "The taxes is $" << taxes << endl; #include <iostream> #include <string> using namespace std; // Function Signature double getIncome(string); double computeTaxes(double); void printTaxes(double); void main() { // Get the income; double income = getIncome("Please enter the employee income: "); // Compute Taxes double taxes = computeTaxes(income); // Print employee taxes printTaxes(taxes); }
Default argument,
3.18 Default Arguments Function call with omitted parameters If not enough parameters, rightmost go to their defaults Default values Can be constants, global variables, or function calls Set defaults in function prototype int myFunction( int x = 1, int y = 2, int z = 3 ); myFunction(3) x = 3, y and z get defaults (rightmost) myFunction(3, 5) x = 3, y = 5 and z gets default
1 // 2 // Using default arguments. 3 #include <iostream> 4 5 6 7 8 // function prototype that specifies default arguments 9 int boxVolume( int length = 1, int width = 1, int height = 1 ); 10 11 int main() 12 { 13 // no arguments--use default values for all dimensions 14 cout << "The default box volume is: " << boxVolume(); 15 16 // specify length; default width and height 17 cout << "\n\nThe volume of a box with length 10,\n" 18 << "width 1 and height 1 is: " << boxVolume( 10 ); 19 20 // specify length and width; default height 21 cout << "\n\nThe volume of a box with length 10,\n" 22 << "width 5 and height 1 is: " << boxVolume( 10, 5 ); 23 Function calls with some parameters missing – the rightmost parameters get their defaults.
24 // specify all arguments 25 cout << "\n\nThe volume of a box with length 10,\n" 26 << "width 5 and height 2 is: " << boxVolume( 10, 5, 2 ) 27 << endl; 28 29 return 0; // indicates successful termination 30 31 } // end main 32 33 // function boxVolume calculates the volume of a box 34 int boxVolume( int length, int width, int height ) 35 { 36 return length * width * height; 37 38 } // end function boxVolume The default box volume is: 1 The volume of a box with length 10, width 1 and height 1 is: 10 width 5 and height 1 is: 50 width 5 and height 2 is: 100
Constant argument,
Constant Reference Parameters Constant reference parameters are used under the following two conditions: The passed data are so big and you want to save time and computer memory The passed data will not be changed or updated in the function body For example void report (const string & prompt); The only valid arguments accepted by reference parameters and constant reference parameters are variable names It is a syntax error to pass constant values or expressions to the (const) reference parameters
Call by value,
II. Using Parameters Function Parameters come in three flavors: Value parameters – which copy the values of the function arguments Reference parameters – which refer to the function arguments by other local names and have the ability to change the values of the referenced arguments Constant reference parameters – similar to the reference parameters but cannot change the values of the referenced arguments
Value Parameters This is what we use to declare in the function signature or function header, e.g. int max (int x, int y); Here, parameters x and y are value parameters When you call the max function as max(4, 7), the values 4 and 7 are copied to x and y respectively When you call the max function as max (a, b), where a=40 and b=10, the values 40 and 10 are copied to x and y respectively When you call the max function as max( a+b, b/2), the values 50 and 5 are copies to x and y respectively Once the value parameters accepted copies of the corresponding arguments data, they act as local variables!
Example of Using Value Parameters and Global Variables #include <iostream.h> int x; // Global variable void fun(int x) { cout << x << endl; x=x+5; } void main() x = 4; fun(x/2+1); x =0 void main() { x = 4; fun(x/2+1); cout << x << endl; } 1
Example of Using Value Parameters and Global Variables #include <iostream.h> int x; // Global variable void fun(int x) { cout << x << endl; x=x+5; } void main() x = 4; fun(x/2+1); x 4 void fun(int x ) { cout << x << endl; x=x+5; } 3 void main() { x = 4; fun(x/2+1); cout << x << endl; } 3 2
Example of Using Value Parameters and Global Variables #include <iostream.h> int x; // Global variable void fun(int x) { cout << x << endl; x=x+5; } void main() x = 4; fun(x/2+1); x 4 void fun(int x ) { cout << x << endl; x=x+5; } 3 8 4 void main() { x = 4; fun(x/2+1); cout << x << endl; } 2
Example of Using Value Parameters and Global Variables #include <iostream.h> int x; // Global variable void fun(int x) { cout << x << endl; x=x+5; } void main() x = 4; fun(x/2+1); x =4 void fun(int x ) { cout << x << endl; x=x+5; } 8 5 void main() { x = 4; fun(x/2+1); cout << x << endl; } 2
Example of Using Value Parameters and Global Variables #include <iostream.h> int x; // Global variable void fun(int x) { cout << x << endl; x=x+5; } void main() x = 4; fun(x/2+1); x =4 void main() { x = 4; fun(x/2+1); cout << x << endl; } 6
Example of Using Value Parameters and Global Variables #include <iostream.h> int x; // Global variable void fun(int x) { cout << x << endl; x=x+5; } void main() x = 4; fun(x/2+1); x =4 void main() { x = 4; fun(x/2+1); cout << x << endl; } 7
Call by reference,
double update (double & x); Reference Parameters As we saw in the last example, any changes in the value parameters don’t affect the original function arguments Sometimes, we want to change the values of the original function arguments or return with more than one value from the function, in this case we use reference parameters A reference parameter is just another name to the original argument variable We define a reference parameter by adding the & in front of the parameter name, e.g. double update (double & x);
Example of Reference Parameters #include <iostream.h> void fun(int &y) { cout << y << endl; y=y+5; } void main() int x = 4; // Local variable fun(x); cout << x << endl; void main() { int x = 4; fun(x); cout << x << endl; } 1 x 4 x ?
Example of Reference Parameters #include <iostream.h> void fun(int &y) { cout << y << endl; y=y+5; } void main() int x = 4; // Local variable fun(x); cout << x << endl; void fun( int & y ) { cout<<y<<endl; y=y+5; } 3 void main() { int x = 4; fun(x); cout << x << endl; } x 4 x ? 2
Example of Reference Parameters #include <iostream.h> void fun(int &y) { cout << y << endl; y=y+5; } void main() int x = 4; // Local variable fun(x); cout << x << endl; void fun( int & y ) { cout<<y<<endl; y=y+5; } 4 9 void main() { int x = 4; fun(x); cout << x << endl; } x ? x 4 2
Example of Reference Parameters #include <iostream.h> void fun(int &y) { cout << y << endl; y=y+5; } void main() int x = 4; // Local variable fun(x); cout << x << endl; void fun( int & y ) { cout<<y<<endl; y=y+5; } 5 void main() { int x = 4; fun(x); cout << x << endl; } x 9 x ? 2
Example of Reference Parameters #include <iostream.h> void fun(int &y) { cout << y << endl; y=y+5; } void main() int x = 4; // Local variable fun(x); cout << x << endl; void main() { int x = 4; fun(x); cout << x << endl; } x 9 x ? 6
Example of Reference Parameters #include <iostream.h> void fun(int &y) { cout << y << endl; y=y+5; } void main() int x = 4; // Local variable fun(x); cout << x << endl; void main() { int x = 4; fun(x); cout << x << endl; } x ? 9 7
Returning values from a function,
Value-Returning Functions For the compiler to use a function you have written, it must know when it finds that function call in your source code … 1. The name of the function 2. The number of parameters, if any 3. The data type of each parameter 4. Data type of the value returned by the function 5. The code required to do the calculation
Value-Returning Functions Consider a function for the area of a circle: double circleArea (double radius) { return 3.14159 * radius * radius; } Note the Heading (type, name, parameters) The body The return statement
Parameters Function definition syntax: functionType functionName (formal parameter list) { statements } Call (invocation of the function) cout << "Enter radius for circle area -> "; cin >> radius; area = circleArea (radius); Parameters in the declaration : formal parameters Parameters in the call: actual parameters
Calling functions with arrays,
4.5 Passing Arrays to Functions Arrays passed-by-reference Functions can modify original array data Value of name of array is address of first element Function knows where the array is stored Can change original memory locations Individual array elements passed-by-value Like regular variables square( myArray[3] );
4.5 Passing Arrays to Functions Functions taking arrays Function prototype void modifyArray( int b[], int arraySize ); void modifyArray( int [], int ); Names optional in prototype Both take an integer array and a single integer No need for array size between brackets Ignored by compiler If declare array parameter as const Cannot be modified (compiler error) void doNotModify( const int [] );
Syntax for accepting an array in parameter list. 1 // Fig. 4.14: fig04_14.cpp 2 // Passing arrays and individual array elements to functions. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <iomanip> 9 10 using std::setw; 11 12 void modifyArray( int [], int ); // appears strange 13 void modifyElement( int ); 14 15 int main() 16 { 17 const int arraySize = 5; // size of array a 18 int a[ arraySize ] = { 0, 1, 2, 3, 4 }; // initialize a 19 20 cout << "Effects of passing entire array by reference:" 21 << "\n\nThe values of the original array are:\n"; 22 23 // output original array 24 for ( int i = 0; i < arraySize; i++ ) 25 cout << setw( 3 ) << a[ i ]; Syntax for accepting an array in parameter list.
Pass a single array element by value; the original cannot be modified. 26 27 cout << endl; 28 29 // pass array a to modifyArray by reference 30 modifyArray( a, arraySize ); 31 32 cout << "The values of the modified array are:\n"; 33 34 // output modified array 35 for ( int j = 0; j < arraySize; j++ ) 36 cout << setw( 3 ) << a[ j ]; 37 38 // output value of a[ 3 ] 39 cout << "\n\n\n" 40 << "Effects of passing array element by value:" 41 << "\n\nThe value of a[3] is " << a[ 3 ] << '\n'; 42 43 // pass array element a[ 3 ] by value 44 modifyElement( a[ 3 ] ); 45 46 // output value of a[ 3 ] 47 cout << "The value of a[3] is " << a[ 3 ] << endl; 48 49 return 0; // indicates successful termination 50 51 } // end main Pass array name (a) and size to function. Arrays are passed-by-reference. Pass a single array element by value; the original cannot be modified.
52 53 // in function modifyArray, "b" points to 54 // the original array "a" in memory 55 void modifyArray( int b[], int sizeOfArray ) 56 { 57 // multiply each array element by 2 58 for ( int k = 0; k < sizeOfArray; k++ ) 59 b[ k ] *= 2; 60 61 } // end function modifyArray 62 63 // in function modifyElement, "e" is a local copy of 64 // array element a[ 3 ] passed from main 65 void modifyElement( int e ) 66 { 67 // multiply parameter by 2 68 cout << "Value in modifyElement is " 69 << ( e *= 2 ) << endl; 70 71 } // end function modifyElement Although named b, the array points to the original array a. It can modify a’s data. Individual array elements are passed by value, and the originals cannot be changed.
Effects of passing entire array by reference: The values of the original array are: 0 1 2 3 4 The values of the modified array are: 0 2 4 6 8 Effects of passing array element by value: The value of a[3] is 6 Value in modifyElement is 12 fig04_14.cpp output (1 of 1)
1 // Fig. 4.15: fig04_15.cpp 2 // Demonstrating the const type qualifier. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 void tryToModifyArray( const int [] ); // function prototype 9 10 int main() 11 { 12 int a[] = { 10, 20, 30 }; 13 14 tryToModifyArray( a ); 15 16 cout << a[ 0 ] << ' ' << a[ 1 ] << ' ' << a[ 2 ] << '\n'; 17 18 return 0; // indicates successful termination 19 20 } // end main 21 Array parameter declared as const. Array cannot be modified, even though it is passed by reference.
22 // In function tryToModifyArray, "b" cannot be used 23 // to modify the original array "a" in main. 24 void tryToModifyArray( const int b[] ) 25 { 26 b[ 0 ] /= 2; // error 27 b[ 1 ] /= 2; // error 28 b[ 2 ] /= 2; // error 29 30 } // end function tryToModifyArray d:\cpphtp4_examples\ch04\Fig04_15.cpp(26) : error C2166: l-value specifies const object d:\cpphtp4_examples\ch04\Fig04_15.cpp(27) : error C2166: l-value specifies const object d:\cpphtp4_examples\ch04\Fig04_15.cpp(28) : error C2166: l-value specifies const object
Scope rules of functions and variables local and global variables.
3.11 Scope Rules Scope File scope Function scope Portion of program where identifier can be used File scope Defined outside a function, known in all functions Global variables, function definitions and prototypes Function scope Can only be referenced inside defining function Only labels, e.g., identifiers with a colon (case:)
3.11 Scope Rules Block scope Function-prototype scope Begins at declaration, ends at right brace } Can only be referenced in this range Local variables, function parameters static variables still have block scope Storage class separate from scope Function-prototype scope Parameter list of prototype Names in prototype optional Compiler ignores In a single prototype, name can be used once
1 // Fig. 3.12: fig03_12.cpp 2 // A scoping example. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 void useLocal( void ); // function prototype 9 void useStaticLocal( void ); // function prototype 10 void useGlobal( void ); // function prototype 11 12 int x = 1; // global variable 13 14 int main() 15 { 16 int x = 5; // local variable to main 17 18 cout << "local x in main's outer scope is " << x << endl; 19 20 { // start new scope 21 22 int x = 7; 23 24 cout << "local x in main's inner scope is " << x << endl; 25 26 } // end new scope Declared outside of function; global variable with file scope. fig03_12.cpp (1 of 5) Local variable with function scope. Create a new block, giving x block scope. When the block ends, this x is destroyed.
27 28 cout << "local x in main's outer scope is " << x << endl; 29 30 useLocal(); // useLocal has local x 31 useStaticLocal(); // useStaticLocal has static local x 32 useGlobal(); // useGlobal uses global x 33 useLocal(); // useLocal reinitializes its local x 34 useStaticLocal(); // static local x retains its prior value 35 useGlobal(); // global x also retains its value 36 37 cout << "\nlocal x in main is " << x << endl; 38 39 return 0; // indicates successful termination 40 41 } // end main 42
43 // useLocal reinitializes local variable x during each call 44 void useLocal( void ) 45 { 46 int x = 25; // initialized each time useLocal is called 47 48 cout << endl << "local x is " << x 49 << " on entering useLocal" << endl; 50 ++x; 51 cout << "local x is " << x 52 << " on exiting useLocal" << endl; 53 54 } // end function useLocal 55 Automatic variable (local variable of function). This is destroyed when the function exits, and reinitialized when the function begins.
56 // useStaticLocal initializes static local variable x only the 57 // first time the function is called; value of x is saved 58 // between calls to this function 59 void useStaticLocal( void ) 60 { 61 // initialized only first time useStaticLocal is called 62 static int x = 50; 63 64 cout << endl << "local static x is " << x 65 << " on entering useStaticLocal" << endl; 66 ++x; 67 cout << "local static x is " << x 68 << " on exiting useStaticLocal" << endl; 69 70 } // end function useStaticLocal 71 Static local variable of function; it is initialized only once, and retains its value between function calls.
72 // useGlobal modifies global variable x during each call 73 void useGlobal( void ) 74 { 75 cout << endl << "global x is " << x 76 << " on entering useGlobal" << endl; 77 x *= 10; 78 cout << "global x is " << x 79 << " on exiting useGlobal" << endl; 80 81 } // end function useGlobal This function does not declare any variables. It uses the global x declared in the beginning of the program. local x in main's outer scope is 5 local x in main's inner scope is 7 local x is 25 on entering useLocal local x is 26 on exiting useLocal local static x is 50 on entering useStaticLocal local static x is 51 on exiting useStaticLocal global x is 1 on entering useGlobal global x is 10 on exiting useGlobal
local x is 25 on entering useLocal local x is 26 on exiting useLocal local static x is 51 on entering useStaticLocal local static x is 52 on exiting useStaticLocal global x is 10 on entering useGlobal global x is 100 on exiting useGlobal local x in main is 5
Thank you