advanced20 min

Pointer Arithmetic and Arrays as Pointers

How array indexing and pointer arithmetic are really the same operation underneath.

What you'll learn

  • Explain that an array name decays to a pointer to its first element in most expressions
  • Predict the result of pointer arithmetic like *(p + 1)
  • Recognize that nums[i] and *(nums + i) are equivalent

Explanation

In most expressions, an array name decays into a pointer to its first element. Given int nums[4] = {10, 20, 30, 40};, writing int *p = nums; makes p point to nums[0], without needing &nums[0] explicitly -- the array name alone already behaves like that address in this context.

Pointer arithmetic doesn't move by raw bytes; p + 1 moves forward by exactly one element of p's pointed-to type, not one byte -- the compiler already knows to scale by sizeof(int) (or whatever type p points to) automatically. So *(p + 1) dereferences the element right after wherever p currently points, which is why array indexing and pointer arithmetic end up being the same operation underneath: nums[i] is defined to mean exactly *(nums + i), and C actually uses this equivalence directly rather than treating indexing as some separate, special mechanism.

A pointer variable, unlike an array, can be reassigned to point elsewhere: p++; moves p forward by one element, so after p++, *p now refers to what was nums[1], not nums[0] anymore. This is genuinely useful for walking through an array without needing a separate index variable, but it also means a pointer can be advanced past the end of a valid array with nothing stopping you -- reading or writing through it there is undefined behavior.

Guided lab

Predict: Pointer arithmetic over an array

CNot executed
This lab does not run in your browser or on VisaSparkSchools's servers. Read the code, predict what it does, then reveal the real expected output.

Read this program and predict exactly what it prints, one value per line.

#include <stdio.h>

int main(void) {
    int nums[4] = {10, 20, 30, 40};
    int *p = nums;

    printf("%d\n", *p);
    printf("%d\n", *(p + 1));
    printf("%d\n", nums[2]);
    printf("%d\n", *(nums + 2));

    p++;
    printf("%d\n", *p);

    return 0;
}

Stuck? Get a hint.

Common mistakes

  • Assuming `p + 1` advances a pointer by one byte, forgetting the compiler scales the step by the size of the pointed-to type.
  • Advancing a pointer past the end of its array (or before its start) and dereferencing it there, which reads or writes outside the array's valid memory.
  • Confusing an array (whose size is fixed and whose name can't be reassigned) with a pointer (which can be reassigned to point anywhere).

Knowledge check

Knowledge check

1. What does `nums[i]` mean in terms of pointer arithmetic?
2. If `p` points to an int, what does `p + 1` actually advance by?
3. What happens to an array name in most expressions?

Takeaway

nums[i] and *(nums + i) mean exactly the same thing in C -- pointer arithmetic scales automatically by the pointed-to type's size, not raw bytes.

Summary

An array name decays to a pointer to its first element; pointer arithmetic advances by whole elements, and array indexing is defined directly in terms of it.

References

Your notes

Notes save automatically.

Finished this lesson?

Mark it complete to track your progress and schedule a future review.