Calculadora en C (Turbo C 2.0)

Iniciado por Saul Hernandez, 29 Diciembre 2013, 02:34 AM

0 Miembros y 1 Visitante están viendo este tema.

Saul Hernandez

Estoy empezando a aprender un poco de C . Este es uno de mis programas ya terminados, quisiera que me digan en que estoy mal o como lo puedo mejorar y si se puede que modifiquen el codigo y me lo manden para compartir ideas. Segun yo el codigo es claro de entender y quiero que se mantenga esa idea.!Por favor soy nuevo en esto!


#include <stdio.h>
#include <math.h>

float a,b,x;
char op;

capturar(char op)
{
a = 0;
b = 0;
x = 0;

printf("-->");
scanf("%f",&a);
if(op=='R'||op=='r') goto fin;

printf("-->");
scanf("%f",&b);

fin:
return(0);
}

tardansa()
{
if(a>=99999999||b>=99999999)
{
printf("[ Advertencia ] El proceso tardara.....\n");
}
return(0);
}

operacion(char op)
{
tardansa();
switch (op){

case '+' :
x = a + b;
break;
case '-' :
x = a - b;
break;
case '*':
x = a * b;
break;
case '/':
x = a / b;
case 'R':
x = sqrt(a);
break;
case 'r':
x = sqrt(a);
}
printf("----> %16.16f \n",x);
return(0);
}

int main()
{

inicio:
printf("\n");
printf("<->");
scanf("%s1",&op);
if(op=='S'||op=='s') goto fin;
if(op=='+'||op=='-'||op=='*'||op=='/'||op=='R'||op=='r')
{
capturar(op);
operacion(op);
}
goto inicio;

fin:
return(0);
}


BloodSharp

#1
Primero yo te recomendaría actualizar el compilador, el turbo c 2 es de la edad de los dinosaurios y el formato no sale en PE sino que sale en NE.
Segundo algunos gotos que tenés en el código se pueden reemplazar por ifs o whiles un poco diferentes siendo así más legible el código... (aunque cada uno lo hace como más le gusta :P)

Ejemplo:
if(op=='R'||op=='r') goto fin;

printf("-->");
scanf("%f",&b);

fin:


reemplazar por:
if(!(op=='R'||op=='r'))return;
printf("-->");
scanf("%f",&b);


y
inicio:
printf("\n");
printf("<->");
scanf("%s1",&op);
if(op=='S'||op=='s') goto fin;
if(op=='+'||op=='-'||op=='*'||op=='/'||op=='R'||op=='r')
{
capturar(op);
operacion(op);
}
goto inicio;


do{
printf("\n");
printf("<->");
if(op=='+'||op=='-'||op=='*'||op=='/'||op=='R'||op=='r'){
scanf("%s1",&op);
capturar(op);
operacion(op);
}
}
while(!(op=='S'||op=='s'));


B#



xoker

Dios, hace años que no veo un GOTO, eso en C esta mas que prohibido, no se si vienes de ensamblador o que estas siguiendo un tutorial de hace mas de 20 años, pero no se cuantos años hace que se desaconsejo el empleo de goto ya que induce a un codigo ilegible y dificilmente modificable, lo que comunmente se llama codigo espaguetti.

Un link de wikipedia donde explica mejor la constroversia con goto: http://es.wikipedia.org/wiki/GOTO

Un saludo!

rollth

Yo no se mucho de programacion, pero lo que yo siempre hago para actualizaciones mas tarde es poner //(una explicacion de lo que hace la linea)
Asi cuando quieras actualizar algo tardaras 20 segundos en vez de una hora, saludos  :laugh:

leosansan

#4
Cita de: Saul Hernandez en 29 Diciembre 2013, 02:34 AM
...........................................
quisiera que me digan en que estoy mal o como lo puedo mejorar y si se puede que modifiquen el código y me lo manden para compartir ideas. Según yo el código es claro de entender y quiero que se mantenga esa idea.
...............

