C++ Functions and Modular Programming, CSE – Study Notes
offline

Difficulty: Intermediate | Prerequisites: C++ variables, data types, operators, loops, conditional statements.

TL;DR

Functions let you break a C++ programme into smaller, reusable pieces, each responsible for one task. You pass data in through parameters, get results back through return values, and choose whether changes inside the function affect the original data (pass by reference) or a copy of it (pass by value). Understanding function prototypes, scope, overloading, and default arguments rounds out the toolkit you need for writing clean, modular code.

Key Terms

Modular programming

The practice of dividing a programme into separate, self-contained functions, each handling a distinct task. Improves readability, reusability, and debugging.

Think of it as: building with LEGO bricks instead of carving from a single block.

Function definition

The block of code that contains the function's actual statements, its return type, its name, and its parameter list.

In simple terms, this means: the full implementation of what the function does.

Function prototype (declaration)

A statement that declares a function's return type, name, and parameter types before the function is defined. Allows the compiler to recognise calls to the function that appear before its definition in the source file.

Think of it as: a preview or promise that tells the compiler "this function exists and looks like this."

Function call

The expression that invokes a function, causing the programme to jump to the function body, execute it, and return.

In simple terms, this means: telling the function to run.

Parameter (formal parameter)

A variable declared in a function's header that acts as a placeholder for incoming data.

Think of it as: an empty slot in the function's definition, waiting to be filled by an argument.

Argument (actual parameter)

The specific value or variable passed to a function when it is called.

Think of it as: the concrete data you hand to the function to work with.

Return value

The value a function sends back to the caller using the return statement. Must match the function's declared return type.

In simple terms, this means: the answer the function gives back after it finishes its work.

Void function

A function with a return type of void, meaning it performs an action but does not return a value to the caller.

Think of it as: a function that does something (prints output, writes to a file) but has no answer to hand back.

Local variable

A variable declared inside a function. It exists only while the function is executing and is not visible to other functions.

In simple terms, this means: the variable is private to that function.

Global variable

A variable declared outside all functions, accessible from anywhere in the programme. Best practice is to minimise their use to avoid unintended side effects.

Think of it as: a shared notice board that any function can read or change, which is risky.

Static local variable

A local variable declared with the static keyword. It retains its value between function calls rather than being reinitialised each time.

Think of it as: a local variable with a memory. It remembers its value from the last call.

Pass by value

A parameter-passing method where the function receives a copy of the argument. Changes inside the function do not affect the original variable.

In simple terms, this means: the function works on a photocopy, not the original.

Pass by reference

A parameter-passing method where the function receives the address of the original variable (using the & symbol). Changes inside the function affect the original.

In simple terms, this means: the function works directly on the original.

Default argument

A value specified in a function's prototype or definition that is used automatically if no argument is provided for that parameter in the call.

Think of it as: a fallback value so the caller does not have to supply every argument every time.

Function overloading

Defining multiple functions with the same name but different parameter lists (different number or types of parameters). The compiler selects the correct version based on the arguments provided.

In simple terms, this means: one function name, several versions that handle different types of data.

Driver (in testing)

A module or small programme written to test another module by calling its functions with known inputs.

Think of it as: a test harness that exercises the function you are developing.

Stub (in testing)

A dummy function that stands in for a real function during early development. It typically returns a fixed value or prints a message to confirm it was called.

Think of it as: a placeholder that lets you test the rest of your programme before the real function is ready.

exit() function

A function from that terminates the entire programme immediately, regardless of where execution currently is.

Think of it as: an emergency stop button for the programme.

Core Content

Modular Programming

  • Breaking a programme into distinct functions, each responsible for a single task

  • Benefits: improved readability, easier debugging, code reuse across projects

  • The main() function calls other functions to perform operations; those functions can call further functions in turn

Function Definition and Prototype

  • A function definition contains the return type, name, parameter list, and the body (the code that runs)

  • A function prototype declares the function's signature before the compiler encounters the full definition, allowing forward references

  • Prototypes specify parameter data types but do not require parameter names

  • Example:

void display(); // prototype

void display() { // definition
    cout << "Display function" << endl;
}

Function Execution Flow

  • Functions run only when explicitly called; defining a function does not execute it

  • When a function is called, control transfers to the function body, executes it, then returns to the point just after the call

  • Example:

void greet() {
    cout << "Hello!" << endl;
}

int main() {
    greet(); // control jumps to greet(), then returns here
    return 0;
}

Parameters and Return Values

  • Parameters are placeholders in the function header; arguments are the actual values supplied at the call site

  • A function can accept zero to many parameters

  • A function can return zero or one value (zero if void)

  • Function headers specify both data types and parameter names; prototypes require only data types

  • Example:

int add(int a, int b) {
    return a + b;
}

int sum = add(5, 10); // 5 and 10 are arguments

Void Functions

  • Return type is void: the function performs an action but sends no value back

  • Commonly used for output tasks such as printing messages or writing to files

  • A bare return; can be used inside a void function to exit early

Local and Global Variables

  • Local variables are declared inside a function and exist only during that function's execution. They are invisible to other functions.

  • Global variables are declared outside all functions and accessible throughout the programme.

  • Best practice: prefer local variables. Globals introduce hidden dependencies and make debugging harder.

Static Local Variables

  • Declared with the static keyword inside a function

  • Initialised only once (on the first call); the value persists between calls

  • Useful for counting how many times a function has been called, or for maintaining state without using a global

  • Example:

