Ads 468x60px

Perfil

lunes, 17 de octubre de 2011

Ejercicios resueltos básicos de lenguaje C


El objetivo de esta práctica es afianzar ciertos conceptos básicos de la programación en lenguaje C:
  • Bucles y tablas.
  • Entrada y salida de datos.
  • Paso de argumentos a un programa.
  • Manejo de archivos.
  • Funciones.
  • Uso de memoria dinámica.

EJERCICIO 1.
Escribir un programa (es decir una función main) que pida por teclado una serie de números enteros, los almacene en una tabla estática y posteriormente escriba por pantalla todos los números introducidos indicando además cual es el mayor y el menor. Lo primero que debe hacer el programa es preguntar al usuario cuantos números se van a introducir y comprobar que dicha cantidad es menor que la dimensión de la tabla. Para dicha dimensión debe definirse una constante (por ejemplo MAX_DIMENSION) a la cual se puede asignar un valor razonable (por ejemplo, 100).
Funciones C a utilizar:
·         scanf: para leer números introducidos por el teclado.
  • printf: para imprimir por pantalla.

Ejemplo de ejecución: lo que se vería por pantalla debe ser algo así como
Introduce la cantidad de números:
3
Introduce los números:
5
7
2
Los números introducidos son:
5
7
2
El mayor es el 7.
El menor es el 2.

/*********************************************************
*   Autor: Victor Sanchez2
*   Web: http://usuarios.tripod.es/VictorSanchez2
*   Correo: victorss18@hotmail.com
*
**********************************************************/ 
   
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define ERR -10001
#define MAX_DIM 100

int enteros[MAX_DIM];         /* Array para guardar los enteros */
int num_total;


int lectura(void);
int sacarpantalla(int max, int min, int num_total);
int calcular(int *max, int *min, int total);
int es_digito(char caracter[]);


int main()
{
  int menor;             /* Numero menor */
  int mayor;             /* Numero mayor */

  if (lectura() == ERR)
   {
    printf("Error al leer el numero de terminos.\n");
    return ERR;
   }
   
   if (calcular(&mayor, &menor, num_total) == ERR)
     {
     printf("Error al intentar calcular el mayor y el menor");
     return ERR;
    }
   
   if (sacarpantalla(mayor, menor, num_total) == ERR)
    {
     printf("Error al mostrar por pantalla.\n");
     return ERR;
    }
 return OK;
}

/*********************************************************
*   Funcion: int lectura(int *total)
*
*   IN: Toma una variable tipo int.
*   OUT: Devuelve OK si se ha leido correctamente, ERR si hay algun fallo.
*   MAKE: Obtiene los numeros que introduce el usuario y los guarda
*         en un array de enteros
**********************************************************/
int lectura(void)
{
 int continuar = OK;
 int n;
 char numeros[MAX_DIM];
   
 for (n = 0; n < (int) strlen(numeros); n++)
  numeros[n] = '0';

 printf("\nCuantos numeros va a introducir? --> ");

 do {
  gets(numeros);
  continuar = OK;
  if ((num_total = es_digito(numeros)) == ERR)
    continuar = ERR;
  if (num_total <= 0)
   {
    printf("Debe introducir un numero positivo.\n");
    continuar = ERR;
   }
 } while (continuar != OK);
   
 printf("\nIntroduzca los numeros: \n");
 for (n = 0; n < num_total; n++)
  {
   gets(numeros);
   if ((enteros[n] = es_digito(numeros)) == ERR)
    {
     printf("Error al leer el numero, por favor repita introduccion.\n");
     n--;
    }
  }
 return OK;
}

