Chapter 11 Intermediate 60 Questions

Practice Questions — Pointers and References

← Back to Notes
8 Easy
7 Medium
7 Hard

Topic-Specific Questions

Question 1
Easy
What is the output of the following code?
int x = 10;
int* p = &x;
cout << *p;
The dereference operator (*) accesses the value at the address stored in the pointer.
10
Question 2
Easy
What is the output?
int a = 5;
int* p = &a;
*p = 15;
cout << a;
Modifying *p modifies the variable that p points to.
15
Question 3
Easy
What is the output?
int arr[] = {10, 20, 30};
cout << *arr;
An array name decays to a pointer to its first element.
10
Question 4
Easy
What is the output?
int x = 100;
int& ref = x;
ref = 200;
cout << x;
A reference is an alias for the original variable.
200
Question 5
Easy
What is the output?
int* p = nullptr;
if (p == nullptr)
    cout << "null";
else
    cout << *p;
nullptr means the pointer does not point to valid memory.
null
Question 6
Medium
What is the output?
int arr[] = {10, 20, 30, 40, 50};
int* p = arr;
p += 2;
cout << *p << endl;
cout << *(p + 1) << endl;
cout << p[-1] << endl;
p += 2 advances the pointer by 2 elements. p[-1] is equivalent to *(p - 1).
30
40
20
Question 7
Medium
What is the output?
int x = 5;
int* p = &x;
int** pp = &p;

cout << **pp << endl;
**pp = 25;
cout << x << endl;
A pointer to pointer requires double dereferencing to reach the final value.
5
25
Question 8
Medium
What is the output?
void modify(int* p) {
    *p = *p + 10;
}

int x = 5;
modify(&x);
cout << x;
The function receives a pointer to x and modifies the value at that address.
15
Question 9
Medium
What is the output?
int arr[] = {1, 2, 3, 4, 5};
int* p = arr + 4;
cout << *p << endl;
cout << p - arr << endl;
Pointer subtraction gives the number of elements between two addresses.
5
4
Question 10
Hard
What is the output?
int arr[] = {10, 20, 30, 40};
int* p = arr;
int* q = arr + 3;

cout << *p + *q << endl;
cout << *(p + 1) + *(q - 1) << endl;
cout << q - p << endl;
p points to arr[0], q points to arr[3]. Compute each expression carefully.
50
50
3
Question 11
Hard
What is the output?
char str[] = "Hello";
char* p = str;
while (*p != '\0') {
    cout << *p;
    p++;
}
cout << endl;
cout << p - str;
The pointer traverses the string character by character until the null terminator.
Hello
5
Question 12
Hard
What is the output?
int x = 10, y = 20;
const int* p = &x;
cout << *p << endl;
p = &y;
cout << *p << endl;
// *p = 30;  // Would this compile?
const int* means the value is read-only through the pointer, but the pointer can be reassigned.
10
20
(The commented line would NOT compile: cannot modify value through pointer to const)
Question 13
Hard
What is the output?
int arr[] = {5, 10, 15, 20, 25};
int* p = arr;

cout << *p++ << endl;
cout << *p << endl;
cout << *++p << endl;
cout << ++*p << endl;
*p++ dereferences first then increments the pointer. *++p increments the pointer first then dereferences. ++*p increments the value.
5
10
15
16

Mixed & Application Questions

Question 1
Easy
What is the output?
int a = 3, b = 7;
int* p = &a;
int* q = &b;
cout << *p + *q;
Dereference both pointers and add the values.
10
Question 2
Easy
What is the output?
int x = 10;
int* p = &x;
int& ref = x;
*p = 20;
cout << ref;
Both the pointer and the reference point to the same variable x.
20
Question 3
Easy
What is the difference between a null pointer and a wild pointer?
One is intentionally set to nothing; the other was never set at all.
A null pointer is explicitly set to nullptr -- it points to nothing and can be safely checked. A wild pointer is an uninitialized pointer that contains a garbage address. Dereferencing either is undefined behavior, but a null pointer can be checked (if (p != nullptr)), while a wild pointer gives no indication that it is invalid.
Question 4
Medium
What is the output?
int arr[] = {2, 4, 6, 8};
int* p = arr;
int sum = 0;
for (int i = 0; i < 4; i++) {
    sum += *(p + i);
}
cout << sum;
*(p + i) accesses each element of the array through the pointer.
20
Question 5
Medium
What is the output?
void changePointer(int** pp, int* newAddr) {
    *pp = newAddr;
}

