int arr[5] = {
10, 20, 30, 40, 50
}
;
int *p = arr;
// works! no & neededPointers vs Arrays in C: Similarities, Differences, and Examples
What is Pointers vs Arrays in C? Core Concept & Direct Summary
What are the exact technical differences and similarities between pointers and arrays in C memory?
"Is an array just a pointer?" It's one of the most-asked questions in C, and the honest answer is the one that frustrates people: almost, but not quite — and the gap between those two is exactly where the bugs live.
Arrays and pointers share syntax, share behavior in most expressions, and get treated as interchangeable in function parameters. Yet they are fundamentally different objects with different memory layouts, different sizeof results, and different rules about what you can change.
This page draws the line precisely. First the similarities (why they feel the same), then the differences (the ones that matter), then the specific situations that cause confusion — with code that demonstrates each.
(Suggested image: the hero diagram — two panels. Left: an array as a fixed block of five adjacent cells with a name label spanning it. Right: a pointer as one small box containing an address, with an arrow pointing at a separate block. Same look at the arrow, different objects.)
How Does Pointers vs Arrays in C Work? In-Depth Mechanics & Architecture
Why They Feel the Same
Start with the parts that genuinely overlap, because they explain most of the confusion.
Similarity 1: The name gives an address
The array name arr, used as a value, evaluates to the address of its first element. So p = arr and p = &arr[0] are the same assignment. This is the foundation of the whole relationship.
Similarity 2: Indexing works identically
Both give 30. You can index a pointer exactly like an array, because (as we covered in the pointer arithmetic tutorial) x[i] is defined as *(x + i) — and that definition applies to any pointer or array.
Similarity 3: Pointer arithmetic works on both
Same mechanism, same result.
Similarity 4: Function parameters erase the distinction
So when you pass arr to f, you're passing a pointer either way. Inside f, there's no array anymore — just a pointer. This is the single biggest source of "arrays and pointers are the same" belief, because in functions, they are.
(Suggested image: the four similarities as small code cards with checkmarks, labeled "identical behavior")
Where They Genuinely Differ
Now the part that matters. Four real differences.
Difference 1: The array has its own storage — the pointer doesn't
An array owns its elements. A pointer is just an address holder; the memory it points to belongs to something else (or nothing at all, until assigned).
Practical consequence: you can't just have a pointer and start storing into it.
This is the #1 practical difference. An array is usable immediately; a pointer needs a valid target first.
(Suggested image: array = boxes with values inside; uninitialized pointer = an arrow pointing at "????" with a warning symbol)
Difference 2: sizeof reports different things
sizeof on an array gives the total bytes of all elements. sizeof on a pointer gives the pointer's own size — always 8 (64-bit) or 4 (32-bit), regardless of how big the array behind it is.
This is the difference with real consequences, covered extensively in the array-size tutorial:
The rule:sizeof knows the array only where the array was declared. Anywhere else — function parameters, pointers — it reports the pointer.
Difference 3: The pointer can be reassigned; the array name cannot
This is the crucial distinction. The array name is a constant address — it references the same storage forever and can't be redirected. A pointer variable can be pointed anywhere, any time.
You can still change array elements:
But you cannot make a refer to different memory. That's the line.
Difference 4: The compiler tracks the array's size
An array type includes its length. The compiler can validate things like int arr[5] and report sizeof accurately, and it may warn about obvious out-of-bounds access on a known-size local array. A pointer type carries no length information at all — the compiler can't warn you about anything.
(Suggested image: a four-row summary table as a graphic — the four differences with array behavior in one column and pointer behavior in the other)
The Comparison Table
(Suggested image: this table styled as a clean infographic — the most linkable asset on the page)
The Key Idea: "Decay"
The mechanism behind most of the similarity is called decay, and it's worth naming precisely.
In most expressions, an array name is automatically converted to a pointer to its first element:
Where an array does NOT decay — the three exceptions where it stays an array:
- As the operand of
sizeof→sizeof(arr)gives the full array size - As the operand of
&→&arris a pointer to the whole array (typeint (*)[5], notint *) - As a string literal initializing a
chararray →char s[] = "text";copies into the array
Everywhere else, "the array" really means "a pointer to its first element." Understand the three exceptions and decay stops being mysterious.
A genuinely interesting consequence — &arr vs arr:
Same numeric address, different types, wildly different arithmetic. A subtle point that marks the boundary of array-versus-pointer understanding — and a favorite interview question.
(Suggested image: the arr vs &arr arrows over the same array — one arrow to element 0, one arrow spanning the whole block — with the +1 results shown differently)
Where the Confusion Bites: Five Demonstrations
1. Inside a function, it's always a pointer
Even though the parameter looks like an array, it's a pointer. This is why arrays need a separate size parameter.
2. You can't assign arrays to each other
Arrays aren't assignable in C. Copy element by element, or use memcpy. (Pointers assign freely — p = q works.)
3. Returning a local array doesn't work — but the failure is a pointer failure
The function can return a pointer. The problem is that the storage it points at no longer exists. This is the dangling-pointer trap — and it's specifically a pointer problem, not an array one.
4. sizeof changes as soon as you leave the declaring scope
Globals are a partial exception (the compiler still sees the declaration), but parameters never are.
5. Strings: the boundary in practice
Same-looking initializations, completely different objects. This is the array-pointer difference in its most practically dangerous form — the same trap from the strings basics tutorial.
(Suggested image: the five confusions as a numbered list graphic with the key line of code beside each)
A Complete Example: Same Result, Both Views
Here's a program showing how the two are used side by side, and where they must be used differently:
Sample Run:
Everything from this page, demonstrated:
sizeofdiffers — 24 for the array, 8 for the pointer, from the same starting addresssizeof(arr)/sizeof(arr[0])works only becausearris still a genuine array inmain- Identical output from array notation and pointer notation
- Pointer walking with
start < end— legal comparison because both pointers are within the same array (plus one-past-the-end) - Reassignment works for
p, and the commented-outarr = othershows the line that would not compile
Note the sumWalk function signature: it takes two pointers, and the caller computes arr + n as the end boundary. That's the pointer arithmetical view of a range — and it's exactly how std::begin/std::end ranges and many C library APIs are shaped.
Common Confusions and Their Fixes
- "Arrays and pointers are the same." They behave the same in most expressions, but an array has storage and a pointer holds an address. Different objects, similar usage.
sizeofinside functions — always a pointer there. Pass the size.- "I can reassign an array." No — the name is fixed. Use a pointer if you need to redirect.
- "A pointer has memory I can fill." Only after pointing it at real storage (an array, or
malloc). - "
&arris the same asarr." Same address value, different type, different arithmetic (+1 moves 4 bytes vs 20). - Declaring
int *p[5]vsint (*p)[5]— the first is an array of 5 pointers; the second is a pointer to an array of 5 ints. Both legal, completely different. (A whole topic in itself.) - Comparing
arr == p— legal (address comparison), and it may be true, but it compares addresses not contents. For contents, compare element by element. - Assuming the compiler protects either one — neither arrays nor pointers are bounds-checked. The array's type carries length info, but nothing enforces access limits at runtime.
(Suggested image: "8 Confusions Fixed" checklist graphic — consistent with the series)
Final Thoughts
The honest summary, in one paragraph: an array is a block of storage; a pointer is a variable holding an address. They behave identically in most expressions because the array's name decays to a pointer to its first element — so indexing, arithmetic, and function passing all work the same. But they diverge precisely where it matters: sizeof (full size vs address size), assignment (fixed name vs reassignable), storage ownership (owned vs borrowed), and compiler knowledge of length (known vs unknown).
The exceptions to decay — sizeof, &, and string initialization — are the three places to keep in mind. Everything else follows.
And the practical payoff: knowing this distinction is what lets you write correct array functions (size passed separately), avoid the dangling-pointer return, and understand why char s[] = "text" and char *s = "text" are not interchangeable. That's a genuinely large fraction of C's difficult-beginner territory, resolved by one clear line.
Runnable C Code Example & Practical Implementation
#include <stdio.h>
int main() {
int arr[5] = {
1, 2, 3, 4, 5
};
int *ptr = arr;
printf("sizeof(arr): %zu bytes (Whole array)\
", sizeof(arr));
printf("sizeof(ptr): %zu bytes (Pointer variable)\
", sizeof(ptr));
printf("arr[2] == *(ptr + 2): %d\
", arr[2] == *(ptr + 2));
return 0;
}Key Takeaways, Best Practices & Memory Safety Rules
sizeof on an array returns the total array size, while sizeof on a pointer returns pointer width.Frequently Asked Questions & Technical Interview Insights
Technical Interview & Viva Questions
Frequently asked C programming interview questionsQ: Is an array strictly a constant pointer in C?
Q: Can you write `arr++` on an array name?
Related Tools, Tutorials & Authoritative References
Recommended Interactive Tools
- Online C Compiler & Runner — Interactive online GCC sandbox to execute C code in real time.
- Online C Code Editor & IDE — Multi-file C programming environment with code formatting.
- C++ Programming Tutorial — Transition from procedural C to Object-Oriented C++ with STL.
- JavaScript Programming Tutorial — Master modern JavaScript fundamentals, DOM APIs, and async patterns.
Authoritative Standards & Citations
- ISO/IEC 9899 (C Language Standard) — Official international C specification by ISO/IEC JTC 1/SC 22/WG 14.
- GNU GCC Documentation — Official reference manual for the GNU Compiler Collection and C libraries.
- The C Programming Language (K&R) — Definitive classic work by Brian Kernighan & Dennis Ritchie at Bell Labs.
- C Reference Documentation (cppreference.com) — Verified reference covering C89 through C23 language features.