I'm practicing pointers and want to substitute pointer operations in place of the arrays to traverse through the elements of the array. I have read numerous articles and cannot grasp this concept. Can someone explain?
Here I made a 2D array and iterated through it using a basic nested for-loop, but want to use pointers;
int test[3][2] = {1,4,2,5,2,8};
for (int i = 0 ; i < 3; i++) {
for (int j = 0; j < 2; j++) {
printf("%d\n", test[i][j]);
}
}
5 Answers
int test[3][2] = {{1,4},{2,5},{2,8}};
// Define a pointer to walk the rows of the 2D array.
int (*p1)[2] = test;
// Define a pointer to walk the columns of each row of the 2D array.
int *p2 = NULL;
// There are three rows in the 2D array.
// p1 has been initialized to point to the first row of the 2D array.
// Make sure the iteration stops after the third row of the 2D array.
for (; p1 != test+3; ++p1) {
// Iterate over each column of the arrays.
// p2 is initialized to *p1, which points to the first column.
// Iteration must stop after two columns. Hence, the breaking
// condition of the loop is when p2 == *p1+2
for (p2 = *p1; p2 != *p1+2; ++p2 ) {
printf("%d\n", *p2);
}
}
In some compilers you can also use a single loop, treating a multidimensional array as a one-dimensional array read in row-major order.
This is mentioned in King's C Programming: A Modern Approach (2nd ed., p268).
#include <stdio.h>
int main(void)
{
int test[3][2] = {{1,4},{2,5},{2,8}}, *p;
for(p = &test[0][0]; p <= &test[2][1]; p++)
{
printf("%d\n", *p);
}
return 0;
}
Try the following and investigate
#include <stdio.h>
int main(void)
{
int test[3][2] = { { 1,4 }, { 2,5 }, { 2,8 } };
for ( int ( *p )[2] = test ; p != test + 3; ++p )
{
for ( int *q = *p; q != *p + 2; ++q ) printf( "%d ", *q );
puts( "" );
}
return 0;
}
The putput is
1 4
2 5
2 8
The first pointer is a pointer to an object of type int[2] that is it points to the first "row" of the array and then due to increments it points to other rows.. The second pointer is a pointer to an object of type int. It points to the first element of each row in the inner loop.
Treating a 2d array as 1d array is very easy using pointer arithmetic to iterate.
void print_2d_array(int *num, size) {
int counter = 0;
while (counter++ < size) {
printf("%i ", *num);
num++;
}
printf("\n");
}
int main() {
int matrix[2][3] = {{2, 11, 33},
{9, 8, 77}};
int matrix_size = sizeof(matrix) / sizeof(int); // 24 bytes / 4 (int size) = 6 itens
print_2d_array(matrix, matrix_size);
return 0;
}
If pointer declaration is the goal of your practice, use the following initialization:
int (*pTest)[rmax][cmax] = test;
Once you do that, the syntax of using pointer indexing mirrors that of array indexing, except that you have to use the * de-referencing operator.
for (int i= 0; i < 3; i++) {
for (int j= 0; j < 2; j++) {
printf ("%d ", *(pTest[i][j]));
}
printf ("\n");
}
However, if pointer arithmetic is the goal of your practice, then the following will work too:
int *res = &test;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
printf ("%d ", *(res + i*2 + j));
}
printf ("\n");
}
OUTPUT
1 4
2 5
2 8