04 - Introduction to C++ Functions

Functions Overview

In C++ programming language, a function consists of a set of statements that perform a specified task. For example, the task of adding two numbers, calculating the salary of an employee or displaying text on screen. In C++, execution of all programs begins from the main() function. The main() function may call other functions, which in turn may further call other functions.

Whenever you want to use a function in your program, it is referred to as ‘calling’ a function. The function that you call is known as the ‘called’ function. The function from which you make the call is known as the ‘calling’ function.

Let’s say, you call a function named sum from main. In this case, main is the ‘calling’ function and sum is the ‘called’ function. Whenever you call a function, the control is transferred to the first statement of the called function. After execution of a function, the control is transferred back to the ‘calling’ function.

Function Definition

In C++, the syntax for creating a function is as follows:

Syntax:

return_type function_name (argument list)
argument declaration;
{
    variable declaration;
    function statements;
    return value;
}
  • Return Type: refers to the type of value a function returns after execution. For example, a function may add two integers and return their sum. Thus it returns a number. In this case, the return type of the function would be int (integer). It is not necessary that each function must return a value. If a function does not return a value, then you use the keyword ‘void’ as the return type.
  • Function Name: It is a unique name that is used to identify a function. You use this name to call a function.
  • Function Body: contains instructions that are used to perform the task for which you’ve created the function. For example, you create function to add two whole numbers. Now, the body of the function includes set of instructions to add these two numbers. It may include variable declarations, assignment statements, and cout statement and so on.
  • Argument List: For more information, see Functions with Parameters.

Let’s first display some text without creating a separate function for the same.

#include<iostream.h>
void main()
{    
    cout<<”Displaying text”<<endl;    
}

The output of the above program is as follows:

Displaying text

In the above program we have written the statement to display text in main. Now, let’s    create a function that displays text and call this function from main():

#include <iostream.h>
void displaytext()
{
    cout<<”This is my first function”<<endl; // Function body
}
void main()
{    
    displaytext();    //function call
}

The output of the above program is as follows:

This is my first function 

In the above program, there are two functions- main() and displaytext(). Instead of writing the code to display text in main (), we have created a separate function called displaytext() and written the code in this function. In main (), we call the display text () function.

      displaytext(); 

The above statement is known as function call. It includes the name of the function followed by semicolon. It calls the displaytext function. When the compiler comes across this statement it transfers control to the first statement of the displaytext() function. In the above program main is the ‘calling’ function and displaytext() is the ‘called’ function. 

Let’s rearrange the displaytext() function such that we write it after main().

#include<iostream.h>

void main()
{    
    displaytext();    //function call
}

void displaytext()
{
    cout<<”This is my first function”<<endl; // function body
}

All programs are executed top to bottom and the execution, in C++, starts from main(). Now, when the compiler comes across the function call displaytext();it doesn’t know what displaytext() is. This is because you have defined the displaytext() function after main(). So, the compiler throws an error. Now, there are two ways to solve the above problem:

1.Define all your functions before main() - Defining includes writing the return type, name of the function, parameters and implementation details (function body).

Let’s create a program that has two functions and call them from the main() function.

void displaytext()
{
    cout<<”Executing the first function”<<endl; // function body
}

void display()
{
    cout<<”Executing the second function<<endl;    // function body
}

void main()
{    
    displaytext();    //function call
    display();        //function call
}

In the above program, we have three functions displaytext(), display (),and main(). To ensure that the compiler doesn’t throw an error, we have defined both functions displaytext() and display() before main(). The execution of the above program begins from top to bottom. So when the compiler comes across the function calls displaytext() and display(), it knows which functions are being referred to. Hence, it doesn’t throw an error. In essence, one way of avoiding compile- time error is by defining all the functions before main().               

This solution is feasible if your program is small. But if you have programs that have multiple function calls or there are functions that call other functions, it becomes difficult to decipher which function to define initially. In such cases we use, Forward Declaration.

Forward Declaration (Function Prototyping)

The other solution is to declare functions before main(), and define them (write the implementation details) after main().The declaration includes the return type, name of the function, parenthesis followed by a semicolon. Function declarations do not include the implementation details (the function body).This is known as function prototyping or forward declaration.

