Question

I have the following code which works fine...

int testarr[3][3] = {
  {1,1,1},
  {1,0,1},
  {1,1,1}
};   
[self testCall: testarr];

Which calls this function:

- (void)testCall: (int[3][3]) arr {

    NSLog(@"cell value is %u",arr[1][1]);
}

I need the array to be of variable length - What is the best way to declare the function?

Using blanks doesn't work:

- (void)testCall: (int[][]) arr { 

Thanks for your help.

Was it helpful?

Solution

I would write this as:

- (void) testCall: (int *) aMatrice;

Doing so allows you to avoid multiple mallocs and the math to calculate a single offset in a linear array based on x, y coordinates in a 2D array is trivial. It also avoids the multiple mallocs implied by int** and the limitations of 2D array syntax perpetuated by the language.

So, if you wanted a 4x5 array, you might do:

#define WIDTH 4
#define HEIGHT 5
#define INDEXOF(x,y) ((y*WIDTH) + x)

int *myArray = malloc(sizeof(int) * 5 * ELEMS_PER_ROW);

You could then initialize the array linearly or with a nested for loop:

for(int x=0; x<width; x++)
    for(int y=0; y<height; y++)
        myArray[INDEXOF(x,y)] = ... some value ...;

And you would pass it to the method like:

[foo testCall: myArray];

Though you might want to also carry along the width and the height or, better yet, create a IntMatrix subclass of NSObject that wraps all of the pointer arithmetic and storage beyond a nice clean API.

(all code typed into SO)

OTHER TIPS

C arrays can't be variable in more than one dimension.

You can't have this:

int testarr[][] = {
  {1,1,1},
  {1,0,1,2},
  {1,1}
};

But you can have this:

int testarr[][3] = {
  {1,1,1},
  {1,0,1},
  {1,1,1},
  {4,5,6},
  {7,8,9}
}

foo(testarr);

void foo(int param[][3])
{
    printf("%d", param[3][1]); // prints 5
}

You can't use int[][] because the size of the second dimension affects how the array is laid out in memory. If you know the second dimension you can use int[][x], otherwise you'll have to use int** which can be accessed just like an array.

Why don't you just use NSArray or NSMutableArray with NSIntegers? Those array classes are of variable length, and much easier to use.

This would result in

- (void)testCall: (NSArray *) arr {
    NSLog(@"cell value is %u", [[arr objectAtIndex:1] objectAtIndex:1]);
}

(Of course, you would also have to define testarr using NSArray.)



If you really want to use C arrays, making the method argument a pointer to an int with

- (void)testCall: (int*) arr {

will probably work (with the rest of the code staying the same).

call

int testarr[3][3] = {
  {1,1,1},
  {1,0,1},
  {1,1,1}
};   
[self testCall: (int *)testarr];

function

- (void)testCall: (int *) arr 
{
    int (*V_arr)[3] = (int(*)[3])arr;
    NSLog(@"cell value is %u",V_arr[1][1]);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top