Lesson 12: User-Defined Functions
Functions are the building blocks of a C/C++ program. A function is a group of statements that together perform a specific task.
Why do we need functions?
- Functions help us in reducing code redundancy. If functionality is performed at multiple places in software, then rather than writing the same code again and again, we create a function and call it everywhere. This also helps in maintenance as we have to change in one place if we make future changes to the functionality.
- Functions make code modular. Consider a big file with many lines of code. It becomes easier to read and use the code if the code is divided into functions.
- Functions provide abstraction. For example, we can use library functions without worrying about their internal work.
12.1 Functions
The basic syntax of a function in C/C++ has 2 parts:
- Function Definition:
A function definition provides the actual body of the function. - Function Declaration:
A function declaration tells the compiler about a function's name, return data type, and parameters.
Function Definition
Function Definition
At the heart of a C/C++ program is the function. It is the place in which all program activity occurs. The general form of a function definition is as below
return_type function_name (parameter_list)
{
// body of function
}
A C++ function definition consists of a function header and a function body. Here are all the parts of a function −
- Return Type
A function may return a value. The type of data returned by a function is specified by return_type. Some functions perform the desired operations without returning a value. In this case, the return_type is the keyword void. - Function Name
This is the actual name of the function. The function's name can be any valid identifier. The function name and the parameter list together constitute the function declaration. - Parameters
The parameter list is a comma-separated (,) list of variables that will receive any arguments passed to the function. The parameter_list refers to the data type, order, and the number of the parameters of a function. Parameters are optional; that is, a function may contain no parameters. - Function Body
The function body contains a collection of statements that define what the function does.
For example, the following function has two integer parameters called i and j, and a double parameter called count, and no return value:
void fn(int i, int j, double count)
{
…
}
Notice you must declare each parameter separately.
Function Declaration
Function Declaration
Function declarations are also called function prototypes. A function declaration tells the compiler about a function name and how to call the function. The actual body of the function can be defined separately. In C++, all functions must be declared. In C, declarations are technically optional but strongly recommended. The syntax of a function declaration is shown here:
ret_type function_name (parameter_list) ;
The function declaration is actually similar to the function definition except in two aspects:
- The parameters' names may not be specified in the function declaration.
- A semicolon must end the function declaration.
For example:
Parameter names are not important in the function declaration; only their data type is required, so the following is also a valid declaration —
int max2 (int, int);
Return Values
Functions terminate and return automatically to the calling procedure when the last brace (}) is encountered. You may force a return before that by using the return statement.
All functions, except those declared as void, return a value. The type of the return value must match the type declaration of the function. Values are returned via the return statement.
Return a variable
For example, the below max2() function is defined to have a return type of int; thus, the function's return statement must have an expression that evaluates to an int.
// An example function that takes two parameters 'x' and 'y' // as input and returns max of two input numbers int max2(int x, int y) { int max; if ( x > y) max = x; else max = y; return max; }
Return the result of an expression
The following functions demonstrate the return expression.
long long square( int value ) { // Cast one operand to long long to force the // expression to be evaluated as type long long. // Note that parentheses around the return expression // are allowed, but not required here. return ( value * (long long) value ); }
In the code, the (long long) type is large enough to hold the product of two int values without overflow.
The parentheses around the return expression in the square() function are evaluated as part of the expression and are not required by the return statement.
The following ratio() function returns the ratio of its two int parameters as a floating-point double value. The return expression is forced to use a floating-point operation by casting one of the operands to double. Otherwise, the integer division operator would be used, and the fractional part would be lost.
double ratio( int numerator, int denominator ) { // Cast one operand to double to force floating-point // division. Otherwise, integer division is used, // then the result is converted to the return type. return numerator / (double) denominator; }
Return without value
If a function does not return any value, a void is used as a return type to indicate this.
The report_square() function will ask for an integer value from the user input, then calculate its square value stored in squared, then printed. The report_square() function has a void return type, so its return statement does not need an expression.
#include <stdio.h> #include <stdlib.h> //#include <iostream> // uncomment for C++ //using namespace std; // uncomment for C++ void report_square( void ) { int value; long long squared; scan(&value); // for C // cin >> value; // for C++ squared = value * (long long) value; printf( "value = %d, squared = %lld\n", value, squared ); // for C // cout << "value = " << value << " squared = " << squared << endl; // for C++ return; // Use an empty expression to return void. }
The report_ratio() function calls ratio() with x and y parameter values. The double result is stored in a fraction and then printed. The report_ratio() function has a void return type, so it does not need to return a value explicitly. Execution of report_ratio() "falls off the bottom" and returns no value to the caller.
void report_ratio( int x, int y ) { double fraction = ratio( x, y ); printf( "%d / %d = %.16f\n", x, y, fraction ); // It is okay to have no return statement for functions that have void return types. }
Return with Conditional Operator
The max2() function can be implemented by using a conditional operator ( ? : ) with a return statement.
int max2(int x, int y) { return (x > y)? x : y; }
Multiple Return Statements
Suppose we want to return a value from a function based on a condition. We can do it in two ways:
Single return statement:
int max3(int a, int b, int c) { int max = b; if ( a > b) max = a; if (max < c) max = c; return max; }
Multiple return statements:
int max3(int a, int b, int c) { if ( a >= b && a >= c) return a; else if (b >= a && b >= c) return b; return c; }
You can have multiple return statements, and it should not matter. Most programmers follow the ruler of structured programming to ensure each function has a single entry and a single exit (SESE). To use multiple return statements, you must release all allocated memories before returning them to the caller.
Multiple or No Parameters
Multiple Parameters
A function definition may have multiple parameters separated by commas. Parameters are assigned with argument values by position: The first parameter with the first argument, the second with the second, etc.
To specify the declaration for a function that takes a variable number of arguments, use three periods (...) at the point at which the variable number of parameters begins. For example, the printf() function could be declared like this:
int printf(const char *format, ...);
No Parameters
In C, to specify use declaration for a function with no parameters, use void in its parameter list. For example:
int fn(void);
In C++, a function definition with no parameters must still have the parentheses with an empty parameter list; the void is optional. Thus, in C++, the preceding declaration can be written like this:
int fn();
The call must include parentheses without argument, as in: fn().
In C++, you can include void in the parameter list, but doing so is redundant.
12.2 Function Calling Methods
Parameters and Arguments
The programmer can influence the behavior of the function through inputs.
- Parameter
A parameter is a function input specified in a function definition. - Argument
An argument is a value provided to a function's parameter during a function call. An argument can be a variable, a constant value, or an expression.
A parameter is like a variable declaration. Upon a call, the parameter's memory location is allocated, and the parameter is assigned with the argument's value. Upon returning to the original call location, the parameter is deleted from memory.
Function Calling
A function call is an invocation of a function's name, causing the function's statements to execute.
Call by Value
Call by Address
Call by Reference (C++)
12.3 Inline Functions
12.4 The main() function
12.5
12.6