Let’s look at an example:

#include<iostream.h>

displaytext(); //forward declaration

void main()
{    
    displaytext();    //function call
}

void displaytext()
{
    cout<<”This is my first function”<<endl; // body of the function
}

The execution begins from top to bottom. In the above program, we declare the function displaytext() before main() and define it after main().When the compiler comes across the function call to displaytext(), it doesn’t throw a compile-time error. This is because of the forward declaration - it knows that we have defined the displaytext() function somewhere later in the program.

Functions with Parameters

While programming, a function may require additional input. This input is made available to the function through parameters. Let’s say that you need to create a function to add two numbers, but you don’t know what these numbers are. Hence, you need to create a function that takes two parameters as input (the numbers you want to add).

Following is the function definition of the addnum() that takes two parameters as its input:

void addnum(int x, int y) 
{
    int total;
    total=x+y;
    cout<< “ The sum is << total << endl;
}

In the first line, there is a function with the name addnum()that takes two whole numbers as its parameters. These parameters are stored in two variables x and y. You use variables to store the parameters because the two numbers that you want to add are not known.

In the second line, we declare an integer variable sum. This variable is used to store the sum of the two numbers.

Next, we assign the variable total a value. The value assigned is the sum of the two numbers, which you want to add.

The last statement is a cout statement that displays the sum of the two numbers on the screen.

Now, when you call the addnum function from main(), you specify the actual numbers in the function call as follows:

void main()
{
    addnum(44,79);
}

