Me tiene loco

Iniciado por kayron8, 7 Abril 2013, 12:31 PM

0 Miembros y 2 Visitantes están viendo este tema.

kayron8

Muy buenos días a todos y a todas, por si no tuviera suficiente con las funciones, ya entramos de lleno al paso por referencia y la recursividad :(

Tengo el siguiente ejercicio que creo que lo tengo casi hecho pero de tal caos que tengo en mi mente no sé cómo continuar...

El ejercicio dice lo siguiente:
4.- Realizar un programa que pida dos números enteros por teclado y muestre por
pantalla el siguiente menú:
+ --> SUMAR      
- --> RESTAR
* --> MULTIPLICAR
/ --> DIVIDIR
^ --> POTENCIA
! --> FACTORIAL
s --> SALIR

El usuario deberá elegir introducir dos valores y a continuación elegir una opción
(pulsando el carácter correspondiente), el programa deberá mostrar el resultado por pantalla.
En este caso para calcular el resultado habrá que llamar a una función con el siguiente prototipo:
void operacion (int n1, int n2, char oper, float* resul, int *error);
siendo:
 • n1, n2: dos parámetros pasados por valor que representan los dos números sobre
los que se quiere operar.
 • oper: un parámetro pasado por valor que indica el tipo de operación que se debe
realizar sobre n1 y n2. Así si queremos realizar una suma este parámetro deberá tener el valor '+', siendo para el resto de los casos: resta '-', multiplicación: '*',
división '/', potencia '^', factorial '!'.
 • result: es un parámetro pasado por referencia donde se almacenará el resultado
de la operación.
 • error: es un parámetro pasado por referencia donde se almacenará si la
operación se ha resuelto o no con éxito. Los posibles valores que puede tomar
son:
o -1: si ha habido problemas al realizar la operación, como por ejemplo una
división entre cero o el factorial de un número negativo.
o 1: si la operación concluyó con éxito.

El código que llevo hasta ahora, es el siguiente:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

//PROTOTIPS
void operacion(int n1, int n2, char oper, float *resul, int *error);
float fact(float n1);

//BLOC PRINCIPAL
int main(){
   char opcio;
   int num1=0,num2=0,error;
   float result=0;
   
   //Demanem 2 numeros a l'usuari
   printf("Introdueix el primer numero:\n");
   scanf("%d",&num1);
   
   printf("Introdueix el segon numero:\n");
   scanf("%d",&num2);
   
   //Mostrem el menú
do{
       printf("+ --> SUMAR\n");
       printf("- --> RESTAR\n");
       printf("* --> MULTIPLICAR\n");
       printf("/ --> DIVIDIR\n");
       printf("^ --> POTENCIA\n");
       printf("! --> FACTORIAL\n");
       printf("s --> SALIR\n");
       
       //Usuari tria una opció
printf("Selecciona una opcio:\n");
       scanf("%c",&opcio);
       
       //Cridem el procediment
       operacion(n1, n2, oper, *resul, *error);
   
//Condició de sortida de while    
   }while(opcio!='s');
 
   system("pause");
   return 0;
}

//PROCEDIMENT
void operacion(int n1, int n2, char oper, float *resul, int *error){
    *error=1;
    switch(oper){
             case '+':
                  *resul=n1+n2;
                      break;
             case '-':
                  *resul=n1-n2;
                      break;
             case '*':
                  *resul=n1*n2;
                      break;
             case '/':
                      if(n2==0)*error=-1;
                      else *resul=n1/n2;
                      break;
             case '^':
                  *resul=pow(n1,n2);
                      break;
             case '!':
                  if(n1==0 || n2==0)*error=-1;
                  else
                  printf("El factorial de n1 es: %lf\n",fact(n1));
                  printf("\n");
                      break;
             case 's':
                  system("exit");
                      break;
             default:
                      printf("No has escollit una opcio correcta\n");                  
    }
}

//FUNCIÓ
float fact(float n1){
   if(n1==0 || n1==1)
      return 1;
   else
       return n1*factorial(n1-1);
}


Espero que me puedan ayudar :D
¡Salu2 a to2!

amchacon

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

kayron8

Cita de: amchacon en  7 Abril 2013, 13:16 PM
Yo lo veo entero...

Bien, una pregunta más, ¿los resultados de las operaciones, que es más correcto, mostrarlas en el switch o en el main?

¿Para mostrarlos con el printf debo poner un & delante del nombre de la variable o algo así?

Es decir, printf("El resultado de la suma es: %f",&resul);

¿O estoy equivocado?

Un saludo
¡Salu2 a to2!

0xDani

Pues a no ser que quieras que el printf te muestre la direccion de memoria en la que esta almacenada la variable, no tienes que ponerle el ampersand (&).

Saludos.
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

avesudra

#4
Cosas que comentarte:
- Al pasarle los parámetros a la función "operación" , éstos tienen que tener el mismo nombre que el que has puesto en el prototipo dado que tu    puedes pasarle cualquier variable del mismo tipo...Me refiero a esta línea:
operacion(n1, n2, oper, *resul, *error);
Donde:
-No están declaradas ni n1 ni n2 ni oper. Y resul no existe, es result.
- Al pasarle a la función un parámetro por referencia le tienes que pasar la dirección de memoria de la variable, con el operador &.Me refiero a la misma línea de antes quedando:
operacion(num1,num2,&result,&error);
Dado que el prototipo es un puntero y le tienes que pasar una dirección de memoria,  como por ejemplo result que es donde se va a guardar el resultado.
-En la función fact, vuelves a llamar a la misma función pero esta se llama fact no factorial  ;)
return n1*factorial(n1-1);
El código lo he corregido así por encima:#include <stdio.h>
#include <stdlib.h>
#include <math.h>

