C Pointers and Arrays

Arrays and pointers are close relatives in C. When you use an array's name in most expressions, it decays into a pointer to its first element. Once you understand this connection, you can walk through arrays using pointers just as easily as using an index.

The array name is an address

If you have an array called numbers, then the bare name numbers acts like &numbers[0], the address of the first element. That means you can assign it directly to a pointer without using the & operator.

Pointing at an array

#include <stdio.h>

int main() {
    int numbers[3] = {10, 20, 30};
    int *p = numbers;   // same as &numbers[0]

    printf("First element: %d\n", *p);       // 10
    printf("Also first: %d\n", numbers[0]);  // 10
    return 0;
}

Looping with a pointer

Because the elements of an array sit next to each other in memory, adding one to a pointer moves it to the next element. You can use this to iterate without ever writing square brackets.

Walking an array with a pointer

#include <stdio.h>

int main() {
    int values[4] = {5, 15, 25, 35};
    int *p = values;

    for (int i = 0; i < 4; i++) {
        printf("Element %d = %d\n", i, *(p + i));
    }
    return 0;
}

The expression *(p + i) is exactly what values[i] means under the hood. In fact, C defines the subscript operator in terms of this pointer math, which is why both give the same result.

  • numbers[i] and *(numbers + i) are equivalent expressions.
  • The array name cannot be reassigned, but a pointer variable can.
  • sizeof(array) gives the whole array size, while sizeof(pointer) only gives the pointer size.
ExpressionMeaning
arrAddress of the first element
arr[2]Third element by index
*(arr + 2)Third element by pointer math
&arr[2]Address of the third element
Note: Although arrays and pointers behave alike in expressions, they are not identical. An array reserves storage for all its elements, while a pointer only holds an address and must be pointed at valid memory before use.