0% found this document useful (0 votes)
18 views

Functions

The document discusses functions in C++. It explains that functions allow code to be reused by defining reusable blocks of code (subroutines) that can be called multiple times from different parts of a program. Functions divide programs into modular, self-contained tasks. Functions receive arguments from the code that calls them, perform operations, and return a value. The document provides examples of defining, calling, and using functions in C++ code. It covers function prototypes, parameters, return types, and variable scopes within functions.

Uploaded by

Sajjad hossain
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

Functions

The document discusses functions in C++. It explains that functions allow code to be reused by defining reusable blocks of code (subroutines) that can be called multiple times from different parts of a program. Functions divide programs into modular, self-contained tasks. Functions receive arguments from the code that calls them, perform operations, and return a value. The document provides examples of defining, calling, and using functions in C++ code. It covers function prototypes, parameters, return types, and variable scopes within functions.

Uploaded by

Sajjad hossain
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

1/13/2020 C++ Basics - C++ Programming Tutorial

21
22 // Access via null-terminated character array
23 for (int i = 0; msg[i] != '\0'; ++i) {
24 cout << msg[i];
25 }
26 cout << endl;
27 return 0;
28 }

9.6  Exercises
[TODO]

10.  Functions

10.1  Why Functions?
At times, a certain portion of codes has to be used many times. Instead of re-writing the codes many times, it is better to put them into a "subroutine", and "call"
this "subroutine" many time - for ease of maintenance and understanding. Subroutine is called method (in Java) or function (in C/C++).

The benefits of using functions are:


1. Divide and conquer: construct the program from simple, small pieces or components. Modularize the program into self-contained tasks.
2. Avoid repeating codes: It is easy to copy and paste, but hard to maintain and synchronize all the copies.
3. Software Reuse: you can reuse the functions in other programs, by packaging them into library codes.

Two parties are involved in using a function: a caller who calls the function, and the function called. The caller passes argument(s) to the function. The function
receives these argument(s), performs the programmed operations within the function's body, and returns a piece of result back to the caller.

10.2  Using Functions

Get Started with an Example


Suppose that we need to evaluate the area of a circle many times, it is better to write a function called getArea(), and re-use it when needed.

1 /* Test Function (TestFunction.cpp) */


2 #include <iostream>
3 using namespace std;
4 const int PI = 3.14159265;
5
6 // Function Prototype (Function Declaration)
7 double getArea(double radius);
8
9 int main() {
10 double radius1 = 1.1, area1, area2;
11 // call function getArea()
12 area1 = getArea(radius1);
13 cout << "area 1 is " << area1 << endl;
14 // call function getArea()
15 area2 = getArea(2.2);
16 cout << "area 2 is " << area2 << endl;
17 // call function getArea()
18 cout << "area 3 is " << getArea(3.3) << endl;
19 }
20
21 // Function Definition
22 // Return the area of a circle given its radius
23 double getArea(double radius) {
24 return radius * radius * PI;
25 }

area 1 is 3.63
area 2 is 14.52
area 3 is 32.67

In the above example, a reusable function called getArea() is defined, which receives a parameter (in double) from the caller, performs the calculation, and
return a piece of result (in double) to the caller. In the main(), we invoke getArea() functions thrice, each time with a different parameter.

https://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp1_Basics.html 31/44
1/13/2020 C++ Basics - C++ Programming Tutorial
In C++, you need to declare a function prototype (before the function is used), and provide a function definition, with a body containing the programmed
operations.

Function Definition
The syntax for function definition is as follows:

returnValueType functionName ( parameterList ) {


functionBody ;
}

The parameterList consists of comma-separated parameter-type and parameter-name, i.e., param-1-type param-1-name, param-2-type param-2-
name,...
The returnValueType specifies the type of the return value, such as int or double. An special return type called void can be used to denote that the function
returns no value. In C++, a function is allowed to return one value or no value (void). It cannot return multiple values. [C++ does not allow you to return an
array!]

The "return" Statement


Inside the function's body, you could use a return statement to return a value (of the returnValueType declared in the function's header) and pass the control
back to the caller. The syntax is:

return expression; // Evaluated to a value of returnValueType declared in function's signature


return; // For function with return type of void

Take note that invoking a function (by the caller) transfers the control to the function. The return statement in the function transfers the control back to the
caller.

Function Naming Convention


A function's name shall be a verb or verb phrase (action), comprising one or more words. The first word is in lowercase, while the rest are initial-capitalized
(known as camel-case). For example, getArea(), setRadius(), moveDown(), isPrime(), etc.

