In C programming, understanding how arrays and pointers relate is fundamental for efficient and bug-free coding. Among the most common points of confusion are the distinctions between array, &array, and &array[0]. This article explores these concepts deeply, with illustrative examples, memory insights, and diagrams to clarify their differences and practical usage.
Introduction to Arrays, &array, and &array[0]
An array in C is a collection of elements of the same data type stored contiguously in memory. However, there are subtle differences when you use the array name alone, its address &array, or the address of its first element &array[0]. These expressions may appear similar but have distinct meanings and types in the context of C pointers and memory.
Understanding array, &array, and &array[0] Basics
&array, and &array[0] BasicsConsider this example declaration:
int arr[5] = {10, 20, 30, 40, 50};
arr: Refers to the address of the first element of the array, which can be used as a pointer toint.&arr: Refers to the address of the entire array, which is a pointer to an array of 5 integersint (*)[5].&arr[0]: Specifically, the address of the first element, same asarr, typeint *.
Though arr and &arr[0] point to the same memory location, their types differ from &arr, which points to the whole array object.
Memory Layout & Pointer Behavior Example
Here is a simple C program and its output to visualize the differences:
#include <stdio.h>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
printf("arr = %p\n", (void*)arr);
printf("&arr = %p\n", (void*)&arr);
printf("&arr[0] = %p\n", (void*)&arr[0]);
printf("sizeof(arr) = %zu bytes\n", sizeof(arr));
printf("sizeof(&arr) = %zu bytes\n", sizeof(&arr));
printf("sizeof(&arr[0]) = %zu bytes\n", sizeof(&arr[0]));
return 0;
}
Expected Output:
arr = 0x7ffee2b8e650 &arr = 0x7ffee2b8e650 &arr[0] = 0x7ffee2b8e650 sizeof(arr) = 20 bytes sizeof(&arr) = 8 bytes sizeof(&arr[0]) = 8 bytes
arr, &arr, and &arr[0] hold the same address but represent different pointer types and sizes. arr or &arr[0] is a pointer to int, while &arr is a pointer to the entire array of 5 ints, showing why sizeof(arr) is 20 bytes (5 * 4 bytes) but sizeof(&arr) is only the size of a pointer (8 bytes on 64-bit systems).
Type Differences and Pointer Arithmetic
The primary difference lies in pointer arithmetic, as the types determine how pointer increments behave:
arr + 1advances bysizeof(int)bytes (usually 4 bytes), pointing toarr[1].&arr + 1advances bysizeof(int[5])bytes (usually 20 bytes), pointing just after the entire array.&arr[0] + 1behaves the same asarr + 1.
Practical Uses and Considerations
- Use
arror&arr[0]when you want a pointer to the first element for iteration or array element access. - Use
&arrwhen you want to pass the entire array as a single pointer or emphasize the array boundary, especially with multidimensional arrays or when precise array sizes are required. - Functions receiving arrays typically use
int *arr, so passingarror&arr[0]is common and expected. - Using
&arras a pointer requires careful handling because its type is different and pointer arithmetic behaves differently.
Example: Function Parameters Differentiation
void func1(int *p) {
printf("%d\n", p[1]); // Access second element
}
void func2(int (*p)[5]) {
printf("%d\n", (*p)[1]); // Access second element of the whole array pointer
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
func1(arr); // arr decays to int*
func1(&arr[0]); // Equivalent to arr
func2(&arr); // Passing pointer to entire array
return 0;
}
Summary Table of Differences
| Expression | Type | Points To | Pointer Arithmetic | Typical Use |
|---|---|---|---|---|
arr |
int * |
First element arr[0] |
Advances by one element (int) |
Access elements, pass array to functions |
&arr |
int (*)[5] |
Whole array arr (all 5 elements) |
Advances by whole array size (5 * int) |
Manipulate entire array as one block |
&arr[0] |
int * |
First element arr[0] |
Advances by one element (int) |
Same as arr, pointer to first element |
Conclusion
Understanding the difference between array, &array, and &array[0] in C is crucial for pointer operations, memory management, and function interfaces. While array and &array[0] often can be used interchangeably as pointers to the first element, &array carries the full array type and size information, affecting pointer arithmetic and type safety. Using these correctly leads to clearer, safer, and more efficient C code.








