2009-09-09 7 views
7

tengo el siguiente código que funciona muy bien ...pasando un array int de longitud variable como un parámetro de la función en C Objetivo

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

que llama a esta función:

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

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

necesito el array de longitud variable: ¿cuál es la mejor manera de declarar la función?

Uso de espacios en blanco no funciona:

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

Gracias por su ayuda.

Respuesta

6

que iba a escribir esto como:

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

Si lo hace, le permite evitar múltiples mallocs y las matemáticas para calcular un solo desplazamiento en una matriz lineal basada en coordenadas x, y en una matriz 2D es trivial. También evita los múltiples mallocs implicados por int ** y las limitaciones de la sintaxis de matriz 2D perpetuada por el lenguaje.

Por lo tanto, si desea una matriz de 4x5, es posible hacer:

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

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

A continuación, puede inicializar la matriz de forma lineal o con un anidado bucle for:

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

y que le pasarlo para el método como:

[foo testCall: myArray]; 

Aunque también es posible que desee llevar a lo largo de la anchura y la altura o, bette Sin embargo, crea una subclase IntMatrix de NSObject que envuelve toda la aritmética y el almacenamiento del puntero más allá de una bonita API limpia.

(todo el código escrito en SO)

+0

Esta fue una forma muy inteligente de resolverlo, gracias. –

+1

No olvide 'libre()' la memoria después de llamar '[foo testCall: myArray];'. –

1

¿Por qué no solo usa NSArray o NSMutableArray con NSInteger s? Esas clases de matriz son de longitud variable y mucho más fáciles de usar.

Esto daría lugar a

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

(Por supuesto, también se tendría que definir testarr usando NSArray.)



Si realmente desea utilizar matrices C, por lo que la método argumento un puntero a un int con

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

probablemente funcione (con el resto del código siendo el mismo).

+2

La OP tendría que usar '(int **)' para obtener una matriz de dos dimensiones. –

+0

no se puede poner en un NSIntegers NSArray desde NSInteger no es un objeto, es sólo un typedef de algún tipo de int. Tendría que usar NSNumber, lo que introduciría algunos gastos generales. – Amok

+0

Chris, (int **) significa un puntero a un puntero a un int, no un puntero a un arreglo bidimensional. Agregar un direccionamiento indirecto no tiene nada que ver con el diseño de la memoria a la que se refiere. – NSResponder

2

No se puede usar int[][] porque el tamaño de la segunda dimensión afecta la disposición de la matriz en la memoria. Si conoce la segunda dimensión, puede usar int[][x], de lo contrario tendrá que usar int** a la que se puede acceder como una matriz.

3

Las matrices C no pueden ser variables en más de una dimensión.

Puede no tener esta:

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

Pero usted puede tener esto:

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

llamada

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

función

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