int a = 10, b = 20;
int* p = &a;
cout << *p << endl;
changePointer(&p, &b);
cout << *p << endl;
The function receives a pointer to pointer and changes what the original pointer points to.
10
20
Question 6
Medium
When should you use a pointer instead of a reference in C++?
Think about null values, reassignment, and dynamic memory.
Use pointers when: (1) the target might be null/optional, (2) you need to reassign to different objects during the lifetime, (3) you need pointer arithmetic, (4) you are working with new/delete (dynamic memory). Use references when: (1) the target is always valid, (2) you want cleaner syntax without * and &, (3) you are passing function parameters for modification.
Question 7
Hard
What is the output?
int x = 5;
int* p = &x;
int** pp = &p;
int*** ppp = &pp;

cout << ***ppp << endl;
***ppp = 99;
cout << x << endl;
Three levels of indirection. Dereference three times to reach x.
5
99
Question 8
Hard
What is the output?
int a = 10, b = 20, c = 30;
int* arr[] = {&a, &b, &c};
int** p = arr;

cout << **p << endl;
p++;
cout << **p << endl;
cout << **(p + 1) << endl;
arr is an array of pointers. p is a pointer to the first element of that array.
10
20
30
Question 9
Hard
What is the output?
void mystery(int* a, int& b) {
    *a += b;
    b += *a;
}

int x = 3, y = 4;
mystery(&x, y);
cout << x << " " << y;
Both a and &b refer to the original variables. Trace the operations step by step.
7 11

Multiple Choice Questions

MCQ 1
What does the & operator do when used with a variable?
  • A. Multiplies the variable by its address
  • B. Returns the memory address of the variable
  • C. Dereferences a pointer
  • D. Declares a reference variable
Answer: B
B is correct. The & operator, when used as a unary operator with a variable (e.g., &x), returns its memory address. In declarations like int& ref = x, it creates a reference (D), but the question asks about using it with an existing variable.
MCQ 2
What is the correct way to declare a pointer to an integer in C++?
  • A. int p;
  • B. int *p;
  • C. pointer int p;
  • D. int &p;
Answer: B
B is correct. int *p; (or int* p;) declares a pointer to an integer. int p; (A) declares a regular integer. pointer int p; (C) is not valid C++ syntax. int &p; (D) declares a reference, which must be initialized.
MCQ 3
What value should an uninitialized pointer be set to in modern C++?
  • A. 0
  • B. NULL
  • C. nullptr
  • D. void
Answer: C
C is correct. nullptr (C++11) is the type-safe null pointer constant. NULL (B) and 0 (A) work but are not type-safe -- they can be confused with integers. void (D) is a type, not a value.
MCQ 4
What is the output of sizeof(int*) on a 64-bit system?
  • A. 4
  • B. 8
  • C. Depends on the type pointed to
  • D. Depends on the compiler
Answer: B
B is correct. On a 64-bit system, all pointers are 8 bytes because they must be able to address the entire 64-bit address space. The size of a pointer does not depend on the type it points to -- int*, double*, and char* are all 8 bytes on 64-bit.
MCQ 5
Which statement about references in C++ is true?
  • A. A reference can be null
  • B. A reference can be reassigned to another variable after initialization
  • C. A reference must be initialized when declared
  • D. A reference requires dereferencing with * to access the value
Answer: C
C is correct. A reference must be initialized at declaration and cannot be null (A is false) or reassigned to another variable (B is false). References are accessed directly without any dereference operator (D is false).
MCQ 6
What does the expression arr[i] internally translate to in C++?
  • A. &arr + i
  • B. *(arr + i)
  • C. arr * i
  • D. &(arr + i)
Answer: B
B is correct. Array subscript arr[i] is syntactic sugar for *(arr + i). The array name decays to a pointer to the first element, pointer arithmetic computes the address of the i-th element, and the dereference operator accesses the value.
MCQ 7
What is the difference between const int* p and int* const p?
  • A. They are the same
  • B. const int* p prevents modifying the value; int* const p prevents changing the pointer
  • C. const int* p prevents changing the pointer; int* const p prevents modifying the value
  • D. Both prevent modifying the value and the pointer
Answer: B
B is correct. const int* p: the value pointed to is const (cannot do *p = ...). int* const p: the pointer itself is const (cannot do p = ...). Read right-to-left: 'p is a const pointer to int' vs 'p is a pointer to const int'.
MCQ 8
What happens when you increment a pointer of type double*?
  • A. The address increases by 1 byte
  • B. The address increases by 4 bytes
  • C. The address increases by 8 bytes (sizeof(double))
  • D. The address increases by the value it points to
