Foros del Web » Programación para mayores de 30 ;) » C/C++ »

¿Algún alma caritativa que me eche una mano?

Estas en el tema de ¿Algún alma caritativa que me eche una mano? en el foro de C/C++ en Foros del Web. Buenas, estoy intentando realizar este ejercicio en el CFree: "Crear un programa que contenga una función llamada copiarVector que reciba dos vectores enteros y el ...
  #1 (permalink)  
Antiguo 17/12/2014, 13:45
Avatar de MrPizza  
Fecha de Ingreso: diciembre-2014
Mensajes: 5
Antigüedad: 9 años, 4 meses
Puntos: 0
¿Algún alma caritativa que me eche una mano?

Buenas, estoy intentando realizar este ejercicio en el CFree:
"Crear un programa que contenga una función llamada copiarVector que reciba dos
vectores enteros y el tamaño de los mismos (deben de ser del mismo tamaño) y que copie en el segundo vector el contenido del primero"

Y esto es lo que estoy haciendo:
#include <stdio.h>
void copiarvector(int tam1, int tam2, int vector1[tam1], int vector2[tam2]);
main()
{
copiarvector(tam1, tam2, vector1[tam1], vector2[tam2]);
for(i=0;i<tam1;i++)
{
printf("El valor del segundo vector en la posicion %d es %d\n",i,vector2[i]);
}
}
void copiarvector(int tam1, int tam2, int vector1[tam1], int vector2[tam2])
{
int i, tam1, int tam2, int vector1[tam1], int vector2[tam2];
printf("Introduzca el tamano del primer vector: \n");
scanf("%d",&tam1);
tam2=tam1;
for(i=0;i<tam1;i++)
{
printf("Introduzca el valor de la posicion %d del primer vector: \n",i);
scanf("%d",&vector1[i]);
vector2[i]=vector1[i];
}
}

Me da bastantes errores, entre ellos que tam1 y compañía no están declarados, cosa que no entiendo ya que dentro de la implementación de la función los he declarado. Help pls.
Gracias de antemano
  #2 (permalink)  
Antiguo 17/12/2014, 13:55
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 11 años, 9 meses
Puntos: 28
Respuesta: ¿Algún alma caritativa que me eche una mano?

Se puede postear el código así o se puede postear el código de esta forma:
Código C++:
Ver original
  1. #include <stdio.h>
  2. void copiarvector(int tam1, int tam2, int vector1[tam1], int vector2[tam2]);
  3.  
  4. main()
  5. {
  6.     copiarvector(tam1, tam2, vector1[tam1], vector2[tam2]);
  7.     for(i=0; i<tam1; i++)
  8.     {
  9.         printf("El valor del segundo vector en la posicion %d es %d\n",i,vector2[i]);
  10.     }
  11. }
  12.  
  13. void copiarvector(int tam1, int tam2, int vector1[tam1], int vector2[tam2])
  14. {
  15.     int i, tam1, int tam2, int vector1[tam1], int vector2[tam2];
  16.     printf("Introduzca el tamano del primer vector: \n");
  17.     scanf("%d",&tam1);
  18.     tam2=tam1;
  19.     for(i=0; i<tam1; i++)
  20.     {
  21.         printf("Introduzca el valor de la posicion %d del primer vector: \n",i);
  22.         scanf("%d",&vector1[i]);
  23.         vector2[i]=vector1[i];
  24.     }
  25. }

Mucho mejor y más fácil que te contentesmos así.

Y el problema esque no has declarado ningún vector en el main (de hecho no has declarado ninguna de las variables *_*).
  #3 (permalink)  
Antiguo 17/12/2014, 14:05
Avatar de MrPizza  
Fecha de Ingreso: diciembre-2014
Mensajes: 5
Antigüedad: 9 años, 4 meses
Puntos: 0
Respuesta: ¿Algún alma caritativa que me eche una mano?

He probado a declararlos en el main añadiendo esto al principio:
int i, tam1, tam2, vector1[tam1], vector2[tam2];
Pero nada, me sigue dando los mismos errores.
Por cierto como has posteado así el código?
  #4 (permalink)  
Antiguo 17/12/2014, 14:17
Avatar de cursillosonline  
Fecha de Ingreso: diciembre-2014
Mensajes: 4
Antigüedad: 9 años, 4 meses
Puntos: 1
Respuesta: ¿Algún alma caritativa que me eche una mano?