Function Prototype
In C++, a function must be declared before it can be called. It can be achieved by either placing the function definition before it is being used, or declare a so-
called function prototype.

A function prototype tells the compiler the function's interface, i.e., the return-type, function name, and the parameter type list (the number and type of
parameters). The function can now be defined anywhere in the file. For example,

// Function prototype - placed before the function is used.


double getArea(double); // without the parameter name
int max(int, int);

You could optionally include the parameter names in the function prototype. The names will be ignored by the compiler, but serve as documentation. For
example,

// Function Prototype
double getArea(double radius); // parameter names are ignored, but serve as documentation
int max(int number1, int number2);

Function prototypes are usually grouped together and placed in a so-called header file. The header file can be included in many programs. We will discuss
header file later.

Another Example
We have a function called max(int, int), which takes two int and return their maximum. We invoke the max() function from the main().

1 /* Testing max function (TestMaxFunction.cpp) */


2 #include <iostream>
3 using namespace std;
4
5 int maximum(int, int); // Function prototype (declaration)
6
7 int main() {
8 cout << maximum(5, 8) << endl; // Call maximum() with literals
9
10 int a = 6, b = 9, c;
11 c = maximum(a, b); // Call maximum() with variables
12 cout << c << endl;
13
14 cout << maximum(c, 99) << endl; // Call maximum()
15 }
16
17 // Function definition
18 // A function that returns the maximum of two given int
19 int maximum(int num1, int num2) {
20 return (num1 > num2) ? num1 : num2;
21 }

The "void" Return Type


Suppose that you need a function to perform certain actions (e.g., printing) without a need to return a value to the caller, you can declare its return-value type as
void. In the function's body, you could use a "return;" statement without a return value to return control to the caller. In this case, the return statement is

https://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp1_Basics.html 32/44
1/13/2020 C++ Basics - C++ Programming Tutorial
optional. If there is no return statement, the entire body will be executed, and control returns to the caller at the end of the body.

Actual Parameters vs. Formal Parameters


Recall that a function receives arguments from its caller, performs the actions defined in the function's body, and return a value (or nothing) to the caller.

In the above example, the variable (double radius) declared in the signature of getArea(double radius) is known as formal parameter. Its scope is within
the function's body. When the function is invoked by a caller, the caller must supply so-called actual parameters (or arguments), whose value is then used for the
actual computation. For example, when the function is invoked via "area1 = getArea(radius1)", radius1 is the actual parameter, with a value of 1.1.

Scope of Function's Local Variables and Parameters


All variables, including function's parameters, declared inside a function are available only to the function. They are created when the function is called, and freed
(destroyed) after the function returns. They are called local variables because they are local to the function and not available outside the function. They are also
called automatic variables, because they are created and destroyed automatically - no programmer's explicit action needed to allocate and deallocate them.

Boolean Functions
A boolean function returns a bool value (of either true or false) to the caller.

Suppose that we wish to write a function called isOdd() to check if a given number is odd.

1 /*
2 * Test Boolean function (BooleanfunctionTest.cpp).
3 */
4 #include <iostream>
5 using namespace std;
6
7 // Function Prototype
8 bool isOdd(int);
9
10 int main() {
11 cout << boolalpha; // print bool as true or false
12 cout << isOdd(5) << endl; // true
13 cout << isOdd(6) << endl; // false
14 cout << isOdd(-5) << endl; // false
15 }
16
17 bool isOdd(int number) {
18 if (number % 2 == 1) {
19 return true;
20 } else {
21 return false;
22 }
23 }

This seemingly correct codes produces false for -5, because -5%2 is -1 instead of 1. You may rewrite the condition:

bool isOdd(int number) {


if (number % 2 == 0) {
return false;
} else {
return true;
}
}

The above code produces the correct answer, but is poor. For boolean function, you should simply return the resultant bool value of the comparison, instead of
using a conditional statement, as follow:

bool isEven(int number) {


return (number % 2 == 0);
}

bool isOdd(int number) {


return !(number % 2 == 0); // OR return !isEven(number);
}

int main() {
int number = -9;
if (isEven(number)) { // Don't write (isEven(number) == true)
cout << "Even" << endl;
}
}

10.3  Default Arguments
C++ introduces so-called default arguments for functions. These default values would be used if the caller omits the corresponding actual argument in calling the
function. Default arguments are specified in the function prototype, and cannot be repeated in the function definition. The default arguments are resolved based
on their positions. Hence, they can only be used to substitute the trailing arguments to avoid ambiguity. For example,

1 /* Test Function default arguments (functionDefaultArgument.cpp) */


