Joel Bodenmann
Joel Bodenmann

Reputation: 2282

pass pointer to multidimensional array

I have a two dimensional array of ints which represents a few dots in a graph.

int16_t myPoints[][3] = {
  {0, 0},
  {20, 40},
  {14, 92}};

How can I pass a pointer to a function which will be able to read these coordinates?

something like?

void foo(int16_t *coordinates[][]) {
   drawPoint(x[0], y[0]);
   drawPoint(x[1], y[1]);
   ...

Thanks for the help.

Upvotes: 1

Views: 1022

Answers (4)

Charley Moore
Charley Moore

Reputation: 488

but does that copy the whole array to foo or does it just pass the pointer to it? I also just know that there will ALWAYS be two coordinates per entry, but I don't know how many entries there will come.

If you're passing a variable length array, you either have to pass the number of elements as a separate parameter or the last element of the array must somehow indicate that it is the last element so that you can terminate the function using a while() loop (like adding a NULL to terminate a string).

enum STATUS { OK, END };
STATUS bar(int16_t x, int16_t y);  /* bar() checks to see if this is the last element */

void foo(int16_t coordinates[][2])
{
    int i = 0;
    while( END != bar(coordinates[i][0], coordinates[i][1]) )
    {
        drawPoint(coordinates[i][0], coordinates[i][1]);
        ++i;
    }
}

Upvotes: 0

John Bode
John Bode

Reputation: 123448

The rule is that when an expression of type "N-element array of T" appears in most contexts, it will be converted to an expression of type "pointer to T".

myPoints is an expression of type "3-element array of 3-element arrays of int16_t". Thus, when myPoints appears in most contexts1 (such as a function call), it will be replaced with an expression of type "pointer to 3-element array of int16_t", or int16_t (*)[3].

If you want to call foo as foo(myPoints), then the prototype will need to be

void foo(int16_t (*coordinates)[3])

or

void foo(int16_t coordinates[][3])

In the context of a function parameter declaration, T a[N], T a[], and T *a are all equivalent, and all declare a as a pointer to T. Note that this is only true in a function parameter declaration.


1 - The exceptions to the rule are when the array expression is an operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration.

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409166

Only the first dimension can be unknown when declaring a function, so you have to declare/define the function like this:

void foo(int16_t coordinates[][3])
{
    drawPoint(coordinates[0][0], coordinates[1][0]);
    drawPoint(coordinates[0][1], coordinates[1][1]);
    drawPoint(coordinates[0][2], coordinates[1][2]);
}

Then you can call it like a normal function:

foo(myPoints);

Edit: Your array declaration is not correct, and I missed it too. It should be:

int16_t myPoints[][2] = {
  /* List of points */
};

Now you have a proper coordinate-array, and it can be as long as you like.

For the function to know the number of entries, you have to pass it to the function, so the new function declaration will be:

void foo(int16_t coordinates[][2], int number_of_points);

Don't worry about copying, the compiler is smart enough to only pass the pointer to the array, so it will not copy the whole array.

Upvotes: 2

unwind
unwind

Reputation: 399793

By repeating the proper declaration for the function's argument:

void foo(int16_t coordinates[][3])
{
  ...
}

You must include all array dimensions except the one immediately following the variable name, which is optional.

Upvotes: 0

Related Questions