Array Name as Pointer in C – Why *(a + 1) Equals a[1]

*(a + 1) looks like pointer code, but a is an array — is that even allowed? Not only allowed: it’s the very definition of how arrays work in C. This question from our C Programming Quiz App tests array decay — the rule that quietly converts every array name into a pointer, and makes a[1] and *(a + 1) the same expression in two spellings.

The Quiz Question

int a[3] = {1, 2, 3};
printf("%d", *(a + 1));

What is printed by this code?

  1. 1
  2. 2
  3. 3
  4. Address of a[1]

The Correct Answer: 2

In an expression, the array name a decays to a pointer to its first element. a + 1 then advances that pointer by one element (not one byte), landing on the second element, and the * dereferences it: 2. Verified on gcc 13.3 and Apple clang 21, clean under -ansi -Wall -Wextra:

$ gcc -ansi -Wall -Wextra decay.c && ./a.out
*(a + 1) = 2
a[1]     = 2
1[a]     = 2
a      = 0x7ffe1ac4ed9c
a + 1  = 0x7ffe1ac4eda0

Note the two addresses: they differ by 4 — one int — even though we only added 1. Pointer arithmetic is always scaled by the element size.

Why Each Wrong Answer Is Wrong

Why not 1?

1 is *(a + 0) — the first element. The + 1 genuinely moves one element forward; it isn’t swallowed by the decay. Readers who pick this are treating a + 1 as “still the array”.

Why not 3?

3 lives at *(a + 2). Picking 3 usually comes from 1-based thinking — “the 1st element” — but C counts from zero: a + 1 is the element at index 1, which is the second value.

Why not “Address of a[1]”?

a + 1 alone is that address — but the expression has a * in front. The dereference collects the value stored there. (And %d would be the wrong way to print an address anyway; that takes %p.)

a[i] Is Defined as *(a + i)

This isn’t a coincidence or a compiler courtesy — the C standard defines the subscript operator by the identity:

a[i]  ≡  *(a + i)

Every consequence follows mechanically. Since addition commutes, *(a + i) is *(i + a), which means the notorious 1[a] spelling is legal and prints 2 here as well (see the output above). Subscripting works on any pointer, not just array names. And it explains why arrays index from zero: a[0] is *(a + 0), the element at zero distance from the start.

One boundary worth knowing: decay applies in expressions, but not to sizeof a, &a, or a string literal initializing an array. That’s why sizeof(a) here is still 12 (three ints) rather than pointer size — the array hasn’t decayed inside sizeof. The moment you pass a to a function, though, decay happens and the size information is gone. For the full arithmetic story — including what p + 1 means for other element types — see pointer arithmetic in C.

Frequently Asked Questions

Is *(a + 1) the same as a[1]?

Yes, by definition. The C standard defines a[i] as *(a + i), so the two spellings compile to identical code. For int a[3] = {1, 2, 3}, both yield 2.

Does a + 1 add one byte or one element?

One element. Pointer arithmetic is scaled by the pointed-to type’s size, so with int elements, a + 1 is 4 bytes past a on typical platforms — as the printed addresses show.

What is array decay in C?

In most expressions, an array name converts automatically to a pointer to its first element. Exceptions: sizeof a, &a, and string literals used as initializers. After decay (for example, inside a called function), the array’s size is no longer recoverable from the pointer.

Related Reading

Recommended Books

This question is #134 in the C Programming Quiz App — 155 questions with explanations covering arrays, strings, pointers, and more.
Download on Google Play →

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>