What's in a name?
In C, pointers and arrays are closely related concepts. In fact, arrays in C are essentially a contiguous block of memory, and the name of the array often decays into a pointer to the first element. This is why you can use pointer notation to access array elements.
Let's go through an example with well-commented code:
#include <stdio.h>
int main() {
// Declare an array of integers
int myArray[5] = {10, 20, 30, 40, 50};
// Declare a pointer to an integer and initialize it with the address of the first element of the array
int *ptr = myArray;
// Access array elements using array notation
printf("Using array notation:\n");
for (int i = 0; i < 5; ++i) {
printf("myArray[%d] = %d\n", i, myArray[i]);
}
// Access array elements using pointer notation with bracket syntax
printf("\nUsing pointer notation:\n");
for (int i = 0; i < 5; ++i) {
// The following two lines are equivalent
printf("*(ptr + %d) = %d\n", i, *(ptr + i));
printf("ptr[%d] = %d\n", i, ptr[i]);
}
return 0;
}
In this example:
We declare an array
myArray
of integers with five elements.We declare a pointer to an integer
ptr
and initialize it with the address of the first element ofmyArray
.We use a loop to print the elements of
myArray
using array notation (myArray[i]
).We use another loop to print the elements of
myArray
using pointer notation with bracket syntax (ptr[i]
is equivalent to*(ptr + i)
).
In C, ptr[i]
is equivalent to *(ptr + i)
, so you can use either notation to access array elements through a pointer. The bracket notation provides a convenient and readable way to work with pointers like arrays.
In C, a multidimensional array is essentially an array of arrays. The name of a multidimensional array, when used in an expression, represents the address of its first element. Let's go through an example with a two-dimensional array:
#include <stdio.h>
int main() {
// Declare a 2D array of integers
int myArray[3][4] = {
{10, 20, 30, 40},
{50, 60, 70, 80},
{90, 100, 110, 120}
};
// Declare a pointer to an array of integers and initialize it with the address of the first row of the 2D array
int (*ptr)[4] = myArray; // pointer to an array of 4 integers
// Access 2D array elements using array notation
printf("Using array notation:\n");
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 4; ++j) {
printf("myArray[%d][%d] = %d\n", i, j, myArray[i][j]);
}
}
// Access 2D array elements using pointer notation with bracket syntax
printf("\nUsing pointer notation:\n");
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 4; ++j) {
// The following two lines are equivalent
printf("ptr[%d][%d] = %d\n", i, j, ptr[i][j]);
printf("*(*(ptr + %d) + %d) = %d\n", i, j, *(*(ptr + i) + j));
}
}
return 0;
}
The expression ptr[i][j]
can be equivalently expressed using pointer arithmetic as *(*(ptr + i) + j)
. Let's break down the equivalence:
ptr[i]
: This expression represents the ith row of the 2D array. It's equivalent to*(ptr + i)
because the name of the arrayptr
by itself is a pointer to the first row, and addingi
moves the pointer to the ith row.ptr[i][j]
: This expression further accesses the jth element in the ith row of the 2D array. It's equivalent to*(*(ptr + i) + j)
because*(ptr + i)
gives the address of the ith row, and addingj
moves to the jth element in that row.
So, in summary, ptr[i][j]
is equivalent to *(*(ptr + i) + j)
in terms of pointer arithmetic.
ptr
is not a double-pointer. It is a pointer to an array of integers (specifically, an array of 4 integers). The type of ptr
is int (*)[4]
.
A double-pointer in C would be a pointer that points to another pointer. In the context of a 2D array, a double pointer could be used to point to an array of pointers, where each pointer points to a row of the 2D array. Here's an example:
#include <stdio.h>
int main() {
// Declare a 2D array of integers
int myArray[3][4] = {
{10, 20, 30, 40},
{50, 60, 70, 80},
{90, 100, 110, 120}
};
// Declare a double pointer to int and initialize it with the address of the first row of the 2D array
int **ptr = (int **)myArray; // casting to int**
// Access 2D array elements using double pointer notation
printf("Using double pointer notation:\n");
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 4; ++j) {
printf("ptr[%d][%d] = %d\n", i, j, ptr[i][j]);
}
}
return 0;
}
In this example, ptr
is a double-pointer (int **
) because it points to an array of pointers, and each of those pointers, in turn, points to a row of the 2D array.