Answer: C
C is correct. Pointer arithmetic is type-aware. Incrementing a double* advances the address by sizeof(double), which is 8 bytes. This ensures the pointer moves to the next element in a double array.
MCQ 9
What is a dangling pointer?
  • A. A pointer set to nullptr
  • B. A pointer that points to freed or out-of-scope memory
  • C. A pointer that has never been initialized
  • D. A pointer to a const variable
Answer: B
B is correct. A dangling pointer points to memory that has been deallocated (via delete) or has gone out of scope (local variable of a returned function). A null pointer (A) is safe to check. An uninitialized pointer (C) is called a wild pointer. A pointer to const (D) is perfectly valid.
MCQ 10
What is the output?
int arr[] = {1, 2, 3};
cout << 2[arr];
  • A. 1
  • B. 2
  • C. 3
  • D. Compilation error
Answer: C
C is correct. 2[arr] is valid C++. Since arr[i] is *(arr + i), and addition is commutative, 2[arr] is *(2 + arr) = *(arr + 2) = arr[2] = 3.
MCQ 11
Which of the following is NOT possible with references in C++?
  • A. Creating an array of references
  • B. Passing to a function by reference
  • C. Returning a reference from a function
  • D. Using a reference as a class member
Answer: A
A is correct. C++ does not allow arrays of references because references are not objects -- they do not have their own address or size. You can pass by reference (B), return references (C), and use reference members in classes (D, but they must be initialized in the constructor initializer list).
MCQ 12
What is the result of subtracting two pointers of the same type?
  • A. The byte difference between the addresses
  • B. The number of elements between the two addresses
  • C. A pointer to the midpoint
  • D. Undefined behavior
Answer: B
B is correct. Subtracting two pointers of the same type yields a ptrdiff_t value representing the number of elements between them, not the byte difference. For int* where int is 4 bytes, if p2 - p1 = 3, the byte difference is 12 but the result is 3.
MCQ 13
What is wrong with this code?
void* vp = new int(10);
cout << *vp;
  • A. void* cannot hold the address of an int
  • B. new int(10) is invalid syntax
  • C. void* cannot be dereferenced without casting
  • D. There is no error
Answer: C
C is correct. A void* can hold any address (A is false), and new int(10) is valid (B is false). However, you cannot dereference a void* because the compiler does not know the size of the data. You must cast it first: *(static_cast(vp)).
MCQ 14
What happens if you use delete instead of delete[] on an array allocated with new[]?
  • A. Only the first element is freed
  • B. All elements are freed correctly
  • C. Undefined behavior
  • D. Compilation error
Answer: C
C is correct. Using delete on memory allocated with new[] is undefined behavior. The runtime may not call destructors for all elements and may corrupt internal bookkeeping. Always match new with delete and new[] with delete[].

Coding Challenges

Challenge 1: Reverse Array Using Pointers

Easy
Write a function reverseArray(int* arr, int size) that reverses an array in-place using pointer arithmetic (no indexing with []). Print the array before and after reversing.
Sample Input
Array: {1, 2, 3, 4, 5}
Sample Output
Before: 1 2 3 4 5 After: 5 4 3 2 1
Use only pointer arithmetic and dereferencing. Do not use array subscript operator [].
#include <iostream>
using namespace std;

void reverseArray(int* arr, int size) {
    int* left = arr;
    int* right = arr + size - 1;
    while (left < right) {
        int temp = *left;
        *left = *right;
        *right = temp;
        left++;
        right--;
    }
}

void printArray(int* arr, int size) {
    for (int* p = arr; p < arr + size; p++) {
        cout << *p << " ";
    }
    cout << endl;
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int size = 5;
    cout << "Before: ";
    printArray(arr, size);
    reverseArray(arr, size);
    cout << "After: ";
    printArray(arr, size);
    return 0;
}

Challenge 2: String Length Using Pointers

Easy
Write a function int strLen(const char* str) that returns the length of a C-string using pointer arithmetic. Do not use strlen().
Sample Input
"Modern Age Coders"
Sample Output
Length: 17
Use a pointer to traverse until the null terminator. Do not use any library function.
#include <iostream>
using namespace std;

int strLen(const char* str) {
    const char* p = str;
    while (*p != '\0') {
        p++;
    }
    return p - str;
}

int main() {
    const char* s = "Modern Age Coders";
    cout << "Length: " << strLen(s) << endl;

    const char* empty = "";
    cout << "Length of empty: " << strLen(empty) << endl;
    return 0;
}

Challenge 3: Swap Two Pointers