/*********************************************************
*   Funcion: int calcular(int *max, int *min, int num_total)
*
*   IN: *max y *min que acumulan el numero mayor y menor. num_total
*       acumula la cantidad de numeros que se van a introducir.
*   OUT: OK si se ha realizado correctamente o ERR si hay fallos.
*   MAKE: Encuentra el minimo y el maximo de los numeros introducidos
*
**********************************************************/
int calcular(int *max, int *min, int total)
{
 int n;
 *min = *max = enteros[0];    /* Lo inicializamos */
   
 for (n = 1; n < total; n++)
  {
   if (*min > enteros[n])
       *min = enteros[n];
   if (*max < enteros[n])
       *max = enteros[n];
  }
 return OK;
}

/*********************************************************
*   Funcion: int sacarpantalla(int max, int min, int num_total)
*
*   IN: toma el valor maximo,minimo y total de elementos
*   OUT: devuelde ERR si no puede y OK si puede  
*   MAKE: Nada
*
**********************************************************/
int sacarpantalla(int max, int min, int num_total)
{
   
 int n;

 printf("Los numeros introducidos son: ");
   
 for (n = 0; n < num_total; n++)
   printf("%d, ", enteros[n]);

 printf("\nMinimo: %d", min);
 printf("\nMaximo: %d\n", max);

 return OK;
}

/*********************************************************
*   Funcion: int es_digito(char caracter)
*
*   IN: Se le da una serie de caracteres para que se pasen a numero       
*   OUT: Nos devolvera ERR si se produce un eroor
*   MAKE: Comprueba la integridad de los datos
*
**********************************************************/
int es_digito(char caracter[])
{

 int i;
 int num = 0;
 int rango;

 /* Si la cadena esta vacia */
 if (caracter[0] == 0)
   return ERR;
   
  if (caracter[0] == '-')     /* Si se ha introducido un numero negativo */
    {
     i = 1;              
 /* Empezamos el bucle para ver si es caracter desde el siguiente caracter */
      rango = 5;
    }
  else              /* Debe ser un numero positivo o hay algun error */
    {
     i = 0;
     rango = 4;
    }

  /* Comprobamos que todos los elementos sean digitos */
  /* El mayor numero que permitimos es 9999 */

  if ((int) strlen(caracter) > rango)      
   {
    printf("No puede introducir esa cantidad de numeros!!!\n");
    printf("Es demasiado grande. Introduzca numeros entre -9999 y 9999\n");    
    return ERR;
   }

 for (i = i; i < (int) strlen(caracter); i++)
  if (caracter[i] < '0' || caracter[i] > '9')
   {
    printf("\nIntroduzca unicamente digitos, por favor.\n");
    return ERR;
   }
   

 /* Si solo se ha introducido un caracter */
 if (strlen(caracter) == 1)
  return num = caracter[0] - '0';  /* Devolvemos el digito */
   

 /* Si hay mas de un caracter */
 for (i = 0; i != (int) strlen(caracter); i++)
   num = (num * 10) + (caracter[i] - '0');

 return num;
}



EJERCICIO 2.
Escribir un programa (es decir una función main) que lea el contenido de un archivo de texto y lo vuelque por pantalla, indicando posteriormente la longitud de la línea más larga. El programa debe recibir el nombre del archivo como argumento, no teniendo que introducirse éste por pantalla. Para ello la función main debe tener el prototipo estándar int main(int argc, char *argv[]).
Funciones C a utilizar:
·         fopen: para abrir un archivo.
  • fclose: para cerrar un archivo.
  • fgets: para leer una línea de un archivo.
  • strlen: para obtener la longitud de una cadena.


/******************************************************************************
*   Autor: Victor Sanchez2
*   Web: http://usuarios.tripod.es/VictorSanchez2
*   Correo: victorss18@hotmail.com
*   Make: Este algoritmo lee un archivo introducido por el usuario
*         y calcula cual es el numero de caracteres de la linea mayor.
*****************************************************************************/

#include <stdio.h>
#include <string.h>
#define ERR -1
#define OK 1
#define MAX_DIM 80       /* Maxima longitud de la linea */
#define mayor(a,b)((a) > (b) ? (a):(b))

char *fgets(char *linea, int max, FILE * fp);
int mayor_linea(void);
int leer_archivo(char *archivo[]);
void ayuda(void);

