Question
Why `a[5]` Equals `5[a]` in C: Array Indexing and Pointer Arithmetic Explained
Question
In C, why does a[5] evaluate to the same thing as 5[a]?
As discussed in The C Programming Language and mentioned in the Stack Overflow podcast, this behavior is often explained as a result of pointer arithmetic. I understand that this is a property of arrays in C, but I do not yet understand why the two expressions are equivalent.
For example:
int a[] = {10, 20, 30, 40, 50, 60};
printf("%d\n", a[5]);
printf("%d\n", 5[a]);
Why do both expressions access the same element?
Short Answer
By the end of this page, you will understand how C array indexing is defined, why a[i] is really shorthand for *(a + i), and why that makes a[5] and 5[a] equivalent. You will also see how this relates to pointers, arrays, memory addresses, and common mistakes beginners make when working with them.
Concept
In C, the array subscript operator [] is defined in terms of pointer arithmetic.
The key rule is:
a[i] == *(a + i)
This means:
arefers to the starting address of the array's first element in most expressionsiis an offseta + imeans “move forwardielements”*(a + i)means “read the value at that computed address”
Because addition is commutative, these two expressions are equivalent:
a + i
i + a
So:
a[i] == *(a + i)
== *(i + a)
== i[a]
That is why a[5] and 5[a] access the same element.
Why this matters
This is important because arrays and pointers are closely related in C:
- arrays often decay to pointers in expressions
- pointer arithmetic is scaled by the size of the pointed-to type
- indexing syntax is just a convenient way to use pointer offsets
Understanding this helps you read C code correctly and avoid memory bugs.
Mental Model
Think of an array like a row of mailboxes.
ais the location of the first mailbox5means “move 5 boxes forward”*(a + 5)means “open the mailbox 5 positions after the first one”
Now imagine giving directions:
- “start at
a, move 5” - “move 5 from
a”
Both describe the same destination.
That is why:
a[5]
and
5[a]
lead to the same mailbox.
The [] operator in C is really just a convenient way of saying “go to this base address, then move by this offset, then dereference.”
Syntax and Examples
The core indexing rule in C is:
x[y] == *(x + y)
That means either side of [] participates in address calculation.
Basic example
#include <stdio.h>
int main(void) {
int a[] = {10, 20, 30, 40, 50, 60};
printf("a[5] = %d\n", a[5]);
printf("5[a] = %d\n", 5[a]);
return 0;
}
Output:
a[5] = 60
5[a] = 60
Both print the same value.
Equivalent forms
int value1 = a[2];
int value2 = *(a + );
value3 = *( + a);
value4 = [a];
Step by Step Execution
Consider this example:
#include <stdio.h>
int main(void) {
int a[] = {11, 22, 33, 44, 55, 66};
int result = 5[a];
printf("%d\n", result);
return 0;
}
Step-by-step
1. The array is created
int a[] = {11, 22, 33, 44, 55, 66};
Memory conceptually looks like this:
| Index | Value |
|---|---|
| 0 | 11 |
| 1 | 22 |
Real World Use Cases
Most programmers do not write 5[a] in production code, because it is confusing. But the idea behind it appears everywhere.
1. Accessing array elements
int nums[] = {4, 8, 15, 16, 23, 42};
int x = nums[3];
This is really pointer arithmetic under the hood.
2. Iterating through buffers
char message[] = "hello";
for (int i = 0; message[i] != '\0'; i++) {
printf("%c\n", message[i]);
}
Each message[i] is *(message + i).
3. Working with strings
C strings are character arrays, so indexing is extremely common:
char *name = "Alice";
printf("%c\n", name[1]);
4. Parsing binary data
Real Codebase Usage
In real C codebases, developers rely on indexing and pointer arithmetic in practical, readable ways.
Common patterns
Guarding bounds before indexing
int get_value(int *arr, int length, int index) {
if (index < 0 || index >= length) {
return -1;
}
return arr[index];
}
This avoids out-of-bounds access.
Iterating with indexes
for (int i = 0; i < length; i++) {
total += arr[i];
}
This is usually clearer than writing explicit pointer arithmetic.
Iterating with pointers
for (int *p = arr; p < arr + length; p++) {
total += *p;
}
This is equivalent in spirit, and sometimes preferred in low-level code.
Using early validation
int read_char(const char *text, index) {
(text == || index < ) {
;
}
text[index];
}
Common Mistakes
1. Thinking arrays and pointers are identical
They are related, but not the same.
int a[10];
int *p = a;
ais an array of 10 integerspis a pointer toint
They behave similarly in many expressions, but they are different types.
2. Forgetting that indexing is pointer arithmetic
Some beginners think a[i] is special syntax only for arrays. But pointers can be indexed too:
int *p = a;
printf("%d\n", p[2]);
This works because p[2] means *(p + 2).
3. Going out of bounds
int a[3] = {1, 2, 3};
printf("%d\n", a[5]); // wrong
Comparisons
| Concept | Meaning | Example | Notes |
|---|---|---|---|
a[i] | Element at index i | a[3] | Standard readable form |
*(a + i) | Dereference after pointer offset | *(a + 3) | Exactly equivalent to a[i] |
i[a] | Same as a[i] | 3[a] | Valid but unusual |
*a + i | First element value plus |
Cheat Sheet
x[y] == *(x + y)
Core rules
a[i]means elementifrom baseaa[i]is exactly the same as*(a + i)- therefore
i[a]is also valid - pointer arithmetic moves in units of the pointed-to type
a + 1forint *amoves bysizeof(int)bytes
Examples
int a[] = {10, 20, 30};
a[1]; // 20
*(a + 1); // 20
1[a]; // 20
Not the same
*a + 1 // first element plus 1
*(a + 1) // second element
Remember
FAQ
Why is 5[a] valid in C?
Because array subscripting is defined as *(a + i). Since a + i and i + a are equivalent, 5[a] means the same as a[5].
Is 5[a] good style?
No. It is valid, but unusual and confusing. Use a[5] in normal code.
Does this only work for arrays?
No. It also works for pointers:
int *p = a;
p[2];
2[p];
Are arrays and pointers the same in C?
Not exactly. Arrays and pointers are different types, but array names often decay to pointers in expressions.
Why does a + 1 move by one element instead of one byte?
Because pointer arithmetic is scaled by the size of the pointed-to type.
What does *(a + i) mean?
It means: start at address a, move forward i elements, then read the value stored there.
Mini Project
Description
Build a small C program that explores array indexing and pointer arithmetic side by side. The program will print values using normal indexing, pointer arithmetic, and reversed indexing such as 2[a]. This helps make the rule x[y] == *(x + y) concrete and visible.
Goal
Create a program that proves several equivalent forms of array access produce the same result.
Requirements
- Declare an integer array with at least five elements.
- Print the same element using
a[i],*(a + i), andi[a]. - Loop through the array and print every element using indexing.
- Loop through the array again using a pointer.
- Avoid any out-of-bounds access.
Keep learning
Related questions
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.
Definition vs Declaration in C and C++: What’s the Difference?
Learn the difference between declarations and definitions in C and C++ with simple examples, common mistakes, and practical usage.
Difference Between #include <...> and #include "..." in C and C++
Learn the difference between #include with angle brackets and quotes in C and C++, including search paths, examples, and common mistakes.