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() {
int myArray[5] = {10, 20, 30, 40, 50};
int *ptr = myArray;
printf("Using array notation:\n");
for (int i = 0; i < 5; ++i) {
printf("myArray[%d] = %d\n", i, myArray[i]);
}
printf("\nUsing pointer notation:\n");
for (int i = 0; i < 5; ++i) {
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 of myArray.
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() {
int myArray[3][4] = {
{10, 20, 30, 40},
{50, 60, 70, 80},
{90, 100, 110, 120}
};
int (*ptr)[4] = myArray;
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]);
}
}
printf("\nUsing 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]);
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 array ptr by itself is a pointer to the first row, and adding i 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 adding j 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() {
int myArray[3][4] = {
{10, 20, 30, 40},
{50, 60, 70, 80},
{90, 100, 110, 120}
};
int **ptr = (int **)myArray;
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.