1

I am having problems declaring a pointer into my 4d array.

I have declared it like this:

int matrix[7][4][5][5] =
{
  {/* Section 1 */
    {
      /* 1st */
      {0,0,1,0,0},
      {0,0,1,0,0},
      {0,0,1,0,0},
      {0,0,0,0,0},
      {0,0,0,1,0}
    },
    {
     /* 2nd */
      {0,0,0,0,0},
      {0,0,0,0,0},
      {1,0,0,1,1},
      {0,0,0,0,0},
      {0,0,0,0,0}
    },
    . . . 
  }/* End Section 1 */
}

I would like to be able to print out the elements in the 2d array underneath the comment /* 2nd */.

I had some code to loop through a 2d array like this:

for(int i = 0; i < 5; i++)
  {
    for(int j=0; j<5; j++)
    {
      std::cout << " " << pMatrixPtr[i][j];
    }
    std::cout << "\n";
  }

But my problem is - I don't know what to set pMatrixPtr to, or what type it should be (I mean levels of pointer . . . should it be **? ). Nothing I try seems to compile, and I think it's because I don't fully understand what types are involved.

Can anyone explain how a 4d array can be accessed via a pointer, and what that pointer should point to?

3 Answers 3

3
int (*pMatrixPointer)[5] = matrix[0][1];

will set pMatrixPointer to point to the second 2D array in matrix. You would then use it as in your code above:

for(int i = 0; i < 5; i++)
{
  for(int j=0; j<5; j++)
  {
    std::cout << " " << pMatrixPtr[i][j];
  }
  std::cout << "\n";
}

Why this works:

In most contexts, an expression of array type will be converted to an expression of pointer type, and the value of the expression will be the address of the first element in the array (this is true for both C and C++).

The expression matrix[0][1] has type "5-element array of 5-element array of int"; by the rule above, the expression is converted to type "pointer to 5-element array of int" (int (*)[5]) and the value is &matrix[0][1].

The expression a[i] is equivalent to *(a + i); there's an implicit dereference in the subscript operation. So pMatrix[i] is equivalent to *(pMatrix + i), which yields a pointer value that we further offset with j, as *(*(pMatriux + i) + j).

Sign up to request clarification or add additional context in comments.

Comments

3

If you want to print the content that are only under the comment /2nd/ then you can chose the first two array blocks manually and apply the loop for last two blocks, such as...

for(int i=0;i<5;i++)
{
   for(int j=0;j<5;j++)
   {
      std::cout<<" "<<matrix[7][1][i][j];
   }
   std::cout<<"\n";
}

Using pointers will make it complicated.

1 Comment

I actually think using pointers makes the code less complicated.
1

Pointers to 4D arrays are not very easy neither readable to define from scratch, I always use typedefs to help:

  typedef int MATRIX_1D[5]; // 5 element array of int
  typedef int* MATRIX_1D_PTR; // pointer to int array
  typedef MATRIX_1D MATRIX_2D[5]; // 5 element array of 5 element array of int
  typedef MATRIX_1D* MATRIX_2D_PTR; // pointer to array of 5 element array of int
  typedef MATRIX_2D MATRIX_3D[4]; // 4 el. arr. of 5 el. arr. of 5 el. arr. of int
  typedef MATRIX_2D* MATRIX_3D_PTR; // pointer to arr. of 5 el. arr. of 5 el. ...
  typedef MATRIX_3D MATRIX_4D[7]; // 7 el. arr. of 4 el. arr. of 5 el. arr. of 5...
  typedef MATRIX_3D* MATRIX_4D_PTR; // pointer to array of 4 element array of ... 

So for your case:

MATRIX_2D_PTR pMatrixPtr = matrix[0][0];    
for(int i = 0; i < 5; i++)
  {
    for(int j=0; j<5; j++)
    {
      std::cout << " " << pMatrixPtr[i][j];
    }
    std::cout << "\n";
  }

As you can see pMatrixPtr is pointer to arrays of arrays of 5 elements of int type. This is how was I defined MATRIX_2D_PTR type.

As a bonus answer - the way how to iterate over entire matrix:

  void printMatrix(MATRIX_4D_PTR* p)
  {
    for (int i1 = 0; i1 < 7; ++i1)
     for (int i2 = 0; i2 < 4; ++i2)
      for (int i3 = 0; i3 < 5; ++i3)
       for (int i4 = 0; i4 < 5; ++i4)
        std::cout << p[i1][i2][i3][i4] << std::endl;
  }
  int main() { printMatrix(matrix); }

3 Comments

Thanks for the answer Piotr. Maybe in this case readability is down to personal preference.
I think what I mean is that, if I used such a sequence of typedefs, then I would end up tracing MATRIX_2D_PTR through all the typedefs, to see what it's defined in terms of. I would find the int (*pMatrixPointer)[5] declaration much easier to read, when debugging ( for example ). But this is totally my personal preference. :-)
@BeeBand Understood. Array of arrays are not so hard to understand/define. Consider array of function pointers - int (*p[4]) (int x, int y);, I prefer typedefs. Matter of taste. And it might be easier to understand for C++ beginners.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.