Skip to content

Functions

A function is a named block of code that performs a specific task. Instead of repeating the same lines everywhere, you write the logic once and call it when needed.

int add(int a, int b) {
return a + b;
}
int main() {
int total = add(3, 5); // total is 8
return 0;
}

Before using classes (OOP), master functions: a class method is a function that belongs to an object.

BenefitExplanation
Reuse codeWrite logic once, use it in many places
ReadabilitycalculateAverage(grades) is clearer than 20 scattered lines
Divide the problemEach function handles one part: read, validate, compute, print
Easier debuggingIf the average fails, inspect only that function
Prepare for OOPA method is a function tied to an object

General form:

return_type name(type param1, type param2, ...) {
// body: statements
return value; // optional if return_type is not void
}

Broken-down example:

double calculateArea(double base, double height) {
double area = base * height / 2.0;
return area;
}
PartIn the exampleMeaning
Return typedoubleWhat type the function returns
NamecalculateAreaHow you identify it when calling
Parametersdouble base, double heightInput data
Body{ ... }What the function does
returnreturn area;Returns a value and exits

Calling a function means running its code with the arguments it needs:

#include <iostream>
void greet(std::string name) {
std::cout << "Hello, " << name << std::endl;
}
int main() {
greet("Ana");
greet("Carlos");
return 0;
}

Basic rules:

  • The call name must match the function name.
  • Arguments ("Ana") bind to parameters (name) in the same order.
  • If the function returns a value, store it in a variable or use it in an expression.
int square(int x) {
return x * x;
}
int main() {
int r = square(4); // r = 16
std::cout << square(5); // prints 25
return 0;
}

When the function only performs an action (print, write a file, modify by reference) and you do not need a return value, use void:

void showMenu() {
std::cout << "1. Add product\n";
std::cout << "2. Search product\n";
std::cout << "3. Exit\n";
}

Do not return a value from a void function. You may use bare return; to exit early if needed.

By default, C++ copies the argument into the parameter. The function works on the copy; the original is unchanged:

void increment(int n) {
n = n + 1; // only changes the local copy
}
int main() {
int x = 10;
increment(x);
std::cout << x; // still 10
return 0;
}

Useful when the function should not modify the original variable.

To let the function modify the original variable, pass by reference with &:

void increment(int& n) {
n = n + 1;
}
int main() {
int x = 10;
increment(x);
std::cout << x; // now 11
return 0;
}

References also avoid copying large data (arrays, long std::string). When you only read the data, combine with const (next section).

For heavy types or read-only access:

#include <string>
void printName(const std::string& name) {
std::cout << name << std::endl;
// name = "other"; // ERROR: cannot modify
}

Good practice: for std::string, structs, and arrays you only read, use const Type&.

Quick summary:

FormCan modify originalCopies data
Type paramNoYes
Type& paramYesNo
const Type& paramNoNo

You can give a parameter a default; if omitted at the call site, the default is used:

void printLine(std::string text, int times = 1) {
for (int i = 0; i < times; i++) {
std::cout << text << std::endl;
}
}
int main() {
printLine("Hello");
printLine("Hello", 3);
return 0;
}

Parameters with defaults must come at the end of the parameter list.

In multi-file projects (see Basic syntax) you separate:

  • Declaration (prototype): tells the compiler the function exists and its signature.
  • Definition: contains the actual body.

include/greet.h — declaration:

#ifndef GREET_H
#define GREET_H
#include <string>
void greet(const std::string& name);
int add(int a, int b);
#endif

src/greet.cpp — definition:

#include "greet.h"
#include <iostream>
void greet(const std::string& name) {
std::cout << "Hello, " << name << std::endl;
}
int add(int a, int b) {
return a + b;
}

src/main.cpp — usage:

#include "greet.h"
int main() {
greet("UNEXPO");
return add(2, 3);
}

The compiler must see the declaration before each call. That is why you #include the .h where you use the function.

Variables declared inside a function are local: they exist only while that function runs.

int global = 100;
void example() {
int local = 5;
std::cout << global << std::endl;
std::cout << local << std::endl;
}
int main() {
example();
// std::cout << local; // ERROR: local does not exist here
return 0;
}

In coursework, prefer passing data via parameters over many global variables.

return sends back a value and ends the function immediately:

int absolute(int n) {
if (n < 0) {
return -n;
}
return n;
}

Every code path in a non-void function must reach a return.

To return multiple values early in the course:

  1. Return a struct with several fields.
  2. Use reference parameters for output.
struct Result {
int quotient;
int remainder;
};
Result divide(int a, int b) {
Result r;
r.quotient = a / b;
r.remainder = a % b;
return r;
}

Small program showing separation of concerns:

#include <iostream>
bool isPositive(int n) {
return n > 0;
}
double average(double a, double b) {
return (a + b) / 2.0;
}
void showResult(double value) {
std::cout << "Average: " << value << std::endl;
}
int main() {
double n1, n2;
std::cout << "Grade 1: ";
std::cin >> n1;
std::cout << "Grade 2: ";
std::cin >> n2;
if (isPositive(static_cast<int>(n1)) && isPositive(static_cast<int>(n2))) {
showResult(average(n1, n2));
} else {
std::cout << "Grades must be positive.\n";
}
return 0;
}

Each function has one clear responsibility: validate, compute, or display.

MistakeWhat happensHow to avoid
Forgetting return in non-void functionUndefined behavior or compile errorEnsure return on every path
Mixing declaration and definition“undefined reference” at link timeDeclare in .h, define in .cpp
Expecting pass-by-value to change the originalOriginal unchangedUse reference & when needed
Default params not at the endCompile errorPut defaults last
Call before declaration“was not declared in this scope”Prototype above or #include header
  • In OOP, functions inside a class are methods and usually operate on the object’s attributes.
  • In assigned exercises, split logic into functions: read data, search an array, sort, write files, etc.
  • The cryptogram exercise requires OOP: logic goes in class methods, but the base idea is the same as functions with parameters and return values.
ConceptRemember
FunctionNamed block that encapsulates a task
ParameterFormal variable the function receives
ArgumentConcrete value you pass when calling
returnReturns a value and exits the function
voidFunction with no return value
By valueCopy; does not modify original
By reference &Can modify original
const &Efficient read-only access
PrototypeDeclaration in .h; definition in .cpp