*(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
- 2
- 3
- 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
- Pointer Arithmetic in C – *(p + 1) Explained
- 2[a] Array Indexing in C – Why It’s Legal
- Pointers in C – Complete Guide
- Array Summation Using Pointers
Recommended Books
- The C Programming Language – Kernighan & Ritchie (India) | Amazon.com
- C Programming: A Modern Approach – K.N. King (India) | Amazon.com
This question is #134 in the C Programming Quiz App — 155 questions with explanations covering arrays, strings, pointers, and more.
Download on Google Play →