# Functions

We’ve used functions in our code a lot so far: all of our code has been inside the “main” function, and we’ve also used a variety of functions when working with vectors and strings, such as `size()` and `pop_back()`. As you may see, functions are great because they allow us to to “give a name” to a certain set of code, making it easier to use that code repeatedly. For example, rather than needing to manually determine the size of a vector every time, we can just use the vector’s `size()` function, which contains all the code needed for getting its size.

Here, I’ll show you how to create and use your own functions, and I’ll go into more detail about how they actually work.

Let’s start with a very simple function (that you probably won’t ever need in a real program):

```#include <iostream>

double add(double num1, double num2) {
return num1 + num2;
}

int main() {
std::cout << add(4.1, 1.7) << "\n";
return 0;
}
```

In this program, “`add`” is a function with two inputs (“parameters”) of data type `double` (containing a decimal point): `num1` and `num2`. You can see that, when using the `add` function in line 8, we put two numbers (separated by a comma) in parentheses. Each of these numbers is an “argument” to the function, meaning that they act as the function’s inputs. These numbers correspond to the parameters for the `add` function, so 4.1 is `num1` and 1.7 is `num2`.

The `add` function also “returns” a value of data type `double` (indicated by the word `double` before the function name). This means that, when the function is actually used (in line 8), the value it takes on is whatever value the function returns. In the case of the `add` function, the value returned is equal to the sum of `num1` and `num2`. What’s returned is denoted by the use of the word `return` followed by whatever you want to return.

When running this program, you should see the value “5.8” printed to the screen because the `add` function adds `num1` (4.1) and `num2` (1.7) and returns that value.

Of course, creating a function for addition isn’t necessary since the code below will do the same thing, but this is just an example to get started.

```#include <iostream>

int main() {
std::cout << 4.1 + 1.7 << "\n";
return 0;
}
```

### Void

Functions don’t actually need to return a value. By using a return type of “`void`“, we can avoid the need for a return statement:

```#include <iostream>
#include <string>

void print(std::string text) {
std::cout << text << "\n";
}

int main() {
print("Hello world!");
return 0;
}
```

### Variable Scope

This is not specifically about functions, but it’s very important to start thinking about now: All variables in C++ follow specific “scoping” rules. Very generally, variables created within a set of curly braces cannot be used outside of those curly braces (excluding classes and structs, which we’ll get to later). For example, the code below will not compile:

```#include <iostream>

double add(double num1, double num2) {
double sum = num1 + num2;
return sum;
}

int main() {
std::cout << add(4.1, 1.7) << "\n";
std::cout << sum << "\n";
return 0;
}
```

Here, `sum` can only be used within the `add` function because it is created within the add function. The `sum` variable is considered to be a “local” variable because it is “local” to the `add` function. For completion, also be aware that function parameters (e.g. `num1` and `num2` above) cannot be used outside of their corresponding function.

These rules also apply to if statements and loops, so the code below won’t compile either:

```#include <iostream>

int main() {
int number = 10;
if (number > 5) {
int anotherNumber = 25;
}
else {
int anotherNumber = 20;
}
std::cout << anotherNumber << "\n";
return 0;
}
```

A solution to the issue with the code above would be to declare the `anotherNumber` variable outside of the if statement:

```#include <iostream>

int main() {
int number = 10;
int anotherNumber;
if (number > 5) {
anotherNumber = 25;
}
else {
anotherNumber = 20;
}
std::cout << anotherNumber << "\n";
return 0;
}
```

### Pass by Value

Arguments (inputs) passed to a function (like the string “Hello world!” above) are passed “by value” in C++. Let’s take a look at what that means.

```#include <iostream>

number += 5;
}

int main() {
int number = 4;
std::cout << "Number before adding 5: " << number << "\n";
std::cout << "Number after adding 5: " << number << "\n";
return 0;
}
```

(Note: Because of variable scope rules, the `number` variable in the `addFive` function is completely different from the `number` variable in the `main` function.)

If you run the code above, you’ll see that the “Number before adding 5” is the same as the “Number after adding 5.” That is, the `number` variable is not modified by the `addFive` function.

Why is this? It’s all because, when passing arguments to a function, the function first makes a copy of the argument and only uses that copy within the function. Here’s another example:

```#include <iostream>
#include <string>

void removeLastLetter(std::string str) {
str.pop_back();
}

int main() {
std::string hello = "Hello world!";
std::cout << "String before removing last letter: " << hello << "\n";
removeLastLetter(hello);
std::cout << "String after removing last letter: " << hello << "\n";
return 0;
}
```

Just like the last example, the string’s values before and after using the `removeLastLetter` function are equivalent because the `hello` variable itself is not actually modified by the `removeLastLetter` function. Only a copy of the variable is modified.

Later, when going over “pointers” in C++, you’ll see one way of working around this issue. Another is to just return the modified value from the function:

```#include <iostream>
#include <string>

std::string removeLastLetter(std::string str) {
str.pop_back();
return str;
}

int main() {
std::string hello = "Hello world!";
std::cout << "String before removing last letter: " << hello << "\n";
hello = removeLastLetter(hello);
std::cout << "String after removing last letter: " << hello << "\n";
return 0;
}
```

### Recursion

Functions in C++ are actually allowed to call themselves. This is what’s known as recursion.

One way of using recursion is for performing the factorial operation, which takes a number and multiplies it by each number smaller than it, down to 1. For example, 5! (5 factorial) = 5 * 4 * 3 * 2 * 1 = 120. Here’s how recursion can be used for this:

```#include <iostream>

int factorial(int number) {
if (number == 1) {
return 1;
}
return number * factorial(number - 1);
}

int main() {
std::cout << "4! = " << factorial(4) << "\n";
std::cout << "5! = " << factorial(5) << "\n";
return 0;
}
```

A good way to visualize this approach is with a tree:

`factorial(4)` is equal to 4 * `factorial(3)`, which is equal to 4 * 3 * `factorial(2)`, and so on…

One thing to be very careful of when using recursion is to ensure that there’s some way for the recursion to end. In the case of factorial, the recursive process ends when reaching a value of 1. You can see this in the code where just the number 1 is returned, as opposed to further evaluation of the factorial. Without doing this, the recursion would go on forever until your computer can recurse no longer.

It turns out that recursion is never the only way of solving a problem, so there’s always some solution to a problem just using loops. For many problems, however, recursion is the simplest way to go.

### Challenge Problem

Write a program containing a function called “`factorial`” that returns the factorial of a parameter without using recursion.

If you get stuck, check out my solution here.