PYnative

Python Programming

  • Learn Python
    • Python Tutorials
    • Python Basics
    • Python Interview Q&As
  • Exercises
  • Quizzes
  • Code Editor
Home » CPP Exercises » C++ Pointers Exercises: Beginner to Advanced

C++ Pointers Exercises: Beginner to Advanced

Updated on: December 10, 2025 | Leave a Comment

Pointers are a fundamental and powerful concept in C++, essential for low-level memory management and efficient array and string manipulation.

This comprehensive article provides 30 C++ pointer exercises, designed to advance your skills from beginner fundamentals to advanced usage.

Each exercise provides a clear problem statement, a helpful hint, a complete C++ solution, and a detailed explanation, ensuring you not only solve the problem but deeply understand why the solution works

What You’ll Practice

The challenges cover the following core topics:

  • Pointers Fundamentals: Declaration, dereferencing (*), address-of (&), size comparison, and null safety (nullptr).
  • Pointer Arithmetic: Array traversal (ptr + N, ptr++) and accessing elements in arrays and C-style strings (char*).
  • Pointers and Functions: Pass-by-pointer (modifying external variables) and returning pointers.
  • Function Pointers: Using function pointers and typedef to implement the callback mechanism.
  • Dynamic Memory Management: Allocation (new, new[]), deallocation (delete, delete[]), and demonstrating memory leaks.
  • Advanced Syntax: Pointers to Structs (using ->), Constant Pointers (const positioning), and arrays of pointers.
+ Table Of Contents

Table of contents

  • Exercise 1: Declaration and Dereference
  • Exercise 2: Changing Value via Pointer
  • Exercise 3: Pointer-to-Pointer (Double Pointer)
  • Exercise 4: Pointer Arithmetic (Increment)
  • Exercise 5: Pointer Arithmetic (Index Access)
  • Exercise 6: Pointer Arithmetic on char Array
  • Exercise 7: NULL Pointer Check
  • Exercise 8: Simple Pass-by-Pointer Function
  • Exercise 9: Size Comparison
  • Exercise 10: Array Summation
  • Exercise 11: Reverse Array
  • Exercise 12: Finding Minimum
  • Exercise 13: 2D Array Traversal
  • Exercise 14: Copying an Array
  • Exercise 15: Comparing Arrays
  • Exercise 16: Sub-array Printing
  • Exercise 17: Pass-by-Pointer (Swap)
  • Exercise 18: Modifying String in Function
  • Exercise 19: Function Pointer Declaration
  • Exercise 20: Callback Function
  • Exercise 21: Pointer to Constant Data
  • Exercise 22: Constant Pointer
  • Exercise 23: Pointer to Struct
  • Exercise 24: Dynamic Allocation (Single Variable)
  • Exercise 25: Dynamic Allocation (Array)
  • Exercise 26: Array of Pointers
  • Exercise 27: Finding a Substring
  • Exercise 28: Memory Leak Demonstration
  • Exercise 29: Reallocation Simulation
  • Exercise 30: Linked List Node (Concept)

Exercise 1: Declaration and Dereference

Problem Statement: Declare an integer variable named value and initialize it to 100. Declare an integer pointer named ptr. Assign the memory address of value to ptr. Finally, print the integer stored in value by using only the pointer ptr and the dereference operator.

Expected Output:

The value is: 100
+ Hint
  • Use the address-of operator (ampersand: &) to get the memory location of the variable.
  • Use the dereference operator (asterisk: *) to access the data stored at the memory location held by the pointer.
+ Show Solution
#include <iostream>