2 #include <iostream>
3 using namespace std;
4
5 // Function prototype - Specify the default arguments here
6 int fun1(int = 1, int = 2, int = 3);

https://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp1_Basics.html 33/44
1/13/2020 C++ Basics - C++ Programming Tutorial
7 int fun2(int, int, int = 3);
8
9 int main() {
10 cout << fun1(4, 5, 6) << endl; // No default
11 cout << fun1(4, 5) << endl; // 4, 5, 3(default)
12 cout << fun1(4) << endl; // 4, 2(default), 3(default)
13 cout << fun1() << endl; // 1(default), 2(default), 3(default)
14
15 cout << fun2(4, 5, 6) << endl; // No default
16 cout << fun2(4, 5) << endl; // 4, 5, 3(default)
17 // cout << fun2(4) << endl;
18 // error: too few arguments to function 'int fun2(int, int, int)'
19 }
20
21 int fun1(int n1, int n2, int n3) {
22 // cannot repeat default arguments in function definition
23 return n1 + n2 + n3;
24 }
25
26 int fun2(int n1, int n2, int n3) {
27 return n1 + n2 + n3;
28 }

You should specify the default arguments in the function prototype (declaration). They can only be defined once (one-definition rule), and cannot be repeated in
the function definition.

Default argument is not absolutely necessary. The codes could be hard to maintain.

10.4  Function Overloading
C++ introduces function overloading (or function polymorphism, which means many forms), which allows you to have multiple versions of the same function
name, differentiated by the parameter list (number, type or order of parameters). The version matches the caller's argument list will be selected for execution. For
example,

1 /* Test Function Overloading (FunctionOverloading.cpp) */


2 #include <iostream>
3 using namespace std;
4
5 void fun(int, int, int); // Version 1
6 void fun(double, int); // Version 2
7 void fun(int, double); // Version 3
8
9 int main() {
10 fun(1, 2, 3); // version 1
11 fun(1.0, 2); // version 2
12 fun(1, 2.0); // version 3
13 fun(1.1, 2, 3); // version 1 - double 1.1 casted to int 1 (without warning)
14
15 // fun(1, 2, 3, 4);
16 // error: no matching function for call to 'fun(int, int, int, int)'
17 // fun(1, 2);
18 // error: call of overloaded 'fun(int, int)' is ambiguous
19 // note: candidates are:
20 // void fun(double, int)
21 // void fun(int, double)
22 // fun(1.0, 2.0);
23 // error: call of overloaded 'fun(double, double)' is ambiguous
24 }
25
26 void fun(int n1, int n2, int n3) { // version 1
27 cout << "version 1" << endl;
28 }
29
30 void fun(double n1, int n2) { // version 2
31 cout << "version 2" << endl;
32 }
33
34 void fun(int n1, double n2) { // version 3
35 cout << "version 3" << endl;
36 }

Overloaded functions cannot be differentiated by the return-type (compilation error).

*Name Mangling
To differentiate between different versions of an overloaded function, many compilers (such as GNU GCC) adopt a name mangling or name decoration scheme
for naming functions.

// Compile source into object code FunctionOverloading.o


> g++ -c FunctionOverloading.cpp

// List the symbol table


> nm FunctionOverloading.o
......
000000b5 T __Z3fundi
000000ed T __Z3funid

https://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp1_Basics.html 34/44
1/13/2020 C++ Basics - C++ Programming Tutorial
00000089 T __Z3funiii
......

Each of the function is identified via a prefix __Z, followed by an integer containing the number of characters of the function name (3 in this case for "fun"),
followed by the parameter type list (where i for int and d for double). For example, di means a double followed by an int; id for an int followed by a
double; iii for 3 ints.

You can choose to use the C's naming protocol by appending the keyword extern "C" to the function prototype. C does not support function overloading.
Thus, it does not need name mangling. It simply append an underscore in front of the function name. For example,

extern "C" void fun(int, int, int, int); // Compiled as _fun

10.5  Functions and Arrays


You can also pass arrays into function. However, you also need to pass the size of the array into the function. This is because there is no way to tell the size of the
array from the array argument inside the called function.

For example,

Example: Computing the Sum of an Array and Print Array's Contents


