Передача массива int переменной длины в качестве параметра функции в Objective C - PullRequest
7 голосов
/ 10 сентября 2009

У меня есть следующий код, который отлично работает ...

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

Который вызывает эту функцию:

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

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

Мне нужен массив переменной длины. Каков наилучший способ объявления функции?

Использование пробелов не работает:

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

Спасибо за вашу помощь.

Ответы [ 5 ]

6 голосов
/ 10 сентября 2009

Я бы написал так:

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

Это позволяет вам избежать нескольких malloc, и математика для вычисления одного смещения в линейном массиве на основе координат x, y в 2D-массиве является тривиальной. Это также позволяет избежать множественных mallocs, подразумеваемых int **, и ограничений синтаксиса 2D-массивов, сохраняемых языком.

Итак, если вам нужен массив 4x5, вы можете сделать:

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

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

Затем можно инициализировать массив линейно или с помощью вложенного цикла for:

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

И вы передадите его методу:

[foo testCall: myArray];

Хотя вы, возможно, захотите также нести ширину и высоту или, что еще лучше, создать подкласс IntMatrix NSObject, который обернет всю арифметику и хранилище указателей за пределы красивого чистого API.

(весь код набран в SO)

3 голосов
/ 10 сентября 2009

C массивы не могут быть переменными в более чем одном измерении.

Этого не может быть:

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

Но вы можете иметь это:

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
}
2 голосов
/ 10 сентября 2009

Нельзя использовать int[][], поскольку размер второго измерения влияет на расположение массива в памяти. Если вы знаете второе измерение, вы можете использовать int[][x], в противном случае вам придется использовать int**, к которому можно обращаться, как к массиву.

1 голос
/ 10 сентября 2009

Почему бы вам просто не использовать NSArray или NSMutableArray с NSInteger с? Эти классы массивов имеют переменную длину и намного проще в использовании.

Это приведет к

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

(Конечно, вы также должны определить testarr с помощью NSArray.)



Если вы действительно хотите использовать массивы C, указав для аргумента метода указатель на int с помощью

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

, вероятно, будет работать (остальная часть кода останется прежней).

0 голосов
/ 07 марта 2013

звонок

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

функция

- (void)testCall: (int *) arr 
{
    int (*V_arr)[3] = (int(*)[3])arr;
    NSLog(@"cell value is %u",V_arr[1][1]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...