FILE * fp;
int max = MAX_DIM;

int main(int argc, char *argv[])
{
 /* Debe introducir <nombre del ejecutable> <nombre del archivo> */
 if (argc != 2)
  {
   ayuda();
   return ERR;
  }

 if (leer_archivo(&argv[1]) == ERR)
  return ERR;
   
 printf("\nLa linea mas larga tiene %d caracteres.\n", mayor_linea());

 fclose(fp);
 return OK;
}

/******************************************************************************
*   Funcion: int leer_archivo(char *archivo[])
*
*   IN: Nombre del archivo
*   OUT: OK si se ha leido correctamente, ERR si ha habido algun fallo
*   MAKE: Lee un archivo introducido por el usuario.
*
*****************************************************************************/
int leer_archivo(char *archivo[])
{
   
 if ((fp = fopen(archivo[0], "r")) == NULL)
  {
   printf("Error al intentar abrir el archivo\n");
   return ERR;
  }

 return OK;
}

/******************************************************************************
*   Funcion: int mayor_linea(void)
*
*   IN:
*   OUT:  Tamagno de la linea de mayor longitud del archivo.
*   MAKE: Calcula el tamagno de la linea mas larga.
*
*****************************************************************************/
int mayor_linea(void)
{
   
 char cad[MAX_DIM];
 int mayor_cad = 0;      /* Inicializamos el valor de la cadena */
 while (!feof(fp))
  {
   fgets(cad, MAX_DIM, fp);
   mayor_cad = mayor(mayor_cad, (int) strlen(cad));
  }
   
 return mayor_cad;
}

/******************************************************************************
*   Funcion: void ayuda(void)
*
*   IN:
*   OUT: Mensaje de ayuda para el usuario.
*   MAKE: Muestra ayuda al usuario para que introduzca los datos correctamente.
*
*****************************************************************************/
void ayuda(void)
{
  printf("\nDebe introducir: <nombre del ejecutable> <nombre del archivo>\n");
}

EJERCICIO 3.
El número e (2.7183...) se puede aproximar mediante la suma:
Descripción: ..\..\..\..\..\..\Prog_C\enunciados de las practicas\Prac_1_archivos\practica1_archivos\Image4.gif
Sumatorio de   1/n!   desde n=0 hasta n=N
En esta expresión la precisión queda determinada por el valor N. El valor n! representa el factorial de n (1·2·...·(n -1)·n). Recordemos que, por definición, 0!=1.
Escribir un programa (es decir una función main) que permita calcular la aproximación al número e dada por N (valor preguntado al usuario). Debe utilizarse una función auxiliar de prototipo float Factorial (int n); dicha función debe ser una función recursiva, puesto que n!=n·(n-1)!.

/*********************************************************
*   Autor: Victor Sanchez2
*   Web: http://usuarios.tripod.es/VictorSanchez2
*   Correo: victorss18@hotmail.com
*
*   MAKE: Este programa realiza la aproximacion al numero e.
*         Lo hemos realizado de 2 maneras:
*           - Recursivamente.
*           - Forma mas eficiente (sin usar recursividad).
*
*         Un ejemplo: (introduciendo 10000 terminos)
*           - Recursividad:  12 segundos aproximadamente
*           - Eficientemente: Se obtiene el resultado instantaneamente.
*
**********************************************************/ 
   
#include <stdio.h>
#include <string.h>
#define OK 1
#define ERR -10001
#define NO 0
#define MAX_TERM 1000000

float n_term;

int eficiente;
int lectura(int *eficiente, float *n_term);
float calcular(float n_term);
int sacarpantalla(float numeroe);
float factorial(int n);
int es_digito(char caracter[]);



int main()
{
 if (lectura(&eficiente, &n_term) == ERR)
  {
   printf("Error al leer el numero de terminos\n");
   return ERR;
  }

 if (sacarpantalla(calcular(n_term)) == ERR)
  {
   printf("Error al sacar por pantalla/calcular el numero\n");
   return ERR;
  }

 return OK;
}

