본문 바로가기

Programming/C++ Basic

[Basic C++] 05 - C++ Functions

In this post, I am going to talk about C++ functions. Functions are extremely useful by which you can save a lot of time. Functions are just a group of codes in which they are programmed to perform certain tasks and sometimes return calculated values.


Table of Contents

1. Syntax of C++ function

2. Reference and function

3. Inline and function prototype


1. Syntax of C++ function

The syntax of C++ function is as simple as below. You specify a return type, a name, input arguments, and statements. Code example 1 shows two functions accepting two arguments, perform arithmetic calculations, and return the results.

 

Figure 1 Syntax of C++ function

On the inside of the main function, the two functions are called with two input arguments and they are stored in other variables.

 

Code example 1

#include <iostream>

int function1(int arg1, int arg2)
{
	int result = arg1 * arg2;
	return result;
}
int function2(int arg1, int arg2)
{
	int result = arg1 + arg2;
	return result;
}

int main()
{
	int f1_rlt = function1(1, 10);
	int tl_rlt = function2(5, 20) + f1_rlt;
	std::cout << tl_rlt;
	std::cin.get();
}

 

1.1 Void functions

There are functions with no return values and we call them "void functions". Let see code example 2. Function 3 does not return anything but prints a message.

 

Code example 2

#include <iostream>

void function3(int arg1, int arg2)
{
	int result = arg1 * arg2;
	std::cout << result;
}

int main()
{
	function3(1, 10);
	std::cin.get();
}

 

 

1.2 Main function

I told you already what the main function was in the previous post. The main function is the entry point of your project. This means that it is always a starting point among all of your functions unless you specify the specific entry point.

 

You might have noticed in the previous examples that the return type of the main function was "int", even though it did not really return anything. This is because the main function is a special function. The main function actually returns implicitly 0 when your project performs successfully and terminates the program. This is why your shell disappears right after your executable file finishes what you've coded inside.

 

"std::cin.get();" exists on the inside of the example codes in order to maintain the shell even after the end of program execution.

 

2. Reference and function

The process of calling a function is not as simple as it sounds. When you call a function with some input arguments, those arguments are not physically passed to the inside of a function but the copies of the arguments. This is why the original variables do not change even if you change them on the inside of a function. Figure 2 explains the process.

 

Figure 2 How are function arguments passed to

However, sometimes you kinda need to modify the original value in the inside of a function. In this case, arguments should be passed to a function by references, not values. Code example 3 shows how a function works with copied variables and references.

 

Code example 3

#include <iostream>

void function3(int arg1, int arg2)
{
	arg1++, arg2++;
}

void function4(int& arg1, int& arg2)
{
	arg1++, arg2++;
}

int main()
{
	int x= 4 , y= 9;

	std::cout << "Varaibles before function 3: " << x << " and " << y << std::endl;

	function3(x, y);

	std::cout << "Varaibles after function 3: " << x << " and " << y << std::endl;

	function4(x, y);

	std::cout << "Varaibles after function 4: " << x << " and " << y << std::endl;

	std::cin.get();
}

Figure 3 Result of code example

When the arguments have been passed to function 3 without the ampersand signs (reference of a value), the original values were still unchanged. On the other hand, the original values were modified when the references of the values were passed to function 4.

 

2.1 Avoiding redundant copies of data ( Reference and Constant )

Coping the original variable for function call may not be a good idea for a large chunk of data like strings. For example, Code example 4 is not a good idea for the efficiency of your code since string if the string values are too big to be copied.

 

Code example 4

#include <iostream>
#include <string>

void function5(std::string a, std::string b)
{
	std::cout << a + b;
}
int main()
{
	std::string a = "MSVC2019";
	std::string b(10, 'a');
	function5(a, b);
	
	std::cin.get();
}

 

In order to avoid coping a large data causing the inefficiency of your code, you can pass the references of the data to a function without having to make large copies. One might think that there is a possibility that the function might change the original value. That is why we need to make the string variables "const". Once you declare a variable is "const", no code can change it anymore. Therefore, you can safely pass the references without being modified by the function.

 

Code example 5

#include <iostream>
#include <string>

void function5(const std::string& a, const std::string& b)
{
	std::cout << a + b;
}
int main()
{
	std::string a = "MSVC2019";
	std::string b(10, 'a');
	function5(a, b);
	
	std::cin.get();
}

You should also know that this does not always improve your code efficiency. It only works when you deal with a large chunk of data like strings

 

3. Inline and function prototype.

3.1 inline (1)

The keyword "inline" exists to decrease the execution time of a function. In order to understand this, you have to know how "function call" works in C++. When a function is executed by function call, a CPU copies the function arguments ( or references ) on the stack memory and transfers control to the corresponding function from where it's initially called. Once the function has been fully executed, the CPU stores the return value and the control goes back to where the function was called. This entire task takes some amount of time.

 

However, sometimes the overhead of function call (above-mentioned process) is too much compared to the size of an executed function. The keyword "inline" appears here. When an inline function is used, C++ substitutes the corresponding function code for function call. The syntax of inlining is below.

 

inline return_type function_name (arguments) {statements}

 

Most C++ compilers including MSVC compiler are programmed to optimize C++ code automatically when there is a chance of optimization. Therefore, The keyword "inline" does not always optimize your function and the process is totally dependent on your compiler's choice. Compiler ignores your inline request (2),

 

1) If a function contains a loop. (for, while, do-while)
2) If a function contains static variables.
3) If a function is recursive.
4) If a function return type is other than void, and the return statement doesn’t exist in function body.
5) If a function contains switch or goto statement.

 

In addition, methods in a class are also implicitly inline. Therefore there is no need to write inline functions inside of a class but only outside.

 

3.2 prototype / signature

In C++, functions are supposed to be declared before the main function. Otherwise, your compiler will raise an error during compilation. The prototype of a function allows you to declare a function after the main function. This method is highly useful when

 

a) you want to arrange the order of multiple functions

b) some functions are mutually called each other.

 

Code example 6

#include <iostream>
#include <string>

void function5(const std::string& a, const std::string& b); // Funtion prototype

int main()
{
	std::string a = "MSVC2019";
	std::string b = "MSVC2018";
	function5(a, b);
	std::cin.get();
}

void function5(const std::string& a, const std::string& b)
{
	std::cout << a + b;
}

 

4. Recursive function

In C++, a function can call itself. This is because, during a compilation, the compiler only needs the declaration of a function, not its definition. It's called a recursive function and it's very useful in solving a lot of problems. One of the most common examples of a recursive function is the factorial function. 

In Math, the factorial of a number n is  " n = n * (n-1) * (n-2) ... *1. See Code example 7.

 

Code example 7

#include <iostream>

int factorial(int a)
{
	int result;

	if (a > 1)
		result = a * factorial(a - 1);
	else
		result = 1;
	return result;
}

int main()
{
	int a;
	std::cout << "Input a number : ";
	std::cin >> a;
	std::cout << factorial(a);
	std::cin.get();
}

REFERENCES

 

(1) http://www.cplusplus.com/doc/tutorial/functions/

(2) https://www.geeksforgeeks.org/inline-functions-cpp/

(3) https://stackoverflow.com/questions/17387617/c-calling-a-function-inside-the-same-functions-definition