Shiklo Tools
PDF40
Image20
Calculators & Converters25
Text & Writing13
Developer26
Video14
Audio14
Document14
Data & Spreadsheet12
Web & SEO9
OCR & Scanning5
Archive & File12
Security & Privacy23
Health & Medical29
QR & Barcode5

C++ Function Parameters

How a parameter is declared decides whether the function gets a copy, can change the caller's variable, or reads it without copying. Choosing well makes programs both correct and fast.

Three ways to pass

ParameterThe function getsUse it for
int xa copysmall values (numbers, characters)
int& xthe caller's variablevalues the function must change
const std::string& sthe original, read-onlybig values the function only reads
#include <iostream>
#include <string>

void byValue(int n) { n = 100; }
void byReference(int& n) { n = 100; }
void show(const std::string& text) { std::cout << text << " (" << text.size() << ")\n"; }

int main() {
    int a = 5, b = 5;
    byValue(a);
    byReference(b);
    std::cout << "a = " << a << ", b = " << b << "\n";
    show("passed without copying");
    return 0;
}
Output
a = 5, b = 100
passed without copying (22)

Default arguments

A parameter can have a default value, used when the call leaves it out. Defaults must come at the end of the parameter list.

#include <iostream>
#include <string>

void greet(const std::string& name, const std::string& greeting = "Hello", int times = 1) {
    for (int i = 0; i < times; i++) {
        std::cout << greeting << ", " << name << "!\n";
    }
}

int main() {
    greet("Asha");
    greet("Ravi", "Welcome");
    greet("Kiran", "Hi", 2);
    return 0;
}
Output
Hello, Asha!
Welcome, Ravi!
Hi, Kiran!
Hi, Kiran!

Returning several values

A function returns one value, but that value can be a struct, or a std::pair for two results. Structured bindings (auto [a, b] = ...) unpack it neatly:

#include <iostream>
#include <utility>
#include <vector>

struct Stats {
    int min, max;
    double average;
};

Stats analyse(const std::vector<int>& v) {
    Stats s{v[0], v[0], 0};
    double sum = 0;
    for (int x : v) {
        if (x < s.min) s.min = x;
        if (x > s.max) s.max = x;
        sum += x;
    }
    s.average = sum / v.size();
    return s;
}

std::pair<int, int> divide(int a, int b) {
    return {a / b, a % b};
}

int main() {
    auto [lo, hi, avg] = analyse({7, 2, 9, 4});
    std::cout << lo << " " << hi << " " << avg << "\n";
    auto [q, r] = divide(17, 5);
    std::cout << "17 / 5 = " << q << " remainder " << r << "\n";
    return 0;
}
Output
2 9 5.5
17 / 5 = 3 remainder 2

Returning a struct is usually clearer than output parameters (references the function fills in), because the call shows what comes back.

A simple rule

For parameters the function only reads: pass numbers, characters and bool by value, and everything bigger (std::string, std::vector, your own classes) **by const&. For parameters the function must change, pass by &**. Following this rule gives correct and fast code in nearly every case.

Practice exercises

  1. Write void scale(std::vector<double>& v, double factor = 2.0) and call it with and without the factor.
  2. Write a function that returns the number of vowels and consonants in a string as a std::pair.
  3. Pass a big vector by value and by const& and explain which is better and why.