/*********************************************************
*   Funcion: int sacarpantalla(float numeroe)
*
*   IN: Toma la variable numeroe de tipo float.
*   OUT: Devuelve OK si lo consigue, ERR si hay algun
*   MAKE: Saca por pantalla el resultado. No modifica ninguna variable.
*
**********************************************************/
int sacarpantalla(float numeroe)
{
   
 printf("\nEl valor de la aproximacion al numero e es: %f\n\n", numeroe);
 return OK;
}

/*********************************************************
*   Funcion: int lectura(int *eficiente, float *n_term)
*
*   IN: Toma la direccion de la variable eficiente, y el numero de términos
*   OUT: Nos devuelve OK si lo consigue ERR si hay algun fallo.
*   MAKE: Se encarga de leer el numero de terminos a calcular. Modifica
*         n_term y eficiente.
*
**********************************************************/
int lectura(int *eficiente, float *n_term)
{
 char numero[5];
 char temp = 0;
 int continuar = NO;
   
 do {
  printf("\nIntroduzca el numero de terminos a calcular del numero e: ");
  gets(numero);
  } while ((*n_term = es_digito(numero)) == ERR || (*n_term < 1));

 do {
   printf("Desea usar el modo de calculo rapido? [S,N]:\t");
   fflush(stdin);
   fflush(stdout);
   scanf("%c", &temp);
   fflush(stdin);
   if ((temp == 'S') || (temp == 'N') || (temp == 's') || (temp == 'n'))
    {
     continuar = OK;
     if ((temp == 'S') || (temp == 's'))
       *eficiente = OK;
     else
      {
       *eficiente = NO;
       if (strlen(numero) > 4) /* Permitimos hasta el numero 9999 */
        {
         printf("\nSi desea calcular este numero con recursividad puede
                  ocasionar problemas.");
         printf("\nIntentelo con la manera eficiente.\n");
         return ERR;
        }
      }
    }
   else
    {
     continuar = NO;
     printf("Por favor introduzca un valor valido!!! \n");
    }
  } while (continuar != OK);

 return OK;
}


/*********************************************************
*   Funcion: float calcular(float terminos)
*
*   IN: Numero de terminos para realizar la aproximacion.
*   OUT: La aproximacion al numero e si es correcto o ERR si ha habido un
*        fallo.
*   MAKE: Calcula la serie: 1 entre el factorial de un numero dado.
*
**********************************************************/

float calcular(float terminos)
{
 float e = 0;
 float facto = 1;        /* Va a ir acumulando el valor del factorial cuando se haya
                               seleccionado "eficiente" */
 int n;

 if (eficiente == OK)
  {
   printf("\nSe esta calculando el numero e de la manera mas eficiente.");
   e = 1;
   for (n = 1; n < (int) terminos; ++n)
    {
     facto *= n;
     e += 1 / facto;
    }
    
   return e;
  }
 else   /* Calculamos la serie usando recursividad */
  {
   do {
     e += (1 / factorial((int) terminos--));
    } while (terminos >= 0);
    
   printf("\nSe esta calculando el numero e usando recursividad.");
  }

return e;
}

/*********************************************************
*   Funcion: float factorial (int n)
*
*   IN:  Numero de terminos de los que se calcularan sucesivos factoriales
*   OUT: El factorial del numero o ERR si ha habido algun error.
*   MAKE: Calcula el factorial de un numero dado.
*
**********************************************************/
float factorial(int n)
{
  if (n == 0)
    return 1;
  else
    return (n * factorial(n - 1));
}


/*********************************************************
*   Funcion: int es_digito(char caracter)
*
*   IN: Se le da una serie de caracteres para que se pasen a numero       
*   OUT: Nos devolvera ERR si se produce un eroor
*   MAKE: Comprueba la integridad de los datos
*
**********************************************************/
int es_digito(char caracter[])
{

int i;
int num = 0;
int rango;

 /* Si la cadena esta vacía */
 if (caracter[0] == 0)
   return ERR;

 if (caracter[0] == '-') /* Si se ha introducido un numero negativo */
  {
   i = 1;          
/* Empezamos el bucle para ver si es caracter desde el siguiente caracter */
   rango = 7;
  }
 else               /* Debe un numero positivo o hay algun error */
  {
   i = 0;
   rango = 7;
  }
   
  /* Comprobamos que todos los elementos sean digitos */
  /* El mayor numero permitido es 9999999 */

  if ((int) strlen(caracter) > rango)  
    {
    printf("No puede introducir esa cantidad de numeros!!!\n");
    printf("Es demasiado grande. Rango: -9999999 y 9999999\n");
    return ERR;
   }

  for (i = i; i < (int) strlen(caracter); i++)
  if (caracter[i] < '0' || caracter[i] > '9')
   {
    printf("\nIntroduzca unicamente digitos, por favor.\n");
    return ERR;
   }

  /* Si solo se ha introducido un caracter */
  if (strlen(caracter) == 1)
    return num = caracter[0] - '0';     /* Devolvemos el digito */

  /* Si hay mas de un caracter */
  for (i = 0; i != (int) strlen(caracter); i++)
    num = (num * 10) + (caracter[i] - '0');

return num;
}

EJERCICIO 4.
Modificar el programa del ejercicio 1 para que en lugar de utilizar una tabla estática utilice una tabla alocada dinámicamente. La tabla debe alocarse una vez que el usuario ha indicado el número de elementos y debe liberarse al finalizar el programa.
Funciones C a utilizar:
·         malloc: para alocar memoria dinámicamente.
  • free: para liberar memoria previamente alocada.

/******************************************************************************
*   Autor: Victor Sanchez2
*   Web: http://usuarios.tripod.es/VictorSanchez2
*   Correo: victorss18@hotmail.com
*
*****************************************************************************/


#include <stdio.h>
#include <alloc.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define ERR -10001
#define NO 0
#define MAX_DIM 9999

int creartabla(int **ptabla, int *numero);
int rellenartabla(int *tabla, int numero);
int controldeerrores(int numero);
int calcular(int *tabla, int numero, int *max, int *min);
int mostrarvalores(int *tabla, int numero, int max, int min);
int es_digito(char caracter[]);
int *tabla = NULL;
int numero, max, min;

int main(void)
{
 if (creartabla(&tabla, &numero) == ERR)
   return ERR;

 if (rellenartabla(tabla, numero) == ERR)
   return ERR;

 calcular(tabla, numero, &max, &min);
 mostrarvalores(tabla, numero, max, min);

return OK;
}

/******************************************************************************
*   Funcion: int creartabla(int **ptabla, int *numero)
*
*   IN: la direccion de un puntero y la direccion del numero de elementos a   
*       guardar
*   OUT: OK si se consigue, ERR si se falla
*   MAKE: Crea una tabla dinamica de enteros en donde se guardaran los numeros
*         introducidos
*
*****************************************************************************/
int creartabla(int **ptabla, int *numero)
{

 int continuar;
 char elementos[MAX_DIM];

 do {
   continuar = OK;
   printf("Por favor introduzca el numero de elementos: ");
   gets(elementos);
   /* Si esta vacio, es negativo o 0... */
   if (elementos[0] == 0 || elementos[0] == '-' || elementos[0] == '0')
     continuar = ERR;
   if ((*numero = es_digito(elementos)) == ERR)
     continuar = ERR;
  } while (continuar != OK);
   
 *ptabla = (int *) malloc(*numero * sizeof(int));
   
 if (*ptabla == NULL)
     return ERR;
   
 return OK;
}

/******************************************************************************
*   Funcion: int rellenartabla(int *tabla, int numero)
*
*   IN: la direccion de la tabla, el numero de enteros a guardar
*   OUT: OK si se consigue ERR si se falla
*   MAKE: rellena la tabla con los numero que introduzca el usuario
*
*****************************************************************************/
int rellenartabla(int *tabla, int numero)
{
   
 int i, continuar;
 char num[MAX_DIM];

 printf("Por favor introduzca los numeros: \n");

 for (i = 0; i < numero; ++i)
  {
   continuar = OK;
   gets(num);
   if (num[0] == 0)
    {
     printf("Deberia introducir algun digito.\n");
     continuar = ERR;
    }
   if ((*tabla++ = es_digito(num)) == ERR)
    {
     printf("Error al leer el numero.\n");
     continuar = ERR;
    }
   if (continuar == ERR)
      i--;
  }

return OK;
}

/******************************************************************************
*   Funcion: int calcular(int *tabla, int numero, int *max, int *min)
*
*   IN: La direccion de la tabla, el numero de elementos, y la direccion del   *       numero mas grande y mas pequeño
*   OUT: OK si se consigue ERR si falla
*   MAKE: calcula el numero mas grande y el mas pequeño
*
*****************************************************************************/
int calcular(int *tabla, int numero, int *max, int *min)
{

 int i;
 *max = *min = tabla[1];

 for (i = 0; i < numero; i++)
  {
   if (tabla[i] > *max)
     *max = tabla[i];
   if (tabla[i] < *min)
     *min = tabla[i];
  }
   
return OK;
}

/******************************************************************************
*   Funcion: int mostrarvalores(int *tabla, int numero, int max, int min)
*
*   IN: La direccion de la tabla y los valores del numero maximo, minimo y    *       numero de enteros
*   OUT: OK si se consigue ERR si falla
*   MAKE: mostrar por pantalla los valores
*
*****************************************************************************/
int mostrarvalores(int *tabla, int numero, int max, int min)
{
   
 int i;

 printf("Los valores introducidos han sido:\t");
   
 for (i = 0; i < numero; i++)
    printf("%d\t", tabla[i]);
   
 free(tabla);
   
 printf("\nEl valor maximo ha sido:\t%d", max);
 printf("\nEl valor minimo ha sido:\t%d", min);
 printf("\nEl numero de terminos introducidos ha sido: %d\t\n", numero);
   
 return OK;
}


/*********************************************************
*   Funcion: int es_digito(char caracter)
*
*   IN: una cadena de caracters
*   OUT: el valor del numero
*   MAKE: nada
*
**********************************************************/
int es_digito(char caracter[])
{
   
 int i;
 int num = 0;
 int rango;

 if (caracter[0] == '-') /* Si se ha introducido un numero negativo */
  {
   i = 1;          
/* Empezamos el bucle para ver si es caracter desde el siguiente caracter */
   rango = 5;
  }
 else               /* Debe un numero positivo o hay algun error */
  {
   i = 0;
   rango = 4;
  }
   
 /* Comprobamos que todos los elementos sean digitos */
 if ((int) strlen(caracter) > rango)   
/* El mayor numero que permitimos es 9999 */
  {
   printf("No puede introducir esa cantidad de numeros!!!\n");
   printf("Es demasiado grande. Introduzca numeros entre -9999 y 9999\n");
   return ERR;
  }

  for (i = i; i < (int) strlen(caracter); i++)
    if (caracter[i] < '0' || caracter[i] > '9')
     {
      printf("\nIntroduzca unicamente digitos, por favor.\n");
      return ERR;
     }

  /* Si solo se ha introducido un caracter */
  if (strlen(caracter) == 1)
    return num = caracter[0] - '0';     /* Devolvemos el digito */
   
  /* Si hay mas de un caracter */
  for (i = 0; i != (int) strlen(caracter); i++)
    num = (num * 10) + (caracter[i] - '0');

return num;
}

1 comentarios:

Victor Manuel Hernandez dijo...

SALUDOS. Quisiera saber si tiene una guia de ejercicios de computacion basica