* Para empezar el programa arranca con unas flechitas <----> que sólo el que ha hecho el código sabe lo que representan.  Faltaría en principio algunos printf  que expliquen que se va hacer. Como ejemplo el primer goto fin; tal como tienes el arranque del código el usuario tiene que "adivinar qué introducir e ídem para las siguientes flechitas que aparecen.

* Como ya te ha comentado IEAX el uso de goto no es nada aconsejable, se pierde legibilidad y se presta a equivocaciones y/o confusión. Fíjate que si introduces 'S' te lleva a fin y este a return 0, o sea fin del programa. Y así en otros lugares.

* Por claridad convendría usar dos variables al comienzo, una para la opción salir o no y otra para la operación elegida.

* Respeto el uso de las variables globales por suponer que no has visto punteros.

* Te sobran un par de "return 0" en las funciones porque no devuelven nada ni interrumpen el programa.

* En el caso raíz te falto el break.

* Tienes que acostumbrarte a indentar o sangrar el código, si no no hay quien se aclare donde empiezan y terminan los bucles y las funciones.

* Te hace falta un bucle en el caso de introducir los números para que no se bloquee el programa si introduces un caracter no numérico.

* Te falta indicar el tipo de las funciones, void en tu caso.

* La variable "op" es un caracter ,+ o - * o/ o R o r, por lo que no tiene mucho sentido el %s1 en su scanf, más bien %c ya que lo tienes asignado como un simple char.

* ¿Pero que pasa si al pedir s o n introduces asd o 325?. Pues como op está definido como un solo caracter tomaría el primero, es decir la a o el 3, y sería equivalente a no. Es decir, sería más correcto definir op como una cadena y si es mayor de 1 que vuelva a preguntar si sí o no. Y lo mismo en el apartado de Indique operación a realizar. Para comprobar si es más de un caracter uso la función longitud_cadena, que puede ser sustituda por strlen (cadena) , incluyendo a cambio la librería <string.h> (Si a alguien se le ocurre una validación mejor por favor comentarmelo)

* Lo que nos lleva a tener que trabajar con op[0] y opc[0] en lugar de op y opc.

* Uso el formato para imprimir los double o float "%g" ya que evita que salgan un porrón de ceros a la derecha del punto decimal después de la última cifra significativa.

* Y aún así, además de entrar en un bucle infinito al introducir una cadena en los scanf de los números también podría darse el caso de aceptar 2asd como 2. Una posible solución es tomar el número, que a lo mejor no lo es -ejemplo mencionado de 2asd- como una cadena y comprobar que no hay carateres no numéricos, y luego transformar la cadena a double, cosa que hago en la función "comprobar_cadena_como_numero". (Repito, si a alguien se le ocurre una validación mejor por favor comentármelo)

* Eliminé la función "tardansa" porque no le encuentro sentido. Los cálculos planteados son cuasi-instantáneos.

* Y ya puestos, ¿por qué limitarlo al cálculo sólo de raíces cuadradas?. :rolleyes:

Por favor, admito toda clase de sugerencias a las validaciones, pero es que en la mayoría de los casos en que se hace uso de scanf no se tiene en cuenta las posibles entradas erróneas de los usuarios y que, en el mejor de los casos, son causa de bucles o cuelgues y en el peor de los casos obtener resultados erróneos; pongo por caso que el usuario quiera introducir 43 y en su lugar introduzca 4w pudiendo en este caso tomar el scanf el 4 como número introducido lo que llevará a un resultado erróneo.

Para hacerlo más rico he usado tanto un while como un do-while e incluso un if con un break y otro con un return 1 pero he buscado respetar el código original. Partiendo de cero saldría otra cosa.   ;) ;) ;)

También he usado el código ASCII para el acento en la o y en la a.

Código (cpp) [Seleccionar]

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_DIGITOS 10

int cont=0;
double a,b,x,rad,r;
char n_1[MAX_DIGITOS],n_2[MAX_DIGITOS],op[10],opc[10];

