JUGInformation Engineering Laboratory - Semester 1

05 - Functions

05 - Functions


🔨 🔥 Assignment 🔥 🔨

Create a new project in the way explained in the first instruction.


Basics

Functions can be used to divide a C++ program into parts of the codes that perform individual tasks. An example - imagine writing a homework with multiple tasks that are called when chosen inside case statement. Using functions it is possible to group statements that concern each task and then execute part of the code when needed. The functions are also handy when you need to execute something multiple times in different parts of the program as you can easily reuse already implemented code.

The most functions follow a scheme:

type function_name(type_p1 parameter1, type_p2 parameter2, ...) { statements }

where:

Let’s take a look at the example:

int add(int a, int b) {
    return a + b;
}

The function with the name add takes 2 parameters, a of type int and b of type int, computes the sum of those elements and returns it. The function can be called in the following manner:

int main() {
    int result = add(12, 15);
    std::cout << result << std::endl;
}

In this example, the function add is called with parameters 12 and 15. Function computes the result of addition (27), returns it and we store the returned value in variable result.

ATTENTION Different functions might return values of different types or no value at all. In case of no returning value, we use the word void in the type of the function, e.g.:

#include <iostream>

void print_text() {
    std::cout << "It is a function without parameters and without return value";
}

int main() {
    print_text();

    return 0;
}

🔨 🔥 Assignment 🔥 🔨

  1. Create a function called subtract, that takes two parameters and returns the result of subtraction. Call the function with constant values, print the result. WARNING Typically a function should not output anything by itself. Handle printing in main().
  2. Modify the program so it asks the user for two values and passes them to subtract function. WARNING User input should also be handled outside the function.

Passing by value and by reference

In C++, it is possible to pass parameters to function by value or by reference. In previous examples, we used passing by value, which means that when calling the function, the values of passed parameters are copied into the variables declared in the header of the function. Example:

#include <iostream>
#include <cmath>

double pythagorean(double a, double b) {
    a = a * a;
    b = b * b;
    return sqrt(a + b);
}

int main() {
    double var1 = 2, var2 = 3;
    double result = pythagorean(var1, var2);

    std::cout << result << std::endl;              // prints: 3.60555
    std::cout << var1 << " " << var2 << std::endl; // prints: 2 3
}

In this case when the function pythagorean is called the values of variables var1 and var2 are copied into variables a and and b. Even though values of a and b are modified inside the pythagorean while calculating second power, values of var1 and var2 are not modified.

Sometimes, it is needed that the value of variable passed to the function is changed also outside the scope of the function. In this case we want for the modification of value inside the function to also affect the value of variable that was passed as parameter. For example it is necessary when we want to obtain more than one result value from the called function. This can be done using passing by reference. Let’s consider a function that adds 10 to a provided number:

#include <iostream>

void add10(int variable) {
    variable = variable + 10;
}

int main() {
    int var = 15;
    add10(var);
    std::cout << var << std::endl;
}

15

#include <iostream>

void add10(int &variable) {
    variable = variable + 10;
}

int main() {
    int var = 15;
    add10(var);
    std::cout << var << std::endl;
}

25

The only difference is the sign & after the type of the variable. With passing by reference, the variable and var are different names for the same variable (they store data in the same place in memory) and therefore it is possible to make changes to var value from inside the add10 function. In case of passing by value, we make changes only to the copy of the value, so we lose all of the changes after the function is executed.

CURIOSITY Choosing the type of passing the parameters to the function influences the performance! When passing by value, the computer program needs to make a copy of the variables, which takes time. When passing by reference, the program uses the already existing places in memory and is faster.

CURIOSITY Sometimes, we need the efficiency of passing by reference, but we don’t want to make changes to the values. To inform the compiler (and other programmers), we can write:

int add(const int &a, const int &b) {
    return a + b;
}

Using the const modifier will NOT allow the function to change the values of the variables.


🔨 🔥 Assignment 🔥 🔨

Change the created subtract function to return the result as the third parameter. HINT Use passing by reference.


Default values in parameters

In C++, the functions can also have optional parameters. Those optional parameters take predefined values and allow to call function with less parameters specified. All parameters with default values have to be located at the end of parameter list.

For example, it is possible to call a function with 3 parameters while specifying just one:

#include <iostream>

int add(int a, int b = 0, int c = 0) {
    return a + b + c;
}

int main() {
    std::cout << add(2) << std::endl;
    std::cout << add(2, 5) << std::endl;
    std::cout << add(2, 5, 6) << std::endl;
}

Declaring functions

The functions must be declared before they can be used. Therefore, in every previous example, we declared the function before the main, where it was called. To avoid the issue, it is possible to declare the function prototype without providing the body of the function. Examples:

#include <iostream>

int add(int a, int b);

int main()
{
    std::cout << add(2, 5) << std::endl;
}

int add(int a, int b)
{
    return a + b;
}

Function is firstly declared without the body and can be called. The body of the function is defined below main().

// Incorrect! Function can not  be called before it is declared.
#include <iostream>

int main()
{
    std::cout << add(2,5) << std::endl; // ERROR!!
}

int add(int a, int b)
{
    return a + b;
}

🔨 🔥 Assignment 🔥 🔨

Move the definition of subtract function below main(). Add proper declaration so the function can be called.


Final assignments 🔥 🔨

Functions calls should be placed in a while loop, so the user will be able to choose what he want to do or terminate the program by pressing x or X. Create a menu.

Exercise 1

Create a function that returns the minimum of two numbers.

Exercise 2

Create a function that returns the minimum of four numbers (use previously created function!). HINT You have to call a function inside a function.

Exercise 3

Create a function that computes the geometric mean of 3 provided numbers - https://en.wikipedia.org/wiki/Geometric_mean.

Exercise 4

Create a function that rounds the provided floating point number according to mathematical rules (if more than 0.5 we round up, otherwise we round down). Use passing by reference.

Exercise 5

Create a function is_prime(int n) that returns true or false. Use it to find all prime numbers that are smaller than 100.

Exercise 6

Create a function that computes the area and volume of a sphere with given radius r. Return values by reference.

Homework 💥 🏠

  1. Write a function that computes the harmonic mean of three provided values - https://en.wikipedia.org/wiki/Harmonic_mean. Return 0 if it is not possible to compute the mean.
  2. Create a function that computes the greatest common divisor (GCD) of two provided numbers.

Use Euclidean Algorithm, which for given a and b can de described in the following steps:

  1. calculate c as the remainder of division of a by b
  2. replace value of a with value of b, then replace value of b with value of c
  3. if b is equal 0, then a is the result (GCD), otherwise go back to step 1
  1. Using the function from Homework task 2, create a function that computes the greatest common divisor of 3 provided numbers

  2. Write a function that ciphers/deciphers a provided character (a small or a capital letter). In ciphering, the i-th letter from the beginning of the alphabet is exchanged for the i-th letter from the end of the alphabet, i.e. A is changed to Z, Z to A, C to X, X to C etc.

Use the function to cipher a message read from the user, and then decipher it back.


Authors: Michał Fularz, Dominik Pieczyński, Tomasz Mańkowski, Jakub Tomczyński