En perl puedo crear arreglos 1D y luego crear arreglos 2D a partir de ellos, de la siguiente manera:
@a1=(a,b,c) @a2=(d,e,f) @a3=(g,h,i) @m23_v1=(\@a1,\@a2,\@a3) Aquí hay otra forma (asumiendo que @a1 , @a2 y @a3 son los mismos que en el ejemplo anterior):
@m23_v2=([@a1],[@a2],[@a3]) La diferencia entre esas dos formas es que cuando se usan barras invertidas, cambiar $a[0][0] también cambiará $a1[0] . Por otro lado, cuando se usan corchetes, el valor se copia, por lo que cambiar $a[0][0] no cambiará $a1[0] . Abajo están las direcciones de memoria de las variables que deberían aclarar lo que quiero decir:
print \$a1[0] SCALAR(0x2006c0a0) print \$m23_v1[0][0] SCALAR(0x2006c0a0) print \$m23_v2[0][0] SCALAR(0x2030a7e8)¿Cómo lograr lo mismo pero en C? He intentado siguiendo el código:
# include <stdio.h> int main(){ int a1[3] = {1,2,3}; int a2[3] = {4,5,6}; int m23[2][3] = {a1, a2}; printf("%d\n", a1[0]); printf("%d\n", m23[0][0]); }Pero me da las siguientes advertencias de compilación:
2d.c: In function 'main': 2d.c:4:3: warning: initialization makes integer from pointer without a cast [enabled by default] 2d.c:4:3: warning: (near initialization for 'm23[0][0]') [enabled by default] 2d.c:4:3: warning: initialization makes integer from pointer without a cast [enabled by default] 2d.c:4:3: warning: (near initialization for 'm23[0][1]') [enabled by default] 2d.c:5:3: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]Después de la ejecución, el código C devuelve lo siguiente:
1 -1077371888Preguntas:
Recibe la advertencia porque cuando inicializa la matriz m23 , las matrices a1 y a2 se descomponen en punteros , lo que hace que tenga una matriz no de matrices sino de punteros. Y así es como resuelve su problema, declarando m23 como una matriz de punteros :
int *m23[2] = { a1, a2 };Puede usar una matriz de punteros para obtener un equivalente de la versión con barra invertida (es decir @m23_v1 ):
#include <stdio.h> int main(void) { int a1[3] = {1,2,3}; int a2[3] = {4,5,6}; int *m23[2] = {a1, a2}; printf("%d\n", a1[0]); printf("%d\n", m23[0][0]); return 0; }En tu código:
int m23[2][3] = {a1, a2}; el inicializador espera que se llene con números enteros. Básicamente, crea una matriz bidimensional con dos números enteros: a1 , a2 . Los elementos restantes se inicializan con ceros. Para ilustrarlo, esto se parece a:
int m23[2][3] = {0xaaee33, 0xaaee55, 0, 0, 0, 0};que es efectivamente lo mismo que:
int m23[2][3] = {{0xaaee33, 0xaaee55, 0}, {0, 0, 0}}; // two rows, three columns Sin embargo, a1 no es un número entero. Es el nombre de la matriz, que se convierte implícitamente a int (después de convertirse en puntero, que apunta al primer elemento de la matriz). En otras palabras, está convirtiendo implícitamente las direcciones de a1 y a2 en dos números enteros. De hecho, tal operación es ilegal en C y dicho código ni siquiera debería compilarse con -pedantic-errors (o equivalente).
¿Cuál es el equivalente para la versión de corchetes (y viceversa)?
El equivalente de la versión reforzada es definir una matriz multidimensional de tamaño específico y luego copiar cada elemento de las matrices a1 y a2 en ella:
#include <stdio.h> #include <string.h> int main(void) { int a1[3] = {1,2,3}; int a2[3] = {4,5,6}; int m23[2][3]; memcpy(m23 + 0, a1, sizeof(a1)); memcpy(m23 + 1, a2, sizeof(a2)); printf("%d\n", a1[0]); printf("%d\n", m23[0][0]); return 0; }Bueno, no puede inicializar la matriz con el uso de otra matriz. Puedes hacerlo así:
int m[2][3] = {{1,2,3},{4,5,6}};Esto se debe a que a1 y a2 se tratan como punteros a int. Puede esto con una matriz de punteros:
int* m[2] = {a1,a2);