Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Álvaro G. Tenorio

#1
Si te digo la verdad no se me había ocurrido eso de que la función seguía activa con su correspondiente gasto de memoria, ya estoy modificando el código, en cuanto pueda lo copio y lo modifico aquí.
#2
¿Qué problema hay con el main();?

Voy a modificar cuando pueda el código para unir la función menu(); y sentidoConversion(); ya me di cuenta de que es inútil tanta división de funciones.

Asimismo eliminaré las funciones de limpiarBuffer(); y limpiarPantalla(); Pero mi pregunta es: ¿si a estas funciones les pusiera un inline delante a efectos de código compilado no tendrían el mismo rendimiento?

Uso un unsigned char para guardar números pequeños del 0 al 255. En cuanto al %hhu es el modificador de formato de scanf para variables de unsigned char

Pongo lo del %lg no para que sólo muestre un decimal sino para que sólo muestre los decimales significativos (los que no son 0).

Quizá si sea enrevesado por todos los comentarios y una dicisión absurda en infinitas funciones inútiles, pero, ¿no es mejor dividir el programa en funciones para que el main(); quede escueto? al menos eso me recomendaron a mi, pues yo antes solía programar unos main(); elefantiásicos...

Ya vi el error de los printf(); cosas de copiar y pegar, lo modificaré en cuanto pueda, muchas gracias, sino se queda ahí...

Por último que me recomiendas: declarar las constantes como globales al principio del código tal que así:

Código (cpp) [Seleccionar]
const double cargaElectron = 1.6e-19;

o por el contrario definirlas como constantes con una directiva al preprocesador:

Código (cpp) [Seleccionar]
#define cargaElectron 1.6e-19L
#3
Este es un pequeño proyecto de media hora.

El programa realiza conversiones entre Julios y Electrón-Voltios en los dos sentidos posibles según indique el usuario, pretende ser una ayuda para no tener que insertar números largos en la calculadora para resolver problemas problemas de
Química de 2º de Bachillerato. Pero es más bien un pequeño reto de programación para principiantes (como yo).

Compilado con MinGW.

Funciona perfectamente bajo Windows, funciona parcialmente bajo GNU/Linux por la códificación de la funcion LimpiarPantalla(); pero no es nada grave. El código está escrito en C usando sólo las cabeceras estándar y está comentado completamente en español.

El programa es software libre y contiene copyleft, lo cual quiere decir que puesdes redistribuir, modificar el código y demás sólamente bajo los términos de la Licencia General Pública de GNU (GPL).

Versión 0.0.1 (No creo que haga falta ninguna otra versión a no ser que
aprenda a hacer GUIs y lo actualice, pero la simplicidad es buena para aprender).

Aquí el código:

Código (cpp) [Seleccionar]

/*Cabeceras incluidas*/
#include <stdio.h>  /*Cabecera estándar*/
#include <stdlib.h> /*Cabecera estándar*/

/*Funciones declaradas (prototipos)*/
void limpiarBuffer (void);     /*Limpia el buffer de entrada*/
void limpiarPantalla (void);   /*Limpia la pantalla de la consola del sistema*/
void menu (void);              /*Imprime un pequeño menú de bienvenida*/
void sentidoConversion (void); /*Indica el sentido en el que se realizará la conversión*/
void J_Ev (void);              /*Realiza la conversion de Julios a Electron-Voltios*/
void Ev_J (void);              /*Realiza la conversion de Electron-Voltios a Julios*/
void reinicio (void);          /*Reinicia o finaliza el programa*/

/*Funcion main*/
int main (void)
{
    menu();
    sentidoConversion();
    reinicio();

    return 0;
}

/*Funciones definidas (cuerpos de las funciones)*/

void limpiarBuffer (void) /*Limpia el buffer de entrada*/
{
    while (getchar() != '\n');
}

void menu (void) /*Imprime un pequeño menú de bienvenida*/
{
    printf("--->Conversor Julios <-> Electron-Voltios\n");
}

void limpiarPantalla (void) /*Limpia la pantalla de la consola del sistema*/
{
    system("cls");
}

