Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Xenomorfo77 en 8 Octubre 2013, 15:47 pm



Título: Ayuda!!
Publicado por: Xenomorfo77 en 8 Octubre 2013, 15:47 pm
Buenas tengo que hacer un programa que le de la vuelta a un array pasandolo como argumento a una funcion. Lo tengo hecho y me sale el resultado bien pero creo k tiene fallos.¿Alguien puede echarle un vistazo? Gracias
Código
  1. #include <stdio.h>
  2.  
  3. #define POSITIONS 25
  4.  
  5. void create(int *pointer);
  6. void print(int *pointer);
  7. void turn(int *pointer);
  8.  
  9. int main()
  10. {
  11.    int numeros[POSITIONS];
  12.    create(numeros);
  13.    print(numeros);
  14.    turn(numeros);
  15.    print(numeros);
  16.  
  17.  
  18.    return 0;
  19. }
  20.  
  21. void create(int *pointer)
  22. {
  23.    int i;
  24.    for(i=0;i<POSITIONS;i++)
  25.    {
  26.        *pointer++=i+10;
  27.    }
  28. }
  29.  
  30. void print(int *pointer)
  31. {
  32.    int i;
  33.    for(i=0;i<POSITIONS;i++)
  34.    {
  35.        printf("%d\n",*pointer++);
  36.    }
  37.  
  38. }
  39.  
  40. void turn(int *pointer)
  41. {
  42.    int i;
  43.    int temp;
  44.    for(i=0;i<POSITIONS;i++)
  45.    {
  46.        temp = *pointer;
  47.        *pointer++ = *pointer+POSITIONS-i-1;
  48.        *pointer = temp;
  49.    }
  50.  
  51. }


Título: Re: Ayuda!!
Publicado por: ivancea96 en 8 Octubre 2013, 15:54 pm
Cumple su función.

¿Qué fallos crees que tiene?


Título: Re: Ayuda!!
Publicado por: eferion en 8 Octubre 2013, 16:08 pm
Código
  1. *pointer++=i+10;
  2.  
  3. *pointer++ = *pointer+POSITIONS-i-1;

Vale que funcione pero, realmente es necesario tener código así?? Te ahorras una o dos líneas de código... realmente merece la pena?? La primera línea todavía... pero la segunda...

Tu piensa lo que te puede llegar a costar entender esto cuando vuelvas al código un par de meses después.


Título: Re: Ayuda!!
Publicado por: Xenomorfo77 en 8 Octubre 2013, 16:16 pm
Código
  1. *pointer++=i+10;
  2.  
  3. *pointer++ = *pointer+POSITIONS-i-1;

Vale que funcione pero, realmente es necesario tener código así?? Te ahorras una o dos líneas de código... realmente merece la pena?? La primera línea todavía... pero la segunda...

Tu piensa lo que te puede llegar a costar entender esto cuando vuelvas al código un par de meses después.

¿Como lo harias tu? Gracias.



Cumple su función.

¿Qué fallos crees que tiene?

La cosa es que lo he hecho pero nose ni como xD no me ha quedao claro lo que hago en turn()



Código
  1. for(i=0;i<POSITIONS;i++)
  2. {
  3.        temp = *pointer;
  4.        *pointer++ = *pointer+POSITIONS-i-1;
  5.        *pointer = temp;
  6. }

1.- Guardo en temp el valor que haya en la direccion de memoria a la que apunta pointer.
2.- Al valor que haya en pointer le meto lo que haya en la ultima y despues se incrementa la posicion.
3.- Ahora a que posicion del array apunta pointer en esta linea?  En la primera ejecucion del for -> ¿0 o 1?


Título: Re: Ayuda!!
Publicado por: ivancea96 en 8 Octubre 2013, 16:40 pm
El metodo es bastante absurdo, pero bueno, funciona -.-'

Si os fijais, en "turn()", *pointer y temp van a ser siempre iguales a 10. Lo qhe haces es ir moviendo el 10 hacia adelante, mientras vas colocando en la posicion 'i', lo que hay en '25-i'.


