Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to access the 3-d array using pointer to an array

Tags:

arrays

c

pointers

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.

like image 442
tamil_innov Avatar asked Oct 12 '13 13:10

tamil_innov


2 Answers

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.

like image 158
legends2k Avatar answered Sep 28 '22 19:09

legends2k


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));
         }         
      }
   }
}
like image 44
Siddhartha Ghosh Avatar answered Sep 28 '22 19:09

Siddhartha Ghosh