Cita:
Iniciado por MrPizza Ver Mensaje
He probado a declararlos en el main añadiendo esto al principio:
int i, tam1, tam2, vector1[tam1], vector2[tam2];
Pero nada, me sigue dando los mismos errores.
Por cierto como has posteado así el código?
Pero no entiendo tu codigo, para que usas tam1 y tam2 si al final haces que tam2 sea igual a tam1?, quieres que tus vectores sean de igual tamaño o diferentes?, ademas tam1 y tam2 no tienen valores asignados todavía, por lo que al llamar a la función.

Código C:
Ver original
  1. copiarvector(tam1, tam2, vector1[tam1], vector2[tam2]);

Este tendrá un comportamiento indefinido.

Es decir, debes definir tus variables tam1 y tam2, y además asignarles un valor.

PD: Por otro lado, si tam2 llega a ser mas chico que tam1 se producira un buffer overflow en la linea 23.

Última edición por cursillosonline; 17/12/2014 a las 22:06
  #5 (permalink)  
Antiguo 18/12/2014, 05:29
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 6 meses
Puntos: 38
Respuesta: ¿Algún alma caritativa que me eche una mano?

Cita:
int i, tam1, tam2, vector1[tam1], vector2[tam2];
Esto no me gusta en absoluto para nada. al declarar a tam1 en la misma linea de vector1[tam1], tam1 no sabes que tamaño tiene. puede ser uno, puede ser cero o puede ser tropecientos trillones XDDDD

Prueba dando un valor a tam1 y tam2: int i=0, tam1=10, tam2=10, vector1[tam1], vector2[tam2];

Entonces ahora sabes que vector1 tiene 10 y vector2 tiene 10. ;)

Recuerda que dar un valor inicial a una variable aun que sea cero es buena practica.

  #6 (permalink)  
Antiguo 18/12/2014, 05:38
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: ¿Algún alma caritativa que me eche una mano?

Cita:
Iniciado por vangodp Ver Mensaje
Esto no me gusta en absoluto para nada
No es sólo que no te guste... es que eso no pertenece al estándar, luego no está garantizada la forma de actuar de ese código. Puede que, lo haga como esperas o puede que empieces a pisar memoria sin saber el por qué.

En vez de hacer eso hay dos opciones:

* Si no quieres usar memoria dinámica, declara un buffer más grande de lo necesario (imprescindible definir un tope) y luego usa otra variable para saber cual es la capacidad real del buffer.

* La opción dos es reservar la memoria necesaria con malloc y, bueno, en este caso también necesitas una segunda variable para que te indique el tamaño del buffer.
  #7 (permalink)  
Antiguo 18/12/2014, 08:42
Avatar de cursillosonline  
Fecha de Ingreso: diciembre-2014
Mensajes: 4
Antigüedad: 9 años, 4 meses
Puntos: 1
Respuesta: ¿Algún alma caritativa que me eche una mano?

Bueno, una solucion al problema podria ser esta.

Código C:
Ver original
  1. #include <stdio.h>
  2.  
  3. int copiarvector(int tam1, int tam2, int vector1[], int vector2[]) {
  4.     int i;
  5.    
  6.     if (tam2 < tam1) {
  7.         puts("El tamano del segundo arreglo es mas chico");
  8.        
  9.         return 0;
  10.     }
  11.     else {
  12.         for(i = 0; i < tam1; i++)
  13.             vector2[i] = vector1[i];
  14.            
  15.         return 1;
  16.     }
  17. }
  18.  
  19. int main() {
  20.     int i, tam1, tam2;
  21.    
  22.     printf("Introduzca el tamano del primer vector: ");
  23.     scanf("%d", &tam1);
  24.    
  25.     printf("Introduzca el tamano del segundo vector: ");
  26.     scanf("%d", &tam2);
  27.    
  28.     int vector1[tam1], vector2[tam2];
  29.    
  30.     for(i = 0; i < tam1; i++) {
  31.         printf("Introduzca el valor de la posicion %d del primer vector: ", i + 1);
  32.         scanf("%d", &vector1[i]);
  33.     }
  34.    
  35.     if (copiarvector(tam1, tam2, vector1, vector2))
  36.         for(i = 0; i < tam2; i++)
  37.             printf("El valor del segundo vector en la posicion %d es %d\n", i + 1, vector2[i]);
  38. }
  #8 (permalink)  