Título: Re: Ayuda!!
Publicado por: eferion en 8 Octubre 2013, 17:00 pm
¿Como lo harias tu? Gracias.

Simplifica las instrucciones. Al final el código tiene algunas líneas más, pero éstas son más claras.

Código
  1. // v1
  2. *pointer++ = *pointer+POSITIONS-i-1;
  3.  
  4. //v2.1
  5. *pointer = *pointer+POSITIONS-i-1;
  6. pointer++;
  7.  
  8. //v2.2
  9. *pointer += POSITIONS-i-1;
  10. pointer++;

El mayor problema, aparte de dificultar la legibilidad del código, que presenta el concatenar operaciones es que es bastante sencillo meter la pata...

Código
  1. // v1
  2. int a = a+b++;
  3.  
  4. // v2, decides poner un preincremento de b porque has leido que es mejor
  5. int a = a+++b;
  6.  
  7. // es lo mismo?? respuesta: no
  8. // en que se traduce a+++b?? respuesta: en (a++) + b


Título: Re: Ayuda!!
Publicado por: ivancea96 en 8 Octubre 2013, 17:27 pm
Código
  1. //v2.2
  2. *pointer += POSITIONS-i-1;
  3. pointer++;
Eso es erróneo. Así estás sumandole a esa casilla, la otra casilla. Sumando y asignando.


Título: Re: Ayuda!!
Publicado por: rir3760 en 8 Octubre 2013, 18:07 pm
tengo que hacer un programa que le de la vuelta a un array pasandolo como argumento a una funcion.
Para invertir el array solo necesitas de un auxiliar y dos punteros (uno ya lo tienes, el parámetro de la función):
Código
  1. void turn(int *p)
  2. {
  3.   int *q;
  4.   int aux;
  5.  
  6.   for (q = p + POSITIONS - 1; p < q; p++, q--){
  7.      aux = *p;
  8.      *p = *q;
  9.      *q = aux;
  10.   }
  11. }

Un saludo


Título: Re: Ayuda!!
Publicado por: eferion en 8 Octubre 2013, 22:49 pm
Eso es erróneo. Así estás sumandole a esa casilla, la otra casilla. Sumando y asignando.

???

Esto:

Código
  1. *pointer++ = *pointer+POSITIONS-i-1;

Es equivalente a esto:

Código
  1. *pointer = *pointer+POSITIONS-i-1;
  2. pointer++;

Y esto a su vez es equivalente a esto:

Código
  1. *pointer += POSITIONS-i-1;
  2. pointer++;

¿ Dónde está el problema entonces ?

Yo te lo digo. El problema es escribir ese tipo de líneas, que generan confusión. Y aquí tienes la prueba.


Título: Re: Ayuda!!
Publicado por: rir3760 en 9 Octubre 2013, 02:44 am
Código
  1. *pointer++ = *pointer+POSITIONS-i-1;

...

2.- Al valor que haya en pointer le meto lo que haya en la ultima y despues se incrementa la posicion.
Esa sentencia tiene dos problemas importantes.

El primero es aplicar indirección y solo entonces sumar "POSITIONS-i-1", la sentencia termina procesada de esta forma:
Código
  1. *pointer++ = (*pointer) + POSITIONS - i - 1;
Cuando debería ser:
Código
  1. *pointer++ = *(pointer + POSITIONS - i - 1);

El otro se debe al uso del operador "++" y las dos instancias del objeto "pointer" en la expresión:
Código
  1. *pointer++ = *(pointer + POSITIONS - i - 1);
  2.   (1)  (2)    (3)
Es un problema porque los lenguajes C y C++ no definen el orden de evaluación de los operandos de una expresión. Dependiendo del orden en que estos se evalúen y el momento en que se aplique el efecto lateral del operador "++" se pueden obtener diferentes resultados.

Lo mejor aquí es seguir la recomendación de eferion evitando expresiones excesivamente complicadas.

Un saludo