Передача массива int переменной длины в качестве параметра функции в Objective C

StackOverflow https://stackoverflow.com/questions/1402250

Вопрос

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

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 { 

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

Это было полезно?

Решение

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

- (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)

Другие советы

Массивы 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
}

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

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

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

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

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



Если вы Действительно хотите использовать массивы C, сделав аргумент метода указателем на целое число с

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

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

вызов

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]);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top