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
- 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
- main's retrun type is int and not void
- It's recommended not to avoid the inner braces
- 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
.