Antiguo 18/12/2014, 08:51
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: ¿Algún alma caritativa que me eche una mano?

Cita:
Iniciado por cursillosonline Ver Mensaje
Bueno, una solucion al problema podria ser esta.
Código C:
Ver original
  1. int vector1[tam1], vector2[tam2];

Ahí tienes el mismo problema que se ha comentado anteriormente. Declarar un array de esta manera es algo a evitar encarecidamente
  #9 (permalink)  
Antiguo 18/12/2014, 09:03
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 6 meses
Puntos: 38
Respuesta: ¿Algún alma caritativa que me eche una mano?

¿Que problema tiene declarar int vector1[tam1], vector2[tam2]; según el estándar? ¿De alguna forma hay que declararlo no?
Lo de pisar memoria solo si fuera:
int tam1, tam2;
int vector1[tam1], vector2[tam2];

...Porque:
int tam1= 10, tam2=10;
int vector1[tam1], vector2[tam2];

...No veo en que va pisar memoria ninguna.
  #10 (permalink)  
Antiguo 18/12/2014, 09:25
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: ¿Algún alma caritativa que me eche una mano?

Cita:
Iniciado por vangodp Ver Mensaje
¿Que problema tiene declarar int vector1[tam1], vector2[tam2]; según el estándar? ¿De alguna forma hay que declararlo no?
El problema es que el estándar dice que, en estos casos, el tamaño del arreglo tiene que quedar establecido en tiempo de compilación... tu ahí estás forzando a que el tamaño se establezca en tiempo de ejecución.

Un ejemplo en el que se ve más claro:

Código C:
Ver original
  1. int funcion( int filas, int columnas, int array[filas][columnas] )
  2. {
  3.   int i, j;
  4.   for ( i=0; i < filas; i++ )
  5.   {
  6.     for ( j=0; j < columnas; j++ )
  7.     {
  8.       printf( "%d ", array[i][j] );
  9.     }
  10.   }
  11. }

¿Me podrías decir cómo puede el compilador saber en este código cuánto vale "columnas" para calcular los saltos correctamente? No puede. Es algo que queda para tiempo de ejecución y solo en aquellos casos en los que el compilador esté preparado para ello... que como digo, al no formar parte del estándar no es algo seguro.

La forma de afrontar estos casos pasa por reservar memoria de forma dinámica con malloc.
  #11 (permalink)  
Antiguo 18/12/2014, 09:33
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 6 meses
Puntos: 10
Respuesta: ¿Algún alma caritativa que me eche una mano?

No se ha hablado de que se pise memoria, sino de que no es la forma.
O se usan constantes:
Código C++:
Ver original
  1. const int tam=5;
  2. int array[tam];

O se usa memoria dinámica.
Código C++:
Ver original
  1. int tam=5;
  2. int *array= new int[tam];

Aquí dos enlaces:
http://c.conclase.net/curso/?cap=010
http://gcc.gnu.org/onlinedocs/gcc-4....ariable-Length

En el 2º enlace te dice que el estandar C99 sí que permite esta forma.
Pero luego, viendo otros artículos, se alerta del problema que puede ocurrir si el tamaño de la memoria a reservar es demasiado grande y nos quedamos sin espacio en la pila.
http://www.clarkcox.com/blog/2009/04...vlas-are-evil/
De ahí que esté desaconsejada esta forma

Saludos!
__________________
Mi calculadora en Qt
  #12 (permalink)  
Antiguo 18/12/2014, 09:35
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 6 meses
Puntos: 10
Respuesta: ¿Algún alma caritativa que me eche una mano?

Ala, ya te has adelantado!
__________________
Mi calculadora en Qt
  #13 (permalink)  
Antiguo 18/12/2014, 09:50
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: ¿Algún alma caritativa que me eche una mano?

Cita:
Iniciado por dehm Ver Mensaje
En el 2º enlace te dice que el estandar C99 sí que permite esta forma.
Siempre había oído la versión opuesta, me lo apunto.
  #14 (permalink)  
Antiguo 18/12/2014, 11:24
Avatar de cursillosonline  
Fecha de Ingreso: diciembre-2014
Mensajes: 4
Antigüedad: 9 años, 4 meses
Puntos: 1
Respuesta: ¿Algún alma caritativa que me eche una mano?