The value 44 is stored in the variable x (x=44) and the value 79 is stored in the variable y (y =79

A diagrammatic representation is as follows:

              

In C++, the complete program for the above example is as follows:

#include<iostream.h>

void addnum(int x, int y) 
{
    int total;
    total=x+y;
    cout<< “ The sum is << total << endl;
}
void main()
{
    addnum(44,79);
}

The output of the above program is as follows:

The sum is 123

C++ Function Invocation

In C++ programming language, you can invoke functions in the following ways:

  • Call by Value
  • Call by Reference

Call by Value

In call by value, a copy of the variable is made and passed to a function as its parameter. Changes made to these parameters in the function (the ‘called’ function) do not affect the variables in the’ calling’ function.

#include<iostream.h)
void Test(int Number)
{
    cout<<Number<<endl;
    Number++;
    cout<< Number<<endl;
} 

In the above program, we increment the value of the variable Number by 1.

Now, let us write our main program in which we call above function (test).

#include <iostream.h>
void main()
{
    int NewNumber=1;
    Test(NewNumber);
    cout<<NewNumber<<endl;
}

The output of the program is: 1 2 1.

In main(), we initialize the variable NewNumber  to 1. Next, we call the function Test and pass NewNumber as the parameter. The control is now transferred to the function Test. A copy of the variable NewNumber is created; now, there are two variables in the memory NewNumber and Number with the value 1. There is a cout statement that displays the value of the Number before it is incremented. In the next statement, the variable Number is increment by 1, and the following cout statement displays the incremented value.

Now, the control is transferred back to main().The variable Number doesn’t exist anymore in memory. Hence, the cout statement displays the value of the variable NewNumber, which is still 1. 

Call by Reference 

In call by value, the address of variable in the memory is passed to the called func-tion as the parameter. Changes made to the variable in the called function will reflect in the calling function. This is because the changes are made to the actual variable not its copy.

#include <iostream.h)
void Test(int &Number)
{
    cout<<Number<<endl;
    Number++;
    cout<< Number<<endl;
};
#include<iostream.h>
void main()
{
    int NewNumber=1;
    Test(NewNumber);
    cout<<NewNumber<<endl;
}

The output of the program is: 1 2 2

In the above program, the address of the variable NewNumber is being passed as the parameter to the Test function. A copy of the variable NewNumber is not created. NewNumber and Number refer to the same location in the memory. Hence, changes made to the variable in the function Test are reflected in main().

Recursive Functions

A recursive function is a function that calls itself. The function definition contains a function call to the same function.

An example of recursive function is as follows:

void display()
{    
        cout<< “Recursive Function”<<endl;
        display();
}

In the above program, you call the function display within its function definition. Thus, display is a recursive function. However, the above program is not the correct way to use recursive functions. The program will cause your computer to crash. This is because there is no end point; the display function keeps calling itself indefinitely and your computer will  crash.

Key Points to Remember

  • While using recursive functions, it’s important to know where to apply recursion. You use recursion when you can break a larger problem into smaller problems of the same form. The idea is to converge to a solution by breaking a problem down.
  • The next thing to know is the end point, that is, when should a function stop calling itself. For this you need to identify a condition that must be met. This condition acts as end point for calling the same function repetitively. This condition is known as the Base Case.

          In arithmetic,  4! = 4*3*2*1

                           Or

          You can say 4!= 4*3!

         Similarly,

  • 3! =3*2*1 or 3!= 3*2!
  • 2!=2*1 or 2!=2*1
  • 1!=1*0!

      Thus, the formula to calculate factorial is as follows:

      n!= n* (n-1) , where n>=1

      Note: 0!= 1 (0! is always 1, as per rule);

We can use recursive functions to calculate the factorial of any integer. A program in C++ to calculate the factorial is as follows:

int factfind(int x)
{
        if (x==1)
        {
            return 1;
        }else
        {
            return x* factfind(x-1);
        }    
}

In the above function, you pass the number for which you want to find the factorial as the parameter.  This number is stored in the variable x.

Let’s say we want to find the factorial of 4. Thus, x=4

1.The function checks if the condition is true.

2. If not, it then executes the following statement:

       return x* factfind(x-1);

It calls the factfind() function again with the value (x-1).

 In this case, 3 (4-1=3); factfind(3)

  • But the compiler doesn’t know value of 3!. So the control returns to Step 1.
  • This time the function factfind is passed the parameter 3 and the the steps 1 and 2 are repeated till the value of x= 1.

3.When the value of x =1 , the function returns 1.

Now the  factfind()function is able to calculate the value of 2!. Once it knows the value of 2!, it calculates the value of 3! And finally the value of 4!

Let’s write a complete C++ program to calculate 4 factorial(4!):

int factfind(int x)
{
        if (x==1)
        {
            return 1;
        }else
        {
            return x* factfind(x-1);
        }    
    }
int main()
{
        cout<<” The value of 4 factorial is “;
        return factfind(4);
}

The output of the above program is 24

A diagrammatic representation of the above function is as follows:

    

Key Points to Remember:

The sub-problems should be of the same type

When to stop; the base case acts as an end point

Inline Functions

Functions help increase the modularity of a program. However, when you call a function in a program, additional tasks are performed to execute the function call. Thus, a program takes additional time to execute. When a function is small, the time required to execute the function is less than execution time of the function call. In such cases, function calls do not make much sense as they increase the program execution time. 

C++ helps solve this problem by allowing you to create inline functions. For inline functions, the function call is replaced with the body of function instead of the control being transferred to the function ‘called’. You can think of it as the compiler copying and pasting the code of the function wherever there is a function call. Though this helps save execution time, the size of the program increases and it occupies more space in the memory. In case of inline functions there is always trade off between the execution time and the size of the program. 

To declare inline functions, the inline keyword is used in the function header. 

Syntax

int main()
{
        cout<<” The value of 4 factorial is “;
        return factfind(4);
}

Let’s create an inline function that displays a value entered by the user.

inline myage(int x)
{    
    cout<<”My age is”<< x <<endl;
}
void main()
{
    myage(44);
}

The program execution begins from and the compiler comes across the function call to myage function. The compiler knows that its an inline function, and instead of transferring the control to the myage function, it copies the function body in main().

Let’s say there are multiple function calls in main() to the myage function as follows:

void main()
{
    myage(44);
    myage(10);
    myage(23);
    myage(60);
}

Each time the compiler comes across a function call it does the following:

void main()
{
    cout<<”My age is”<< x <<endl;
    cout<<”My age is”<< x <<endl;
    cout<<”My age is”<< x <<endl;
    cout<<”My age is”<< x <<endl;
} 

As you can see, the size of the program increases, and it occupies more memory space. There may come a time when using inline functions may not make sense because the size of the program would have increased considerably. 

Note: In C++, inline functions are used only for small functions.

Like us on Facebook