This article presents 18 C++ Function Exercises designed to test and build your skills across the entire spectrum of function-related topics.
Each exercise includes a clear problem statement, a helpful hint, a complete C++ solution, and a detailed explanation. This ensures you not only solve the problem but deeply understand why the solution works.
What You Will Practice:
- Function Fundamentals & Parameters: Defining, calling, and understanding the difference between Pass by Value and Pass by Reference.
- Signatures & Overloading: Implementing Function Overloading and using Default Arguments for flexibility.
- Recursion: Writing recursive functions to solve classic problems like Factorial, Fibonacci, and GCD.
- Advanced Features: Utilizing Inline Functions, Function Pointers, and Function Templates for optimization and generic programming.
- Application & Modularity: Encapsulating complex logic (e.g., prime checks, input validation) and integrating with STL containers.
+ Table Of Contents
Table of contents
- Exercise 1: Add Two Numbers
- Exercise 2: Value Swap (No Effect)
- Exercise 3: Reference Swap (Effective)
- Exercise 4: Pass Array to Function
- Exercise 5: Modify Array Element
- Exercise 6: Function Overloading
- Exercise 7: Default Arguments
- Exercise 8: Recursive Function
- Exercise 9: Fibonacci Sequence
- Exercise 10: Inline Function
- Exercise 11: Function Pointer
- Exercise 12: Calculator using Function Pointers
- Exercise 13: Function Template (Max)
- Exercise 14: Function Template (Swap)
- Exercise 15: Pass by Constant Reference
- Exercise 16: Prime Check
- Exercise 17: Vector Sum
Exercise 1: Add Two Numbers
Problem Statement: Create a C++ function named add(int a, int b) that accepts two integers as arguments and returns their sum as an integer. Demonstrate its use by adding two numbers and printing the result in main.
Expected Output:
The sum of 15 and 27 is: 42
3 + 7 = 10
+ Hint
- The function signature should use the
intreturn type:int add(int a, int b). - Use the
returnkeyword to send the calculated sum back to the calling function.
+ Show Solution
#include <iostream>
// Function definition
int add(int a, int b) {
return a + b;
}
int main() {
int num1 = 15;
int num2 = 27;
// Function call and storing the returned value
int sum = add(num1, num2);
std::cout << "The sum of " << num1 << " and " << num2 << " is: " << sum << std::endl;
// Another way to call the function
std::cout << "3 + 7 = " << add(3, 7) << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
- This exercise demonstrates passing arguments to a function and using a non-void return type (
int). - The values of
num1(15) andnum2(27) are passed by value to the parametersaandb. - The function calculates the sum and uses
return sum;to send the result back to themainfunction, where it is stored in thesumvariable.
Exercise 2: Value Swap (No Effect)
Problem Statement: Write a function swap_value(int a, int b) that attempts to swap the values of its parameters (a and b) inside the function body. Call this function from main and print the original variables before and after the call to demonstrate that the swap does not affect the original variables in main.
Expected Output:
Before call: x = 10, y = 20
Inside swap_value function: a = 20, b = 10
After call: x = 10, y = 20
+ Hint
When primitive data types are passed, C++ uses pass by value, meaning a copy of the argument is made. The changes are only local to the function.
+ Show Solution
#include <iostream>
// Function definition using Pass by Value
void swap_value(int a, int b) {
int temp = a;
a = b;
b = temp;
std::cout << "Inside swap_value function: a = " << a << ", b = " << b << std::endl;
}
int main() {
int x = 10;
int y = 20;
std::cout << "Before call: x = " << x << ", y = " << y << std::endl;
swap_value(x, y); // x and y are passed by value (copied)
std::cout << "After call: x = " << x << ", y = " << y << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
This exercise is crucial for understanding Pass by Value. When swap_value(x, y) is called, the function receives copies of x (10) and y(20) into its local variables a and b.
The swap successfully happens to a and b inside the function, but the original variables x and y in main remain unchanged.
Exercise 3: Reference Swap (Effective)
Problem Statement: Write a function swap_reference(int &a, int &b) that successfully swaps the values of the two variables passed to it by using pass by reference. Print the original variables in main before and after the call to show the effect.
Expected Output:
Before call: x = 10, y = 20
Inside swap_reference function: a = 20, b = 10
After call: x = 20, y = 10
+ Hint
To use pass by reference, declare the parameters with an ampersand (&): int &a. This tells the compiler that the parameter is an alias for the original argument.
+ Show Solution
#include <iostream>
// Function definition using Pass by Reference
void swap_reference(int &a, int &b) {
int temp = a; // temp holds the value currently in x (10)
a = b; // x's value becomes y's value (20)
b = temp; // y's value becomes temp (10)
std::cout << "Inside swap_reference function: a = " << a << ", b = " << b << std::endl;
}
int main() {
int x = 10;
int y = 20;
std::cout << "Before call: x = " << x << ", y = " << y << std::endl;
swap_reference(x, y); // x and y are passed by reference (alias)
std::cout << "After call: x = " << x << ", y = " << y << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
This demonstrates Pass by Reference. By using int &a and int &b, the parameters a and b become aliases for the variables x and y in main.
Any operation performed on a and b is directly performed on x and y. Therefore, the swap operation successfully changes the values of the original variables in the calling function.
Exercise 4: Pass Array to Function
Problem Statement: Write a function print_array(int arr[], int size) that accepts an integer array and its size, then iterates through the array and prints all its elements, separated by a space.
Given:
int numbers[] = {10, 20, 30, 40, 50};Code language: C++ (cpp)
Expected Output:
Array elements: 10 20 30 40 50
+ Hint
- Arrays are inherently passed like pointers (effectively by reference) in C++.
- You must explicitly pass the array’s size as a separate argument because C++ array parameters decay into pointers, losing size information.
- Use a
forloop to iterate.
+ Show Solution
#include <iostream>
// Function definition
void print_array(int arr[], int size) {
std::cout << "Array elements: ";
for (int i = 0; i < size; ++i) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
int main() {
int numbers[] = {10, 20, 30, 40, 50};
int n = sizeof(numbers) / sizeof(numbers[0]); // Calculate size
print_array(numbers, n);
return 0;
}Code language: C++ (cpp)
Explanation:
This exercise demonstrates passing an array to a function.
- When an array is passed as a parameter (
int arr[]), it decays into a pointer to its first element. Therefore, its size is lost, and it must be passed separately (int size). - The function then uses the size and pointer arithmetic (via the array indexing
arr[i]) to iterate and access all elements.
Exercise 5: Modify Array Element
Problem Statement: Define a function set_to_zero(int arr[], int index) that takes an integer array and an index, and sets the element at the specified index of the array to 0.
Given:
int data[] = {1, 2, 3, 4, 5};Code language: C++ (cpp)
Expected Output:
Original Array: 1 2 3 4 5
Modified Array: 1 2 0 4 5
+ Hint
Since arrays are passed by reference/pointer, any modification made to the array inside the function will be permanent and visible outside the function. Use array indexing: arr[index] = 0;.
+ Show Solution
#include <iostream>
// Function definition
void set_to_zero(int arr[], int index) {
// Check for a basic valid index before modifying
if (index >= 0) {
arr[index] = 0;
}
}
int main() {
int data[] = {1, 2, 3, 4, 5};
int size = 5;
int target_index = 2; // We want to change the element '3'
std::cout << "Original Array: ";
for (int i = 0; i < size; ++i) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
set_to_zero(data, target_index);
std::cout << "Modified Array: ";
for (int i = 0; i < size; ++i) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
This exercise confirms the behavior seen in the previous exercise: when an array is passed, its contents can be modified within the function because the function operates directly on the memory location of the array elements. The function uses the provided index to specifically target and change a single element to 0.
Exercise 6: Function Overloading
Problem Statement: Implement Function Overloading by defining two functions named area.
- The first function,
area(double length, double width), should calculate and return the area of a rectangle. - The second function,
area(double side), should calculate and return the area of a squareside *side. Demonstrate that the C++ compiler can correctly choose between the two functions based on the number of arguments provided in the main function.
Expected Output:
Area of rectangle (10x5): 50
Area of square (7x7): 49
+ Hint
Function overloading is achieved by defining multiple functions with the same name but different parameter lists (either different number of parameters or different types).
+ Show Solution
#include <iostream>
// 1. Function for Rectangle (Two parameters)
double area(double length, double width) {
return length * width;
}
// 2. Overloaded Function for Square (One parameter)
double area(double side) {
return side * side;
}
int main() {
// Call 1: Rectangle area (uses the 2-parameter function)
double rect_area = area(10.0, 5.0);
std::cout << "Area of rectangle (10x5): " << rect_area << std::endl;
// Call 2: Square area (uses the 1-parameter function)
double sq_area = area(7.0);
std::cout << "Area of square (7x7): " << sq_area << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
- This exercise demonstrates Function Overloading. The C++ compiler determines which version of the
areafunction to call based on the number of arguments provided during the function call. - When two arguments are provided (
area(10.0, 5.0)), the two-parameter version is executed. - When one argument is provided (
area(7.0)), the single-parameter version is executed.
Exercise 7: Default Arguments
Problem Statement: Write a function power(double base, int exponent = 2) that calculates baseexponent. Use a default argument of 2 for the exponent. The function should calculate the square if the exponent is omitted during the call.
Expected Output:
7 raised to 3: 343
5 squared (default): 25
+ Hint
- Default arguments are assigned in the function prototype or definition (usually the prototype).
- Use the
std::powfunction from the<cmath>library for the calculation, or implement a simple loop
+ Show Solution
#include <iostream>
#include <cmath> // For std::pow
// Function definition with a default argument
double power(double base, int exponent = 2) {
// Note: C++ allows default arguments only once (in the declaration or definition).
return std::pow(base, exponent);
}
int main() {
// Call 1: Explicit exponent (7^3)
double result1 = power(7.0, 3);
std::cout << "7 raised to 3: " << result1 << std::endl; // Output: 343
// Call 2: Default exponent (5^2)
double result2 = power(5.0);
std::cout << "5 squared (default): " << result2 << std::endl; // Output: 25
return 0;
}Code language: C++ (cpp)
Explanation:
- This exercise demonstrates Default Arguments. By setting
exponent = 2in the parameter list, the compiler automatically substitutes2if the caller omits the second argument. - This makes the function more flexible and reduces the need for overloading in cases where one argument is frequently used.
Exercise 8: Recursive Function
Problem Statement: Write a recursive function factorial(int n) to calculate n! (n factorial). Recall that n! = n * (n-1) *...*1, and the base case is 0! = 1.
To find the factorial of a number, you multiply it by every positive integer smaller than it until you reach 1. For example, 5! =5×4×3×2×1=120
Expected Output:
5! is: 120
+ Hint
The recursive step is n! = n * (n-1)!. The base case, which stops the recursion, is when n=0
+ Show Solution
#include <iostream>
// Recursive function definition
long long factorial(int n) {
// Base Case: stops the recursion
if (n == 0) {
return 1;
}
// Recursive Step: calls itself with a smaller input
return n * factorial(n - 1);
}
int main() {
int number = 5;
long long result = factorial(number);
std::cout << number << "! is: " << result << std::endl; // Output: 120
return 0;
}Code language: C++ (cpp)
Explanation:
- This is a classic example of Recursion, where a function calls itself.
- Every recursive function must have a base case (
if (n == 0)) to prevent infinite calls, and a recursive step (n * factorial(n - 1)) that moves the input closer to the base case. - The function breaks the problem (finding 5!) into a smaller problem (finding 4!) until it reaches the solvable base case (0!).
Exercise 9: Fibonacci Sequence
Problem Statement: Write a recursive function fibonacci(int n) that returns the n-th number in the Fibonacci sequence. The sequence starts 0, 1, 1, 2, 3, 5, 8, …, where F(0) equals 0, F(1) equals 1, and F(n) equals F(n-1) + F(n-2) for n greater than 1.
Expected Output:
The 8th Fibonacci number is: 21
+ Hint
- The recursive function requires two base cases to stop the recursion: when n equals 0, return 0; and when n equals 1, return 1.
- For all other cases, the function should recursively call itself with inputs n-1 and n-2 and sum the results.
+ Show Solution
#include <iostream>
// Recursive function definition
int fibonacci(int n) {
// Base Case 1
if (n == 0) {
return 0;
}
// Base Case 2
if (n == 1) {
return 1;
}
// Recursive Step
return fibonacci(n - 1) + fibonacci(n - 2);
}
int main() {
int index = 8;
int result = fibonacci(index);
// F(8) is 21
std::cout << "The " << index << "th Fibonacci number is: " << result << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
- The two base cases (n=0 and n=1) are crucial as they provide the starting values and prevent infinite calls.
- The recursive step breaks the original problem into two smaller, identical sub-problems (finding the preceding two numbers), and the process continues until all branches hit a base case.
Exercise 10: Inline Function
Problem Statement: Convert a simple addition function that takes two integers and returns their sum into an inline function.
Expected Output:
x:15 y:5
Inline add result: 20
+ Hint
- The
inlinekeyword is a request to the compiler to substitute the function call with the function body at the call site. - Place the
inlinekeyword before the function’s return type in the definition
+ Show Solution
#include <iostream>
// Function defined as inline
inline int add(int a, int b) {
return a + b;
}
int main() {
int x = 15;
int y = 5;
std::cout << "x:" << x <<" y:" <<y << std::endl;
// The compiler is requested to replace this call with the function body.
int result = add(x, y);
std::cout << "Inline add result: " << result << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
- The
inlinekeyword suggests that the compiler perform function substitution (or “inlining”) at the call site rather than generating a normal function call. - This avoids the overhead associated with function calls, which can improve performance for small, frequently called functions.
Exercise 11: Function Pointer
Problem Statement: Create a function pointer that points to a simple function, for example, a function that returns the larger of two integers. Use the function pointer to call the target function and print the result.
Expected Output:
Using function pointer, max of 45 and 90 is: 90
+ Hint
The function pointer declaration must match the target function’s signature: return_type (*pointer_name)(parameter_list).
+ Show Solution
#include <iostream>
// Target function
int max_of_two(int a, int b) {
return (a > b) ? a : b;
}
int main() {
// Declaration and initialization of a function pointer
int (*ptr_max)(int, int) = max_of_two;
int x = 45;
int y = 90;
// Calling the function using the pointer
int result = ptr_max(x, y);
std::cout << "Using function pointer, max of " << x << " and " << y << " is: " << result << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
A function pointer stores the memory address of a function, allowing the function to be called indirectly. The declaration defines the pointer as pointing to a function taking two integers and returning an integer.
Exercise 12: Calculator using Function Pointers
Problem Statement: Write a function execute_operation(int a, int b, int (*operation)(int, int)) that takes two numbers and a function pointer. The function should execute the pointed-to function (like add or subtract) using a and b and return the result. Define separate add and subtract functions to pass to it.
Expected Output:
Addition result (10 + 3): 13
Subtraction result (10 - 3): 7
+ Hint
This exercise uses a function pointer as a parameter, allowing the calling function to select the behavior of the called function dynamically.
+ Show Solution
#include <iostream>
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
// Function that accepts a function pointer as an argument
int execute_operation(int a, int b, int (*operation)(int, int)) {
return operation(a, b);
}
int main() {
int num1 = 10;
int num2 = 3;
// Pass the 'add' function's address
int sum = execute_operation(num1, num2, add);
std::cout << "Addition result (10 + 3): " << sum << std::endl;
// Pass the 'subtract' function's address
int difference = execute_operation(num1, num2, subtract);
std::cout << "Subtraction result (10 - 3): " << difference << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
This exercise demonstrates passing a function pointer as a parameter. The function’s behavior is determined entirely by the function passed to it, which is the basis for implementing callback mechanisms.
Exercise 13: Function Template (Max)
Problem Statement: Write a function template max_value that can find and return the maximum of two values of any data type (e.g., int, double, or char) that supports the greater-than operator (>).
Expected Output:
a = 5, b = 10 Max int: 10
a = 3.14 b = 2.71 Max double: 3.14
a = "z" b= "a" Max char: z
+ Hint
Begin the template definition with template <typename T>. Use T as the placeholder type for the function’s parameters and return value.
+ Show Solution
#include <iostream>
#include <string>
// Function Template definition
template <typename T>
T max_value(T a, T b) {
return (a > b) ? a : b;
}
int main() {
// 1. Using with integers
std::cout << "Max int: " << max_value(5, 10) << std::endl;
// 2. Using with doubles
std::cout << "Max double: " << max_value(3.14, 2.71) << std::endl;
// 3. Using with characters
std::cout << "Max char: " << max_value('z', 'a') << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
- A Function Template defines a generic function that can operate on different data types without being rewritten for each type.
- The compiler generates specific versions of the function at compile time, a concept known as generic programming.
Exercise 14: Function Template (Swap)
Problem Statement: Create a function template swap_generic that can successfully swap the values of any two variables of the same data type using pass by reference.
Expected Output:
After swap (int): x = 200, y = 100
After swap (double): d1 = 9.9, d2 = 5.5
+ Hint
The template parameters must be passed by reference (T&) for the swap to affect the original variables.
+ Show Solution
#include <iostream>
// Function Template definition
template <typename T>
void swap_generic(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
int main() {
int x = 100;
int y = 200;
double d1 = 5.5;
double d2 = 9.9;
swap_generic(x, y); // Swapping integers
swap_generic(d1, d2); // Swapping doubles
std::cout << "After swap (int): x = " << x << ", y = " << y << std::endl;
std::cout << "After swap (double): d1 = " << d1 << ", d2 = " << d2 << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
This template combines generic programming with pass by reference. By using T& for the parameters, the function can swap any two variables of type T, avoiding code duplication while maintaining efficiency.
Exercise 15: Pass by Constant Reference
Problem Statement: Write a function print_string(const std::string &s) that takes a string object by constant reference. Inside the function, print the string. The purpose is to avoid copying the string and prevent its modification.
Expected Output:
String value (read-only): This is a long message.
Original string remains: This is a long message.
+ Hint
Using const & (constant reference) is the preferred way to pass large objects (like strings or vectors) to a function when you only need to read them, as it avoids the performance cost of copying the object.
+ Show Solution
#include <iostream>
#include <string>
// Function definition using constant reference
void print_string(const std::string &s) {
std::cout << "String value (read-only): " << s << std::endl;
// This line would cause a compile-time error:
// s = "Attempted modification";
}
int main() {
std::string message = "This is a long message.";
print_string(message);
std::cout << "Original string remains: " << message << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
Pass by Constant Reference (const T&) is an optimization. The use of & avoids creating a full copy of the large string object. The use of const guarantees that the function cannot modify the original object, maintaining data integrity.
Exercise 16: Prime Check
Problem Statement: Write a function is_prime(int n) that returns true if n is a prime number (only divisible by 1 and itself, n is greater than 1), and false otherwise. Use this function in your main function to print all prime numbers between 1 and 20.
Expected Output:
Prime numbers between 1 and 20:
2 3 5 7 11 13 17 19
+ Hint
- To check for primality, loop from 2 up to the square root of n. If n is divisible by any number in that range, it is not prime.
- Handle the cases n less than or equal to 1 separately.
+ Show Solution
#include <iostream>
#include <cmath>
bool is_prime(int n) {
if (n <= 1) return false;
// Check divisibility up to the square root of n
for (int i = 2; i <= std::sqrt(n); ++i) {
if (n % i == 0) {
return false;
}
}
return true;
}
int main() {
std::cout << "Prime numbers between 1 and 20:" << std::endl;
for (int i = 1; i <= 20; ++i) {
if (is_prime(i)) {
std::cout << i << " ";
}
}
std::cout << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
This exercise emphasizes function modularity. The complex primality logic is encapsulated within is_prime, allowing the main function to remain clean and readable, focused only on the loop and output
Exercise 17: Vector Sum
Problem Statement: Write a function sum_vector(const std::vector<int> &vec) that takes a reference to a constant vector of integers and returns the sum of all its elements.
Expected Output:
The sum of the vector elements is: 100
+ Hint
You must include the <vector> library. Use a loop to iterate through the vector elements and accumulate the sum. Pass by const std::vector<int> & for efficiency and safety.
+ Show Solution
#include <iostream>
#include <vector>
// Function definition: takes const reference
int sum_vector(const std::vector<int> &vec) {
int total = 0;
// Range-based for loop for easy iteration
for (int element : vec) {
total += element;
}
return total;
}
int main() {
std::vector<int> data = {10, 20, 30, 40};
int total_sum = sum_vector(data); // Expected sum: 100
std::cout << "The sum of the vector elements is: " << total_sum << std::endl;
return 0;
}Code language: C++ (cpp)
Explanation:
This exercise applies function concepts to the Standard Template Library (STL). By using const reference (const std::vector<int> &), we achieve efficiency (no vector copy) and safety (the function cannot modify the original vector).

Leave a Reply