Passing Arrays to Functions

When you pass an array to a function in C++, it is implicitly converted to a pointer to its first element. This behavior is a key characteristic of arrays in C++, which makes understanding pointer arithmetic and memory layout critical. Let’s break down how this works.

How Arrays Are Passed to Functions

When you declare an array in C++, like:

int arr[5] = {1, 2, 3, 4, 5};

and pass it to a function:

void printArray(int arr[], int size) {
    for (int i = 0; i < size; ++i) {
        std::cout << arr[i] << " ";
    }
}

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    printArray(arr, 5);
    return 0;
}

The function parameter int arr[] is implicitly converted to a pointer (int* arr). So what’s actually passed to the function is a pointer to the first element of the array. Inside the printArray function, the parameter arr behaves like a pointer, and thus any size information about the original array is lost. You must manually pass the array size if needed.

Why Is an Array Passed as a Pointer?

This conversion from an array to a pointer is automatic in C++. When you pass an array to a function, only the memory address of the first element is passed. This reduces the overhead of copying the entire array into the function. However, the trade-off is that you lose information about the array’s size.

Equivalent Function Signature Using a Pointer

These two function signatures are equivalent:

void printArray(int arr[], int size); // Equivalent to:
void printArray(int* arr, int size);

Both are interpreted as taking a pointer to an integer (int*) as the first argument.

Implications of Array-to-Pointer Decay

When an array is passed to a function, it “decays” into a pointer. This means that:

  1. You cannot directly determine the size of the array within the function: The sizeof operator returns the size of the pointer, not the array. You need to pass the array size as an additional parameter.
  2. Pointer arithmetic can be performed: Inside the function, you can treat the array as a pointer and perform pointer arithmetic.

Example: Passing and Modifying an Array in a Function

Since the function receives a pointer to the array’s elements, any changes made to the array elements inside the function will affect the original array:

#include <iostream>

// Function to modify an array
void modifyArray(int arr[], int size) {
    for (int i = 0; i < size; ++i) {
        arr[i] = arr[i] * 2;  // Doubling each element
    }
}

int main() {
    int arr[5] = {1, 2, 3, 4, 5};

    modifyArray(arr, 5);

    // Printing the modified array
    for (int i = 0; i < 5; ++i) {
        std::cout << arr[i] << " ";
    }

    return 0;
}

Output: 2 4 6 8 10

In this case, the changes made inside modifyArray reflect in the original array because we’re working with pointers to the actual elements.

Arrays as Const Pointers

If you want to ensure that the function does not modify the array, you can pass it as a constant pointer:

void printArray(const int arr[], int size); // Equivalent to:
void printArray(const int* arr, int size);

This enforces that the function cannot change the elements of the array.

Summary

  • Arrays decay into pointers when passed to functions, and this pointer points to the first element of the array.
  • Inside the function, size information is lost, so you must pass the size separately.
  • Arrays are passed by reference through pointers, allowing modifications within the function to affect the original array.
  • Using const with array parameters can enforce immutability of the elements.

This behavior makes working with arrays in functions efficient, but it requires careful management of array sizes to avoid errors and unexpected behavior.