6

i have declared a pointer to a group of 3-d array which I have shared below.I have a problem in accessing elements of the 3-d array using pointers to the 3-d array.

#include <stdio.h>

void main()
{
   int m,row,col;
   int *ptr,*j;
   int array[2][5][2]={10,20,30,40,50,60,70,80,90,100,18,21,3,4,5,6,7,81,9,11};
   int (*p)[5][2];   //  pointer to an group of 3-d array
   p=array;
   for(m=0;m<2;m++)
   {
      ptr=p+m;
      for(row=0;row<5;row++)
      {
         ptr=ptr+row;
         for(col=0;col<2;col++)
         {
            printf("\n the vale is %d",*(ptr+col));
         }
      }
   }
}

output:

 the value is 10
 the value is 20
 the value is 20
 the value is 30
 the value is 40
 the value is 50
 the value is 70
 the value is 80
 the value is 18
 the value is 21
 the value is 18
 the value is 21
 the value is 21
 the value is 3
 the value is 4
 the value is 5
 the value is 7
 the value is 81
 the value is -1074542408
 the value is 134513849

my question is how to access the elements of 3-d array using pointer to an array and in my case the output shows my code not accessing the elements 90,100,9,11 and how do i can access this in the above code.Thanks in advance.

mathmaniage
  • 299
  • 1
  • 14
tamil_innov
  • 223
  • 1
  • 7
  • 16

4 Answers4

11

Although flattening the arrays and accessing them as 1-d arrays is possible, since your original question was to do so with pointers to the inner dimensions, here's an answer which gives you pointers at every level, using the array decay behaviour.

#include <stdio.h>

/* 1 */
#define TABLES  2
#define ROWS    5
#define COLS    2

/* 2 */
int main()
{
    /* 3 */
    int array[TABLES][ROWS][COLS] = {
                                        { {10, 20}, {30, 40}, {50, 60}, {70, 80}, {90, 100} },
                                        { {18, 21}, {3, 4}, {5, 6}, {7, 81}, {9, 11} }
                                    };
    /* pointer to the first "table" level - array is 3-d but decays into 2-d giving out int (*)[5][2] */
    /* name your variables meaningully */
    int (*table_ptr)[ROWS][COLS] = array;  /* try to club up declaration with initialization when you can */
    /* 4 */
    size_t i = 0, j = 0, k = 0;
    for (i = 0; i < TABLES; ++i)
    {
        /* pointer to the second row level - *table_ptr is a 2-d array which decays into a 1-d array */
        int (*row_ptr)[COLS] = *table_ptr++;
        for (j = 0; j < ROWS; ++j)
        {
            /* pointer to the third col level - *row_ptr is a 1-d array which decays into a simple pointer */
            int *col_ptr = *row_ptr++;
            for (k = 0; k < COLS; ++k)
            {
                printf("(%lu, %lu, %lu): %u\n", (unsigned long) i, (unsigned long) j, (unsigned long) k, *col_ptr++);  /* dereference, get the value and move the pointer by one unit (int) */
            }         
        }
    }
    return 0;   /* report successful exit status to the platform */
}

Inline code comments elaborated with reference

  1. It's good practise to have the dimensions defined commonly somewhere and use it elsewhere; changing at one place changes it at all places and avoids nasty bugs
  2. main's retrun type is int and not void
  3. It's recommended not to avoid the inner braces
  4. Use size_t to hold size types

Problems in your code

