Passaggio di una matrice int di lunghezza variabile come parametro di funzione nell'obiettivo C
-
05-07-2019 - |
Domanda
Ho il seguente codice che funziona bene ...
int testarr[3][3] = {
{1,1,1},
{1,0,1},
{1,1,1}
};
[self testCall: testarr];
Che chiama questa funzione:
- (void)testCall: (int[3][3]) arr {
NSLog(@"cell value is %u",arr[1][1]);
}
Ho bisogno che l'array abbia una lunghezza variabile - Qual è il modo migliore per dichiarare la funzione?
L'uso degli spazi vuoti non funziona:
- (void)testCall: (int[][]) arr {
Grazie per il tuo aiuto.
Soluzione
Lo scriverei come:
- (void) testCall: (int *) aMatrice;
In questo modo puoi evitare malloc multipli e la matematica per calcolare un singolo offset in un array lineare basato su coordinate x, y in un array 2D è banale. Evita anche i molteplici malloc impliciti da int ** e i limiti della sintassi dell'array 2D perpetuati dalla lingua.
Quindi, se volevi un array 4x5, potresti fare:
#define WIDTH 4
#define HEIGHT 5
#define INDEXOF(x,y) ((y*WIDTH) + x)
int *myArray = malloc(sizeof(int) * 5 * ELEMS_PER_ROW);
È quindi possibile inizializzare l'array in modo lineare o con un ciclo nidificato per:
for(int x=0; x<width; x++)
for(int y=0; y<height; y++)
myArray[INDEXOF(x,y)] = ... some value ...;
E lo passeresti al metodo come:
[foo testCall: myArray];
Anche se potresti voler portare anche con la larghezza e l'altezza o, meglio ancora, creare una sottoclasse IntMatrix di NSObject che avvolge tutta l'aritmetica del puntatore e lo spazio di archiviazione oltre una bella API pulita.
(tutto il codice digitato in SO)
Altri suggerimenti
Le matrici C non possono essere variabili in più di una dimensione.
Non puoi avere questo:
int testarr[][] = {
{1,1,1},
{1,0,1,2},
{1,1}
};
Ma puoi avere questo:
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
}
Non puoi usare int [] []
perché la dimensione della seconda dimensione influenza il modo in cui l'array è disposto in memoria. Se conosci la seconda dimensione puoi usare int [] [x]
, altrimenti dovrai usare int **
a cui puoi accedere proprio come un array.
Perché non usi semplicemente NSArray
o NSMutableArray
con NSInteger
s? Queste classi di array sono di lunghezza variabile e molto più facili da usare.
Ciò comporterebbe
- (void)testCall: (NSArray *) arr {
NSLog(@"cell value is %u", [[arr objectAtIndex:1] objectAtIndex:1]);
}
(Naturalmente, dovresti anche definire testarr usando NSArray.)
Se veramente vuoi usare le matrici C, rendendo l'argomento del metodo un puntatore a un int con
- (void) testCall: (int *) arr {
probabilmente funzionerà (con il resto del codice che rimane lo stesso).
chiamata ??p>
int testarr[3][3] = {
{1,1,1},
{1,0,1},
{1,1,1}
};
[self testCall: (int *)testarr];
Funzione
- (void)testCall: (int *) arr
{
int (*V_arr)[3] = (int(*)[3])arr;
NSLog(@"cell value is %u",V_arr[1][1]);
}