Skip to content
Educora
Intermediate18 min4 / 10

Functions

Write your own functions: return values, parameters, prototypes, overloading, default arguments, and passing by value or by reference.

Check yourself
In this lesson you will learn
  • Write a function with a return type, parameters and return, and call it
  • Overload functions and use default arguments
  • Explain the difference between passing by value and by reference
  • Pass large objects by const reference

Imagine that your game calculates the distance between two characters in ten places, and each time you copy the same three lines. If you find a mistake in the formula, you will have to fix it in ten places! Functions solve this problem: you write the code once, give it a name and call it as often as you need. You already know one function — main.

Defining and calling a function

In C++ a function definition has four parts: the return type, the name, the parameters in parentheses and the body in curly braces. return sends the result back to where the function was called. A function that returns nothing has the type void.

C++
#include <iostream>
#include <string>

int square(int x) {
    return x * x;
}

void greet(std::string name) {
    std::cout << "Hello, " << name << "!\n";
}

int main() {
    greet("Leyla");
    int s = square(7);
    std::cout << "7 squared is " << s << '\n';
    std::cout << square(3) + square(4) << '\n';
    return 0;
}
Expected output
Hello, Leyla!
7 squared is 49
25
Definition
Parameter and argument

A parameter is the variable written in the function definition (int x). An argument is the actual value passed to it in a call (7 in square(7)).

The compiler reads the file from top to bottom, so a function must at least be declared before it is called. If you want to write the function after main, put its prototype — the header without a body — at the top:

C++
#include <iostream>

int cube(int x);   // declaration (prototype)

int main() {
    std::cout << cube(3) << '\n';
    return 0;
}

int cube(int x) {  // definition
    return x * x * x;
}
Expected output
27

Function overloading

In C++ several functions can share the same name, as long as the number or the types of their parameters differ. This is called overloading. The compiler looks at the arguments in the call and picks the matching version itself. The expression a > b ? a : b in the example is the ternary operator: it means “if the condition is true, a, otherwise b”.

C++
#include <iostream>

int maxOf(int a, int b) {
    return a > b ? a : b;
}

double maxOf(double a, double b) {
    return a > b ? a : b;
}

int maxOf(int a, int b, int c) {
    return maxOf(maxOf(a, b), c);
}

int main() {
    std::cout << maxOf(3, 8) << '\n';
    std::cout << maxOf(2.5, 1.5) << '\n';
    std::cout << maxOf(4, 9, 6) << '\n';
    return 0;
}
Expected output
8
2.5
9

Default arguments

A parameter can have a default value: if the argument is left out in a call, this value is used. The rule is that parameters with default values must come at the end of the list.

C++
#include <iostream>
#include <string>

void printPrice(std::string item, int price, std::string currency = "AZN") {
    std::cout << item << ": " << price << ' ' << currency << '\n';
}

int main() {
    printPrice("Book", 12);
    printPrice("Headphones", 40, "USD");
    return 0;
}
Expected output
Book: 12 AZN
Headphones: 40 USD

Passing by value and by reference

By default C++ passes a copy of the argument: even if the function changes its parameter, the caller's variable stays untouched. If you write & after the parameter type, the parameter becomes a reference — another name for the original variable. Then the function's changes affect the original too.

C++
#include <iostream>

void addBonusCopy(int points) {
    points += 10;
}

void addBonus(int& points) {
    points += 10;
}

int main() {
    int score = 50;
    addBonusCopy(score);
    std::cout << "After copy: " << score << '\n';
    addBonus(score);
    std::cout << "After reference: " << score << '\n';
    return 0;
}
Expected output
After copy: 50
After reference: 60

References are especially useful in two cases: when a function must change several variables (for example, swap two values) and when it must read a large object without copying it. In the second case we write const std::string&: no copy is made, and the function cannot change the text.

C++
#include <iostream>
#include <string>

void swapValues(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

void printBanner(const std::string& text) {
    std::cout << "*** " << text << " ***\n";
}

int main() {
    int x = 3;
    int y = 8;
    swapValues(x, y);
    std::cout << "x = " << x << ", y = " << y << '\n';
    printBanner("Game over");
    return 0;
}
Expected output
x = 8, y = 3
*** Game over ***
MethodSyntaxCan the original change?When to use
by valueint xnosmall types: int, double, char
by referenceint& xyesthe function must change the variable
by const referenceconst std::string& snolarge objects that are only read

Key points

  • A function is defined as type name(parameters) { ... }; void returns nothing.
  • A function must be declared before it is called — write a prototype if needed.
  • Overloading means functions with the same name but different parameters; the compiler picks the right one.
  • Parameters with default values go at the end of the list.
  • Passing by value makes a copy, & works with the original, and const & reads safely without copying.

Check yourself

10 questions. Every correct answer earns XP.

1 / 10
What is the return type of a function that returns nothing?