JT1
JT1

Reputation: 453

Notationally cleanest way of passing multidimensional array

I was working on these problems that I found online and one of the asks to rotate a two-dimensional NxN array in-place. My code for it is the following:

#include <stdio.h>

void rotate(int n, int *s)
{
   int nx, ny, tmp;
   int i, j;

   if(n < 1) return;

   /* Compute upper small square as basis for trajectories */
   if(n % 2 == 0) {
       nx = ny = n/2;
   }
   else {
       ny = (n-1)/2;
       nx = ny+1;
   }

   /* Move elements along their trajectories */
   for(i = 0; i < nx; i++) {
       for(j = 0; j < ny; j++) {
           tmp                      = *(s + n*j + n-1-i);
           *(s + n*j + n-1-i)       = *(s + n*(n-1-i) + n-1-j);
           *(s + n*(n-1-i) + n-1-j) = *(s + n*(n-1-j) + i);
           *(s + n*(n-1-j) + i)     = *(s + n*i + j);
           *(s + n*i + j)           = tmp;
       }
   }
}

int main(void)
{
    int test[4][4] = {
         { 1, 2, 3, 4 },
         { 5, 6, 7, 8 },
         { 9, 10, 11, 12},
         { 13, 14, 15, 16}};

    int n = 4;
    int i, j;

    for(i = 0; i < n; i++) {
        for(j = 0; j < n; j++) {
            printf("%d ", test[i][j]);
        }
        printf("\n");
    }

    printf("\nRotating matrix in place...\n\n");
    rotate(n, test);

    for(i = 0; i < n; i++) {
        for(j = 0; j < n; j++) {
            printf("%d ", test[i][j]);
        }
        printf("\n");
    }

    return 0;
}

I know that the compiler will complain when I pass the two-dimensional array to rotate() in the main() function, because of the double pointer conversion from arrays to pointers. My issues are the following:

  1. What is the correct way to declare the type of the rotate() function.

  2. How can I do it in a way that I can use the s[i][j] notation within the function rotate() without having to resort to pointer arithmetic? I realize that the type must be able to somehow dynamically take into account the value of n, so is it possible?

  3. I know I could circumvent the ugly notation by defining a pair of inline getter and setter functions, but that would require typing too much.

Upvotes: 0

Views: 48

Answers (1)

2501
2501

Reputation: 25753

Pass additional parameters along with the pointer to an array:

void Func( size_t y , size_t x , int(*a)[x] ) {...

This is identical to

void Func( size_t y , size_t x , int a[][x] ) {...

or

void Func( size_t y , size_t x , int a[y][x] ) {...

Apart from the outermost one, all dimensions must be provided for a. In this case y is optional. But you still need it to determine the outer size of the array in the function.

The notation is then identical as with the array:

a[y-1][x-1] = 1234 ;

Upvotes: 1

Related Questions