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

problemas al ejecutar una función recursiva.

Estas en el tema de problemas al ejecutar una función recursiva. en el foro de C/C++ en Foros del Web. hola; tengo lio para ejecutar este programa debe darme el tamaño de un numero aun estoy revisando los errores pero los que mas me esta ...
  #1 (permalink)  
Antiguo 03/10/2012, 11:00
 
Fecha de Ingreso: septiembre-2012
Mensajes: 29
Antigüedad: 11 años, 7 meses
Puntos: 0
problemas al ejecutar una función recursiva.

hola; tengo lio para ejecutar este programa debe darme el tamaño de un numero aun estoy revisando los errores pero los que mas me esta dando problemas son el de el de "expected primary-expression before "float" y "error: expected `,' or `;' before '(' token" en lo que he leido parece que estoy llamando mal la función pero no se que estoy haciendo mal.
Código C++:
Ver original
  1. #include <iostream>
  2. #include <cstdlib>
  3.  
  4.  
  5. using namespace std;
  6. float tamaño (float a,float& b)
  7. {
  8.  
  9. if(-1>a>1){//divide el numero para contar las veces que el numero es dividido
  10.     return tamaño (a/10,b);
  11. b=1;
  12. b=b+1;
  13. }//cuenta las veces que se divide el numero
  14. else  
  15. return a;
  16. }
  17. int main()
  18. {
  19. float num;
  20. cout<< "introdusca el numero";  
  21. cin>>num;
  22. cout<<"el tamaño es"<<tamaño(num,b);//llama a la funcion tamaño
  23. system("pause");
  24.     return 0;
  25. }


SinNombre4.cpp:6: error: stray '\241' in program

SinNombre4.cpp:6: error: `tama' does not name a type
SinNombre4.cpp:10: error: stray '\241' in program
make.exe: *** [SinNombre4.o] Error 1

Última edición por sonrasiel; 03/10/2012 a las 22:03 Razón: reescribi todo el programa
  #2 (permalink)  
Antiguo 04/10/2012, 04:53
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: problemas al ejecutar una función recursiva.

Basicament tu compilador te comenta que no puedes usar 'ñ' en el nombre de una función, y que la variable 'b' no está declarada en el ambito de la funcion 'main'. La solucion es: no usar la letra 'ñ' en el nombre de la funcion, y declarar una variable tipo float con nombre 'b' en el ambito del main (y supongo que tambien deberás inicializarla a algo para que las comparaciones funcionen)

vosk
  #3 (permalink)  
Antiguo 04/10/2012, 13:43
 
Fecha de Ingreso: septiembre-2012
Mensajes: 29
Antigüedad: 11 años, 7 meses
Puntos: 0
Respuesta: problemas al ejecutar una función recursiva.

gracias vosk aunque aun nose como llamar la variable b que esta fuera del main apra que la imprima, es lo que deseo ya que mi objetivo es que imprima la cantidad de cifras se me ocurrio que este era el cambio a seguir pero no me aparece declarada b para imprimirla.

Código C++:
Ver original
  1. #include <iostream>
  2. #include <cstdlib>
  3.  
  4.  
  5. using namespace std;
  6. float tam (float a)
  7. {
  8.  
  9. if(-1>a>1){//divide el numero para contar las veces que el numero es dividido
  10.     return tam (a/10);
  11.     float b;
  12. b=1;
  13. b=b+1;
  14. }//cuenta las veces que se divide el numero
  15. else  
  16. return a;
  17. }
  18. int main()
  19. {
  20. float num;
  21. cout<< "introdusca el numero";  
  22. cin>>num;
  23. cout<<"el tamaño es"<<b;//llama a la funcion tamaño
  24. system("pause");

este es el nuevo informe de errores.

main.cpp:23: error: `b' undeclared (first use this function)
main.cpp:23: error: (Each undeclared identifier is reported only once for each function it appears in.)

main.cpp:25: error: expected `}' at end of input
  #4 (permalink)  
Antiguo 04/10/2012, 15:17
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: problemas al ejecutar una función recursiva.

El error en la linea 23 dice que sigues sin declarar la variable 'b' en el main, y el de la 25 dice que olvidaste cerrar la funcion main.

De todas formas aunque consigas compilar el programa este no hará lo que esperas; haz una prueba simple con el algoritmo de tu funcion 'tam()' para verificar que el condicional if(-1>a>1) resuelve de forma correcta y adaptada a tu caso (puedes hacerlo a papel y lapiz) y hazte la siguiente pregunta: existe un valor que sea menor que -1 y a la vez mayor que 1? (ya te digo ahora que si que resuelve de forma correcta, pero no resuelve de forma adaptada a tu caso porque el condicional siempre será falso, cosa que equivale a decir que la funcion nunca llega a llamarse a si misma y retorna directamente el valor del argumento).

Otra cosa, revisa los corchetes de la funcion 'tam()': todo lo que hay entre la llamada a 'return' y el corchete de cierre del condicional no se ejecuta nunca porque el return lo evita.

De momento intenta que compile correctamente, si es necesario repasa tu manual de programacion; una vez compile sin errores de corchetes y declaraciones ya te pelearas con la funcion.

Saludos
vosk
  #5 (permalink)  
Antiguo 05/10/2012, 02:04
 
Fecha de Ingreso: junio-2010
Ubicación: Madrid
Mensajes: 620
Antigüedad: 13 años, 11 meses
Puntos: 73
Respuesta: problemas al ejecutar una función recursiva.

if(-1>a>1)

Extraña condición.

En primer lugar, si -1 es mayor que a, a nunca puede ser mayor que 1.
En segundo lugar, si a es mayor que 1, nunca puede ser menor que -1.
Conclusión: El resultado de esto siempre será FALSO.

Interpreto que lo que quieres es ver si a está entre -1 y 1. La condición correcta sería (matemáticamente):

if (-1 < a < 1)[/B]

En segundo lugar, al programar no puedes encadenar condicionales de esa manera. La evaluación de la expresión de arriba sería:

(1) Evaluar (-1 < a). Si a está entre -1 y 1, el resultado será VERDADERO (o sea, 1).
(2) Evaluar el resultado de (1) con 1, es decir, comparas 1 con 1, son iguales, 1 no es menor que 1, el resultado va a ser siempre FALSO.

Por ello, cuando necesites hacer comparaciones múltiples, debes hacerlas por separado. En este caso:

if ( (-1 < a) && (a < 1) )

Otra cosa que estás haciendo es que, cada vez que entras a la función, haces b=1 y acto seguido incrementas en 1 su valor, por lo que hagas lo que hagas al salir b siempre valdrá 2. Para lo que (aparentemente) quieres hacer, prueba con esto:

Código C++:
Ver original
  1. int tam (float a)
  2. {
  3.     int b=0;
  4.  
  5.     while (fabs(a) >= 1.0)
  6.     {
  7.         a /= 10.0;
  8.         b++;
  9.     }
  10.     return b;
  11. }

Nota: Para utilizar fabs (valor absoluto en coma flotante) probablemente tendrás que incluir <math.h> en tu programa.

Y una sugerencia final: Cuando utilices constantes de tipo float o double, pon siempre el punto decimal (como he hecho arriba) para forzar a que el compilador te las evalúe como tales, si no lo más normal es que te las evalúe como enteros y puedes encontrarte con que el resultado final no coincide con el que debería ser, por ejemplo, 1/4 con aritmética entera va a ser 0, pero 1.0/4.0 va a ser 0.25.

Saludos,
  #6 (permalink)  
Antiguo 05/10/2012, 16:19
 
Fecha de Ingreso: septiembre-2012
Mensajes: 29
Antigüedad: 11 años, 7 meses
Puntos: 0
Respuesta: problemas al ejecutar una función recursiva.

Gracias a los 2 les agradezco su paciencia ya que soy re novato en c++ sin enseñarme bucles ni condicionales me sentaron a programar funciones, estaba mirándolo como un dominio en vez de un condicional.pero aun no logro hacer lo que quiero para el programa la prueba de escritorio que yo supongo seria algo así.

introduzca un numero
236
b=0
236>1? si
b=0+1
imprime 1, "aunque no pasa"
retorna 236/10 a tam
23,6>1? si
b=1+1
imprime 2, "aunque no pasa"
retorna 23,6/10 a tam
2,36>1? so
b=2+1
imprime 3, "aunque no pasa"
retorna 2.36/10 a tam
0.23>1? no
imprime 3
----------
ya en el main
b=0.23 pero imprime 0 ó 4 si hago el cambio en 9 10 y 21
--------
la prueba de escritorio cuando este pulido el prog:
introduzca un numero
236
b=0
236>1? si
b=0+1

retorna 236/10 a tam
23,6>1? si
b=1+1

retorna 23,6/10 a tam
2,36>1? so
b=2+1

retorna 2.36/10 a tam
0.23>1? no
imprime 3
----


Código C++:
Ver original
  1. #include <iostream>
  2. #include <cstdlib>
  3.  
  4.  
  5. using namespace std;
  6.  
  7. float tam (float a)
  8. {
  9.    
  10. if ( (-1 > a) || (a > 1) ){
  11.     int b=0;
  12.     return tam  (a/10);
  13.         b++;
  14.         //return b;
  15.         cout<< b <<",";    
  16. }
  17. else{
  18.     return 0;//b;
  19. }}
  20.  
  21. int main()
  22. {
  23. float num,b;
  24. cout<< "introduzca el numero";  
  25. cin>>num;
  26. b=tam(num);
  27. cout<<" el tamaño es "<< b;  
  28. system("pause");
  29. return 0;
  30. }}

linea 9: copiando en el codigo
float b;
b=4; ...ejecutando lineas 9 y 10, y cambiando la linea 21 por return b; por que esta variable no se rompe al salir de la funcion y se imprime 4 dentro del main mientras b++ no?*/
linea 12: // aqui si entendi bien devuelve el valor num/10 a la funcion y la evalua denuevo.
linea 13: //cuenta las veces que se divide el numero, no estoy seguro de si lo esta haciendo.
linea 15 : //este b no se imprime, creia que es por que la variable no esta en el main y se rompe al salir de tam.
linea 26 : //si el numero es 236, b no deberia se = a 0.236 al ser el ultimo numero que retorno a tam?
linea 27: /*"aqui deberia llamar a la variable b++ del float de tam pero no se como llamarla
si esta en una funcion fuera del main "*/

Última edición por sonrasiel; 05/10/2012 a las 16:37
  #7 (permalink)  
Antiguo 06/10/2012, 07:56
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: problemas al ejecutar una función recursiva.

Bien, muy bien, has hecho un seguimiento del flujo de datos del programa para ver que hace cada linea; es una buena practica.

Una cosa: en el codigo que has colgado hay un error de corchetes, debes solucionarlo antes de seguir.

Lo que te interesa: como manipulas 'b' para que sea accesible desde main() y desde tam(). La solucion está en las referencias. Si no tienes claro el tema de referencia / desreferencia de valores es mejor que le eches un vistazo. La idea es la siguiente: declaras una variable 'b' en el main y envias una referencia a 'tam()', de forma que dentro de tam() vas a incrementar esa referencia en vez de trabajar con una variable declarada en el ambito de tam(), ok?

Ahora como estas trabajando sobre la referencia ya puedes olvidarte de los valores retornados, es decir que la funcion será de tipo void y puedes quitar todos los return.

Basicamente harás lo siguiente:

Código:
void tam(double a, int *b) {
    (si se cumple el condicional) {
        incrementa la referencia;
        recursion;
    }
}
No te dejo el codigo resuelto porque esa es tu tarea ok? Lo de copiar/pegar sería demasiado facil :)

Observa bien el orden de ejecucion de esto que te he colgado y contrastalo con lo que tienes en tu ultimo codigo: primero haces el incremento, luego llamas a la funcion (tu lo hiciste del revés y lo puesiste debajo del return, es decir que las lineas 13, 14, 15 nunca llegaban a ejecutarse).

Aun otra cosa que no has tenido en cuenta: el tamaño nunca será negativo ni de coma flotante verdad? Puedes declarar 'b' como entero no signado. Si acaso esto dejalo para el final.

Lo que yo haría es lo siguiente y en este orden: corregir el codigo para que compile sin errores, implementar la funcion tam() con referencias, implementar la llamada a la funcion tam() con referencias, y asegurarme que compila sin errores.

Una ultima observación: si estas trabajando con esta funcion para resolver el tamaño de un valor es mejor que uses el codigo que colgó Fw190 con el bucle while y sin recursión; si por el contrarion estas trabajando con esta funcion como practica para el tema de recursividad no te queda otra opcion que resolver de esta forma (puedes usar globales estaticas, aunqué es mas facil es poco elegante y ya ni te lo comento).

Saludos
vosk
  #8 (permalink)  
Antiguo 10/10/2012, 14:09
 
Fecha de Ingreso: septiembre-2012
Mensajes: 29
Antigüedad: 11 años, 7 meses
Puntos: 0
Respuesta: problemas al ejecutar una función recursiva.

ya leido el tema no doy pie con bola, paraentemente es facil pero la sintaxis me esta matando.

Código C++:
Ver original
  1. #include <iostream>
  2. #include <cstdlib>
  3.  
  4.  
  5. using namespace std;
  6.  
  7. void tam (float a)
  8. {
  9.    
  10. if ( (-1 > a) || (a > 1) ){
  11.     int x=0,*b,c;
  12.     return tam  (a/10);
  13.         x++;
  14.           b=x;
  15.           *b=c;
  16.         //return b;
  17.         cout<< b <<",";    
  18. }
  19. else{
  20. //b;
  21. }}
  22. int main()
  23. {
  24. int c;
  25. float num;
  26. //float *num;
  27. cout<< "introduzca el numero";  
  28. cin>>num;
  29. num=tam//*num=tam
  30. cout<<" el tamaño es "<< c;  
  31. system("pause");
  32. return 0;
  33. }

este el el informe de errores

C:\Documents and Settings\bibliotecas.UNAL\Mis documentos\numero.cpp: In function `void tam(float)':
C:\Documents and Settings\bibliotecas.UNAL\Mis documentos\numero.cpp:14: error: invalid conversion from `int' to `int*'

C:\Documents and Settings\bibliotecas.UNAL\Mis documentos\numero.cpp: In function `int main()':
C:\Documents and Settings\bibliotecas.UNAL\Mis documentos\numero.cpp:30: error: cannot convert `void ()(float)' to `float' in assignment
C:\Documents and Settings\bibliotecas.UNAL\Mis documentos\numero.cpp:30: error: expected `;' before "cout"


segun lo veo hasta la linea 13 se ejecuta el bucle.
linea 14 copio el valor de x.
linea 15 apunto el valor de 15 en la variable c del main.
imprime c = al ultimo valor de x.
tengo duda con el void no entiendo es como si no aceptara una variable tipo float no me queda claro ese error.
si no lo logro sera tratar de hacer una funcion main recursiva debe ser mas facil que andar llamando valores desde otras funciones, aunque donde estudie eso no lo explican muy bien ya que el ejemplo que vi son apuntadores funciones que apuntan a otras funciones.

Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. int addition (int a, int b)
  5. { return (a+b); }
  6.  
  7. int subtraction (int a, int b)
  8. { return (a-b); }
  9.  
  10. int operation (int x, int y, int (*functocall)(int,int))
  11. {
  12.   int g;
  13.   g = (*functocall)(x,y);
  14.   return (g);
  15. }
  16.  
  17. int main ()
  18. {
  19.   int m,n;
  20.   int (*minus)(int,int) = subtraction;
  21.  
  22.   m = operation (7, 5, addition);
  23.   n = operation (20, m, minus);
  24.   cout <<n;
  25.   return 0;
  26. }

Última edición por sonrasiel; 10/10/2012 a las 14:18
  #9 (permalink)  
Antiguo 11/10/2012, 01:14
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: problemas al ejecutar una función recursiva.

Debes hacer lo mismo que el tu ultimo codigo de punteros a funciones, pero trabajando con punteros a variables.

Antes que nada una cosa: tu programa se para en la linea 12 porque el return evita que siga ejecutandose, aun cuando sea una funcion recursiva. Es decir, que cuando haces la recursion con el return en la linea 12 esa funcion no espera que termine la ejecucion de la funcion llamada para seguir con la linea 13, sino que finaliza esa funcion y nunca llega a la linea 13. Todas las operaciones tienes que hacerlas antes del return.

El informe de errores: en la linea 14 estas asignando a una referencia (*b es una referencia); solo puedes asignarle valores desreferenciandola (p.ej. *b=x) o asignandole otra referencia (b=&x); en cualquier caso eso no te soluciona el ejercicio.
En la linea 29 estas asignando una funcion de forma incorrecta (ni la referencias ni la llamas de forma directa).

"...tengo duda con el void no entiendo es como si no aceptara una variable tipo float no me queda claro ese error..."

Lo que te dice el compilador es que en la linea 29 no puedes asignar directamente a una variable tipo float una funcion tipo void()(float), la variable es float y la funcion es void por muchos floats que lleve como argumentos.

En el main tienes la variable 'c' que indicará el tamaño del valor 'num'; 'c' es un entero iniciado a 0 por defecto y 'num' es un real entrado por el usuario:

Código:
int c = 0;
float num = 236;
La funcion 'tam()' recibe dos argumentos: el valor de trabajo 'num' (que siguiendo el ejemplo de tu codigo en el ambito de la funcion 'tam' pasa a llamarse 'a'), y una referencia al sitio donde se guarda el resultado 'c':

Código:
void tam(float a, int *c) {...}
En la funcion tienes un condicional que cuando no se cumple no hace nada (simplemente termina la funcion), y cuando se cumple incrementa 1 el contador 'c' y hace una recursion con el nuevo valor calculado, de forma que la rellamada a 'tam' se hace enviando los dos argumentos esperados: un valor real (en este caso un decimo de 'a'), y una referencia al resultado. Como la funcion ya recoge una referencia de entrada para el resultado, para la rellamada no tienes de re-referenciar esa variable porque ya está referenciada (es un puntero):

Código:
if((-1 > a) || (a > 1)) {
    *c += 1;
    tam (a/10, c);
}
Solo te queda hacer la primera llamada desde el main, que tal como está descrita la funcion tam() tendras que enviarle dos argumentos: un valor real y una referencia (un puntero) al valor resultado:

Código:
tam(num, &c);
Ahora en 'c' ya tienes el valor esperado, lo sacas por pantalla y finalizas.

Saludos
vosk

Última edición por vosk; 11/10/2012 a las 07:32

Etiquetas: int, programa
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 03:08.