Functions

A function is a unit of code grouped to perform a specific task. Functions provide a way to compartmentalise and organise a program. Functions are identified by a name, enclosed within scope brackets, and may be terminated by a return statement. After a function call, the execution of the program branches to the first statement in that function and continues until it reaches a return statement or the function's last statement. At that point, execution resumes at the place where the function was called. A function can have multiple parameters separated by commas, but it can have only one return type. A function that does not need to return a value is declared void.  In C++, one function cannot be embedded within another function. Functions are denoted by the function name followed by the parentheses and preceded by the return type(if any).

Function Prototype

The function prototype declares a function before its definition and details its name, the list of parameters the function accepts, and the return type. The compiler needs to know this information before the function is called. A function defined before main() (forward declaration) does not need a function prototype.

Function calls

A function call is an expression that passes control and arguments (if any) to a function. When a function declaration contains parameters, the function call sends arguments. Arguments are values the function requests within its parameter list.

Function Parameters

The purpose of parameters is to allow functions to receive arguments. These parameters don’t have to be of the same data type. Any valid C++ expression can be a function parameter, including constants, logical expressions, objects, and other functions that return a value. Parameter data can be passed into and out of methods and functions by value or reference with multiple parameters separated by a comma.

Pass by Value - The data associated with the actual parameter is copied into a separate storage location assigned to the function parameter. Any modifications to the function parameter variable inside the called function or method affect only the local parameter.  The parameters passed to a function become local variables within that function, even if they have the same name as variables within the scope of the statement calling the function.

Pass by Reference - Using "pass by reference", the function parameter receives a reference or pointer to the variable in the calling environment. Any changes to the function parameter are reflected in the original calling environment variable.  bPass-by-references are more efficient than pass-by-value because it does not copy the arguments.

The code selection below outlines 3 different methods for passing data to a function

#include <iostream>
using namespace std;
void swapThemByVal(int, int);
void swapThemByRef(int& , int&);
void swapThemByPtr(int *, int *) ;
main()
{
int x = 10, y = 20;//declare and initialise variable values
swapThemByVal(x, y);//pass be value
cout << x<< "  " << y << endl;     // displays 10  20
swapThemByRef(x, y);//pass by reference
cout << x << "  " << y << endl;     // displays 20  10
swapThemByPtr(&x, &y);//pass by pointer
cout << x << "  " << y << endl;     // displays 20  10
return 0;
}
void swapThemByVal(int num1, int num2)
{
int temp = num1;
num1 = num2;
num2 = temp;
}
void swapThemByRef(int &num1, int &num2)
{
int temp = num1;
num1 = num2;
num2 = temp;
}
void swapThemByPtr(int *num1, int *num2)
{
int temp = *num1;
*num1 = *num2;
*num2 = temp;
}

Using Variables with Functions

Local Variables - A variable created in a function is called a local variable because it only exists within the function scope. When the function returns, all local variables go out of scope and cease to exist. Local variables are declared like any other variable. The parameters received by the function are also considered local variables. Local variables get stored in an area of memory called the stack.

Global Variables - In C++, variables defined outside of all functions, including the main() function are known as global variables and are visible everywhere in the program.  Since Global variables can be changed in any part of the program this can lead to a problem in tracking down errors.  Limiting the scope of a variable to a particular section of a program limits the amount of checking that must be done in the event of an error. The use of global variables is not considered good programming practice. Non-constant global variables are stored in the "data" segment of memory.

Default Function Parameters

Normally when a function is declared in a prototype to receive one or more parameters, the function can only be called with parameters of that data type, however, if the function prototype declares a default value for a parameter the function can be called without that parameter.

Default arguments are only allowed in the parameter lists of function declarations. The default values can be overridden with a user-supplied value if required using the normal call syntax. When a function has more than one parameter, default values are assigned based on the order of the parameters. Any parameter can be assigned a default value, with one important restriction: If a parameter does not have a default value, no previous parameter may have a default value.

The following declaration is not permitted

long setvalues(int x, int y, int z = 1, int t) - note that x & y are before z

The correct declaration would be

long setvalues(int x, int y, int t,int z = 1);

Passing an Array of Values to a Function

C++ does not allow an entire array to be passed as an argument to a function. Pointers to an array are passed as an argument by specifying the array's name without an index. The argument represents the memory address of the first element of the array. Any changes in the function will therefore be reflected in the original array. To pass a single-dimension array as an argument in a function using one of the following.

All these variants are functionally identical. Each effectively tells the compiler that an integer pointer is to be received.

void myFunction(int *param) - array passed as pointer
void myFunction(int param[10])  - array passed a sized array
void myFunction(int param[]) - array passed as unsized array 

Returning Values from Functions

Functions can return a value or return nothing (void).To return a value from a function, the keyword return is followed by the value to return. A function’s return value is copied into a placeholder on the stack. The return value is popped off the stack and can be assigned as the value of the function. If the value of the function isn’t assigned to anything, no assignment takes place, and the value is lost. After a return statement, program execution continues immediately after the statement that called the function. A function can have multiple return statements

Auto-Typed Return Values

Another feature added with version C++14 is the automatic deduction of a function’s return type with the auto keyword. This tells the compiler to deduce the return type of the functions by deduction -

auto subtract(int x, int y)
{
return x — y;
}

Functions that rely on automatic return type deduction need to be defined before invoked so the compiler knows a function’s return type where it is used. If a function has multiple return statements, they need to be the same type.

Overloading Functions

Functions with the same name and return type but with different parameters are called overloaded functions. Overloaded functions can be used where the function called depends on the parameter type specified in the function call. It is, therefore, possible to create a function that performs a task on different data types without creating unique names for each function. Overloaded functions don't have to have the same return type, but it is not possible to overload by return type.  Function overloading is also called function polymorphism.

Inline Functions

Since a function call results in some overhead, declaring a function as inline causes the contents of the function to be placed inline where it's called.  The C++ compiler carries out this substitution at compile time. Inline functions will generally only increase efficiency if they are small. To make any function inline, start its definitions with the keyword “inline".

The syntax for defining the function inline is:

inline return-type function-name(parameters)
{
    // code
}  

Recursion—Functions That Invoke Themselves

A function that calls itself is known as a recursive function. The recursion proceeds until some condition is met which breaks the recursive cycle. The following simple recursion function demonstrates how a countdown procedure calls itself until the exit condition is met.

#include <iostream>
void printFun(int countp)
{
if (countp < 1) //exit function if value of countp is smaller than 1
return;
else
{
printf("Count value = %.i \n", countp);
printFun(countp-1); //recursive function calls itself
return;
}
}
int main()
{
int count = 3;
printFun(count); //call recursive function
}