int longitud_cadena (char cadena[10]){
   int i;
   for (i=0;cadena[i];i++);
   return i;
}

void comprobar_cadena_como_numero (char numero[MAX_DIGITOS]){
   int i;
   cont=0;
   for (i=0;numero[i];i++)
       if (numero[i]<'0' || numero[i]>'9'){
           cont++;
           break;
       }
}

void capturar(char op[10])
{
   do {
       if (op[0]=='R' || op[0]=='r'){
           printf("\n\nRadicando = ");
           fflush (stdout);
           }
       else {
           printf("\n\nPrimer numero = ");
           fflush (stdout);
       }
       scanf("%s",n_1);
       comprobar_cadena_como_numero (n_1);
   }while (cont > 0);
   a = atof(n_1);
   do {
       if (op[0]=='R' || op[0]=='r'){
           printf("\n\nIndice raiz = ");
           fflush (stdout);
           }
       else {
           printf("\n\nSegundo numero = ");
           fflush (stdout);
       }
       scanf("%s",n_2);
       comprobar_cadena_como_numero (n_2);
   }while (cont > 0);
   b = atof(n_2);
}

void operacion(char op[10])
{
   switch (op[0]){
       case '+' :
           x = a + b;
           break;
       case '-' :
           x = a - b;
           break;
       case '*':
           x = a * b;
           break;
       case '/':
           x = a / b;
       case 'R':
           x = pow(a,1/b);
           break;
       case 'r':
           x = pow(a,1/b);
           break;
       default:
           break;
    }
    if (op[0]=='R' || op[0]=='r'){
       printf("\n\nRaiz %g de %g = %g  \n\n",b,a,x);
    }
    else
       printf("\n\n%g %c %g = %g \n\n",a,op[0],b,x);
       system ("pause");
       system ("cls");

}

int main()
{
   int longitud=0;
   cont=0;
   do{
       printf("\n\nDesea realizar alguna operaci%cn ( SI = S(s) NO = cualquier otro valor): ",162);
       fflush (stdout);
       do {
       cont = (scanf("%s",opc));
       longitud =longitud_cadena(opc);
       if (longitud>1)
           printf("\n\nIntroduzca UN caracter v%clido :  ",160);
       }while (cont == 0 || longitud>1  );
       if (opc[0]!='S'&& opc[0]!='s')
           return 1;

       while (1) {
           printf("\n\nIndique la operaci%cn a realizar( + - * / Raiz = R o r):  ",162);
           cont = (scanf("%s",op));
           longitud =longitud_cadena(op);
           if (( op[0]=='+' || op[0]=='-' || op[0]=='*' || op[0]=='/' || op[0]=='R' || op[0]=='r') && ( cont!= 0 || longitud==1 ))
               break;
       }
           capturar(op);
           operacion(op);
   }while(opc[0]=='S'||opc[0]=='s');
return 0;
}

[/size]

Sí ya lo sé, queda el caso del no o N, pero algo hay que dejarle a los demás. :silbar:

;-)  ;-) Felices Navidades y Próspero Año Nuevo.  ;-)  ;-)

¡¡¡¡ Saluditos! ..... !!!!



SoyelRobert

jo-der losansan ole tus cojones de verdad  ;-)
getting louder!

Saul Hernandez

Como ya les dije apenas estoy empezando tengo 15 años y me esta empezando a fascinar el mundo de las computadoras, les doy las gracias por sus consejos y espero ponerlos en practica para mejorar mi programa y volverlo a publicar. Eso de cambiar el Turbo C 2.0 no lo voy ha hacer ya que pienso dominar el C en MS-DOS para lograr hacer programas buenos con unos 640 KB. Es algo lo loco lo se ,hacer programas buenos con unos cuantos KB . Gracias por su ayuda volvere por más conocimiento.

leosansan

#7
Cita de: Saul Hernandez en 29 Diciembre 2013, 19:31 PM
Como ya les dije apenas estoy empezando tengo 15 años y me esta empezando a fascinar el mundo de las computadoras..........................

