punteros puntero multidimensionales matriz matrices dinamicos dinamico dinamica declarar como arreglos arreglo c

multidimensionales - punteros c++



¿Por qué no podemos usar el puntero doble para representar matrices bidimensionales? (5)

En C, una matriz bidimensional es una matriz de matrices .

Necesita un puntero a matriz para referirse a él, no un puntero doble:

char array[2][6] = {"hello", "hai"}; char (*p)[6] = array; //char **x = array; // doesn''t compile.

Para que un puntero doble se refiera a "datos bidimensionales", debe referirse al primer elemento de una matriz de punteros . Pero una matriz bidimensional en C (matriz de matrices) no es lo mismo que una matriz de punteros, y si solo define una matriz bidimensional, entonces no existe una matriz correspondiente de punteros.

La única similitud entre los dos es la sintaxis [][] utilizada para acceder a los datos: los datos en sí están estructurados de manera muy diferente.

¿Por qué no podemos usar el puntero doble para representar matrices bidimensionales?

arr[2][5] = {"hello","hai"}; **ptr = arr;

Aquí, ¿por qué el puntero doble (** ptr) no funciona en este ejemplo?


Hacer una matriz de punteros a cada fila para obtener un objeto que "se parece" a una matriz multidimensional de tamaño variable es una opción de diseño costosa por el bien del azúcar sintáctica . No lo hagas

La forma correcta de hacer una matriz multidimensional de tamaño variable es algo como:

if (w > SIZE_MAX/sizeof *m/h) goto error; m = malloc(w * h * sizeof *m); if (!m) goto error; ... m[y*w+x] = foo;

Si quiere que se vea "bonito" para poder escribir m[y][x] , debería usar un lenguaje diferente, tal vez C ++.


Tener puntero a puntero significa que cada fila (o columna, si prefiere pensar de esa manera) puede tener una longitud diferente de las otras filas / columnas.

También puede representar una matriz 2D con solo un puntero al elemento de inicio y un entero que especifica el número de elementos por fila / columna:

void matrix_set(double *first, size_t row_size, size_t x, size_t y, double value) { first[y * row_size + x] = value; }


Vamos a empezar hablando del código legal. Lo que ha escrito (asumiendo un carácter delante de cada declaración) no se compilará, por varias razones: tiene demasiados inicializadores (seis caracteres para arr [0], y su tamaño es 5), y por supuesto, carácter ** p no tiene un tipo compatible con char arr [2] [5]. Corrigiendo por esos problemas, obtenemos:

char arr[2][6] = { "hello", "hai" }; char (*p)[6] = arr;

Sin ningún doble puntero. Si desea acceder a los caracteres individuales de lo anterior, debe especificar el elemento del que provienen:

char* pc = *arr;

funcionaría, si quisiera acceder a los caracteres del primer elemento en arr.

C ++ no tiene matrices bidimensionales. La primera definición anterior define una matriz [2] o matriz [6] de char. La conversión implícita de matriz a puntero da como resultado puntero a matriz [6] de char. Después de eso, por supuesto, no hay una conversión de matriz a puntero, porque ya no tiene una matriz.


Voy a tratar de dibujar como

int array[10][6];

y

int **array2 = malloc(10 * sizeof *array2); for (int i = 0; i < 10; ++i) array2[i] = malloc(6 * sizeof **array2);

se ven como en la memoria y en qué se diferencian (y que no se pueden unir entre sí)

array ve como

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | | | | | | | | | | | | | ..............| | | (10*6 elements of type int) - - - - - - - - - - - - - - - - - - - - - - < first row >< second row> ...

array2 ve como:

_ _ _ _ _ _ _ _ _ _ | | | | | | | | | | | (10 elements of type int *) - - - - - - - - - - | | .... | _ _ _ _ _ _ | | /-->| | | | | | | (6 elements of type int) | | - - - - - - | | | | _ _ _ _ _ _ | / -->| | | | | | | (6 elements of type int) | - - - - - - | | | _ _ _ _ _ _ / -->| | | | | | | (6 elements of type int) - - - - - -

Cuando dices array[x][y] , se traduce en *((int *)array+x*6+y)

Mientras, cuando dices array2[x][y] , se traduce en *(*(array2+x)+y) cuenta que para array , esta fórmula también funciona (lee hasta el final de la publicación, y luego los comentarios )).

Es decir, una matriz 2d estática es de hecho una matriz 1d con filas puestas en una línea. El índice se calcula por la row * number_of_columns_in_one_row + column la fórmula row * number_of_columns_in_one_row + column .

Una matriz 2D dinámica, sin embargo, es solo una matriz 1D de punteros. Cada puntero se asigna dinámicamente para apuntar a otra matriz 1d. En verdad, ese puntero podría ser cualquier cosa. Podría ser NULL , o apuntar a una sola variable, o apuntar a otra matriz. Y cada uno de esos punteros se establece individualmente, por lo que pueden tener diferentes naturalezas.

Si necesita pasar el puntero de la array algún lugar, no puede convertirlo en int ** (imagine lo que sucedería. Los valores int de las celdas de la array se interpretan como punteros y se eliminan de la referencia -> ¡Bam! ¡Fallo de segmentación!). Sin embargo, puede pensar en la array como una matriz 1d de int [6] s; es una matriz de elementos 1d, con el tipo int [6] . Para escribir eso, dices

int (*p)[6] = array;