void sentidoConversion (void) /*Indica el sentido en el que se realizará la conversión*/
{
    /*Declaración de variables*/
    unsigned char eleccion = 0; /*Valor por defecto en 0*/

    /*Trámites con el usuario*/
    printf("Como desea realizar la conversion?:\n");
    printf("[1] -> Julios -> Electron-Voltios\n");
    printf("[2] -> Electron-Voltios -> Julios\n");
    printf("Su eleccion: ");
    scanf("%hhu", &eleccion);
    limpiarBuffer();

    /*Derivar a una u otra funcion según la decisión del usuario*/
    switch (eleccion)
    {
        case 1:
            limpiarPantalla();
            J_Ev();
            break;
        case 2:
            limpiarPantalla();
            Ev_J();
            break;
        default:
            printf("ERROR: Inserte 1 o 2 segun el sentido de la conversion que desee.\n");
            printf("Pulse [ENTER] para continuar...");
            getchar();
            limpiarPantalla();
            sentidoConversion();
            break;
    }
}

void J_Ev (void) /*Realiza la conversion de Julios a Electron-Voltios*/
{
    /*Declaración de variables*/
    double J;
    double Ev;
    const double cargaElectron = 1.6e-19;

    /*Trámites con el usuario*/
    printf("Julios a convertir: ");
    scanf("%lf", &J);
    limpiarBuffer();
    printf("Convirtiendo...\n");

    /*Conversion*/
    Ev = J/cargaElectron;
    printf("%lg J = %lg Ev\n", J, Ev);
}

void Ev_J (void) /*Realiza la conversion de Electron-Voltios a Julios*/
{
    /*Declaración de variables*/
    double J;
    double Ev;
    const double cargaElectron = 1.6e-19;

    /*Trámites con el usuario*/
    printf("Electron-Voltios a convertir: ");
    scanf("%lf", &Ev);
    limpiarBuffer();
    printf("Convirtiendo...\n");

    /*Conversion*/
    J = Ev*cargaElectron;
    printf("%lg Ev = %lg J\n", J, Ev);
}

void reinicio (void) /*Reinicia o finaliza el programa*/
{
    /*Declaración de variables*/
    unsigned char eleccion = 0; /*Valor por defecto en 0*/

    /*Trámites con el usuario*/
    printf("Desea realizar otra conversion?\n");
    printf("[1] -> Si\n");
    printf("[2] -> No\n");
    printf("Su eleccion: ");
    scanf("%hhu", &eleccion);
    limpiarBuffer();

    /*Derivar a una u otra funcion según la decisión del usuario*/
    switch (eleccion)
    {
        case 1:
            limpiarPantalla();
            main();
            break;
        case 2:
            break;
        default:
            printf("ERROR: Inserte 1 o 2 la opcion que desee.\n");
            printf("Pulse [ENTER] para continuar...");
            getchar();
            limpiarPantalla();
            break;
    }
}


Probablemente la química no sea de vuestra competencia, pero la informática sí, agradecería opiniones sobre el código, estoy abierto a críticas para mejorar.
#4
Cita de: Eternal Idol en  3 Septiembre 2013, 00:00 AM
Es decir que la funcion no sirve mas que para este main ... bueno.

Ahora lo corrijo, dame un momento.




Ahora me surge una pregunta, qué diferencia hay entre un:
size_t numero;
y un:
unsigned int numero;
a parte de la convención de que size_t se usa para representar tamaños y es un tipo propio en vez un tipo y un modificador, trasteando un poco con sizeof no paría haber diferencias en el tamaño.
#5
Cita de: Eternal Idol en  2 Septiembre 2013, 22:56 PM
Por algo strlen devuelve un size_t y no un unsigned char, tu funcion no podra devolver el valor correcto si la cadena es mayor a 255 caracteres.

Claro, strlen(); pretende ser una función universal estándar, la mía es una implementación casera ya tuve en cuenta el problema del límite de almacenamiento de unsigned char, por eso el array de caracteres que se toma del usuario es de 140 huecos. (suficiente para algo rapidillo, pero modificaré el código).

Gracias por la explicación del error del 32, ahora lo corrijo.
#6
No me tomé a mal tu comentario, simplemente me intenté explicar, muchas gracias por la información a cerca de las variables static, es un modificador que no suelo usar porque no se mucho de él, al fin y al cabo fallando se aprende, ya he modificado el código para solventar el error.

Por cierto, no entendí la solución que me ofreciste para lo del 32, te referías a sumar tal que así:
Código (cpp) [Seleccionar]
texto[contador] += 'A';

