</>CodexBash
C++
C++Beginner11 min

Functions and references

Writing functions, passing by value, by reference and by const reference, default arguments, overloading, and returning several values with a pair.

How a function call returnsstep 1/6
main
in = main
The program starts in main. The stack holds one frame: main's own variables.

Writing a function#

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

void greet(const string &name) {
    cout << "Hello, " << name << "\n";
}

A function names its return type (void for none), its parameters and their types. Define it above where it is used, or declare it there first with a prototype: int square(int x);.

Three ways to pass an argument#

This is the most important thing to get right in C++ functions.

By value: a copy. Changes stay inside the function.

void addOne(int x) { x++; }          // the caller's variable is untouched

By reference: the original. Add &, and changes reach the caller.

void addOne(int &x) { x++; }

int n = 5;
addOne(n);       // n is now 6

By const reference: the original, read-only. No copy, and no changes allowed.

long long sum(const vector<int> &nums) {
    long long total = 0;
    for (int x : nums) total += x;
    return total;
}

The rule of thumb:

Parameter isWrite
a number, char or boolby value: int x
something to read, like a vector or stringby const reference: const vector<int> &v
something the function must changeby reference: vector<int> &v

Passing a vector by value copies every element. A helper called many times with a large vector by value can turn a fast solution into a slow one.

Default arguments#

int power(int base, int exponent = 2) {
    int result = 1;
    for (int i = 0; i < exponent; i++) result *= base;
    return result;
}

power(5);       // 25
power(2, 10);   // 1024

Overloading#

Two functions may share a name if their parameters differ:

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

The compiler picks the one that matches the arguments. The standard max and min already do this for you.

Returning two values#

A pair holds two values, and structured bindings unpack it:

pair<int, int> minMax(const vector<int> &v) {
    return {*min_element(v.begin(), v.end()), *max_element(v.begin(), v.end())};
}

auto [lo, hi] = minMax(nums);

For three or more, use tuple, or better, a small struct with named fields.

Recursion#

long long factorial(int n) {
    if (n <= 1) return 1;          // base case
    return n * factorial(n - 1);
}

Every recursive function needs a case it answers directly, or it calls itself until the program crashes.

Key points#

  • Pass small values by value, things you only read by const &, things you change by &.
  • Passing a vector by value copies all of it.
  • Defaults make parameters optional; overloading reuses a name for different types.
  • pair and auto [a, b] return and unpack two values.

Next: vectors, C++'s growable arrays.

Practise it

The same idea, in the order it is worth meeting it.

  1. Not startedHow many digitsEasy
  2. Not startedIs it a palindromeEasy
Create a free account to track your progress