1 /* Function to compute the sum of an array (SumArray.cpp) */
2 #include <iostream>
3 using namespace std;
4
5 // Function prototype
6 int sum(int array[], int size); // Need to pass the array size too
7 void print(int array[], int size);
8
9 // Test Driver
10 int main() {
11 int a1[] = {8, 4, 5, 3, 2};
12 print(a1, 5); // {8,4,5,3,2}
13 cout << "sum is " << sum(a1, 5) << endl; // sum is 22
14 }
15
16 // Function definition
17 // Return the sum of the given array
18 int sum(int array[], int size) {
19 int sum = 0;
20 for (int i = 0; i < size; ++i) {
21 sum += array[i];
22 }
23 return sum;
24 }
25
26 // Print the contents of the given array
27 void print(int array[], int size) {
28 cout << "{";
29 for (int i = 0; i < size; ++i) {
30 cout << array[i];
31 if (i < size - 1) {
32 cout << ",";
33 }
34 }
35 cout << "}" << endl;
36 }

10.6  Pass-by-Value vs. Pass-by-Reference


There are two ways that a parameter can be passed into a function: pass by value vs. pass by reference.

Pass-by-Value
In pass-by-value, a "copy" of argument is created and passed into the function. The invoked function works on the "clone", and cannot modify the original copy.
In C/C++, fundamental types (such as int and double) are passed by value. That is, you cannot modify caller's value inside the function - there is no side effect.

Example (Fundamental Types are Passed by Value)


1 /* Fundamental types are passed by value into Function (TestPassByValue.cpp) */
2 #include <iostream>
3 using namespace std;
4
5 // Function prototypes
6 int inc(int number);
7
8 // Test Driver
9 int main() {
10 int n = 8;
11 cout << "Before calling function, n is " << n << endl; // 8
12 int result = inc(n);
13 cout << "After calling function, n is " << n << endl; // 8
14 cout << "result is " << result << endl; // 9
15 }
16

https://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp1_Basics.html 35/44
1/13/2020 C++ Basics - C++ Programming Tutorial
17 // Function definitions
18 // Return number+1
19 int inc(int number) {
20 ++number; // Modify parameter, no effect to caller
21 return number;
22 }

Pass-by-Reference
On the other hand, in pass-by-reference, a reference of the caller's variable is passed into the function. In other words, the invoked function works on the same
data. If the invoked function modifies the parameter, the same caller's copy will be modified as well.

In C/C++, arrays are passed by reference. That is, you can modify the contents of the caller's array inside the invoked function - there could be side effect in
passing arrays into function.

C/C++ does not allow functions to return an array. Hence, if you wish to write a function that modifies the contents of an array (e.g., sorting the elements of an
array), you need to rely on pass-by-reference to work on the same copy inside and outside the function. Recall that in pass-by-value, the invoked function works
on a clone copy and has no way to modify the original copy.

Example (Array is passed by Reference): Increment Each Element of an Array


1 /* Function to increment each element of an array (IncrementArray.cpp) */
2 #include <iostream>
3 using namespace std;
4
5 // Function prototypes
6 void inc(int array[], int size);
7 void print(int array[], int size);
8
9 // Test Driver
10 int main() {
11 int a1[] = {8, 4, 5, 3, 2};
12
13 // Before increment
14 print(a1, 5); // {8,4,5,3,2}
15 // Do increment
16 inc(a1, 5); // Array is passed by reference (having side effect)
17 // After increment
18 print(a1, 5); // {9,5,6,4,3}
19 }
20
21 // Function definitions
22
23 // Increment each element of the given array
24 void inc(int array[], int size) { // array[] is not const
25 for (int i = 0; i < size; ++i) {
26 array[i]++; // side-effect
27 }
28 }
29
30 // Print the contents of the given array
31 void print(int array[], int size) {
32 cout << "{";
33 for (int i = 0; i < size; ++i) {
34 cout << array[i];
35 if (i < size - 1) {
36 cout << ",";
37 }
38 }
39 cout << "}" << endl;
40 }

Array is passed into function by reference. That is, the invoked function works on the same copy of the array as the caller. Hence, changes of array inside the
function is reflected outside the function (i.e., side effect).

Why Arrays are Pass-by-Reference?


Array is designed to be passed by reference, instead of by value using a cloned copy. This is because passing huge array by value is inefficient - the huge array
needs to be cloned.

10.7  const Function Parameters


Pass-by-reference risks corrupting the original data. If you do not have the intention of modifying the arrays inside the function, you could use the const
keyword in the function parameter. A const function argument cannot be modified inside the function.

Use const whenever possible for passing references as it prevent you from inadvertently modifying the parameters and protects you against many programming
errors.

Example: Search an Array using Linear Search


In a linear search, the search key is compared with each element of the array linearly. If there is a match, it returns the index of the array between [0, size-1];
otherwise, it returns -1 or the size of of the array (some implementations deal with only positive indexes). Linear search has complexity of O(n).

1 /* Search an array for the given key using Linear Search (LinearSearch.cpp) */
2 #include <iostream>

https://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp1_Basics.html 36/44

You might also like