advertencia: pasar el argumento 1 de ‘barra’ del tipo de puntero incompatible
Aunque la llamada ‘foo’ parece estar bien.
Gracias 🙂
Johannes Schaub – litb
Bueno, ciertamente no es bien entendido por la comunidad C como se puede ver al echar un vistazo a SO. La magia es, todos los siguientes son totalmente, 100%, equivalentes:
Está muy Es importante establecer la distinción entre un puntero y una matriz. Una matriz no es un puntero. Una matriz se puede convertir en un puntero a su primer elemento. Si tienes un puntero tienes esto:
Con el puntero, los datos están en otro planeta, pero vinculados por el puntero. Una matriz tiene los datos en sí. Ahora, una matriz multidimensional es solo una matriz de matrices. Las matrices están anidadas en una matriz principal. Entonces, el tamaño de su matriz es:
(sizeof(int) * 10) * 10
Eso es porque tiene 10 arreglos, todos los cuales son arreglos de 10 enteros. Ahora, si desea pasar esa matriz, se convierte. ¿Pero a qué? Un puntero a su primer elemento. El tipo de elemento es no un puntero, sino una matriz. Como consecuencia, pasa un puntero a una matriz de 10 int:
int (*)[10] // a pointer to an int[10]
No es ni una matriz de int*ni un int**. Puede preguntar por qué la matriz no se pasa como un int**. Es porque el compilador tiene que saber la longitud de la fila. si haces un array[1][0]el compilador se dirigirá a un lugar sizeof(int) * 10 bytes aparte del comienzo de la matriz bidimensional. Decodifica esa información en el tipo de puntero a matriz.
Por lo tanto, debe elegir entre uno de los prototipos de funciones totalmente equivalentes anteriores. Naturalmente, el último es simplemente confuso. El compilador simplemente ignora silenciosamente cualquier número escrito en la dimensión más externa si un parámetro se declara como una matriz. Así que tampoco usaría la penúltima versión. Lo mejor es usar la primera o la segunda versión. Lo que es importante recordar es que C no tiene parámetros de matriz (reales)! El parámetro será un puntero al final (puntero a matriz en este caso).
Observe cómo el caso multidimensional de arriba es similar al caso degenerado y unidimensional de abajo. Todas las siguientes 4 versiones son totalmente equivalentes:
Aunque la respuesta de Mark Pim se centra completamente en el problema principal de mi pregunta, quiero compensar de alguna manera todo su esfuerzo por tratar de explicar las sutilezas de las matrices como parámetros en C configurando esta respuesta como se recomienda. ¡Gracias!
La pregunta que debe hacerse es cómo usará bar. Si siempre sabe que se le pasará una matriz de 10×10, vuelva a escribirlo como
bar(int matrix[10][10]);
Si desea hacer frente a matrices de diferentes dimensiones, es posible que deba pasar las longitudes:
bar(int *matrix, int width, int height);
La tuya es una gran respuesta. ¡Gracias!
– Aurón
14 de febrero de 2009 a las 0:40
El problema es que la matriz de estructura de datos[10][10] en realidad no es una tabla de diez punteros a la matriz[10]’s, pero es una matriz secuencial de 100 enteros. La firma adecuada para bar es
bar (int matrix[10][10])
Si realmente desea representar la matriz usando indirección y tiene int **matrix como el tipo de parámetro para la barra, entonces debe asignarlo de manera diferente:
int *matrix[10];
int my_data[100];
int i;
for (i = 0; i < 10; i++) { matrix[i] = &(my_data[i * 10]); }
bar(matrix);
Ahora ‘matriz’ coincide con el tipo int **. ‘matriz’ es una matriz de diez punteros, y puede pasarla por puntero, obteniendo así el segundo *.
“El problema es que la matriz de estructura de datos[10][10] en realidad no es una tabla de diez punteros a la matriz[10]’s, pero es una matriz secuencial de 100 enteros.” ¡Por eso estaba tan confundido!
– Aurón
13 de febrero de 2009 a las 18:54
Aquí hay un código para practicar: contiene todos los tipos posibles de matriz bidimensional y código para acceder a los valores de los elementos.
En C, todas las matrices deben pasarse como int* (o type_of_element* para otros tipos).
int ** estaría bien si sus datos fueran realmente una matriz de punteros. int[*data[] por ejemplo. Eso es lo que obtienes main(int argc, char *argv[]).
dwc
int **matrix
indicaría que tiene un puntero a un puntero a int. Eso se usa comúnmente para indicar un puntero a una matriz de punteros (también llamado vector). Definitivamente NO es el caso con
int matrix[10][10]
que es más un puntero a una sola sección de memoria con un tamaño de 10×10 entradas. Intenta cambiar a:
void bar(int *matrix[])
¿Ha sido útil esta solución?
Tu feedback nos ayuda a saber si la solución es correcta y está funcionando. De esta manera podemos revisar y corregir el contenido.
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos.
Configurar y más información