6

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]);
    }
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
ryan
  • 625
  • 3
  • 10
  • 23
  • Do it in steps. Write some code to iterate through a 1-D array and make it work correctly. Copy it into a function and get that to work on a 1-D array correctly. There you are - it's almost done. Iterate one dimension and call the function on each element, (ie. each 1-D array:), found. – Martin James Sep 30 '14 at 16:45
  • 1
    printf("%d\n", *(*(test+i) + j)); – ryan Sep 30 '14 at 16:47

5 Answers5

10
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);
    }
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 2
    A bit of explaination would suit your answer well. However 1+ for a fully pointer driven approach ... :-) – alk Oct 01 '14 at 06:12
2

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.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

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;
}
p-robot
  • 4,652
  • 2
  • 29
  • 38
1

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;
}
Rafael Áquila
  • 141
  • 1
  • 1
  • 6
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
lifebalance
  • 1,846
  • 3
  • 25
  • 57