int main() {
    int value = 100;
    int* ptr;

    // 1. Assign the address of 'value' to 'ptr'
    ptr = &value;

    // 2. Print the value using the pointer and dereference operator
    std::cout << "The value is: " << *ptr << std::endl; 

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The line int* ptr; declares a pointer variable named ptr that is designed to hold the memory address of an integer.
  • The line ptr = &value; uses the address-of operator (&) to load the actual memory address of value into the pointer ptr.
  • Finally, *ptr is the dereference operation, which follows the pointer’s address to retrieve the data (the integer 100) stored at that location.

Exercise 2: Changing Value via Pointer

Problem Statement: Declare an integer variable named number initialized to 50. Declare an integer pointer named num_ptr and make it point to number. Change the value of number to 99 using only the pointer num_ptr. Print the final value of the variable number.

Expected Output:

The final value of number is: 99
+ Hint

The dereference operator (*) can be used on the left side of an assignment operator (=) to modify the value that the pointer is currently pointing to.

+ Show Solution
#include <iostream>

int main() {
    int number = 50;
    int* num_ptr = &number;

    // Change the value of 'number' using only the pointer
    *num_ptr = 99;

    // Print the final value of the variable 'number'
    std::cout << "The final value of number is: " << number << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The statement int* num_ptr = &number; initializes the pointer to hold the address of number.
  • The key line is *num_ptr = 99;. The *num_ptr expression refers to the data at the address stored in num_ptr (which is the variable number). Assigning 99 to this expression directly modifies the content of the variable number itself.

Exercise 3: Pointer-to-Pointer (Double Pointer)

Problem Statement: Declare an integer variable x initialized to 42. Declare an integer pointer p1 that points to x. Declare a double integer pointer (pointer to a pointer) p2 that points to p1. Access and print the initial value of x using the double pointer p2.

Expected Output:

The value accessed via double pointer is: 42
+ Hint

A double pointer requires two asterisks (**) in its declaration. To access the final value, you will need to apply the dereference operator (*) twice

+ Show Solution
#include <iostream>

int main() {
    int x = 42;
    int* p1 = &x;       // p1 points to x
    int** p2 = &p1;     // p2 points to p1

    // Access the value of x using the double pointer p2
    std::cout << "The value accessed via double pointer is: " << **p2 << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The pointer p1 holds the address of x. The double pointer p2 holds the address of p1.
  • The expression *p2 dereferences p2, which results in the content of p1 (the address of x).
  • The expression **p2 then dereferences this result (the address of x), which finally gives us the integer value 42 stored in x.
  • This structure is used in more complex data structures or when implementing pass-by-reference for pointers.

Exercise 4: Pointer Arithmetic (Increment)

Problem Statement: Declare an integer array named data with the elements {10, 20, 30, 40, 50}. Declare an integer pointer data_ptr and point it to the first element of the array. Use pointer increment (ptr++) and the dereference operator to traverse the array and print all five elements.

Given:

int data[] = {10, 20, 30, 40, 50};Code language: C++ (cpp)

Expected Output:

Elements using pointer increment: 10 20 30 40 50
+ Hint
  • C++ knows the size of the underlying data type.
  • When you increment an integer pointer, it automatically moves to the next integer in memory by adding sizeof(int) bytes, which is exactly one element away in an array.
+ Show Solution
#include <iostream>

int main() {
    int data[] = {10, 20, 30, 40, 50};
    int size = sizeof(data) / sizeof(data[0]);

    // Initialize pointer to the start of the array
    int* data_ptr = data; 
    
    std::cout << "Elements using pointer increment: ";

    for (int i = 0; i < size; ++i) {
        // Print the value the pointer currently points to
        std::cout << *data_ptr << " "; 
        
        // Move the pointer to the next element
        data_ptr++;             
    }
    std::cout << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The line int* data_ptr = data; initializes the pointer to the base address of the array. Inside the loop, *data_ptr accesses the current element.
  • The key operation is data_ptr++. Since data_ptr is an integer pointer, this operation adds sizeof(int) bytes to the address, effectively moving the pointer to the memory address of the next integer element in the array.

Exercise 5: Pointer Arithmetic (Index Access)

Problem Statement: Declare an integer array named scores with elements {85, 90, 78, 95, 88}. Declare a pointer score_ptr and point it to the first element. Access and print the third element (which is 78) of the array using pointer arithmetic in the form *(ptr + N).

Given:

int scores[] = {85, 90, 78, 95, 88};Code language: C++ (cpp)

Expected Output:

The value of the third element is: 78
+ Hint
  • The third element is at index 2. To access it via pointer arithmetic, you must add 2 to the base pointer.
  • Remember that ptr + 2 calculates the address, and the dereference operator (*) retrieves the value at that address.
+ Show Solution
#include <iostream>

int main() {
    int scores[] = {85, 90, 78, 95, 88};
    
    // Pointer points to the first element (scores[0])
    int* score_ptr = scores; 

    // Access the third element (index 2) using pointer arithmetic
    int third_element = *(score_ptr + 2);

    std::cout << "The value of the third element is: " << third_element << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The expression score_ptr + 2 performs pointer arithmetic, calculating the address of scores[2] by adding two times the size of an integer to the base address.
  • The outer dereference operator (*) then retrieves the value (78) at that calculated memory address. This demonstrates that using scores[i] is functionally equivalent to using *(scores + i).

Exercise 6: Pointer Arithmetic on char Array

Problem Statement: Declare a char array word[] = "CODE". Declare a char pointer p pointing to the beginning of the array. Use pointer arithmetic (p + N) and the dereference operator to print the third character (‘D’) of the array.

Expected Output:

The third character is: D
+ Hint

The third character is at index 2. Pointer arithmetic for the third element is *(p + 2).

+ Show Solution
#include <iostream>

int main() {
    char word[] = "CODE";
    char* p = word; 

    // Access the third character (index 2)
    char third_char = *(p + 2);

    std::cout << "The third character is: " << third_char << std::endl;
    
    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This confirms that pointer arithmetic works the same way for char arrays as it does for int arrays.
  • Since char is typically 1 byte, p + 2 moves the pointer exactly two bytes forward to the memory location of the third character.

Exercise 7: NULL Pointer Check

Problem Statement: Declare an integer pointer named safe_ptr and initialize it to nullptr. Write a conditional statement to check if the pointer is null before attempting to dereference it. If it is null, print “Pointer is null, cannot dereference.” If it is not null, initialize a variable, assign its address to the pointer, and print the dereferenced value.

Expected Output:

Pointer is null, cannot dereference.
Pointer is now valid. Dereferenced value: 77
+ Hint

Always check if a pointer is not nullptr before using the dereference operator (*). Dereferencing a null pointer leads to undefined behavior, often a program crash.

+ Show Solution
#include <iostream>

int main() {
    int* safe_ptr = nullptr;

    if (safe_ptr == nullptr) {
        std::cout << "Pointer is null, cannot dereference." << std::endl;
        
        // Safely assign a valid address for the second check
        int valid_data = 77;
        safe_ptr = &valid_data;
    } 

    // Now, we can safely check again and dereference if assigned
    if (safe_ptr != nullptr) {
        std::cout << "Pointer is now valid. Dereferenced value: " << *safe_ptr << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The initialization int* safe_ptr = nullptr; explicitly sets the pointer to a known, invalid state. The first if statement checks this state using safe_ptr == nullptr.
  • This is a crucial safety check to prevent crashes. The second part demonstrates assigning a valid address (&valid_data) and then safely using the pointer only after verifying it’s no longer null.

Exercise 8: Simple Pass-by-Pointer Function

Problem Statement: Write a function named increment_value that takes an integer pointer as its only argument. Inside the function, increment the value that the pointer points to by 10. In main, call the function using the address of an integer variable and print the updated value.

Expected Output:

Before increment: 50
After increment: 60
+ Hint

The function signature should be void increment_value(int* ptr). To modify the value, use the expression *ptr += 10;.

+ Show Solution
#include <iostream>

// Function accepts a pointer and modifies the original value
void increment_value(int* ptr) {
    if (ptr != nullptr) {
        // Dereference the pointer to access and change the value
        *ptr += 10; 
    }
}

int main() {
    int counter = 50;

    std::cout << "Before increment: " << counter << std::endl;

    // Pass the address of 'counter'
    increment_value(&counter);

    std::cout << "After increment: " << counter << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This exercise is a basic demonstration of pass-by-pointer.
  • By passing the address (&counter), the function receives a pointer (ptr) that allows it to directly access and modify the original variable (counter) in the calling function’s memory space, which is impossible with standard pass-by-value.

Exercise 9: Size Comparison

Problem Statement: Declare an integer variable i and an integer pointer ptr. Use the sizeof() operator to print the size (in bytes) of the i variable and the size of the ptr pointer on your system. Note and discuss the difference between the two sizes.

Expected Output:

Size of an int variable: 4 bytes
Size of an int pointer (address): 8 bytes
+ Hint
  • The size of a variable depends on its data type (e.g., typically 4 bytes for an int).
  • The size of a pointer depends on the architecture of the system (e.g., 8 bytes for 64-bit systems), as it must be large enough to hold any memory address.
+ Show Solution
#include <iostream>

int main() {
    int i = 0;
    int* ptr = &i;

    std::cout << "Size of an int variable: " << sizeof(i) << " bytes" << std::endl;
    std::cout << "Size of an int pointer (address): " << sizeof(ptr) << " bytes" << std::endl;

    return 0;
}

/* Expected Output on a typical 64-bit system:
Size of an int variable: 4 bytes
Size of an int pointer (address): 8 bytes
*/Code language: C++ (cpp)
Run

Explanation:

  • The sizeof(i) reports the size required to store the actual integer data (usually 4 bytes).
  • The sizeof(ptr) reports the size required to store a memory address itself. This size is determined by the system’s architecture (32-bit or 64-bit).
  • The key takeaway is that the size of a pointer is constant regardless of the type it points to, because it only stores an address.

Exercise 10: Array Summation

Problem Statement: Write a program to calculate and print the sum of all elements in a given integer array {1, 5, 10, 15, 20} using only pointer arithmetic to access the elements. Do not use the array index operator ([]).

Expected Output:

The sum of array elements is: 51
+ Hint

Loop through the array. Inside the loop, access the element at index i using the expression *(array_name + i) and add it to a running total.

+ Show Solution
#include <iostream>

int main() {
    int arr[] = {1, 5, 10, 15, 20};
    int size = sizeof(arr) / sizeof(arr[0]);
    int sum = 0;

    // The array name 'arr' decays to a pointer to the first element
    int* arr_ptr = arr; 

    for (int i = 0; i < size; ++i) {
        // Access element using pointer arithmetic: *(arr_ptr + i)
        sum += *(arr_ptr + i); 
    }

    std::cout << "The sum of array elements is: " << sum << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The pointer arr_ptr holds the base address of the array. The expression arr_ptr + i performs scaled pointer arithmetic, calculating the memory address of the element at the current index i.
  • The dereference operator (*) then retrieves the integer value at that address, which is accumulated in sum. This explicitly demonstrates how pointers are used to traverse arrays in C++.

Exercise 11: Reverse Array

Problem Statement: Write a program to print the elements of an integer array {1, 2, 3, 4, 5} in reverse order using only pointer notation and arithmetic. You must not use the array index operator ([]).

Given:

int numbers[] = {1, 2, 3, 4, 5};Code language: C++ (cpp)

Expected Output:

Elements in reverse order: 5 4 3 2 1
+ Hint
  • Calculate the address of the last element first.
  • Use a while loop and the decrement operator (--) on the pointer to move backward through the array until the pointer reaches the base address.
+ Show Solution
#include <iostream>

int main() {
    int numbers[] = {1, 2, 3, 4, 5};
    int size = sizeof(numbers) / sizeof(numbers[0]);

    // Pointer to the first element (the base address)
    int* start_ptr = numbers; 

    // Calculate the address of the LAST element: &numbers[size - 1]
    int* current_ptr = start_ptr + (size - 1); 

    std::cout << "Elements in reverse order: ";

    // Loop backward while the current pointer is >= the start pointer
    while (current_ptr >= start_ptr) {
        std::cout << *current_ptr << " ";
        current_ptr--; // Decrement the pointer to move to the previous element
    }
    std::cout << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The pointer current_ptr is initialized to the address of the last array element. The while loop checks that the pointer is still within the array bounds.
  • The core operation is current_ptr--, which moves the pointer backward by sizeof(int) bytes, effectively pointing to the memory location of the previous element, allowing the array to be traversed and printed in reverse order.

Exercise 12: Finding Minimum

Problem Statement: Write a function named find_min_ptr that takes an integer array and its size as input, and returns a pointer to the smallest element in that array. In the main function, call this function and use the returned pointer to print the minimum value.

Given:

int data[] = {45, 12, 67, 8, 33};Code language: C++ (cpp)

Expected Output:

The smallest element is: 8
+ Hint
  • Initialize your result pointer to point to the first element of the array. Iterate through the array using another pointer (or index).
  • Inside the loop, compare the value pointed to by the current element with the value pointed to by your result pointer. If the current element is smaller, update the result pointer.
+ Show Solution
#include <iostream>

// Function that returns a pointer to the smallest integer
int* find_min_ptr(int arr[], int size) {
    if (size == 0) {
        return nullptr; // Handle empty array case
    }
    
    // Initialize the minimum pointer to the first element
    int* min_ptr = arr; 

    for (int i = 1; i < size; ++i) {
        // Compare the value pointed to by the current array index (arr[i])
        // with the value pointed to by min_ptr (*min_ptr)
        if (arr[i] < *min_ptr) {
            // Update the pointer to point to the new minimum element
            min_ptr = &arr[i]; 
        }
    }
    return min_ptr;
}

int main() {
    int data[] = {45, 12, 67, 8, 33};
    int size = sizeof(data) / sizeof(data[0]);

    int* min_element_ptr = find_min_ptr(data, size);

    if (min_element_ptr != nullptr) {
        std::cout << "The smallest element is: " << *min_element_ptr << std::endl;
    } else {
        std::cout << "The array is empty." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The function find_min_ptr is designed to return an int*. It initializes min_ptr to the start of the array. Inside the loop, it compares the current element (arr[i]) with the value pointed to by min_ptr (*min_ptr).
  • If a smaller value is found, min_ptr is updated using the address-of operator (&) to point to the new minimum element’s location (&arr[i]).
  • The main function then dereferences the returned pointer to get the actual minimum value (8).

Exercise 13: 2D Array Traversal

Problem Statement: Declare a small two-dimensional integer array, for example, a 3×3 array initialized with values. Write a program that uses an integer pointer to access and print all elements of the 2D array, treating it as a contiguous block of memory. You must use pointer arithmetic, not standard bracket indexing ([][]).

Given:

int matrix[3][3] = {
     {1, 2, 3},
     {4, 5, 6},
     {7, 8, 9}
};Code language: C++ (cpp)

Expected Output:

2D Array elements accessed contiguously:
1 2 3
4 5 6
7 8 9
+ Hint
  • A 2D array is stored contiguously in memory (row by row). You can treat the array name as a pointer to the first element of the first row.
  • Use a single for loop that runs from 0 up to total_elements - 1. Access the element at index i using *(ptr + i).
+ Show Solution
#include <iostream>

int main() {
    int matrix[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
    
    // Calculate total elements
    const int ROWS = 3;
    const int COLS = 3;
    const int TOTAL_ELEMENTS = ROWS * COLS;

    // The array name 'matrix' can be cast or implicitly converted 
    // to a pointer to the first element's data type (int*) for contiguous access
    int* ptr = (int*)matrix; 

    std::cout << "2D Array elements accessed contiguously:" << std::endl;
    for (int i = 0; i < TOTAL_ELEMENTS; ++i) {
        // Access the element using pointer arithmetic
        std::cout << *(ptr + i) << " "; 
        
        // Add a newline after every row (every 3 elements)
        if ((i + 1) % COLS == 0) {
            std::cout << std::endl;
        }
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The line int* ptr = (int*)matrix; casts the 2D array’s starting address to a simple integer pointer (int*).
  • Since the array elements are stored sequentially in memory, we can use a single loop iterating from 0 to 8. In each iteration, ptr + i calculates the address of the i-th element from the start, and *(ptr + i) retrieves its value. This highlights how multi-dimensional arrays are physically arranged in memory.

Exercise 14: Copying an Array

Problem Statement: Write a function named copy_array that takes three arguments: a destination integer array, a source integer array, and the size of the arrays. The function must use pointers to copy the contents from the source array into the destination array.

Given:

int source[] = {10, 20, 30, 40, 50};Code language: C++ (cpp)

Expected Output:

Destination array contents: 10 20 30 40 50
+ Hint
  • Use a single for loop that iterates over the size.
  • Inside the loop, you can use either bracket notation with pointers (dest_ptr[i]) or pure pointer arithmetic (*(dest_ptr + i)) for assignment. The simplest approach is *(destination + i) = *(source + i).
+ Show Solution
#include <iostream>

// Function to copy source array to destination array using pointers
void copy_array(int* dest, const int* src, int size) {
    for (int i = 0; i < size; ++i) {
        // Copy value from source address to destination address
        *(dest + i) = *(src + i); 
    }
}

int main() {
    const int SIZE = 5;
    int source[] = {10, 20, 30, 40, 50};
    int destination[SIZE]; // Array to receive the copy

    copy_array(destination, source, SIZE);

    std::cout << "Destination array contents: ";
    for (int i = 0; i < SIZE; ++i) {
        std::cout << destination[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The function parameters are defined as pointers (int* dest, const int* src), which are the typical way to pass arrays to functions in C++.
  • The const keyword on the source pointer is good practice, indicating that the source data will not be modified. The core logic *(dest + i) = *(src + i); dereferences the i-th element of the source array to get its value, and then assigns that value to the location pointed to by the i-th address of the destination array.

Exercise 15: Comparing Arrays

Problem Statement: Write a function named compare_arrays that takes two integer arrays and their size as input. The function should use pointers to check if the two arrays are identical (i.e., they have the same size and the same elements in the same order). Return true if they are identical, and false otherwise.

Given:

int a1[] = {1, 2, 3, 4};
int a2[] = {1, 2, 3, 4};
int a3[] = {1, 2, 9, 4};Code language: C++ (cpp)

Expected Output:

Array a1 and a2 are identical.
Array a1 and a3 are NOT identical.
+ Hint
  • Iterate through the arrays element by element. Use pointer dereference to compare the values at the current addresses: *ptr1 != *ptr2.
  • If a mismatch is found at any point, immediately return false. If the loop completes without finding any differences, return true.
+ Show Solution
#include <iostream>

// Function to compare two arrays using pointers
bool compare_arrays(const int* arr1, const int* arr2, int size) {
    for (int i = 0; i < size; ++i) {
        // Access elements using pointer arithmetic and dereference
        if (*(arr1 + i) != *(arr2 + i)) {
            return false; // Found a difference
        }
    }
    return true; // No differences found
}

int main() {
    const int SIZE = 4;
    int a1[] = {1, 2, 3, 4};
    int a2[] = {1, 2, 3, 4};
    int a3[] = {1, 2, 9, 4};

    // Compare a1 and a2 (Identical)
    if (compare_arrays(a1, a2, SIZE)) {
        std::cout << "Array a1 and a2 are identical." << std::endl;
    } else {
        std::cout << "Array a1 and a2 are NOT identical." << std::endl;
    }

    // Compare a1 and a3 (Different)
    if (compare_arrays(a1, a3, SIZE)) {
        std::cout << "Array a1 and a3 are identical." << std::endl;
    } else {
        std::cout << "Array a1 and a3 are NOT identical." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The function compare_arrays takes constant pointers to ensure the original arrays aren’t accidentally modified.
  • It loops from i=0 up to size-1. The check if (*(arr1 + i) != *(arr2 + i)) compares the values at the current memory addresses in both arrays. If the values differ, the function immediately terminates and returns false.
  • This early exit optimization is efficient. If the loop finishes, it means all elements matched, and true is returned.

Exercise 16: Sub-array Printing

Problem Statement: Given an integer array, a starting index (start), and an ending index (end), write a program that uses a pointer to print only the elements in that specific sub-range (inclusive of start, exclusive of end).

Given:

int data[] = {10, 20, 30, 40, 50, 60};
int start_index = 2; // Element 30
int end_index = 5;   // Up to element 50 (exclusive)Code language: C++ (cpp)

Expected Output:

Sub-array elements: 30 40 50
+ Hint
  • Initialize a pointer to the base address of the array. Calculate the starting pointer for the sub-range using pointer arithmetic: array_ptr + start.
  • Loop from this starting pointer until the address equals array_ptr + end.
+ Show Solution
#include <iostream>

void print_sub_array(int* arr, int start, int end) {
    // Calculate the pointer to the start of the sub-range
    int* current_ptr = arr + start; 
    
    // Calculate the pointer to one element PAST the end of the sub-range
    int* end_ptr = arr + end; 
    
    std::cout << "Sub-array elements: ";
    
    // Loop while the current pointer has not reached the end pointer
    while (current_ptr < end_ptr) {
        std::cout << *current_ptr << " ";
        current_ptr++;
    }
    std::cout << std::endl;
}

int main() {
    int data[] = {10, 20, 30, 40, 50, 60};
    int start_index = 2; // Element 30
    int end_index = 5;   // Up to element 50 (exclusive)

    print_sub_array(data, start_index, end_index); // Expected: 30 40 50 

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The function first calculates the starting and ending addresses for the print range using pointer arithmetic (arr + start and arr + end).
  • The while loop uses the addresses themselves for the boundary condition (current_ptr < end_ptr). Inside the loop, *current_ptr prints the value, and current_ptr++ moves the pointer to the next element.
  • This technique is common in C++ iterators, where ranges are defined by a starting pointer (or iterator) and an exclusive ending pointer.

Exercise 17: Pass-by-Pointer (Swap)

Problem Statement: Write a function called swap that takes two integer pointers as arguments. The function must swap the values stored in the memory locations that these pointers point to. In main, declare two integers and call swap using their addresses.

Given:

int a = 10;
int b = 20;Code language: C++ (cpp)

Expected Output:

Before swap: a = 10, b = 20
After swap: a = 20, b = 10
+ Hint
  • When implementing the swap logic inside the function, you must use the dereference operator (*) on the pointers to access and modify the actual variables from the main function.
  • Use a temporary variable to hold one value during the swap process.
+ Show Solution
#include <iostream>

// Function to swap the values pointed to by p1 and p2
void swap(int* p1, int* p2) {
    int temp = *p1; // Store the value at p1's address
    *p1 = *p2;      // Assign the value at p2's address to p1's address
    *p2 = temp;     // Assign the stored value (original p1) to p2's address
}

int main() {
    int a = 10;
    int b = 20;

    std::cout << "Before swap: a = " << a << ", b = " << b << std::endl;

    // Pass the addresses of a and b to the function
    swap(&a, &b);

    std::cout << "After swap: a = " << a << ", b = " << b << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This is the classic example of pass-by-pointer, which allows a function to modify variables defined in the calling function (main). When swap(&a, &b) is called, the addresses of a and b are passed.
  • Inside swap, the pointers p1 and p2 hold these addresses. By using the dereference operator (*p1 and *p2), the function accesses and changes the values of the variables a and b directly in the main function’s memory space.

Exercise 18: Modifying String in Function

Problem Statement: Write a function named to_uppercase that takes a character pointer (char*) representing a C-style string. The function must iterate through the string using pointer arithmetic and modify the characters in place to convert all lowercase letters to uppercase. Use the standard library function toupper() from <cctype>.

Given:

char text[] = "hello pointers exercise";Code language: C++ (cpp)

Expected Output:

Original: hello pointers exercise
Uppercase: HELLO POINTERS EXERCISE
+ Hint
  • A C-style string ends with the null-terminator (\0).
  • Loop while the character pointed to is not \0 (while (*str_ptr != '\0')).
  • Inside the loop, use *str_ptr = toupper(*str_ptr) to modify the character, and then increment the pointer (str_ptr++).
+ Show Solution
#include <iostream>
#include <cctype>

// Function to convert a C-style string to uppercase in place
void to_uppercase(char* str_ptr) {
    // Loop until the null-terminator is reached
    while (*str_ptr != '\0') {
        // Use toupper() to convert the character and assign it back 
        // to the memory location pointed to by str_ptr
        *str_ptr = std::toupper(*str_ptr); 
        
        // Move the pointer to the next character
        str_ptr++; 
    }
}

int main() {
    // Note: Must be char array, not const char* literal, to allow modification
    char text[] = "hello pointers exercise"; 

    std::cout << "Original: " << text << std::endl;
    
    to_uppercase(text);
    
    std::cout << "Uppercase: " << text << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The function to_uppercase accepts the string’s base address via char* str_ptr. The while loop uses the dereferenced value (*str_ptr) as its condition, ensuring it stops at the null-terminator.
  • The assignment *str_ptr = std::toupper(*str_ptr); modifies the character at the current memory location.
  • Since the function is passed the address of the original array (text), the changes are permanent and visible in main. The str_ptr++ moves the pointer to the next memory address (one byte further).

Exercise 19: Function Pointer Declaration

Problem Statement: Write a simple function add that takes two integers and returns their sum. In main, declare a function pointer that can point to a function with this signature. Assign the add function to this pointer and then call the add function using the function pointer.

Given:

int a = 10;
int b = 5;Code language: C++ (cpp)

Expected Output:

Result 1 (10 + 5): 15
+ Hint
  • The syntax for a function pointer is verbose: return_type (*pointer_name)(parameter_list).
  • For the add function, the declaration is int (*func_ptr)(int, int);.
+ Show Solution
#include <iostream>

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

int main() {
    // 1. Declare a function pointer named 'op_ptr'
    int (*op_ptr)(int, int);

    // 2. Assign the 'add' function's address to the pointer
    op_ptr = add; 

    // 3. Call the function using the pointer (dereference is optional but good practice)
    int result1 = op_ptr(10, 5); 
    int result2 = (*op_ptr)(25, 75); // Equivalent call using explicit dereference

    std::cout << "Result 1 (10 + 5): " << result1 << std::endl;
    std::cout << "Result 2 (25 + 75): " << result2 << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The line int (*op_ptr)(int, int); declares op_ptr as a pointer that can store the address of any function that takes two ints and returns an int.
  • Assignment is simple: op_ptr = add; (the function name decays to its address).
  • Calling the function via the pointer (op_ptr(10, 5)) is virtually identical to calling the function directly. Function pointers are essential for implementing callback functions and designing flexible interfaces.

Exercise 20: Callback Function

Problem Statement: Define two simple functions: multiply(int, int) and subtract(int, int). Write a function called compute_result that takes three arguments: two integers and a function pointer (which must match the signature of multiply or subtract). Inside compute_result, use the function pointer to perform the operation on the two integers and return the result. Use compute_result to call both multiply and subtract.

Given:

int x = 50;
int y = 10;Code language: C++ (cpp)

Expected Output:

Multiplication result: 500
Subtraction result: 40
+ Hint
  • The compute_result function must accept the function pointer as one of its parameters.
  • You can call the pointed-to function directly within compute_result using the function pointer’s name and arguments.
+ Show Solution
#include <iostream>

// Type definition for easier readability of the function pointer signature
typedef int (*OperationPtr)(int, int);

int multiply(int a, int b) {
    return a * b;
}

int subtract(int a, int b) {
    return a - b;
}

// Function that takes a function pointer (callback) as an argument
int compute_result(int val1, int val2, OperationPtr operation) {
    // Call the function pointed to by 'operation'
    return operation(val1, val2); 
}

int main() {
    int x = 50;
    int y = 10;

    // Pass the multiply function's address (decayed name)
    int product = compute_result(x, y, multiply);
    std::cout << "Multiplication result: " << product << std::endl; 

    // Pass the subtract function's address (decayed name)
    int difference = compute_result(x, y, subtract);
    std::cout << "Subtraction result: " << difference << std::endl; 

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The typedef makes the function pointer signature more readable. The compute_result function is designed as a generic interface. It doesn’t know which operation it will perform until runtime.
  • When called, the multiply or subtract function’s address is passed. Inside compute_result, the line return operation(val1, val2); executes the function currently pointed to by operation.
  • This pattern is known as a callback and allows for highly flexible and extensible code design.

Exercise 21: Pointer to Constant Data

Problem Statement: Write a function named print_constant_value that accepts a pointer to a constant integer (const int*). Inside the function, print the value pointed to. In main, attempt to call the function and then try to use the pointer inside the function to modify the pointed-to value. Observe and explain the resulting compilation error.

Given:

int data = 100;Code language: C++ (cpp)

Expected Output:

Value via const pointer: 100
Value via const pointer: 200
+ Hint

The declaration const int* ptr; means the pointer can change (point to something else), but the data it points to cannot be changed through this pointer. The compiler enforces this protection.

+ Show Solution
#include <iostream>

// Function accepts a pointer to constant data
void print_constant_value(const int* ptr) {
    if (ptr != nullptr) {
        std::cout << "Value via const pointer: " << *ptr << std::endl;
        
        // ** Attempting to modify the value here will cause a compile error **
        // *ptr = 500; 
        // Uncommenting the line above results in: 
        // error: assignment of read-only location ‘*ptr’
    }
}

int main() {
    int data = 100;
    
    // The pointer itself is not constant, but the data is treated as such
    print_constant_value(&data);

    // We can still modify 'data' directly because it's not constant
    data = 200;
    print_constant_value(&data);

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The function signature const int* ptr declares a pointer to constant data. This means that although the variable data in main is not constant, the function guarantees it will treat the data pointed to by ptr as read-only.
  • This is a crucial safety mechanism: it allows the function to read data without the risk of accidental modification. The compiler prevents the assignment *ptr = 500 because it violates the const contract specified in the function parameter.

Exercise 22: Constant Pointer

Problem Statement: Declare an integer variable x initialized to 5. Declare a constant pointer to an integer (int* const) named const_ptr and initialize it to point to x. Use the pointer to successfully change the value of x to 10. Then, declare a second integer y and attempt to make const_ptr point to y. Observe and explain the resulting compilation error.

Given:

int x = 5;
int y = 25;Code language: C++ (cpp)

Expected Output:

x after modification via pointer: 10
+ Hint
  • The declaration int* const ptr; means the pointer must always point to the same memory location, but the value at that location can be changed.
  • The const applies to the pointer variable itself, preventing its address from being reassigned.
+ Show Solution
#include <iostream>

int main() {
    int x = 5;
    int y = 25;
    
    // Constant pointer: must always point to the address of 'x'
    int* const const_ptr = &x; 

    // 1. SUCCESS: We can modify the data 'x' via the pointer
    *const_ptr = 10;
    std::cout << "x after modification via pointer: " << x << std::endl; // Prints 10

    // 2. FAILURE: Attempting to change the pointer itself
    // const_ptr = &y; 
    // Uncommenting the line above results in: 
    // error: assignment of read-only variable ‘const_ptr’

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The declaration int* const const_ptr = &x; defines a constant pointer. The const modifier is placed after the asterisk, making the pointer address itself immutable.
  • Thus, the pointer must always point to the address of x and cannot be reassigned to point to y. However, since the data type (int) is not constant, the value at the address (i.e., x) can be freely changed using the dereference operator (*const_ptr = 10).

Exercise 23: Pointer to Struct

Problem Statement: Define a structure named Rectangle with two integer members: length and width. Declare a Rectangle variable, initialize its members, and then declare a pointer to that structure. Access and modify the structure members using the arrow operator (->). Print the final dimensions.

Expected Output:

Original dimensions: 10 x 5
New dimensions: 15 x 7
+ Hint
  • The arrow operator (->) is a shorthand in C++ specifically designed for pointers to structures or classes.
  • It combines the dereference operator and the member access operator: ptr->member is equivalent to (*ptr).member.
+ Show Solution
#include <iostream>

struct Rectangle {
    int length;
    int width;
};

int main() {
    Rectangle rect = {10, 5};
    
    // Declare and initialize a pointer to the structure
    Rectangle* rect_ptr = &rect; 

    std::cout << "Original dimensions: " << rect_ptr->length 
              << " x " << rect_ptr->width << std::endl;

    // Modify members using the arrow operator
    rect_ptr->length = 15;
    rect_ptr->width = 7;

    std::cout << "New dimensions: " << rect.length 
              << " x " << rect.width << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The line Rectangle* rect_ptr = &rect; sets up the structure pointer.
  • The arrow operator (->) is used to access members through the pointer, such as rect_ptr->length. This operator automatically dereferences the pointer and accesses the specified member, making code much cleaner than using the verbose (*rect_ptr).length syntax.
  • This is fundamental when working with linked lists or dynamic objects in C++

Exercise 24: Dynamic Allocation (Single Variable)

Problem Statement: Use the new operator to dynamically allocate memory for a single float variable on the heap. Store the address in a float pointer. Initialize the allocated memory to the value 3.14. Print the value, and then use the delete operator to deallocate the memory.

Sample Output:

Dynamically allocated float value: 3.14
Address on heap: 0x61499874f920
+ Hint
  • Dynamic allocation uses new Type. Deallocation uses delete pointer.
  • Failing to use delete results in a memory leak. Always check if the pointer is not nullptr after allocation (though new throws an exception by default if allocation fails).
+ Show Solution
#include <iostream>

int main() {
    // Dynamically allocate a single float on the heap
    float* float_ptr = new float; 
    
    // Check if allocation was successful (optional but good practice)
    if (float_ptr == nullptr) {
        std::cerr << "Memory allocation failed!" << std::endl;
        return 1;
    }

    // Initialize the allocated memory
    *float_ptr = 3.14f;

    std::cout << "Dynamically allocated float value: " << *float_ptr << std::endl;
    std::cout << "Address on heap: " << float_ptr << std::endl;

    // Deallocate the memory to prevent memory leak
    delete float_ptr;
    
    // Set the pointer to nullptr after deletion to avoid dangling pointer issues
    float_ptr = nullptr;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The statement float* float_ptr = new float; allocates enough memory on the heap to hold a single float and stores the starting address in float_ptr.
  • The value is set using dereference: *float_ptr = 3.14f;. Crucially, delete float_ptr; returns the allocated memory back to the system, preventing a memory leak.
  • Setting the pointer to nullptr after deletion is important to avoid a dangling pointer—a pointer that still holds the address of deallocated memory.

Exercise 25: Dynamic Allocation (Array)

Problem Statement: Use the new[] operator to dynamically allocate an integer array of size 8. Use a pointer to fill the array with the values 10, 20, 30, …, 80. Print all values using pointer arithmetic traversal. Finally, use the delete[] operator to correctly deallocate the entire array.

Expected Output:

Dynamically allocated array: 10 20 30 40 50 60 70 80
+ Hint
  • To allocate an array, use new Type[size].
  • To deallocate the array, you must use the array form of delete: delete[] pointer. Using delete pointer on an array leads to undefined behavior.
+ Show Solution
#include <iostream>

int main() {
    const int SIZE = 8;
    
    // Dynamically allocate an array of 8 integers on the heap
    int* array_ptr = new int[SIZE]; 

    // Fill the array using pointer arithmetic
    for (int i = 0; i < SIZE; ++i) {
        *(array_ptr + i) = (i + 1) * 10;
    }

    // Print the array using pointer traversal
    std::cout << "Dynamically allocated array: ";
    for (int i = 0; i < SIZE; ++i) {
        std::cout << array_ptr[i] << " "; // Using [] is fine after allocation
    }
    std::cout << std::endl;

    // Crucial step: Deallocate the entire array
    delete[] array_ptr;
    array_ptr = nullptr;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The statement int* array_ptr = new int[SIZE]; allocates a contiguous block of memory large enough for 8 integers.
  • We then treat array_ptr just like a regular array name. The loop fills the elements using pointer arithmetic. The command delete[] array_ptr; is mandatory for arrays.
  • The square brackets inform the C++ runtime that it needs to run destructors (if applicable) and deallocate the entire contiguous block, not just the memory for the first element.

Exercise 26: Array of Pointers

Problem Statement: Declare five individual integer variables (e.g., n1, n2, …). Declare an array of 5 integer pointers (int* array_of_ptrs[5]). Make each element in the array of pointers point to one of the five individual integer variables. Use the array of pointers to print all five integer values.

Given:

int n1 = 10;
int n2 = 20;
int n3 = 30;
int n4 = 40;
int n5 = 50;Code language: C++ (cpp)

Expected Output:

Values via array of pointers: 10 20 30 40 50
+ Hint

The array stores addresses. You must use both the index operator ([]) to select the pointer from the array and the dereference operator (*) to get the value at the pointed-to address. For example: *array_of_ptrs[i].

+ Show Solution
#include <iostream>

int main() {
    int n1 = 10;
    int n2 = 20;
    int n3 = 30;
    int n4 = 40;
    int n5 = 50;

    // Declare an array of 5 integer pointers
    int* array_of_ptrs[5];

    // Assign the address of each integer to an element in the pointer array
    array_of_ptrs[0] = &n1;
    array_of_ptrs[1] = &n2;
    array_of_ptrs[2] = &n3;
    array_of_ptrs[3] = &n4;
    array_of_ptrs[4] = &n5;

    std::cout << "Values via array of pointers: ";
    for (int i = 0; i < 5; ++i) {
        // Dereference the pointer stored at index i
        std::cout << *array_of_ptrs[i] << " "; 
    }
    std::cout << std::endl;

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • The declaration int* array_of_ptrs[5]; creates an array on the stack where each of the five slots is designed to hold a memory address (an int*).
  • We populate this array with the addresses of the five stack variables. In the loop, array_of_ptrs[i] retrieves the stored address, and the leading * operator retrieves the value from that address. This structure is often used to manage a collection of scattered data efficiently.

Exercise 27: Finding a Substring

Problem Statement: Write a function named find_first_occurrence that mimics a simplified strstr. It takes two char pointers: a source string and a target string (substring). It should search for the first occurrence of the target substring within the source string. If found, the function must return a pointer to the starting character of the match within the source string. If not found, return nullptr.

Given:

const char* main_str = "programming in c++ is fun";
const char* sub_str = "c++";Code language: C++ (cpp)

Expected Output:

Substring found starting at: c++ is fun
Source string starting from match: c++ is fun
+ Hint
  • This requires nested loops. The outer loop traverses the source string.
  • The inner loop compares characters from the current position in source with the characters in target. If all characters match until the target‘s null terminator, return the current source pointer.
+ Show Solution
#include <iostream>

// Returns a pointer to the first occurrence of target in source, or nullptr
char* find_first_occurrence(const char* source, const char* target) {
    if (*target == '\0') return (char*)source; // Empty target is a special case
    
    const char* current_source = source;
    
    // Outer loop: Iterate through the source string
    while (*current_source != '\0') {
        const char* s = current_source;
        const char* t = target;
        
        // Inner loop: Compare characters from current position
        while (*t != '\0' && *s == *t) {
            s++;
            t++;
        }
        
        // Check if the inner loop reached the end of the target string
        if (*t == '\0') {
            return (char*)current_source; // Match found, return the start address
        }

        current_source++; // Move to the next character in the source
    }

    return nullptr; // No match found
}

int main() {
    const char* main_str = "programming in c++ is fun";
    const char* sub_str = "c++";

    char* found_ptr = find_first_occurrence(main_str, sub_str);

    if (found_ptr != nullptr) {
        std::cout << "Substring found starting at: " << found_ptr << std::endl;
        std::cout << "Source string starting from match: " << found_ptr << std::endl;
    } else {
        std::cout << "Substring not found." << std::endl;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This function uses multiple pointers to manage the search. current_source tracks the starting point in the main string.
  • The inner pointers (s and t) perform the character-by-character comparison. If the inner while loop completes because *t hit the null-terminator (\0), it means a full match was found.
  • The function then returns current_source, the address where the match began. If the outer loop finishes, the function returns nullptr, indicating no match.

Exercise 28: Memory Leak Demonstration

Problem Statement: Write a function named leak_memory that contains a simple for loop that runs 100 times. Inside the loop, use new int to dynamically allocate memory for an integer, but do not use delete. In main, call this function and explain why this pattern leads to a memory leak. (Note: Running this in a real scenario will increase memory usage, but for the exercise, just understand the mechanism).

+ Hint
  • A memory leak occurs when a program loses the only pointer to a dynamically allocated block of memory before that memory is deallocated.
  • Once the function finishes, the local pointer goes out of scope, and the memory becomes inaccessible.
+ Show Solution
#include <iostream>

void leak_memory(int count) {
    std::cout << "Allocating " << count << " integers without deletion..." << std::endl;
    
    for (int i = 0; i < count; ++i) {
        // A temporary pointer is created
        int* temp_ptr = new int(i); 
        
        // The pointer goes out of scope at the end of the loop iteration, 
        // losing the only reference to the memory block it pointed to.
        // We MUST call delete temp_ptr; here, but we are intentionally skipping it.
    }

    // All 100 memory blocks are now "leaked"
    std::cout << "Memory leak simulated. The system is holding inaccessible memory." << std::endl;
}

int main() {
    leak_memory(100);
    // The program will finish, but the operating system won't reclaim the 
    // memory until the entire process terminates.
    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • Inside the loop, int* temp_ptr = new int(i); allocates a block of heap memory.
  • When the loop iterates to the next cycle, the local variable temp_ptr is destroyed (it goes out of scope). However, the memory block it pointed to on the heap remains allocated.
  • Since temp_ptr was the only variable holding the address of that block, the program has lost the ability to call delete.
  • This inaccessible memory is a memory leak, reducing the available memory until the program terminates and the operating system automatically reclaims it.

Exercise 29: Reallocation Simulation

Problem Statement: Dynamically allocate a small integer array (size 5) and initialize it. Write a function named resize_array that simulates reallocation by: 1) creating a new, larger array (size 10) on the heap, 2) using pointers to copy the contents of the old array to the new array, and 3) correctly deleting the old array. Return the pointer to the new array.

Given:

int old_size = 5;
int new_size = 10;Code language: C++ (cpp)

Expected Output:

Original array (size 5): 1 2 3 4 5 
Resized array (size 10): 1 2 3 4 5 99 99 99 99 99
+ Hint

The function must accept a pointer to the old array. After copying, use delete[] on the old pointer before returning the new pointer.

+ Show Solution
#include <iostream>

// Returns a pointer to the new array, requires size updates in calling code
int* resize_array(int* old_array, int old_size, int new_size) {
    // 1. Create a new, larger array
    int* new_array = new int[new_size]; 

    // 2. Copy contents from old array to new array using pointers
    for (int i = 0; i < old_size; ++i) {
        *(new_array + i) = *(old_array + i);
    }
    
    // 3. Clean up the old array memory
    delete[] old_array; 

    return new_array;
}

int main() {
    int old_size = 5;
    int new_size = 10;
    
    // Initial dynamic allocation
    int* data_ptr = new int[old_size]{1, 2, 3, 4, 5}; 

    std::cout << "Original array (size 5): ";
    for (int i = 0; i < old_size; ++i) std::cout << data_ptr[i] << " ";
    std::cout << std::endl;

    // Simulate reallocation
    data_ptr = resize_array(data_ptr, old_size, new_size);
    old_size = new_size; // Update size tracking variable

    // The new array has copied data and new uninitialized space
    std::cout << "Resized array (size 10): ";
    for (int i = 0; i < old_size; ++i) {
        std::cout << (data_ptr[i] == 0 ? 99 : data_ptr[i]) << " "; // Print 99 for uninitialized
    }
    std::cout << std::endl;

    delete[] data_ptr;
    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • C++ does not have a built-in realloc like C. This function demonstrates the manual process: allocate new memory (new int[new_size]), copy data, and deallocate old memory (delete[] old_array).
  • The key challenge is ensuring the old pointer is correctly deleted, and the new pointer (the base address of the larger block) is correctly returned and used to update the pointer variable (data_ptr) in main.
  • This is the fundamental mechanism behind C++ container classes like std::vector when they grow in size.

Exercise 30: Linked List Node (Concept)

Problem Statement: Define a simple structure named Node containing an integer data member and a pointer named next that points to another Node structure (i.e., Node* next). Create three such nodes dynamically (n1, n2, n3). Link them sequentially using the next pointer (n1 -> n2 -> n3). Finally, traverse the small list using a temporary pointer and print all the data values.

Expected Output:

Linked List Traversal: 10 20 30 
+ Hint
  • The declaration Node* next; is a self-referential structure, the basis of a linked list.
  • To link n1 to n2, you set n1.next = &n2;. The traversal starts at the head and continues while (temp_ptr != nullptr).
+ Show Solution
#include <iostream>

struct Node {
    int data;
    Node* next; // Pointer to the next node in the list
};

int main() {
    // 1. Create three nodes dynamically
    Node* n1 = new Node{10, nullptr};
    Node* n2 = new Node{20, nullptr};
    Node* n3 = new Node{30, nullptr};

    // 2. Link them sequentially
    n1->next = n2; // n1 points to n2
    n2->next = n3; // n2 points to n3
    // n3->next is already nullptr

    // 3. Traverse the list starting from the head (n1)
    Node* current = n1;
    
    std::cout << "Linked List Traversal: ";
    while (current != nullptr) {
        std::cout << current->data << " ";
        current = current->next; // Move to the next node using the pointer
    }
    std::cout << std::endl;

    // 4. Clean up (essential for dynamic structures)
    current = n1;
    while (current != nullptr) {
        Node* next_node = current->next;
        delete current;
        current = next_node;
    }

    return 0;
}Code language: C++ (cpp)
Run

Explanation:

  • This exercise demonstrates the core concept of a linked list, which relies entirely on pointers. The Node structure is self-referential because it contains a pointer to its own type.
  • The links are established by setting the next pointer of one node to the address of the subsequent node (e.g., n1->next = n2;). Traversal starts at the head (n1) and moves forward by continually updating the current pointer to the value stored in current->next.
  • The cleanup phase is critical: memory must be deallocated node by node to avoid leaks.

Filed Under: CPP Exercises

Did you find this page helpful? Let others know about it. Sharing helps me continue to create free Python resources.

TweetF  sharein  shareP  Pin

About Vishal

Image

I’m Vishal Hule, the Founder of PYnative.com. As a Python developer, I enjoy assisting students, developers, and learners. Follow me on Twitter.

Related Tutorial Topics:

CPP Exercises

All Coding Exercises:

C Exercises
C++ Exercises
Python Exercises

Python Exercises and Quizzes

Free coding exercises and quizzes cover Python basics, data structure, data analytics, and more.

  • 15+ Topic-specific Exercises and Quizzes
  • Each Exercise contains 25+ questions
  • Each Quiz contains 25 MCQ
Exercises
Quizzes

Leave a Reply Cancel reply

your email address will NOT be published. all comments are moderated according to our comment policy.

Use <pre> tag for posting code. E.g. <pre> Your entire code </pre>

In: CPP Exercises
TweetF  sharein  shareP  Pin

  CPP Exercises

  • All C++ Exercises
  • C++ Exercise for Beginners
  • C++ Loops Exercise
  • C++ Functions Exercise
  • C++ Arrays Exercise
  • C++ String Exercise
  • C++ Pointers Exercise
  • C++ OOP Exercise
  • C++ File Handling Exercise
  • C++ Structures and Enums Exercise
  • C++ Templates & Generic Programming Exercise

All Coding Exercises

C Exercises C++ Exercises Python Exercises

About PYnative

PYnative.com is for Python lovers. Here, You can get Tutorials, Exercises, and Quizzes to practice and improve your Python skills.

Explore Python

  • Learn Python
  • Python Basics
  • Python Databases
  • Python Exercises
  • Python Quizzes
  • Online Python Code Editor
  • Python Tricks

Follow Us

To get New Python Tutorials, Exercises, and Quizzes

  • Twitter
  • Facebook
  • Sitemap

Legal Stuff

  • About Us
  • Contact Us

We use cookies to improve your experience. While using PYnative, you agree to have read and accepted our:

  • Terms Of Use
  • Privacy Policy
  • Cookie Policy

Copyright © 2018–2025 pynative.com

Advertisement