Medium
Write a function that takes two int** parameters and swaps what the original pointers point to. After the swap, the first pointer should point to the second variable and vice versa.
Sample Input
a = 10, b = 20, p1 = &a, p2 = &b
Sample Output
Before: *p1=10, *p2=20 After: *p1=20, *p2=10
The function must modify the original pointers using pointer-to-pointer. The values of a and b must NOT change.
#include <iostream>
using namespace std;

void swapPointers(int** pp1, int** pp2) {
    int* temp = *pp1;
    *pp1 = *pp2;
    *pp2 = temp;
}

int main() {
    int a = 10, b = 20;
    int* p1 = &a;
    int* p2 = &b;

    cout << "Before: *p1=" << *p1 << ", *p2=" << *p2 << endl;
    swapPointers(&p1, &p2);
    cout << "After: *p1=" << *p1 << ", *p2=" << *p2 << endl;

    // Verify a and b are unchanged
    cout << "a=" << a << ", b=" << b << endl;
    return 0;
}

Challenge 4: Find Min and Max Using Pointers

Medium
Write a function findMinMax(int* arr, int size, int* min, int* max) that finds the minimum and maximum values in an array and stores them through pointers. The function should not return anything.
Sample Input
Array: {34, 12, 56, 7, 89, 23}
Sample Output
Min: 7 Max: 89
Use pointer parameters for output. Traverse the array using pointer arithmetic.
#include <iostream>
using namespace std;

void findMinMax(int* arr, int size, int* min, int* max) {
    *min = *arr;
    *max = *arr;
    for (int* p = arr + 1; p < arr + size; p++) {
        if (*p < *min) *min = *p;
        if (*p > *max) *max = *p;
    }
}

int main() {
    int arr[] = {34, 12, 56, 7, 89, 23};
    int min, max;
    findMinMax(arr, 6, &min, &max);
    cout << "Min: " << min << endl;
    cout << "Max: " << max << endl;
    return 0;
}

Challenge 5: Dynamic Array -- Create, Fill, and Print

Hard
Write a program that asks the user for a size n, dynamically allocates an array of n integers, fills it with the first n squares (1, 4, 9, ...), prints the array using pointer arithmetic, and properly deallocates the memory.
Sample Input
n = 5
Sample Output
Squares: 1 4 9 16 25
Use new[] to allocate, pointer arithmetic to fill and print, and delete[] to free. Do not use vector.
#include <iostream>
using namespace std;

int main() {
    int n;
    cout << "Enter size: ";
    cin >> n;

    int* arr = new int[n];

    // Fill using pointer arithmetic
    for (int* p = arr; p < arr + n; p++) {
        int idx = p - arr + 1;
        *p = idx * idx;
    }

    // Print using pointer arithmetic
    cout << "Squares: ";
    for (int* p = arr; p < arr + n; p++) {
        cout << *p << " ";
    }
    cout << endl;

    delete[] arr;
    arr = nullptr;
    return 0;
}

Challenge 6: Matrix Transpose Using Dynamic 2D Array

Hard
Dynamically allocate a 3x3 matrix using an array of pointers (int**), fill it with values 1-9, transpose it, and print both the original and transposed matrices. Free all allocated memory.
Sample Input
(No input required)
Sample Output
Original: 1 2 3 4 5 6 7 8 9 Transposed: 1 4 7 2 5 8 3 6 9
Use int** for the 2D array. Allocate rows with new int*[rows] and each row with new int[cols]. Free in reverse order.
#include <iostream>
using namespace std;

int main() {
    int rows = 3, cols = 3;

    // Allocate original matrix
    int** mat = new int*[rows];
    for (int i = 0; i < rows; i++)
        mat[i] = new int[cols];

    // Fill with 1-9
    int val = 1;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
            mat[i][j] = val++;

    // Print original
    cout << "Original:" << endl;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++)
            cout << mat[i][j] << " ";
        cout << endl;
    }

    // Allocate and compute transpose
    int** trans = new int*[cols];
    for (int i = 0; i < cols; i++)
        trans[i] = new int[rows];

    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
            trans[j][i] = mat[i][j];

    // Print transpose
    cout << "\nTransposed:" << endl;
    for (int i = 0; i < cols; i++) {
        for (int j = 0; j < rows; j++)
            cout << trans[i][j] << " ";
        cout << endl;
    }

    // Free memory
    for (int i = 0; i < rows; i++) delete[] mat[i];
    delete[] mat;
    for (int i = 0; i < cols; i++) delete[] trans[i];
    delete[] trans;

    return 0;
}

Need to Review the Concepts?

Go back to the detailed notes for this chapter.

Read Chapter Notes

Want to learn C++ with a live mentor?

Explore our C++ Masterclass