Pregunto.
#7
Obviamente que en la librería estándar de C y C++ han metido la mano ingenieros con mucha más preparación que yo, no pretendo superarles ni mucho menos, todavía estoy aprendiendo.

No, la función magnitudTexto(); no añade nada a la función strlen(); de string.h pero en muchas universidades (todavía no estoy en esa edad) tengo constancia de que piden a modo de ejercicio para familiarizarse con eso de los algoritmos y demás hacer implementaciones propias de algunas funciones de la librería stándar (he aquí la mía a modo de aporte).

En cuanto a las otras dos funciones son diferentes de toupper(); y tolower(); en el sentido en que estas dos funciones estándar trabajan con caracteres individuales, teniendo que hacer tú mismo el bucle correspondiente para pasar una cadena entera a mayúsculas o minúsculas. Las funciones de mi aporte no tienen sustituto en el estándar.

Una de las razones por la que me registré en el foro fue para aprender, por tanto gracias por tu consejo sobre las variables estáticas de las que no se mucho aunque tengo entendido que si uno llama en sucesivas ocasiones a una función al ser la variable estática sólo se inicializa una vez, mejorando el rendimiento del programa. Me gustaría saber más sobre el tema, al igual que de programación multihilo de la que sólo he tocado un poco en Java.
#8
He estado investigando últimamente sobre este tema del manejo de cadenas de caracteres en C y C++ y os traigo un código con 3 funciones que pueden resultar interesantes para este tema.

La primera función es un sustituto de strlen();

La segunda es un sucedáneo de toupper(); pero que cambia todo el texto de minúsculas a mayúsculas y no solo un caracter concreto.

La última es lo mismo que la anterior peor con tolower();

Código (cpp) [Seleccionar]

/*#include <stdio.h> en C*/
#include <cstdio>

/*Prototipos de funciones utiles para el manejo de cadenas de caracteres*/
inline size_t magnitudTexto (char texto []);
inline void textoMayusculas (char texto [], size_t numeroCaracteres);
inline void textoMinusculas (char texto [], size_t numeroCaracteres);

/*Funcion main*/
int main (void)
{
   /*Declaracion de variables*/
   const unsigned char CARACTERES_MAXIMOS = 140; /*Constante para no usar numeros magicos*/
   char texto [CARACTERES_MAXIMOS]; /*Array de caracteres de 140 espacios*/
   unsigned char caracteresTexto = 0;

   /*Tramites con el usuario*/
   printf("Introduzca un texto: \n");
   fgets(texto, CARACTERES_MAXIMOS, stdin); /*Uso de fgets(); para evitar desbordamientos de buffer*/

   /*Comprobaciones del funcionamiento de las funciones*/
   caracteresTexto = magnitudTexto(texto);
   printf("El texto tiene %hhu caracteres.\n", caracteresTexto); /*%hhu para variables unsigned char, de 0 a 255*/

   textoMayusculas(texto, caracteresTexto);
   printf("El texto pasado a mayusculas:\n%s", texto);

   textoMinusculas(texto, caracteresTexto);
   printf("El texto pasado a minusculas:\n%s", texto);

   return 0;
}

inline size_t magnitudTexto (char texto [])
{
   size_t magnitud = 0;

   while (texto [magnitud] != '\0') /*Los arrays de caracteres finalizan con un \0*/
   {
       magnitud++;
   }

   return magnitud;
}

inline void textoMayusculas (char texto [], size_t numeroCaracteres)
{
   size_t contador = 0;

   while (contador <= numeroCaracteres)
   {
       if ((texto [contador] >= 'a') && (texto [contador] <= 'z'))
       {
           texto [contador] -= 'a' - 'A'; /*Consultar la tabla ASCII*/
           contador++;
       }
       else
       {
           contador++;
       }
   }
}

inline void textoMinusculas (char texto [], size_t numeroCaracteres)
{
   size_t contador = 0;

   while (contador <= numeroCaracteres)
   {
       if ((texto [contador] >= 'A') && (texto [contador <= 'Z']))
       {
           texto [contador] += 'a' - 'A';
           contador++;
       }
       else
       {
           contador++;
       }
   }
}


Decidme qué os parece, si funciona correctamente y demás, yo lo he probado compilandolo en Code::Blocks en C++ bajo el compilador g++ en Ubuntu 13.04, debería funcionar en Windows también.

Corregido el error del static.
Corregido el error de tipos demasiado cortos (unsigned char).
Corregido el error de "+- 32".