Cita:
Iniciado por dehm Ver Mensaje
En el 2º enlace te dice que el estandar C99 sí que permite esta forma.
Pero luego, viendo otros artículos, se alerta del problema que puede ocurrir si el tamaño de la memoria a reservar es demasiado grande y nos quedamos sin espacio en la pila.
[URL="http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/"]http://www.clarkcox.com/blog/2009/04/07/c99s-vlas-are-evil/[/URL]
De ahí que esté desaconsejada esta forma

Saludos!
Leyendo un poco más (se que se podian hacer VLAs desde el C99, pero no he leído mucho del tema) el problema es que a diferencia de usar malloc (que retorna null en caso de haber fallado), un VLA puede ser más peligroso por que no retorna null en caso de que no halla memoria suficiente para el arreglo (y en el stack el espacio de memoria es pequeño), pero para arreglos de tamaño pequeños no creo que halla mucho drama, aun así la mayoría recomienda no usarlos.
  #15 (permalink)  
Antiguo 18/12/2014, 11:50
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 6 meses
Puntos: 38
Respuesta: ¿Algún alma caritativa que me eche una mano?

¿Me podrías decir cómo puede el compilador saber en este código cuánto vale "columnas" para calcular los saltos correctamente?
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define f 0
  5. #define c 0
  6.  
  7. void funcion ( int filas, int columnas, int array[f+filas][c+columnas] ) {
  8.     int i, j;
  9.    
  10.     for ( i = 0; i < filas; i++ ) {
  11.         for ( j = 0; j < columnas; j++ ) {
  12.             printf ( "%d ", array[i][j] );
  13.         }
  14.     }
  15. }
  16.  
  17. int main () {
  18.     int fil, col, contador = 0;
  19.    
  20.     fil = col = 3;
  21.     int a[fil][col];
  22.    
  23.     int i, j;
  24.    
  25.     for ( i = 0; i < fil; i++ ) {
  26.         for ( j = 0; j < col; j++ ) {
  27.             a[i][j] = contador;
  28.             contador++;
  29.         }
  30.     }    
  31.    
  32.     funcion( fil, col, a );
  33.  
  34.  
  35.     getchar();
  36.     return 0;
  37. }
¿Que te parece? XDDDD
  #16 (permalink)  
Antiguo 18/12/2014, 11:51
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 6 meses
Puntos: 10
Respuesta: ¿Algún alma caritativa que me eche una mano?

Hola:

Yo entiendo que si se usa esta forma en funciones, las cuales van a dimensionar un array y además no sabemos muy bien qué tamaño podría llegar a manejar, estamos jugando con fuego.

En casos como el que indicas, en los que me limito a almacenar el tamaño del array en una variable, y luego declarar el array en función de esta variable, pues no parece peligroso, siempre que estemos seguros de que esa variable no se va a usar para otros usos y cosas raras así.(que ciertamente es fácil controlar esta cuestión)

Pero aún así, siempre va a dar un warning, y en mi caso, con el -pedantic-errors activado, no me compilaría.
__________________
Mi calculadora en Qt
  #17 (permalink)  
Antiguo 18/12/2014, 12:04
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 6 meses
Puntos: 38
Respuesta: ¿Algún alma caritativa que me eche una mano?

¿Pero va decir que no mola lo de?:
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4.  
  5. int main () {
  6.     const int FILAS = 0;
  7.     const int COLUMNAS = 0;
  8.    
  9.     int f = 5;
  10.     int c = 5;
  11.    
  12.     char arreglo[FILAS+f][COLUMNAS+c];
  13.  
  14.     getchar();
  15.     return 0;
  16. }
Es una constante no constante jajaja
XDDD

Ademas si es para grandes cantidades de memoria creo que cualquiera de aquí sabe que debe ser en el heap.
  #18 (permalink)  
Antiguo 19/12/2014, 13:43
Avatar de MrPizza  
Fecha de Ingreso: diciembre-2014
Mensajes: 5
Antigüedad: 9 años, 4 meses
Puntos: 0
Respuesta: ¿Algún alma caritativa que me eche una mano?

Pues muchas gracias a tod@s, me han venido bastante bien las respuestas. Saludos ;)

Etiquetas: Ninguno
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 04:57.