Autor
|
Tema: [C] Paso de arreglos bidimensionales a funciones. (?) (Leído 12,583 veces)
|
oblivionxor
Desconectado
Mensajes: 19
No hay mayor fracaso que apresurar el exito
|
Hola que tal. Lo que pasa es que en este codigo: /*Asignacion de valores en arreglos bidimensionales*/ #include <stdio.h> /*Prototipos de funciones*/ void imprimir_arreglo( const int a[2][3] ); /*Inicia la ejecucion del programa*/ int main() { int arreglo1[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; int arreglo2[2][3] = { 1, 2, 3, 4, 5 }; int arreglo3[2][3] = { { 1, 2 }, { 4 } }; printf( "Los valores en el arreglo 1 de 2 filas y 3 columnas son:\n" ); imprimir_arreglo( arreglo1 ); printf( "Los valores en el arreglo 2 de 2 filas y 3 columnas son:\n" ); imprimir_arreglo( arreglo2 ); printf( "Los valores en el arreglo 3 de 2 filas y 3 columnas son:\n" ); imprimir_arreglo( arreglo3 ); return 0; } /*Fin de main*/ /*Definiciones de funciones*/ void imprimir_arreglo( const int a[2][3] ) { int i; /*Contador filas*/ int j; /*Contador columnas*/ for (i = 0; i <=1; i++) { for (j = 0; j <= 2; j++) { } } } /*Fin de funcion imprime_arreglo*/
Cuando compilo de esa manera me da estos errores mi compilador: ArreglosBidimensionales.c: In function ‘main’: ArreglosBidimensionales.c:16:3: warning: passing argument 1 of ‘imprimir_arreglo’ from incompatible pointer type [enabled by default] ArreglosBidimensionales.c:5:6: note: expected ‘const int (*)[3]’ but argument is of type ‘int (*)[3]’ ArreglosBidimensionales.c:19:3: warning: passing argument 1 of ‘imprimir_arreglo’ from incompatible pointer type [enabled by default] ArreglosBidimensionales.c:5:6: note: expected ‘const int (*)[3]’ but argument is of type ‘int (*)[3]’ ArreglosBidimensionales.c:22:3: warning: passing argument 1 of ‘imprimir_arreglo’ from incompatible pointer type [enabled by default] ArreglosBidimensionales.c:5:6: note: expected ‘const int (*)[3]’ but argument is of type ‘int (*)[3]’
Pero cuando compilo quitandole el calificador de tipo const al prototipo y definicion de funciones es decir asi: /*Prototipos de funciones*/ void imprimir_arreglo( int a[2][3] ); ....... /*Definiciones de funciones*/ void imprimir_arreglo( int a[2][3] ) {
Si puedo compilar correctamente. Por que pasa eso? Por que en arreglos unidimensionales si puedo compilar con el calificador const y en los bidimensionales no? Alguien me puede ayudar con esta duda? Por cierto uso el compilador GNU GCC. Agradecimientos por adelantado.
|
|
|
En línea
|
|
|
|
Sputnik_
Desconectado
Mensajes: 80
|
en c++ funciona saludos
|
|
« Última modificación: 19 Febrero 2013, 17:49 pm por PajaroUyUyUy »
|
En línea
|
Las personas lo suficientemente locas como para pensar que pueden cambiar el mundo son las que lo cambian.
|
|
|
leosansan
Desconectado
Mensajes: 1.314
|
Ya te lo está diciendo el compilador: espera un const int y tú le mandas un int. Lo que quiere decir que tienes mal tipificadaos los arreglos, que deberían ser:.................................................................... const int arreglo1[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
const int arreglo2[2][3] = { 1, 2, 3, 4, 5 }; const int arreglo3[2][3] = { { 1, 2 }, { 4 } }; .......................................................................
Saluditos!.
|
|
|
En línea
|
|
|
|
oblivionxor
Desconectado
Mensajes: 19
No hay mayor fracaso que apresurar el exito
|
leosansan pero por que cuando declaro arreglos unidimensionales, aunque no los declare como const, si puedo compilar correctamente cuando paso los arreglos a parametros const de una funcion? Asi mira: #include <stdio.h> void intenta_modificar_arreglo( const int b[] ); /* Inicia la ejecucion */ int main() { int a[] = { 1, 2, 10 }; intenta_modificar_arreglo( a ); printf( "%d %d %d\n", a [0], a [1], a [2] ); return 0; } /* Fin de main */ /*------------------Definicion de funciones-----------------------*/ void intenta_modificar_arreglo( const int b[] ) { b[0] /= 2; b[1] /= 2; b[2] /= 2; } /* Fin de funcion intenta_modificar_arreglo */
Que es lo que pasa, por que en arreglos unidimensionales si se puede evadir la declaracion const y en los bidimensionales no?? Esa es mi duda???
|
|
|
En línea
|
|
|
|
leosansan
Desconectado
Mensajes: 1.314
|
.......................... Esa es mi duda???
Y me has creado otra a mí. Espero que alguien como rir o afín nos saque de la duda. por cierto, para mantener el paralelismo con el bidimensional he usado: #include <stdio.h> void intenta_modificar_arreglo( const int b[3] ); /* Inicia la ejecucion */ int main() { int a[3] = { 1, 2, 10 }; intenta_modificar_arreglo( a ); return 0; } /* Fin de main */ /*------------------Definicion de funciones-----------------------*/ void intenta_modificar_arreglo( const int b[3] ) { int j; for (j = 0; j <= 2; j++) { printf( "%d ", b[j] ); } } /* Fin de funcion intenta_modificar_arreglo */
Pero no "cantan" ahora los warnings Saluditos!.
|
|
« Última modificación: 19 Febrero 2013, 22:42 pm por leosansan »
|
En línea
|
|
|
|
oblivionxor
Desconectado
Mensajes: 19
No hay mayor fracaso que apresurar el exito
|
Si espero que nos saquen de la duda :c ojala y sean tan amables de aclararnoslo.
|
|
|
En línea
|
|
|
|
amchacon
Desconectado
Mensajes: 1.211
|
En C++ tira perfecto, creo que tiene que ver con las limitaciones de C y la pila. Puedes crearlo dinámicamente y entonces si te irá: /*Asignacion de valores en arreglos bidimensionales*/ #include <stdio.h> #include <stdlib.h> /*Prototipos de funciones*/ void imprimir_arreglo( const int** a); /*Inicia la ejecucion del programa*/ int main() { int i = 0; int** arreglo1 = (int**)malloc(3*sizeof(int*)); for (i = 0; i < 3;i++) arreglo1 [i ] = (int*)malloc(2*sizeof(int)); //int** arreglo2[2][3] = { {1, 2, 3},{ 4, 5, 6 }}; //int** arreglo3[2][3] = { { 1, 2 }, { 4 } }; printf( "Los valores en el arreglo 1 de 2 filas y 3 columnas son:\n" ); imprimir_arreglo((const int**) arreglo1 ); printf( "Los valores en el arreglo 2 de 2 filas y 3 columnas son:\n" ); //imprimir_arreglo( arreglo2 ); printf( "Los valores en el arreglo 3 de 2 filas y 3 columnas son:\n" ); //imprimir_arreglo( arreglo3 ); return 0; } /*Fin de main*/ /*Definiciones de funciones*/ void imprimir_arreglo( const int** a) { int i; /*Contador filas*/ int j; /*Contador columnas*/ for (i = 0; i <=1; i++) { for (j = 0; j <= 2; j++) { } } } /*Fin de funcion imprime_arreglo*/
|
|
|
En línea
|
|
|
|
BatchianoISpyxolo
Desconectado
Mensajes: 166
|
Te pego una práctica que hice hará 2 meses o así para que veas más o menos el manejo de arrays bidimensionales en C. /* FIC - 2º GRADO - Algortimos Practica 4 Maquina donde se han testado los algoritmos: Equipo portatil personal. Intel(R) Core(TM) i3 CPU M 370 @ 2.40GHz x64 */ #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <limits.h> #include <math.h> #include "lista.h" typedef int ** matriz; // algoritmo de prim lista prim(matriz m, int tam) { int min, i, j, r, k=0; arista a; lista l; int *masProximo = (int *) malloc(tam *sizeof(int)); int *distanciaMinima = (int *) malloc(tam *sizeof(int)); crear_lista(&l); distanciaMinima[0] = -1; for(i = 1; i < tam; i++) { masProximo[i] = 0; distanciaMinima[i] = m[i][0]; } for (r=1; r<tam; r++) { /* bucle voraz */ min = INT_MAX; for (j=1;j<tam;j++) { if (0<=distanciaMinima[j] && distanciaMinima[j]<min) { min = distanciaMinima[j]; k = j; } } a.x = masProximo[k]; a.y = k; a.peso = min; insertar(a,&l); distanciaMinima[k] = -1; for (j=1;j<tam;j++) { if (m[j][k] < distanciaMinima[j]) { distanciaMinima[j] = m[j][k]; masProximo[j] = k; } } } return l; } // crea una matriz matriz crear_matriz(int n) { int i; matriz aux; if ((aux = (int **) malloc(n *sizeof(int *))) == NULL ) return NULL; for (i=0; i<n; i++) if ((aux [i ] = (int *) malloc(n *sizeof(int))) == NULL ) return NULL; return aux; } // genera la matriz del primer ejemplo matriz matriz_primer_ejemplo() { int i,j; matriz m = (matriz)crear_matriz(5); m[0][1] = 1; m[0][2] = 8; m[0][3] = 4; m[0][4] = 7; m[1][2] = 2; m[1][3] = 6; m[1][4] = 5; m[2][3] = 9; m[2][4] = 5; m[3][4] = 3; for (i=0; i<5; i++) for (j=0; j<=i; j++) if (i==j) m[i][j] = 0; else m[i][j] = m[j][i]; return m; } // genera la matriz del segundo ejemplo matriz matriz_segundo_ejemplo() { int i,j; matriz m = (matriz)crear_matriz(4); m[0][1] = 1; m[0][2] = 4; m[0][3] = 7; m[1][2] = 2; m[1][3] = 8; m[2][3] = 3; for (i=0; i<4; i++) for (j=0; j<=i; j++) if (i==j) m[i][j] = 0; else m[i][j] = m[j][i]; return m; } // genera la matriz del tercer ejemplo matriz matriz_tercer_ejemplo() { int i,j; matriz m = (matriz)crear_matriz(7); m[0][1] = 7; m[0][2] = 99; m[0][3] = 5; m[0][4] = 99; m[0][5] = 99; m[0][6] = 99; m[1][2] = 8; m[1][3] = 9; m[1][4] = 7; m[1][5] = 99; m[1][6] = 99; m[2][3] = 99; m[2][4] = 5; m[2][5] = 99; m[2][6] = 99; m[3][4] = 15; m[3][5] = 6; m[3][6] = 99; m[4][5] = 8; m[4][6] = 9; m[5][6] = 11; for (i=0; i<7; i++) for (j=0; j<=i; j++) if (i==j) m[i][j] = 0; else m[i][j] = m[j][i]; return m; } void inicializar_matriz(matriz m, int n) { /* Crea un grafo completo no dirigido con pesos aleatorios entre 1 y n */ int i, j; for (i=0; i<n; i++) for (j=i+1; j<n; j++) m [i ][j ] = rand() % n + 1; for (i=0; i<n; i++) for (j=0; j<=i; j++) if (i==j) m[i][j] = 0; else m[i][j] = m[j][i]; } void liberar_matriz(matriz m, int n) { int i; for (i=0; i<n; i++) } void solucion(lista l) { pnodo it = primera(l); int peso_total = 0; while (it != NULL) { printf("(%d, %d) ", it ->elemento. x, it ->elemento. y); peso_total += it->elemento.peso; it = siguiente(it); } printf("\nPeso total minimo: %d\n", peso_total ); eliminar_lista(&l); } void test () { printf("\n- test para probar el correcto funcionamiento del algoritmo -\n\n"); matriz m = matriz_primer_ejemplo(); matriz n = matriz_segundo_ejemplo(); matriz o = matriz_tercer_ejemplo(); solucion(prim(m,5)); printf("\nSegundo ejemplo.\n"); solucion(prim(n,4)); printf("\nTercer ejemplo.\n"); solucion(prim(o,7)); liberar_matriz(m,5); liberar_matriz(n,4); liberar_matriz(o,7); } double microsegundos() { struct timeval t; if (gettimeofday(&t, NULL) < 0 ) return 0.0; return (t.tv_usec + t.tv_sec * 1000000.0); } double obtener_tiempo(int N, int *umbral){ #define ITER 1000 int i; double t1, t2, t3, t4, t5, t6, t; matriz M = crear_matriz(N); inicializar_matriz(M,N); t1 = microsegundos(); prim(M,N); t2 = microsegundos(); t = t2-t1; liberar_matriz(M,N); *umbral = 0; // t < 500us if (t<500) { *umbral = 1; // t >= 500us matriz A = crear_matriz(N); // t3 = tiempo de inicializacion + tiempo prim for (i=1; i<=ITER; i++) { t1 = microsegundos(); inicializar_matriz(A,N); prim(A,N); t2 = microsegundos(); t3 += (t2-t1); } // t6 = tiempo de inicializacion for (i=1; i<=ITER; i++) { t4 = microsegundos(); inicializar_matriz(A,N); t5 = microsegundos(); t6 += (t5-t4); } t = (t3-t6) / ITER; liberar_matriz(A,N); } return (t<0 ? -t : t); } void medicion_tiempos() { #define REPS 6 int n, N, it; // variables para control de bucles y parámetros de entrada int umbral; // umbral de tiempo de ejecucion (500 us) { 1 = Supera umbral, 0 = No supera umbral } double t; // tiempo de ejecucion double h, g, f; // valores para acotar printf("- Medicion de tiempos del algoritmo -\n\n"); printf("-> h(n) = cota subestimada\n"); printf("-> g(n) = cota ajustada\n"); printf("-> f(n) = cota sobrestimada\n"); printf("\n-------------------------------------------------------------------------\n"); printf("\n%9s%13s%13s%13s%13s%10s\n","n", "t(n)", "t(n)/h(n)", "t(n)/g(n)", "t(n)/f(n)", "Umbral"); // encabezado n = 16; for (it=1; it<=REPS; it++) { n = n*2-1; t = obtener_tiempo(N, &umbral); h = t / pow(N *N , 1.8); // t(n)/h(n) g = t / pow(N *N , 2); // t(n)/g(n) f = t / pow(N *N , 2.2); // t(n)/f(n) printf("%9d%13.6f%12.6f%13.6f%13.6f%8d\n", N *N , t , h , g , f , umbral ); } printf("\n-------------------------------------------------------------------------\n"); } int main () { printf("\nPractica 4: Analisis del algortimo de Prim.\n"); test(); medicion_tiempos(); }
|
|
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
Por partes. Por que en arreglos unidimensionales si puedo compilar con el calificador const Primero porque las funciones no ven en ningún momento un array, cuando de declara una función en la forma: int fn(int a[]); /* O */ int fn(int a[N]);
Esta se procesa como si la declaración fuera: int fn(int *a);
Es por ello que no puede obtenerse el tamaño del array pasado como argumento y tampoco importa indicar el numero de elementos de este, la función simplemente recibe un puntero: la dirección en memoria de su primer elemento. Segundo por que a una función que espere como argumento un puntero a objeto constante (tipo "const T *") puede pasarse un puntero sin el calificador const (tipo "T *") sin ningún problema: la conversión implícita de un tipo a otro ("T *" ==> "const T *") se aplica de forma transparente salvo una excepción. Un ejemplo para explicar de una forma mas clara los dos puntos anteriores: #include <stdio.h> #include <stdlib.h> int suma(const int *valor, size_t num_elem); int main(void) { int valor[] = {1, 2, 3}; size_t num_elem = sizeof valor / sizeof valor[0]; printf("Suma == %d\n", suma (valor , num_elem )); return EXIT_SUCCESS; } int suma(const int *valor, size_t num_elem) { size_t i; int total; total = 0; for (i = 0; i < num_elem; i++) total += valor[i]; return total; }
y en los bidimensionales no? Porque la excepción son los "arrays bidimensionales". Aquí un paréntesis: C no tiene punteros "dobles", "triples", etc. como tampoco arrays "unidimensionales", "bidimensionales", etc. solo tiene punteros y arrays. Que el tipo apuntado sea también un puntero o el elemento del array un array es otra historia. Cuando se pasa un array de arrays como argumento de una función esta recibe la dirección de su primer elemento, si el tipo del array es "T [N][M]" la función recibe un puntero de tipo "T (*)[M]". Y aquí la conversión implícita "T *" ==> "const T *" falla porque el calificador const no se aplica al array, se aplica a sus elementos. Es por ello que tu compilador genera el mensaje de tipos distintos: ArreglosBidimensionales.c:5:6: note: expected ‘const int (*)[3]’ but argument is of type ‘int (*)[3]’ La única solución es declarar al array utilizando const o bien realizar la conversión explicita en la llamada a función. Un saludo
|
|
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
oblivionxor
Desconectado
Mensajes: 19
No hay mayor fracaso que apresurar el exito
|
Wow rir quedo todo superclaro! Muchisimas gracias por tu respuesta! Saludos.
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Programa Orientado a Objetos en Java con arreglos bidimensionales :)
Java
|
Neostream
|
3
|
43,935
|
1 Marzo 2008, 18:36 pm
por **Adem**
|
|
|
Parametros de entrada, arreglos bidimensionales
« 1 2 »
.NET (C#, VB.NET, ASP)
|
greenselves
|
13
|
11,429
|
16 Marzo 2010, 05:45 am
por [D4N93R]
|
|
|
arreglos bidimensionales y funciones
Programación C/C++
|
m@o_614
|
3
|
2,982
|
16 Julio 2013, 22:33 pm
por eferion
|
|
|
duda con arreglos bidimensionales
Programación C/C++
|
nicolas04
|
1
|
2,095
|
26 Junio 2014, 21:23 pm
por Flakito81
|
|
|
Paso de funciones a otras funciones
Programación C/C++
|
eaz95
|
1
|
2,488
|
18 Julio 2017, 11:59 am
por ivancea96
|
|