15 añitos, ¡quien los pillara!. Mejor imposible, tienes todo el tiempo del mundo, ilusión frescura de mente y encima supongo te hacen las cosas cotidianas. Yo en cambio tengo 59, con lo que conlleva en falta de tiempo por dedicación a la familia, amigos, estudios varios, tareas del hogar,etc. Y aún no llevo un año neto con esto del C. Aunque empecé hace cosa de dos años,  la enfermedad me resta mucho tiempo: operaciones, sesiones de quimioterapia, rehabilitación, deshidrataciones .... :rolleyes: pero no me falta el animo y los usuarios del foro ayudan mucho, y no lo digo por mí. ¡Animo!. ;) ;)

Cita de: Saul Hernandez en 29 Diciembre 2013, 19:31 PM
........................................
Eso de cambiar el Turbo C 2.0 no lo voy ha hacer ..................
.........................................

Déjate de tonterías, estas hablado de la edad de piedra. No hay motivo justificado que te conduzca a esa triste y primitiva opción. Mi consejo, usa un entorno de programación actual, potente, gratuito y cómodo:Code::Blocks

Elige la de 96.8 MB, la codeblocks-13.12mingw-setup-TDM-GCC-481.exe.


Cita de: Saul Hernandez en 29 Diciembre 2013, 19:31 PM
...........................................
ya que pienso dominar el C en MS-DOS para lograr hacer programas buenos con unos 640 KB
................................................

¿Otra vez?, ¿MS-DOS?. ¡Tá loco boludo!, dicho con respeto y cariño,y no soy argentino sino canarión, pero es que en Canarias los del otro lado del charco son como hermanos nuestros. Pero a lo que iba, ¿no te has enterado que el MS-DOS dejo de usarse desde que se paso del Windows Media al Xp y subsiguientes versiones, alias Windows 7 y 8?.El MS-DOS actual es una capa de emulación, no es ya un sistema operativo independiente. Eso estaría cuasi justificado  por mi edad, en mi caso ya que yo si lo manejaba y tengo multitud de cositas que corren en MS.DOS, pero todas ya desfasadas y/o superadas, Deja, deja, eres joven y tienes que pensar hacia delante, como se suele decir, pá tras ni pá coger impulso.

Cita de: Saul Hernandez en 29 Diciembre 2013, 19:31 PM
...................................
para lograr hacer programas buenos con unos 640 KB. Es algo loco lo se ,hacer programas buenos con unos cuantos KB
...........................................

¡Pero bueno!, ¿en qué mundo vives?. Si hoy en día es hasta difícil encontrar un ordenata que tenga menos de 1 GB de memoria. El mío como ejemplo empieza a ser ya un  carcamal, tiene más de tres años, y sin embargo posee 8 GB de memoria. Otra cosa distinta es el tamaño de los programas que hagas, que pueden ser de unos pocos ciento KB , si es eso lo que quieres. Pero no te pongas límites de entrada, ¡piensa siempre a lo grande!, que ya luego la vida nos pone en su sitio.

Cita de: SoyelRobert en 29 Diciembre 2013, 17:01 PM
jo-der leosansan ole tus cojones de verdad  ;-)

Gracias, gracias, pero no es para tanto.


:rolleyes: :rolleyes: :rolleyes: :rolleyes: :rolleyes: :rolleyes:

;-)  ;-) Felices Navidades y Próspero Año Nuevo.  ;-)  ;-)

¡¡¡¡ Saluditos! ..... !!!!



Saul Hernandez

Mi quierido Leosansan

Estoy de acuerdo en todo pero menos en lo ultimo :

" 15 añitos, ¡quien los pillara!. Mejor imposible, tienes todo el tiempo del mundo, ilusión frescura de mente y encima supongo te hacen las cosas cotidianas."

Por que digamos que soy un poco independiente no del todo pero si algo.

Gracias por tus palabras las tomare en cuenta.