//PROTOTIPS
void operacion(int n1, int n2, char oper, float *resul, int *error);
float fact(float n1);

//BLOC PRINCIPAL
int main()
{
   char opcio;
   int num1 = 0,num2 = 0,error;
   float result = 0;

   //Demanem 2 numeros a l'usuari
   printf("Introdueix el primer numero:\n");
   scanf("%d",&num1);

   printf("Introdueix el segon numero:\n");
   scanf("%d",&num2);
   /*Limpio stdin (el buffer de entrada) porque a mí no me funciona...
    *Las llaves son para marcar bloques,así la variable c no existirá despues de ese bloque.
    */
   {
       char c = 5;
       while( (c != EOF) && c != '\n')
       {
           c = getchar();
       }
   }
   //Mostrem el menú
   do
   {
       printf("+ --> SUMAR\n");
       printf("- --> RESTAR\n");
       printf("* --> MULTIPLICAR\n");
       printf("/ --> DIVIDIR\n");
       printf("^ --> POTENCIA\n");
       printf("! --> FACTORIAL\n");
       printf("s --> SALIR\n");

       //Usuari tria una opció
       printf("Selecciona una opcio:\n");

       scanf("%c",&opcio);
       //Cridem el procediment
       operacion(num1, num2, opcio, &result, &error);
       printf("%f\n",result);
       /* Esto tampoco me funciona a mí y tengo que poner dos getchar o limpiar el buffer de nuevo.*/
       {
           char c = 5;
           while( (c != EOF) && c != '\n')
           {
               c = getchar();
           }
       }
       getchar();

       system("cls");// "clear" en linux...
       //Condició de sortida de while
   }
   while(opcio!='s');

   system("pause");
   return 0;
}

//PROCEDIMENT
void operacion(int n1, int n2, char oper, float *resul, int *error)
{
   *error=1;
   switch(oper)
   {
   case '+':
       *resul=n1+n2;
       break;
   case '-':
       *resul=n1-n2;
       break;
   case '*':
       *resul=n1*n2;
       break;
   case '/':
       if(n2==0)*error=-1;
       else *resul=n1/n2;
       break;
   case '^':
       *resul=pow(n1,n2);
       break;
   case '!':
       if(n1==0 || n2==0)*error=-1;
       else
           printf("El factorial de n1 es: %lf\n",fact(n1));
       printf("\n");
       break;
   case 's':
       system("exit");
       break;
   default:
       printf("No has escollit una opcio correcta\n");
   }
}

//FUNCIÓ
float fact(float n1)
{
   if(n1==0 || n1==1)
       return 1;
   else
       return n1*fact(n1-1);
}

Lo de limpiar el buffer no es algo que me guste, lo veo chapucero, pero bueno...
Creo que el problema es que sigues sin tener soltura con las funciones,y entonces si ya te meten punteros... Una función la declaras:
int miFuncion(int miParametro1,int miParametro2);
Y después al llamarla puedes pasarle la variable que quieras siempre respetando que sea un entero! Así por ejemplo:
valorDeRetorno = miFuncion(1,2);
O :
valorDeRetorno = miFuncion(num1,num2);
En el caso del paso de parámetros por referencia, lo que se le pasa es la dirección de la variable en vez de copiar su valor, un programa de ejemplo vale más que mi palabras:
#include <stdio.h>

/*
* Se copian los valores en direcciones de memoria distintas.
* @param[in] miParametro1 Valor de una variable.
* @param[in] miParametro2 Valor de otra variable.
* @return    Multiplicación de miParámetro1 por miParametro2.
*/
int miFuncionNormal(int miParametro1,int miParametro2);
/*
* Se pasan las direcciones a esos valores.
* @param[in] miParametro1 Dirección de variable.
* @param[in] miParametro2 Dirección de otra variable.
* @return    Multiplicación de miParámetro1 por miParametro2.
*/
int miFuncionPorReferencia (int * miParametro1,int * miParametro2);
/*
* Las variables de los parámetros asumen la dirección de la variables pasadas.
* @param[in] miParametro1 Variable.
* @param[in] miParametro2 Variable.
* @return    Multiplicación de miParámetro1 por miParametro2.
*/
int miFuncionPorReferencia2(int &miParametro1,int &miParametro2);

