Why arr, &arr, and arr[0] Aren’t the Same in C++

Table of contents
- Introduction
- 1. What is an Array in C++?
- 2. How Arrays Relate to Pointers
- ❌ 3. The Wrong Way: int* p = &arr;
- 4. Correct Way to Get Array’s Address
- 🛑 5. Don’t Do This: Assigning a Value to a Pointer
- 7. Using Pointers to Traverse, Access, and Modify Array Elements
- But... Why Use Pointers Instead of Indexes?
- How to Traverse an Array Using Pointers
- Modifying Array Elements with Pointers
- 🧩 Summary: What You Can Do With Pointers to Arrays
- Bonus Insight: ptr[i] Works Just Like arr[i]
- Why This Works?
- ✅ Updated Example Using ptr[i] Directly:
- Conclusion: Your Final Pointer Options
- 7. Memory Layout: Visualized
- 🔚 Final Summary Table
- Complete Working Example
- Conclusion

Introduction
If you’ve worked with arrays and pointers in C++, you might have noticed some confusing behavior. For example, arr == &arr[0]
works fine, but int* p = &arr;
throws an error. In this post, I’ll explain what’s going on behind the scenes with simple examples, why these things behave differently, and how pointers actually work with arrays.
1. What is an Array in C++?
When you declare:
int arr[] = {3, 45, 6, 78, 89, 9, 0};
You're telling the compiler to:
Allocate 7 consecutive memory locations, each capable of storing an
int
.Name the starting point of this block as
arr
.
2. How Arrays Relate to Pointers
arr
itself acts like a constant pointer to the first element, meaning arr == &arr[0]
.You can assign the array name to a pointer:
int* p1 = arr; // ✅ valid
int* p2 = &arr[0]; // ✅ valid
Both p1
and p2
now point to the first element of the array (arr[0]
).
cout << p1 << endl; // prints address of arr[0]
cout << &arr << endl; // prints address of the entire array (same address, different type!)
cout << &arr[0] << endl; // prints address of arr[0]
Though &arr
and &arr[0]
may print the same value, they are not the same in type.
Key Type Differences
Expression | Type | Meaning |
arr | int* | Pointer to the first element |
&arr[0] | int* | Address of the first element |
&arr | int (*)[7] | Pointer to the entire array |
Think of
&arr
as: “Here’s the whole array block.”
Think of&arr[0]
orarr
as: “Here’s where the block begins.”
❌ 3. The Wrong Way: int* p = &arr;
It may be completely valid for variables but this is complete opposite of that
int* p = &arr; // ❌ Invalid!
This leads to a type mismatch, because:
&arr
is of typeint (*)[7]
(pointer to array of 7 integers)p
is of typeint*
(pointer to a single int)
Even though both arr
and &arr
may point to the same address, they are fundamentally different in what they point to.
Trying to use
int* p = &arr;
will either:
Fail to compile, or
Work with unsafe behavior (e.g., pointer arithmetic won't work as expected)
4. Correct Way to Get Array’s Address
If you really want to point to the entire array, you should write:
In most real-world cases, you just need a pointer to the first element:
int* p = arr; // ✅ Common and clean
🛑 5. Don’t Do This: Assigning a Value to a Pointer
int* p = arr[0]; // ❌ WRONG!
Why this fails:
arr[0]
is the value stored in the array (like3
), not its address.You're trying to store an
int
into anint*
(pointer) → invalid!
7. Using Pointers to Traverse, Access, and Modify Array Elements
Pointers aren't just for accessing the first element. Once you have a pointer to the start of an array, you can:
✅ Traverse the array
✅ Access each element
✅ Modify elements directly — without using array indexing (arr[i]
)
But... Why Use Pointers Instead of Indexes?
Using pointers gives:
More control over memory.
Efficient low-level access (important in systems programming).
Better performance in some cases (like iterators in STL).
It's a must for dynamic memory (
new[]
,malloc()
, etc.).
How to Traverse an Array Using Pointers
#include <iostream>
using namespace std;
int main() {
int arr[] = {10, 20, 30, 40, 50};
int* ptr = arr; // Same as &arr[0]
cout << "Accessing array using pointer:\n";
for (int i = 0; i < 5; i++) {
cout << "Element " << i << ": " << *(ptr + i) << endl;
}
return 0;
}
💡 Explanation:
ptr
points toarr[0]
*(ptr + i)
gives the value atarr[i]
ptr + i
moves the pointer to the ith memory location
✅ This is called pointer arithmetic
Modifying Array Elements with Pointers
Let’s say you want to double all elements of an array:
#include <iostream>
using namespace std;
int main() {
int arr[] = {1, 2, 3, 4, 5};
int* ptr = arr;
for (int i = 0; i < 5; i++) {
*(ptr + i) *= 2; // Modify value at each location
}
cout << "Modified array:\n";
for (int i = 0; i < 5; i++) {
cout << arr[i] << " "; // Now shows: 2 4 6 8 10
}
return 0;
}
🧩 Summary: What You Can Do With Pointers to Arrays
Operation | Example | Description |
Access | *(ptr + i) | Access the value at arr[i] |
Modify | *(ptr + i) = x; | Change the value at arr[i] |
Traverse | ptr++ in loop | Move from one element to next |
Range Loop | while (ptr < arr+N) | Loop from start to end via pointer |
Bonus Insight: ptr[i]
Works Just Like arr[i]
Once you have a pointer to the beginning of the array:
int* ptr = arr;
You can absolutely use:
ptr[i] // same as *(ptr + i)
This works because in C++, array indexing is just syntactic sugar over pointer arithmetic.
ptr[i]
is defined as*(ptr + i)
arr[i]
is defined as*(arr + i)
Even cooler:
i[arr] == arr[i] // damnnn this is true!
Why This Works?
Because array subscript notation is defined like this:
cppCopyEdita[b] ≡ *(a + b)
So whether arr
is the array or ptr
is a pointer:
ptr[i]
→ gets the value at offseti
from the pointerptr[i] = 100
→ modifies that value
✅ Updated Example Using ptr[i]
Directly:
#include <iostream>
using namespace std;
int main() {
int arr[] = {5, 10, 15, 20};
int* ptr = arr;
for (int i = 0; i < 4; i++) {
cout << "Value at index " << i << ": " << ptr[i] << endl;
}
// Modifying values using pointer
for (int i = 0; i < 4; i++) {
ptr[i] *= 2;
}
cout << "Modified array:\n";
for (int i = 0; i < 4; i++) {
cout << arr[i] << " "; // Output: 10 20 30 40
}
return 0;
}
Conclusion: Your Final Pointer Options
Expression | Purpose |
ptr[i] | Access using array-style syntax |
*(ptr + i) | Access using pointer arithmetic |
ptr++ | Move to next element (use with care!) |
Both styles are valid. Which one to use depends on:
Readability
Performance (negligible difference in most cases)
Personal or team preference
7. Memory Layout: Visualized
Here’s how your array looks in memory:
cssCopyEditAddress Value
0x1000 3 ← arr[0]
0x1004 45 ← arr[1]
0x1008 6 ← arr[2]
... ...
Now,
arr
or&arr[0]
→ points to0x1000
arr + 1
or&arr[1]
→ points to0x1004
And so on...
So you can do pointer arithmetic:
int* p = arr;
cout << *(p + 2); // Output: 6 (arr[2])
🔚 Final Summary Table
Expression | Valid? | Meaning |
int* p = arr; | ✅ | Pointer to first element |
int* p = &arr[0]; | ✅ | Also pointer to first element |
int* p = &arr; | ❌ | Type mismatch (&arr is pointer to whole array) |
int (*p)[7] = &arr; | ✅ | Pointer to the entire array |
int* p = arr[0]; | ❌ | Invalid: assigning int to int pointer |
Complete Working Example
#include<iostream>
using namespace std;
int main() {
int arr[] = {3, 45, 6, 78, 89, 9, 0};
int* p1 = arr;
cout << "p1 (arr): " << p1 << endl;
cout << "&arr: " << &arr << endl;
cout << "&arr[0]: " << &arr[0] << endl;
// int* p2 = arr[0]; // ❌ Error: assigning int to pointer
int* p3 = &arr[0];
cout << "p3 (&arr[0]): " << p3 << endl;
// int* p4 = &arr; // ❌ Invalid, explained above
int (*p5)[7] = &arr; // ✅ Pointer to the whole array
cout << "p5 (&arr): " << p5 << endl;
cout << "(*p5)[2] (arr[2]): " << (*p5)[2] << endl;
return 0;
}
Conclusion
Understanding the small but important differences between arr
, &arr
, and arr[0]
helps you build a solid grasp of how arrays and pointers behave in C++. These are not just minor syntax details — they affect how your code works at the memory level. Knowing how pointers interact with arrays makes it easier to debug pointer-related issues, write cleaner code, and handle more advanced concepts like pointer arithmetic, dynamic memory allocation using new
and delete
, working with functions that take pointers as arguments, and even low-level tasks like writing your own data structures or memory-efficient code. If you’re planning to go deeper into system programming or just want to be confident with C++, this is one of the fundamentals you can’t skip.
Subscribe to my newsletter
Read articles from Santwan Pathak directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Santwan Pathak
Santwan Pathak
"A beginner in tech with big aspirations. Passionate about web development, AI, and creating impactful solutions. Always learning, always growing."