C Notes
Understand the deep connection between pointers and arrays in C, array name as pointer, pointer-based array access, and key differences with practical examples.
One of the most important concepts in C is the intimate relationship between pointers and arrays. They are not the same thing — but they're so closely related that in many contexts, they behave identically. Understanding exactly where they overlap and where they differ is key to writing correct and efficient C code.
The Fundamental Connection
When you use an array name in an expression, it automatically "decays" into a pointer to its first element:
Equivalent Access Methods
There are multiple ways to access the same array element:
arr[2] = 300 *(arr + 2) = 300 ptr[2] = 300 *(ptr + 2) = 300 2[arr] = 300
The subscript operator [] is actually defined as: a[b] ≡ *(a + b). Since addition is commutative, a[b] = b[a] — which is why 2[arr] works (though you should never write it that way in real code!).
Using Pointers to Traverse Arrays
Element | Address | ptr offset --------|------------|---------- 5 | 0x7ffd0010 | ptr + 0 10 | 0x7ffd0014 | ptr + 1 15 | 0x7ffd0018 | ptr + 2 20 | 0x7ffd001c | ptr + 3 25 | 0x7ffd0020 | ptr + 4 30 | 0x7ffd0024 | ptr + 5
Key Differences: Array vs Pointer
Despite their similarities, arrays and pointers are not the same:
sizeof(arr) = 20 (total array size) sizeof(ptr) = 8 (pointer size only) &arr = 0x7ffd00100010 (address of entire array) &ptr = 0x7ffd00100028 (address of pointer variable) arr = 0x7ffd00100010 (decays to &arr[0]) ptr = 0x7ffd00100010 (value stored in ptr)
Complete Difference Table
| Feature | int arr[5] | int *ptr |
|---|---|---|
sizeof() | Total array bytes (20) | Pointer size (4 or 8) |
| Modifiable? | Cannot reassign (arr = ...) | Can reassign (ptr = ...) |
| Memory | Contains the actual data | Contains only an address |
&variable | Address of array block | Address of pointer variable |
| Storage | Usually stack | Variable that can point anywhere |
| Existence | Always valid while in scope | May be NULL or dangling |
Pointer to an Entire Array
There's a subtle difference between int *p (pointer to int) and int (*p)[5] (pointer to array of 5 ints):
p = 0x7ffd0010 p + 1 = 0x7ffd0014 (advances 4 bytes) ap = 0x7ffd0010 ap + 1 = 0x7ffd0024 (advances 20 bytes)
p + 1 advances by one int (4 bytes), while ap + 1 advances by one entire array of 5 ints (20 bytes).
Array of Pointers vs Pointer to Array
Array of pointers: arrOfPtrs[0] = 0x7ffd001c → 10 arrOfPtrs[1] = 0x7ffd0020 → 20 arrOfPtrs[2] = 0x7ffd0024 → 30 Pointer to array: (*ptrToArr)[0] = 100 (*ptrToArr)[1] = 200 (*ptrToArr)[2] = 300
| int *arrOfPtrs[3] | (Array of 3 pointers) |
| int (*ptrToArr)[3] | (One pointer to array of 3) |
| │ &nums ─┼─────── | │100 │200 │300 │ Points to entire array |
Practical Example: Pointer-Based String Array
Programming languages: 1. C (at 0x400800) 2. Python (at 0x400802) 3. JavaScript (at 0x400809) 4. Rust (at 0x400814) 5. Go (at 0x400819) Memory comparison: Pointer array: 40 bytes 2D char array: 75 bytes
When Decay Does NOT Happen
Array-to-pointer decay does not occur in these cases:
sizeof(arr)— returns full array size&arr— gives pointer to entire array, not pointer to first element- String literal initialization:
char str[] = "Hello"copies the string
Interview Questions
Q1: Are arrays and pointers the same thing in C?
No. An array is a fixed-size block of contiguous memory; a pointer is a variable holding an address. However, in most expressions, an array name decays to a pointer to its first element, which is why they often appear interchangeable.
Q2: What does arr + 1 return when arr is int arr[5]?
It returns a pointer to arr[1] — the address of the second element. The compiler adds 1 × sizeof(int) bytes to the base address. To get the value, you'd dereference it: *(arr + 1).
**Q3: What's the difference between int *p[10] and int (*p)[10]?**
int *p[10] is an array of 10 pointers to int. int (*p)[10] is a pointer to an array of 10 ints. The parentheses change the binding of * with p.
Q4: Why does sizeof(arr) give the full size inside main but pointer size inside a function?
Because when passed to a function, the array decays to a pointer. The function parameter int arr[] is actually int *arr. Inside main, arr is still an array, so sizeof reports the total allocated memory.
Summary
- Array names decay to pointers to their first element in most expressions
arr[i]is equivalent to*(arr + i)— both use pointer arithmetic internally- Arrays cannot be reassigned or incremented; pointers can
sizeof(array)gives total size;sizeof(pointer)gives pointer sizeint *p[N]is array of pointers;int (*p)[N]is pointer to array- Decay doesn't occur with
sizeof,&, or string literal initialization - Pointer-based string arrays are more memory-efficient than 2D char arrays
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Pointers and Arrays in C - The Relationship Explained.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this C Programming topic.
Search Terms
c-programming, c programming, programming, pointers, and, arrays, pointers and arrays in c - the relationship explained
Related C Programming Topics