views:

86

answers:

2

Hi,

I'm writing a simple test program to pass multidimensional arrays. I've been struggling to get the signature of the callee function.

The code I have:

void p(int (*s)[100], int n) { ... }

...

{
  int s1[10][100], s2[10][1000];
  p(s1, 100);
}

This code appears to work, but is not what I intended. I want the function p to be oblivious whether the range of values is either 100 or 1000, but should know there are 10 pointers (by use of function signature).

As a first attempt:

void p(int (*s)[10], int n) // n = # elements in the range of the array

and as a second:

void p(int **s, int n) // n = # of elements in the range of the array

But to no avail can I seem to get these to work correctly. I don't want to hardcode the 100 or 1000 in the signature, but instead pass it in, keeping in mind there will always be 10 arrays.

Obviously, I want to avoid having to declare the function:

void p(int *s1, int *s2, int *s3, ..., int *s10, int n) 

FYI, I'm looking at the answers to a similar question but still confused.

+2  A: 

You could also create a struct for the matrix and pass it to the function p

struct Matrix{
     int **array;
     int n;
     int m;
};


void p(Matrix *k){
     length=k->m;
     width=k->n;
     firstElement=k->array[0][0];
}
zoli2k
This approach works and is more general, in that it allows flexibility in both dimensions of the array. However, it must be made clear that `array` is a single array of `n` pointers to integers, each of which points to an array of `m` integers. In spite the of the syntactic similarities, this is very different than the simple declaration `int array[N][M]` for some constants N and M.
Dale Hagglund
+4  A: 

You need to transpose your arrays for this to work. Declare

int s1[100][10];
int s2[1000][10];

Now, you can pass these to a function like this:

void foo(int (*s)[10], int n) {
    /* various declarations */
    for (i = 0; i < n; i++)
        for (j = 0; j < 10; j++)
            s[i][j] += 1
}

Because of the way the C type system works, an array argument can only be "flexible" in the sense you want in its left-most index.

Dale Hagglund
Alternatively, `void p(int s[][10], int n)`
outis
@outis: Quite correct. I used `int (*s)[10]` in part because I was mimicking the original question, and also because I personally tend to avoid argument declarations like `int s[][10]` since they mislead the reader about what's actually being passed to the function.
Dale Hagglund
Thanks Dale. This looks like to be the correct method to enforce what I originally wanted. The only issue is the transposed structure hinders my code.It appears the other answer that suggests dynamically constructing the multidimensional array and passing in the range would be more suitable and clearer to understand.
nn
You're welcome. If the transposed arrays make your code too awkward, then it's certainly worth trying out the idea described by @shakov.
Dale Hagglund