int main(int argc, char *argv[])
{
   int miNumero1 = 1;
   int miNumero2 = 2;
   printf("Direccion de memoria de miNumero1: \t 0x%X \t Valor: %d\n",&miNumero1,miNumero1);
   printf("Direccion de memoria de miNumero2: \t 0x%X \t Valor: %d\n",&miNumero2,miNumero2);
   /*
    * Pasamos los valores.
    */
   miFuncionNormal(miNumero1,miNumero2);
   /*
    * Pasamos las direcciones de memoria.
    */
   miFuncionPorReferencia(&miNumero1,&miNumero2);
   /*
    * Pasamos las direcciones de memoria y se les hace el cast.
    */
   miFuncionPorReferencia2(miNumero1,miNumero2);
   return 0;
}
int miFuncionNormal(int miParametro1, int miParametro2)
{
   printf("\n\nDireccion de memoria de miParametro1: 0x%X \t Valor: %d\n",&miParametro1,miParametro1);
   printf("Direccion de memoria de miParametro2: 0x%X \t Valor: %d\n",&miParametro2,miParametro2);
   printf("Direcciones de memoria diferentes a las de miNumero, pero valores iguales.\n\n");
   return miParametro1 * miParametro2;
}
int miFuncionPorReferencia (int * miParametro1,int * miParametro2)
{
   printf("Direccion de memoria de miParametro1: 0x%X \t Valor: %d\n",miParametro1,*miParametro1);
   printf("Direccion de memoria de miParametro2: 0x%X \t Valor: %d\n",miParametro2,*miParametro2);
   printf("Direcciones de memoria iguales a las de miNumero, accediendo a los mismos valores obviamente.\n\n");
   /*
    *  Accediendo a los valores de las direcciones de memoria con el operador '*'.
    */
   return *miParametro1 * *miParametro2;
}
int miFuncionPorReferencia2(int &miParametro1,int &miParametro2)
{
   printf("\n\nDireccion de memoria de miParametro1: 0x%X \t Valor: %d\n",&miParametro1,miParametro1);
   printf("Direccion de memoria de miParametro2: 0x%X \t Valor: %d\n",&miParametro2,miParametro2);
   printf("Direcciones de memoria diferentes a las de miNumero, pero valores iguales.\n\n");
   return miParametro1 * miParametro2;
}

La función miFuncionPorReferencia2 no la tengo muy clara,se utilizarla pero no se explicarla resulta raro pero así es, a ver si alguno de aquí te lo puede explicar mejor.Ejecuta ese programa y mira detenidamente las salidas, te dejo mi salida por si no puedes o lo que sea:
Direccion de memoria de miNumero1: 0x1A9CBD38 Valor: 1
Direccion de memoria de miNumero2: 0x1A9CBD3C Valor: 2


Direccion de memoria de miParametro1: 0x1A9CBD0C Valor: 1
Direccion de memoria de miParametro2: 0x1A9CBD08 Valor: 2
Direcciones de memoria diferentes a las de miNumero, pero valores iguales.

Direccion de memoria de miParametro1: 0x1A9CBD38 Valor: 1
Direccion de memoria de miParametro2: 0x1A9CBD3C Valor: 2
Direcciones de memoria iguales a las de miNumero, accediendo a los mismos valores obviamente.



Direccion de memoria de miParametro1: 0x1A9CBD38 Valor: 1
Direccion de memoria de miParametro2: 0x1A9CBD3C Valor: 2
Direcciones de memoria diferentes a las de miNumero, pero valores iguales.
Regístrate en

kayron8

#5
Una cosilla, yo el EOF sí que se lo que es, lo que pasa que en clase no lo hemos hecho aún, ¿como lo puedo substituir para que me siga funcionando?

Gracias una vez más :D
¡Salu2 a to2!

avesudra

Ni idea, supongo que podrás sustituirlo por su valor simbólico pero es lo mismo osea que nada. Una sugerencia, no cites cuando los comentarios son tan largos  ;)
Regístrate en

85

qué citón que se mandó XD, por cierto que idioma es ese de kayron8, parece español pero no precisamente..

Saludos
Me cerraron el Windows Live Spaces, entonces me creé un WordPress XD
http://etkboyscout.wordpress.com/

avesudra

Cita de: 85 en  7 Abril 2013, 16:41 PM
qué citón que se mandó XD, por cierto que idioma es ese de kayron8, parece español pero no precisamente..

Saludos
Te respondo por kayron8 si no te importa.Es Catalán, se habla en Cataluña, comunidad autónoma de España y cuya capital es Barcelona.(la zona resaltada es la comunidad autónoma). Si eres Argentino o del otro lado del charco como aquí decimos, creo que es algo normal que no lo conozcas, a no ser que seas culé(aficionado al F.C Barcelona).
Regístrate en

85

Lo que conocía es que hay una región llamada Cataluña (no sabía su localización específica), se de la ciudad Barcelona y se del 'Barsa' XD, pero no sabía del idioma o dialecto de esa región.  ;-) ;-)
gracias por la información.
Me cerraron el Windows Live Spaces, entonces me creé un WordPress XD
http://etkboyscout.wordpress.com/