2009-09-09 10 views
7

Mam następujący kod, który działa poprawnie ...Mijając tablicę int o zmiennej długości, jako parametr funkcji w Objective C

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

Który nazywa tę funkcję:

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

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

muszę tablica ma zmienną długość - Jaki jest najlepszy sposób deklarowania funkcji?

Korzystanie wykroje nie działa:

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

Dzięki za pomoc.

Odpowiedz

6

chciałbym napisać to jako:

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

Takie postępowanie pozwala uniknąć wiele malloców i matematyka do obliczenia pojedynczego przesunięcia w tablicy liniowej opartej na współrzędnych x, y w tablicy 2D jest trywialne. Pozwala to również uniknąć wielu malloców implikowanych przez int ** i ograniczeń składni tablic 2D utrwalanych przez język.

Tak więc, jeśli chcesz tablicę 4x5, można zrobić:

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

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

Następnie można zainicjować tablicę liniowo lub zagnieżdżonej pętli for:

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

I czy to przejdzie do metody podobnej do:

[foo testCall: myArray]; 

Chociaż można również przenosić wzdłuż szerokości i wysokości lub bette r jednak utwórz podklasę IntMatrix dla NSObject, która opakuje całą arytmetykę wskaźnika i pamięć masową poza ładny czysty interfejs API.

(cały kod wpisany do SO)

+0

To był bardzo sprytny sposób na rozwiązanie - dzięki. –

+1

Nie zapomnij o 'free()' pamięci po wywołaniu '[foo testCall: myArray];'. –

1

Dlaczego po prostu nie używasz NSArray lub NSMutableArray z NSInteger s? Te klasy macierzy mają różną długość i są znacznie łatwiejsze w użyciu.

Spowodowałoby

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

(Oczywiście, będzie trzeba także określić testarr używając NSArray.)



Jeśli naprawdę chcesz używać tablic C, dzięki czemu argument metody wskaźnik do int z

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

prawdopodobnie zadziała (pozostała część kodu pozostanie bez zmian).

+2

PO musiałby użyć '(int **)' aby uzyskać dwuwymiarową tablicę. –

+0

Nie można umieścić NSIntegers w NSArray, ponieważ NSInteger nie jest obiektem, to tylko typedef o jakiejś int. Musiałbyś użyć NSNumber, co wprowadziłoby pewien narzut. – Amok

+0

Chris, (int **) oznacza wskaźnik do wskaźnika na int, a nie wskaźnik do tablicy dwuwymiarowej. Dodanie pośredniej nie ma nic wspólnego z układem pamięci, do której się odwołujesz. – NSResponder

2

Nie można użyć wartości int[][], ponieważ rozmiar drugiego wymiaru wpływa na sposób układania macierzy w pamięci. Jeśli znasz drugi wymiar, możesz użyć int[][x], w przeciwnym razie będziesz musiał użyć int**, do którego można uzyskać dostęp podobnie jak tablica.

3

C tablic nie można zmieniać w więcej niż jednym wymiarze.

Nie można mieć to:

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

Ale można mieć to:

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 
} 
0

wezwanie

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

funkcja

- (void)testCall: (int *) arr 
{ 
    int (*V_arr)[3] = (int(*)[3])arr; 
    NSLog(@"cell value is %u",V_arr[1][1]); 
} 
Powiązane problemy