void counterFunction() {
    static int count = 0;
    count++;
    cout << "Count: " << count << endl;
}

Calling counterFunction() three times prints Count: 1, Count: 2, Count: 3.

Pass by Value vs Pass by Reference

  • Pass by value: the function receives a copy of the argument. Modifications inside the function have no effect on the caller's variable.

  • Pass by reference: the function receives the variable's address (using &). Modifications inside the function change the original.

  • Example:

void incrementByValue(int num) {
    num++; // only the copy changes
}

void incrementByReference(int& num) {
    num++; // the original changes
}

Default Arguments

  • A function can specify default values for one or more parameters

  • If the caller omits those arguments, the defaults are used

  • Default parameters must appear at the right end of the parameter list

  • Example:

void displayMessage(string msg = "Hello") {
    cout << msg << endl;
}

displayMessage();         // prints "Hello"
displayMessage("Hi");     // prints "Hi"

Function Overloading

  • Multiple functions can share the same name if they differ in their parameter lists (different number or types)

  • The compiler selects the correct version based on the arguments provided at the call site

  • Example:

int add(int a, int b);
double add(double a, double b);

Return Statement

  • Ends the function and optionally sends a value back to the caller

  • The returned value must match the function's declared return type

  • In void functions, return; (with no value) can be used for early exit

  • Example:

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

Boolean Functions

  • Return type is bool; the function returns true or false

  • Useful for conditions and decision-making logic

  • Example:

bool isEven(int num) {
    return (num % 2 == 0);
}

Programme Termination with exit()

  • exit() terminates the entire programme immediately, from any point in the code

  • Requires #include

  • exit(0) signals successful termination; non-zero values indicate an error

  • Use sparingly; normal programme flow through return statements is preferred

Drivers and Stubs in Testing

  • A driver is a test programme that calls the function under test with known inputs and checks the outputs

  • A stub is a placeholder function that returns a fixed value, letting you test the rest of the programme before the real function is written

  • Both are standard techniques for incremental testing during development

Common Misconceptions

  • Students often think a function definition also executes the function. It does not. A function runs only when it is called.

  • Students often assume pass by value and pass by reference behave the same way. With pass by value, the original variable is untouched. If your function is supposed to change the caller's variable and you forget the &, the change will silently not happen.

  • Students often place default argument values in the function definition instead of the prototype (or both). Default values should appear in the prototype (or the definition, if there is no separate prototype), but not in both places.

  • Students often think function overloading means the same function handles different types automatically. Each overloaded version is a distinct function; the compiler picks the one whose parameter list matches the arguments.

Why It Matters / Exam Flags

  • ⚠️ Trace-through questions involving pass by value vs pass by reference are extremely common. Be able to show the state of variables after each function call.

  • ⚠️ Know the difference between a parameter and an argument. Exams test the vocabulary.

  • ⚠️ Static local variables are a favourite for "what does this output?" questions involving multiple calls to the same function.

  • ⚠️ Function prototypes are often tested: can you call a function before its definition if a prototype exists? (Yes.)

  • ⚠️ Overloaded functions: be able to identify which version the compiler will call given specific arguments.

Quick Self-Test

  1. True or False: A void function can contain a return statement.

  1. Fill in the blank: A variable declared inside a function is called a ______ variable.

  1. True or False: Pass by reference uses the & symbol in the parameter list.

  1. Fill in the blank: When multiple functions share the same name but have different parameter lists, this is called function ______.

  1. True or False: A static local variable is reinitialised to its starting value every time the function is called.

Answers: 1. True (it can use return; to exit early, just not return a value). 2. Local. 3. True. 4. Overloading. 5. False (it retains its value between calls).

Practice Q&A

Q: What is the output of the following code?

void modify(int x) {
    x = x + 10;
}

int main() {
    int num = 5;
    modify(num);
    cout << num;
}

A: 5. The function receives a copy of num (pass by value). The original is unchanged.

Q: Rewrite the function above so that it changes the original variable.

A: Change the parameter to a reference: void modify(int& x) { x = x + 10; }. Now the original num becomes 15.

Q: What is the output if counterFunction() (with a static local count starting at 0) is called three times in a row?

A: Count: 1, Count: 2, Count: 3. The static variable retains its value between calls.

Q: Can a function prototype omit parameter names? Why?

A: Yes. The compiler needs only the parameter types to validate calls. Names are optional in prototypes (though they can improve readability).

Q: What happens if you call displayMessage() with no arguments when it is declared as void displayMessage(string msg = "Hello")?

A: It prints "Hello". The default argument fills in for the missing argument.

Connections to Other Topics

Functions are the bridge between loops and object-oriented programming. The loop patterns you learned (counters, accumulators, sentinel loops) are routinely wrapped inside functions so they can be reused and tested independently.

When you reach classes and OOP, member functions are simply functions that belong to a class. Everything about parameters, return values, and scope carries over directly.

Pass by reference becomes especially important with arrays and large objects, where copying would be expensive.

Related Terms / Search Tags

C++ functions, modular programming, function definition, function prototype, function declaration, function call, parameter, argument, formal parameter, actual parameter, return value, return type, void function, local variable, global variable, variable scope, lifetime, static local variable, pass by value, pass by reference, reference parameter, default argument, optional parameter, function overloading, polymorphism, return statement, bool function, boolean function, exit function, cstdlib, driver, stub, unit testing, incremental development