For the line ptr=p+m;, GCC throws assignment from incompatible pointer type; reason is p is of type int (*)[5][2] i.e. pointer to an array (size 5) of array (size 2) of integers, which is assigned to ptr which is just an integer pointer. Intead if you change it to int (*ptr) [5]; and then do ptr = *(p + m);. This is what my code does (I've named p as table_ptr), only that it doesn't use m but it increments p directly.

After this at the third level (inner most loop), you need a integer pointer say int *x (in my code this is col_ptr) which you'd do int *x = *(ptr + m1). Bascially you need to have three different pointers, each for one level: int (*) [5][2], int (*) [2] and int *. I've named them table_ptr, row_ptr and col_ptr.

Community
  • 1
  • 1
legends2k
  • 31,634
  • 25
  • 118
  • 222
  • 2
    @haccks: You're welcome. I found it out recently only but it seems immensely helpful so I pass it around :) – legends2k Oct 12 '13 at 17:55
3

Rewritten your code below and just used the pointer p to print everything.

#include <stdio.h>

void main()
{
   int m,row,col;
   int array[2][5][2]={10,20,30,40,50,60,70,80,90,100,18,21,3,4,5,6,7,81,9,11};
   int (*p)[5][2];   //  pointer to an group of 3-d array
   p=array;
   for(m=0;m<2;m++)
   {
      for(row=0;row<5;row++)
      {         
         for(col=0;col<2;col++)
         {
            printf("\n the vale is %d", *((int*)(p+m) + (row*2) + col));
         }         
      }
   }
}
Siddhartha Ghosh
  • 2,988
  • 5
  • 18
  • 25
  • 2
    General formula: How much a pointer moves ahead would depend on what type it points to. About your code: `p=p+m` worked correctly as p points to a group of 2-d array. ptr is just `int*`. `ptr=ptr+row` won't work correctly. Try to think the iterations. At row =0, it points to 10. At row = 1, it just increments 1 place (1 place = size of an int here) to 20 (Not 2 places) ... and so on. – Siddhartha Ghosh Oct 12 '13 at 16:51
  • @tamil_innov: I've pointed out in my answer what's the issue in your code. – legends2k Oct 12 '13 at 17:23
1

You can easily access all the elements simply by a looping through 2*5*2 = 20 and using a pointer to the first element of array, i.e, array[0][0][0] assuming 3D array as 1D array of arrays of arrays of int's.

#include <stdio.h>

void main()
{
   int m; //row,col;
   int *ptr; //,*j;
   int array[2][5][2]={10,20,30,40,50,60,70,80,90,100,18,21,3,4,5,6,7,81,9,11};
   //int (*p)[5][2];   //  pointer to an group of 3-d array
   //p=array;
   ptr = &array[0][0][0];
   for(m=0;m <2;m++)
   {
        for (m = 0; m < 20; m++)
      /* ptr=ptr+m;
      for(row = 0;row < 5;row ++)
      {
         ptr=ptr+row;
         for(col=0;col<2;col++)
         {
            printf("\n the vale is %d",*(ptr+col));
         }
      }*/
      printf("\n the vale is %d", *(ptr++));
   }
} 

I commented some parts of your code and left it in the modified code to let you clear what I have done.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • thanks for pointing out , actually ptr=p+m where p is a pointer to an 3-d array. – tamil_innov Oct 12 '13 at 13:59
  • 1
    @tamil_innov: No, the `p` in your question is not a pointer to a 3D array, it is the pointer to a 2D array. When you said `p=array;`, your 3D array *decayed* to a pointer to its first element, which is precisely the type of `p`. If you want a pointer to a 3D array, you can do so with `int (*p)[2][5][2]; p = &array;`. Note that the usage `&array` is one of only two contexts where an array does not decay to a pointer to its first element. – cmaster - reinstate monica Oct 12 '13 at 17:56
1
#include<stdio.h>


int main()
{
int array[2][2][2]={1,2,3,4,5,6,7,8};

 int *p;
p=&array[0][0][0];


int i=0,j,k;

 /*Accessing data using pointers*/

     for(i=0;i<2;i++)
        {
          for(j=0;j<2;j++)
            {

              for(k=0;k<2;k++)
               {
               printf("%d\n",*p);
                p++;
               }
            }

         }

  return 0;

}

This is a sample code where elements in a 2X2X2 array is been accessed using pointers. Hope it helps !!!!

Benny Dalby
  • 182
  • 4