Functions
Main idea
Section titled “Main idea”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.
Why use functions
Section titled “Why use functions”| Benefit | Explanation |
|---|---|
| Reuse code | Write logic once, use it in many places |
| Readability | calculateAverage(grades) is clearer than 20 scattered lines |
| Divide the problem | Each function handles one part: read, validate, compute, print |
| Easier debugging | If the average fails, inspect only that function |
| Prepare for OOP | A method is a function tied to an object |
Anatomy of a function
Section titled “Anatomy of a function”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;}| Part | In the example | Meaning |
|---|---|---|
| Return type | double | What type the function returns |
| Name | calculateArea | How you identify it when calling |
| Parameters | double base, double height | Input data |
| Body | { ... } | What the function does |
return | return area; | Returns a value and exits |
Calling (invoking) a function
Section titled “Calling (invoking) a function”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;}Functions that return nothing (void)
Section titled “Functions that return nothing (void)”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.
Parameters: pass by value
Section titled “Parameters: pass by value”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.
Parameters: pass by reference (&)
Section titled “Parameters: pass by reference (&)”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).
Parameters: const reference (const &)
Section titled “Parameters: const reference (const &)”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:
| Form | Can modify original | Copies data |
|---|---|---|
Type param | No | Yes |
Type& param | Yes | No |
const Type& param | No | No |
Default parameter values
Section titled “Default parameter values”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.
Declaration vs definition
Section titled “Declaration vs definition”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);
#endifsrc/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.
Variable scope
Section titled “Variable scope”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 and multiple outputs
Section titled “return and multiple outputs”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:
- Return a
structwith several fields. - 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;}Full example: validate and compute
Section titled “Full example: validate and compute”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.
Common mistakes
Section titled “Common mistakes”| Mistake | What happens | How to avoid |
|---|---|---|
Forgetting return in non-void function | Undefined behavior or compile error | Ensure return on every path |
| Mixing declaration and definition | “undefined reference” at link time | Declare in .h, define in .cpp |
| Expecting pass-by-value to change the original | Original unchanged | Use reference & when needed |
| Default params not at the end | Compile error | Put defaults last |
| Call before declaration | “was not declared in this scope” | Prototype above or #include header |
Relation to OOP and assignments
Section titled “Relation to OOP and assignments”- 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.
Summary
Section titled “Summary”| Concept | Remember |
|---|---|
| Function | Named block that encapsulates a task |
| Parameter | Formal variable the function receives |
| Argument | Concrete value you pass when calling |
return | Returns a value and exits the function |
void | Function with no return value |
| By value | Copy; does not modify original |
By reference & | Can modify original |
const & | Efficient read-only access |
| Prototype | Declaration in .h; definition in .cpp |
Next steps
Section titled “Next steps”- Organize multiple files with Files and compilation.
- Once comfortable with standalone functions, move to Classes and objects.
- For same-name functions with different parameters, see Overloading.