Documentos de Académico
Documentos de Profesional
Documentos de Cultura
MEMORIAS DE LAS
PRACTICAS DE
PROGAMACION
INDUSTRIAL
2
Índice
Tutorial………….págs. 7
Corrección de errores……….págs. 7
División………………………….págs. 14-16
Tipos……………………págs. 16-18
Precisión……………..págs. 19-21
Millas…………págs.22-24
Navegador………..págs. 29-30
Ordenar………………..págs. 31-32
Cambio……………….págs. 33-36
Fibonacci…………….págs. 37-39
Engranajes………..págs. 39-40
Perfecto……………págs. 41-43
Pofuente……….págs. 44-46
Facturación………….págs. 47-49
Calculos………………págs. 50-52
3
Recursiva………………págs. 52-55
Inver_cadena………….págs. 56-59
Desintegración………págs. 60-67
Traza……………págs. 68-70
Cuadrado_vector……………………..págs. 74-75
Potencias_vector……………………págs. 75-77
Capicúa……………………………..págs. 78-80
Vocales………………..pág. 80-81
Prueba………………..págs. 82-83
Ascensores………………..págs. 86-87
Stack……………………..págs. 94-95
4
5
PRÁCTICA Nº 1 : INTRODUCCIÓN AL COMPILADOR “Dev-C++”
OBJETIVO GENERAL:
OBJETIVO:
Detectar y corregir los errores del siguiente programa. Para ello deberá
compilar y ejecutar el programa. Guardar el programa corregido en el fichero
1_errores.c:
#include <stdio.h>
void main( )
{ int numero;
numero = 2;
printf( "El valor es % c" Numero );
getch();
}
#include <stdio.h>
main( )
{ int numero;
numero = 2;
printf( "El valor es % i" ,numero );
getch();
} Archivo: 1_errores.c
6
EJERCICIO C) :TÍTULO: Estudiar el mapa de memoria.
#include <stdio.h>
int main() {
int a,b;
a=0;
b=a+8;
printf("Dirección de a: %u\n", (unsigned int)&a);
printf("Dirección de b: %u\n", (unsigned int)&b);
getch();;
}
Archivo: memoria.c
Inicio
a , b: Enteros
a=0;
b=a+8;
Fin
7
RESOLUCIÓN: Los resultados obtenidos en esta ejecución son:
(Los resultados variaran con cada ejecución).
Dirección de a: 3219265152
Dirección de b: 3219265148
8
EJERCICIO D): TÍTULO: Tamaño tipos de datos
OBJETIVO: A partir del siguiente código cree un programa y ejecútelo.
#include <stdio.h>
int main(void)
{
int a, b;
char c, d;
a = 2147483647;
b = a + a;
c = 127;
d = c + c;
printf ("%d\n", a);
printf ("%d\n", b);
printf (“%d\n”, d);
getch();
} Archivo: desbordamiento. c
REQUISITOS:
El alumno deberá editar el programa y probarlo. Guardarlo con el nombre
1_desbordamiento. c .
Los alumnos que presenten memorias deberán explicar cómo influyen los
formatos utilizados en las salidas observadas.
Inicio
a , b: Enteros
c,d: Caracteres
a=2147483647;
b=a+a;
c=127;
d=c+c;
a.
b.
d.
Fin
9
RESOLUCIÓN:
2147483647
-2
-2
10
PRÁCTICA PROPUESTA Nº 2
REQUISITOS:
El programa pedirá al usuario que introduzca por pantalla la base (b) y la altura
(a) en dos variables reales y presentará el área del triángulo. Para calcular el
área se creará una macro denominada “AREA(x, y) ” .
El programa resultante se guardará como macro.c
RESOLUCIÓN:
Archivo: macro. c
11
INICIO
Introducir : base
Leer : base
Introducir : altura
leer: altura
Llamada a :
1 AREA(B .A)
IMPRIMIR AREA
FIN
1
INICIO
Calcular :
AREA =((X)*(Y))
RETURN (AREA)
12
CUESTIONES ( macro.c)
OBJETIVO:
Se trata de realizar un programa para estudiar como funcionan los operadores
de división (/) y resto (%) con distintos tipos de variables. Se comprobará la
diferencia entre la ‘división real o en punto flotante’, la ‘división entera o
cociente ’ y el ‘ resto de una división’.
REQUISITOS:
En la función printf(), el especificador de formato debe de estar de acuerdo con
el tipo de argumentos. Para la división real, utilizar el formato de salida %6.3f,
que reserva un total de 6 espacios de salida, de los cuales tres serán
decimales.
13
/* fichero division.c */
# include <stdio.h>
{ clrscr();
printf(" division entera: 5/4 es %6d\n", .................);
printf(" division entera: 6/3 es %6d\n", ................);
printf(" division entera: 7/4 es %6d\n", .................);
printf(" division flotante: 7./4. es %6.3f\n", ...............);
printf(" division mixta: 7./4 es %6.3f\n", .................);
printf(“ resto de una division....7%4 es %6d\n”,...........);
RESOLUCIÓN:
/* fichero division.c */
# include <stdio.h>
void main(void)
{
system ("cls");
printf("división entera: 5/4 es %6d\n",5/4 );
printf( "división entera: 6/3 es %6d\n",6/3 );
printf( "división entera: 7/4 es %6d\n",7/4 );
printf( "división flotante: 7./4. es %6.3f\n",7./4. );
printf( "división mixta: 7./4 es %6.3f\n" ,7./4 );
printf( "resto de una división....7/4 es %6d\n" ,7%4);
14
INICIO
Borrar pantalla :
system (" cls")
FIN
OBJETIVO:
Escribir un programa para ver las longitudes en bytes y los valores máximos y
mínimos de los tipos básicos de variables en C.
REQUISITOS:
El alumno deberá completar las sentencias incompletas. Se usaran las
funciones SIZEOF, INT_MIN, INT_MAX, CHAR_MIN, CHAR_MAX, etc.
disponibles en las librerías <limits.h> y <float.h> .
15
RESOLUCIÓN:
#include <stdio.h>
#include <conio.h>
#include <limits.h>
#include <float.h>
main()
{char a;
short int b;
int c;
long int d;
unsigned char e;
unsigned short int f;
unsigned int g;
unsigned long int h;
float i;
double j;
long double k;
/* LONGITUDES */
printf ( "Longitud de cada uno de los tipos basicos \n\n");
printf ( "La longitud de char a= %d \n" ,sizeof(a));
printf ( "La longitud de short int b= %d \n" ,sizeof(b));
printf ( "La longitud de int c= %d \n" ,sizeof(c));
printf ( "La longitud de long int d= %d \n" ,sizeof(d));
printf ( "La longitud de unsigned char e= %d \n" ,sizeof(e));
printf ( "La longitud de unsigned short int f= %d \n" ,sizeof(f));
printf ( "La longitud de unsigned int g= %d \n" ,sizeof(g) );
printf ( "La longitud de unsigned long int h= %d \n" ,sizeof(h));
printf ( "La longitud de float i= %d \n" ,sizeof(i));
printf ( "La longitud de double j= %d \n" , sizeof(j));
printf ( "La longitud de long double k= %d \n" ,sizeof(k));
Archivo: tipos. C
16
DIAGRAMA DE FLUJO ( tipos.c)
INICIO
Definir variables de
varios tipos
imprimir longitud
de cada tipo de
variable en bytes
imprimir de rango
valores de cada
tipo de variable
FIN
Diagrama de flujo : tipos. C
CUESTIONES ( tipos.c)
17
EJERCICIO D ): TÍTULO: Precisión tipos de datos
OBJETIVO:
Ejecute el siguiente código :
#include <stdio.h>
int main() {
int a,b;
char c,d;
float decimal;
a=512;
b=127;
c=a;
d=b;
printf( "c= %d y d= %d\n" , c,d);
decimal = 2/3;
a = 2/3;
printf( "decimal= %f y a= %d\n" , decimal, a);
decimal = 2.0/3.0;
printf( "decimal= %f\n" , decimal);
getch();}
Archivo: precision. C
RESOLUCIÓN:
INICIO
DEFINE:
"a" y "b" : enteros
"c" y "d" :caracteres
"decimal" : real
a = 512
b = 127
c = a
d=b
1
18
Buy SmartDraw!- purchased copies print this
document without a watermark .
Visit www.smartdraw.com or call 1-800-768-3729.
CUESTIONES ( precision.c)
Diga cuales son los resultados obtenidos. Explique el motivo por el cual
se obtienen dichos valores.
CUESTIONES ( precision.c)
a) Indique porque motivo se obtienen los valores de “0” para la variable ‘c’ y
‘decimal’ en el primer ‘printf’ y segundo ‘printf’ respectivamente.
Sale cero por que es una variable de tipo char que solo puede almacenar un byte y es
desbordada al asignarle el valor de a que es el número 512(en binario la desborda).
Decimal sale 0.0000 ya que al asignarle el valor de la división entre dos enteros el
resultado tiene que ser otro entero que en este caso es 0 y los cuatro 0 que hay después
de la coma vienen dados por %f.
19
b) ¿Es el valor de ‘decimal’ en el tercer ‘printf’ igual al segundo? Indique el
motivo
No ya que en el segundo caso se trata de una división real por lo que los decimales son
representados.
20
PRÁCTICA PROPUESTA Nº 3
OBJETIVO:
Se trata de codificar un programa que calcule el número de número de
kilómetros correspondientes a un número N de millas marinas introducidas por
teclado. El número de metros de una milla marina es de 1852.
REQUISITOS:
1º. En la codificación del programa se define una constante CONV_MILLAS
que indica el número de kilómetros de una milla. Defina dicha constante de dos
formas diferentes.
Guardar el código en un fichero con nombre millas1.c. y millas2.c para cada
definición de constante respectivamente.
2º. El programa pedirá por teclado que se “Introduzca el numero de millas”.
3º. Se calculan el número de kilómetros correspondientes a las millas
introducidas.
4º. Se presentan los resultados de millas y kilómetros.
RESOLUCIÓN:
#include <stdio.h>
#define CONV_MILLAS 1.852
main()
{
float millas , kilometros;
21
DIAGRAMA DE FLUJO ( millas.c)*
*El mismo para millas1, millas2 y
millas3
#include<stdio.h>
main()
{
float millas, kilometros, CONV_MILLAS=1.852 ;
/* Inicializamos CONV_MILLAS al valor 1.852 */
Archivo: millas2. C
22
CUESTIONES ( millas.c)
const CONV_MILLAS=1.852;
#include<stdio.h>
main()
{
float millas, kilometros ;
const float CONV_MILLAS=1.852 ;
/* Inicializamos CONV_MILLAS al valor 1.852 */
23
EJERCICIO B ): TÍTULO: Cambios de base
OBJETIVO:
Desarrollar un programa para pasar un nº entero, leído por teclado, a base
octal, hexadecimal y binaria. Este algoritmo se podría utilizar para analizar las
lecturas de distintos puertos del ordenador.
REQUISITOS:
1º.) El programa pedirá un nº por teclado. Por simplicidad considerar números
enteros positivos de 8 bits máximo (0 a 255).
2º.) Para cambiar a las bases octal y hexadecimal, bastará utilizar en printf, los
especificadores de formato “%O” y “%X”
3º.) Se mejorará el programa para que realice también la transformación a
binario.
El programa irá presentando cada uno de los bits obtenidos, en la pantalla.
4º.) El código se guardara en el fichero binario.c.
• Pseudocódigo:
• Explicación:
RESOLUCIÓN:
24
/* Pasar a binarios ,hexadecimal y octal*/
#include <stdio.h>
main()
{
do {
printf ("Introduce un numero entero de 0 a 255:\t");
scanf ("%u",&dato);
if (dato<0||dato>255)
printf("\n\a ERROR, el numero no puede ser ni menor que 0 ni mayor que 255\n");
}while (dato<0||dato>255);
for(i=7;i>=0;i--)
{
if((dato&(int)pow(2,i))!=0) /* se utiliza el operador de bit &(and)
para realizar el paso a binario,como se
indica en el enunciado de la practica */
printf("1");
else
printf ("0");
}
printf("\n");
printf("El numero en octal es %o\t\n", dato);
printf("El numero en hexadecimal es %X \t", dato);
/* Se emplean los especificadores de formato de octal y hexadecimal para
pasar de decimal a cualquiera de las dos bases. */
getch();
Archivo: binario. C
25
1
NO
El numero en
binario es:
Escribe :0
Escribe : 1
si
NO si
i
desde i=7
numero &2 0 hasta i=0
decremento =1
NO
FIN
26
EJERCICIO C ): TÍTULO: Calcular la letra del N.I.F.
OBJETIVO:
El código NIF está compuesto de los 8 dígitos del DNI, más una letra de
control. Escribir un programa que pida y guarde el dni y calcule la letra de
control del NIF.
REQUISITOS:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
I R W A G M Y F P D X B N J Z
Dicha tabla de caracteres puede estar almacenada en una variable tipo vector
inicializado de la forma char letra[ ] = {'I','R','W','A','G','M','Y','F','P','D',..........};
Nota:. Guardar como nif.c .Usar variables enteras de suficiente tamaño para
guardar un DNI y evitar el “overflow”. Para redondear puede usar el “cociente
entero”, usarse la función flloor, etc.
RESOLUCIÓN:
#include<stdio.h>
char letra[]={'I','R','W','A','G','M','Y','F','P','D','X','B','N','J','Z'};
main(){
int division, multiplicacion, resta, nif;
getch();
}
Archivo: nif. C
27
DIAGRAMA DE FLUJO ( nif.c)
OBJETIVO:
Cualquier receptor GPS recibe la posición del usuario en coordenadas geográficas
(longitud y latitud). Esta información es necesario pasarla a coordenadas planas
(distancia, dirección) para ser utilizadas por un programa de navegación más o menos
sofisticado.
SE PIDE:
Construir un programa que permita pasar de coordenadas geográficas introducidas por
teclado, a coordenadas polares planas.
RESOLUCIÓN:
28
/* Mini navegador*/
#include <stdio.h>
#include <math.h>
#define Pi 3.1415
main ()
{
float Lo_g, Lo_m ,La_g ,La_m, Lat_rad ,Dy,Dx,A,D;
printf ("Introduzca la longitud en grados\t");
scanf ("%f",&Lo_g);
printf ("\n Introduzca la longitud en metros\t");
scanf ("%f",&Lo_m);
printf ("\n Introduzca la latitud en grados\t");
scanf ("%f",&La_g);
printf ("\n Introduzca la latitud en metros \t");
scanf ("%f",&La_m);
getch();
}
Archivo: GPS. C
29
PRÁCTICA PROPUESTA Nº 4
OBJETIVO:
Se pretende codificar un programa que lea 3 números por teclado y los muestre
ordenados de mayor a menor.
REQUISITOS:
Los tres números introducidos serán enteros y el programa mostrará una salida
con los números ordenados de mayor a menor. Solo podrá utilizar tres
variables, a, b, c, para almacenar cada número entero.
NO podrá utilizar variables auxiliares.
Sírvase utilizar sentencias de control (por ejemplo tres if…). Guardar el
programa como ordenar.c
RESOLUCIÓN:
Archivo: ordenar. C
30
DIAGRAMA DE FLUJO ( ordenar.c)
INICIO
PIDE 3 NUMEROS :
a,b,c
LEE LOS 3
NUMEROS
LOS NUMEROS DE
MAYOR A MENOR
SON:
si
muestra : a a>b y a>c
NO
b>c si
si NO b>a y b>c muestra : b
muestra : b , c muestra : c , b NO
a>c
si NO si
muestra : c c>a y c>b
muestra : c , a muestra : a , c
NO
a>b
si NO
muestra : a , b
muestra : b , a
FIN
31
EJERCICIO B ): TÍTULO: Cambio optimo de monedas
OBJETIVO:
Programa que pida una cantidad en euros y la descomponga en
billetes/monedas de 100, 50,20, 10, 5, 2, 1. .
REQUISITOS:
a) En una primera versión del programa bastará con tres tipos de billetes,
por ejemplo : 100, 50 y 20.
Utilizaremos, tres estructuras “if ” independientes, una para cada
descomposición. Guardar el programa como cambio1.c
ALGORITMO PROPUESTO:
Declarar entre otras variables el vector: int monedas[ ]= {200, 100, 50, 20, 10,
5, 2, 1};.
Leer una cantidad por teclado.
Mediante una estructura repetitiva generar un índice para recorrer el vector de
monedas.
Si cantidad >= monedas [indice].
vuelta = cociente(cantidad/monedas[indice]).
imprimir vuelta.
cantidad = resto(cantidad/monedas[indice]).
Siguiente índice.
Imprimir cantidad (restante).
EJEMPLO DE EJECUCIÓN :
RESOLUCIÓN:
32
CODIGO FUENTE ( cambio1.c)
#include <stdio.h>
main()
if (cantidad>100)
{
billetes100=cantidad/100;
printf("\n Son %li billetes de 100\n",billetes100);
cantidad1=cantidad-(billetes100*100);
}
if (cantidad>50)
{
billetes50=cantidad1/50;
printf ("\n Son %li billetes de 50\n",billetes50);
cantidad2=cantidad1-(billetes50*50);
}
if (cantidad>20)
{
billetes20=cantidad2/20;
printf("\n Son %li billetes de 20\n",billetes20);
sobrante=cantidad2-(billetes20*20);
printf ("Lo que sobra es:\t %li",sobrante);
}
getch();
}
Archivo: cambio1. C
33
DIAGRAMA DE FLUJO ( cambio1.c)
INICIO
DEFINO :
cantidad ,
billetes100 ,billetes50 ,billetes2
0 ,sobrante ,cantidad2 ,cantida
d3 ,cantidad1
como enteros
NO
IMPRIME :
nº de billetes de
100
NO
IMPRIME :
nº de billetes de
50
NO
IMPRIME :
nº de billetes de 20;
Lo que sobra ,
FIN
34
CODIGO FUENTE ( cambio2.c)
#include<stdio.h>
main()
{
int cantidad,vuelta,i;
int monedas[]={100,50,20,10,5,2,1};
printf("Introduzca una cantidad: ");
scanf("%i",&cantidad);
for(i=0;i<7;i++) { /* El bucle for recorre el array de monedas y con ayuda
del if, va comparando la cantidad con cada moneda y
si es mayor la divide entre el valor de la moneda para
calcular el nº de monedas .Después se le asigna la cantidad
restante a la variable cantidad*/
if(cantidad>=monedas[i]) {
vuelta = cantidad/monedas[i];
printf("%i de %i. \n",vuelta,monedas[i]);
cantidad = cantidad%monedas[i];
}}
getch();
}
Archivo: cambio2. C
DIAGRAMA DE FLUJO ( cambio2.c)
INICIO
DEFINO :
Un array entero con los valores de los billetes
cantidad ,vuelta, i :enteros
si DESDE i =0
cantidad>=monedas [i] HASTA i<7
si
NO
NO
vuelta = cantidad/monedas[i];
cantidad =
cantidad %monedas [i];
IMPRIME:
el numero de monedas que
corresponden a cada valor de
moneda
FIN
i = i+1
35
EJERCICIO C ): TÍTULO: Números de Fibonacci
OBJETIVO:
Codificar el programa en C que genere los n primeros números de Fibonacci.
REQUISITOS:
Un número de Fibonacci es siempre igual a la suma de los dos números de
Fibonacci anteriores F i =Fi-1+ Fi-2 donde Fi es el número i-ésimo de Fibonacci.
Cualquier lista de números de Fibonacci comienza con un 0 y un 1 como los
dos primeros términos. El tercer término es igual a 0+1, es decir, 1. El cuarto
término es igual a 1 +1, o sea 2.
Para ello se recomienda utilizará como mínimo las variables n, (que guarda el
número introducido), anterior (que guarda el nº fibonacci calculado en el bucle
anterior), y nuevo (que guarda el nº fibonacci calculado en el bucle en curso).
Todas estas variables serán de tipo entero.
Presentar por pantalla los resultados en formato entero.
SE PIDE:
1º) Codificar el programa en C que genere los n primeros números de
Fibonacci, donde n es un valor introducido por el usuario.
Guardar el código con el nombre fibonaci.c
2º) Calcular y escribir en el papel la serie de Fibonacci para los dos valores
siguientes de n:
n=12 ====> n=26 ====>
RESOLUCIÓN:
36
DIAGRAMA DE FLUJO ( fibonaci.c)
INICIO
DEFINO :
n,i,aux,anterior=0, nuevo =1 :
como enteros
IMPRIME :
SI
n=1
un cero
NO
SI
IMPRIME :
un cero y un uno
n>2 ó n=2
NO
IMPRIME : NO
el valor de la variable
nuevo
i=i+1;
FIN
37
CUESTIONES ( fibonaci.c)
n=26 ====> 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89,144, 233, 377, 610, 987, 1597, 2584,
4181, 6765, 10946, 17711, 28657, 46368, 75025.
REQUISITOS:
Se deberá copiar y completar el programa. Se completará la sentencia ‘if’ para
comprobar que pares de numeros cumplen estrictamente dicha relación. (es
decir, que el cociente de n1/n2 == n y resto de n1/n2 ==0 ).
Guardarlo como engranajes.c
RESOLUCIÓN:
#include <stdio.h>
#include <conio.h>
int n ,n1 ,n2, c, r;
main()
{
printf("Relacion de transmision buscada?:\t ");
scanf("%i",&n);
for (n1=20; n1 <= 50; n1++)
{
for (n2=20; n2 <= n1; n2++)
{ c=n1/n2;
r=n1%n2;
if((n1/n2==n)&&((n1%n2)==0))
printf("\n n1=%i, n2=%i",n1,n2);
}
}
getch();
}
Archivo: engranajes. C
38
DIAGRAMA DE FLUJO ( engranajes.c)
INICIO
DEFINO :
n ,n1 ,n2 , c, r :
como enteros
PIDE UNA RELACION (n)
LEE LA RELACION (n)
SI
NO
SI
DESDE : n2=20
n1 = n1+1
DESDE : n1=20
HASTA : n2 <= n1
HASTA : n1 <= 50
SI
NO
c=n1/n2 ;
r=n1% n2;
(n1 /n2 )=n
y
NO
(n1% n2)=0
SI
IMPRIME :
valor de n1
n2 = n2+1; valor de n2
n2 = n2+1;
FIN
CUESTIONES ( engranajes.c)
N N1 N2 C(1) R(2)
a) 2 40 20 2 0
b) 2 42 21 2 0
c) 2 44 22 2 0
d) 2 46 23 2 0
39
EJERCICIO E ): TÍTULO: Números perfectos
OBJETIVO:
REQUISITOS:
ALGORITMO PROPUESTO:
Inicializar N
Mientras N >0
Leer por teclado un entero N
Mediante un bucle, generar posibles divisores enteros I entre 1 y N-1
Para cada numero I generado. calcular el restos como r=N mod I
Si el resto es cero, acumular suma=suma+I.
Fin bucle para generar enteros
Comprobar Si N = Suma e imprimir mensaje
Fin Mientras
EJEMPLO DE EJECUCIÓN:
Dame un número: 6
El número 6 es un número perfecto.
Dame un número: 7
El número 7 no es un número
perfecto.
Dame un número: 28
El número 28 es un número perfecto
Dame un número: 0
40
RESOLUCIÓN:
#include<stdio.h>
#include<math.h>
main()
{
int i,aux,n;
do
{
aux=0;
printf("Introduzca un numero: \n");
scanf("%i",&n);
if(n<0)
printf("ERROR:numero negativo\n");
break;
for(i=1;i<=(n/2);i++)
{
if((n%i)==0)
aux=aux+i;
}
if(aux==n)
printf("El numero %i es un numero perfecto \n",n);
else
printf("El numero %i no es un numero perfecto \n",n);
}while(0);
printf("Fin del programa");
getch();
}
41
DIAGRAMA DE FLUJO ( perfecto.c)
INICIO
DEFINO :
i, aux, n : COMO
ENTEROS
SI
0
NO
aux=0
PIDE UN
NUMERO (n)
LEE NUMERO (n)
SI
n<0
IMPRIME :
error
NO
NO
DESDE : i=1
aux=n
SI
HASTA :i<=(n/2)
NO
IMPRIME :
IMPRIME : SI
numero perfecto
numero no
perfecto
NO
RESTO de n/i
=0
SI IMPRIME :
final programa
aux=aux+i;
FIN
42
PRÁCTICA PROPUESTA Nº 5
OBJETIVO:
Para practicar el uso de funciones, desarrollar un programa que calcule la
potencia entregada por una fuente de alimentación usando funciones. Se
introduce por teclado la I y la E de la fuente.
La Potencia eléctrica entregada es P = I x E. Donde: I = Corriente de la fuente
(en amperios). E = Voltaje de la fuente (en voltios). P = Potencia entregada (en
Watios)
REQUISITOS:
1) El programa principal solamente llamará a tres funciones según se
indica en el listado de la figura.
float I,E,P;
main(void)
{ system (’’cls’’ );
explicacion_programa( );
obtener_valores( );
calcular_y_presentar(I, E);
getch(); }
43
CODIGO FUENTE ( pofuente.c)
#include <stdio.h>
float I,E,P;
main()
{
system ("cls" ); /* Borra la pantalla*/
explicacion_programa();
obtener_valores();
calcular_y_presentar(I, E); /* Toma como argumentos los valores E y I leidos
por la funcion obtener valores */
getch(); }
Archivo: engranajes. C
44
DIAGRAMA DE FLUJO ( perfecto.c)
INICIO
LLAMADA:
1 explicacion _ progr
ama(void)
1
LLAMADA:
2 obtener _ valores(v
oid) IMPRIME :
el programa calcula la
potencia generada por una
LLAMADA : fuente.
calcular_y_present una vez introducida la
3 ar ( float intensidad y tension.
I_local,float
E_local)
FIN
FIN
3
2
P=I*E
Pide el voltaje
Lee el voltaje
Pide la intensidad IMPRIME :
Lee la intensidad POTENCIA DEL
GENERADOR
FIN
FIN
OBJETIVO:
Escribir un programa que pida el consumo de los clientes (el número de Kwh) y
mediante una función calcular la facturación total y mostrarlo por pantalla.
REQUISITOS:
Escribir una función declarada como int cargo (int kwh) que reciba del programa
principal un consumo en Kwh y devuelva la correspondiente cantidad a pagar al
programa principal.
Para construit la función, suponer que se facturan los 200 primeros Kwh a 1.5
euros/Kwh, los siguientes 300 a 1euro/Kwh y los restantes a 0.5euros/Kwh..
Guardar el programa como facturación.c
RESOLUCIÓN:
#include <stdio.h>;
float tarifa1,tarifa2,tarifa3,factura;
int cargo (int kwh) { /* Funcion cargo calcula la factura
segun las distintas tarifas */
if (kwh<=200){
factura=kwh*1.5; /*si menos de 200kwh se cobra a 1.5e/kwh */
/*El importe se acumula en factura*/
}
if (kwh>200&&kwh<=500) { /* Entre 200 y 500 se cobra a 1e/kwh/*
tarifa1=200*1.5; /*El importe se va acumulando en factura*/
kwh=kwh-200;
tarifa2=kwh*1;
factura=tarifa1+tarifa2;
}
if (kwh>500) { /* Mayor de 500 se cobra a 0.5e/kwh
El importe se va acumulando en factura*/
tarifa1=200*1.5;
tarifa2=300*1;
kwh=kwh-500;
tarifa3=kwh*0.5;
factura=tarifa1+tarifa2+tarifa3;
}
return(factura);}
main() {
int kwh;
printf (" Introduzca el consumo en KWH:\t");
scanf ( "%i",&kwh);
cargo(kwh); /* Funcion cargo toma como argumento los kwh*/
printf ("\n La factura es de: %.2f euros", factura);
getch(); }
Archivo: facturacion. C
46
DIAGRAMA DE FLUJO ( facturacion.c)
INICIO
1 LLAMA A:
pago( k
wh)
MUESTRA:
la cantidad de la
factura
FIN
47
Facturacion. C (Modulo 1)
1
DEFINO :
tarifa1 ,tarifa2 ,tarifa
3 ,factura , kwh :
COMO REALES
SI
factura =kwh *1.5 kwh <=200
NO
NO
NO
RETURN
(factura )
48
EJERCICIO C ): TÍTULO: Inclusión de ficheros externos:
La directiva·#INCLUDE
OBJETIVO:
Se trata de construir un fichero externo que contenga directivas y macros, e
incluirlo en el programa principal para poder usarlas.
REQUISITOS:
Analizar y copiar el siguiente programa de nombre calculos.c
Construir una librería de nombre miscosas.h . Dicha librería deberá contener
las directivas del preprocesador, constantes y macros que consideres
necesarias para que el programa principal (cálculos.c) calcule el area de un
circulo.
Guardar ambos archivos en disco como calculos.c y miscosas.h . Compilar el
archivo calculos.c
RESOLUCIÓN:
#include "C:\Temp\miscosas.h"
main(void)
{ float r;
printf("Dame el radio del circulo");
scanf("%f",&r);
printf (" el area es %5.2f", area(r));
/* Se llama a la funcion area ,a la que se le da como
argumento r */
getch();
}
Archivo: calculos. C
CODIGO FUENTE ( miscosas.c)
/* MISCOSAS */
#include <stdio>
# Area(x) 3.14*x*x
Archivo: miscosas.h
49
DIAGRAMA DE FLUJO ( calculos.c)
INICIO
PIDE RADIO
LEE RADIO
1 MISCOSAS.H
IMPRIME :
AREA
FIN
Area= 3.14*x*x
return(Area)
50
CUESTIONES ( calculos.c)
OBJETIVO:
Dado el siguiente programa que utiliza una función recursiva.
REQUISITOS:
A.- Completarlo para que calcule, de forma recursiva, el sumatorio de todos los
números, desde el introducido en ‘n’ hasta el 1.
Guardarla como recursiva1.c.
B.- Completarlo para que calcule, de forma recursiva, el factorial del numero
introducido .
Guardarla como recursiva2.c.
PROGRAMA PROPUESTO:
#include <stdio.h>
int dato;
int func(int n);
main (void)
{ scanf("%i",&dato);
printf ("\n %i", func(dato));
getch();
}
int func (int n)
{ int s = …;
if (n!=0) s= n +………..;
return s;
}
RESOLUCIÓN:
51
CODIGO FUENTE ( recursiva1.c)
/* recursiva1*/
#include <stdio.h>
int dato;
int func(int n);
main (void)
{
printf (" Introduzca el numero del cual desea calcular la recursiva:\t");
scanf("%i",&dato);
printf ("\nLa recursiva es: \t%i", func(dato));
/* Se llama a la funcion func dandole como argumento dato */
getch();
}
int func (int n) /* La funcion func calcula el sumatorio de todos los
numeros desde el numero introducido hasta 1 */
{
int s =0;
if (n!=0) s= n + func(n-1) ;
return s;
}
Archivo: recursiva1. C
52
1
DEFINO :
n , s :
como enteros
s=0
SI
s= n + func (n-1) n 0
NO
RETURN (s)
{
printf (" Introduzca el numero del cual desea calcular el factorial:\t");
scanf("%i",&dato);
printf ("\nEl factorial es: \t%i", func(dato));
/* Se llama a la funcion func dandole como argumento dato */
getch();
}
int func (int n) /* La funcion func calcula el factorial del numero
introducido por teclado. */
{ int s =1;
if (n!=0) s= n*func(n-1) ;
return s;
}
Archivo: recursiva2.c
53
DIAGRAMA DE FLUJO ( recursiva2.c)
INICIO
PIDE UN
NUMERO( dato)
LEE EL NUMERO( dato)
1 LLAMA A:
func(dato)
IMPRIME:
el valor de la
factorial
FIN
1
DEFINO :
n , s :
como enteros
s=1
SI
s= n * func (n-1) n 0
NO
RETURN (s)
54
EJERCICIO E ): TÍTULO: Inversión cadena de caracteres
OBJETIVO:
Completar las funciones del siguiente programa que permite teclear una
cadena, obtener su longitud, e invertir dicha cadena.
REQUISITOS:
Declarar, entre otras dos variables globales, char cadena1[20], cadena2[20]
-La función para introducir la cadena se puede declarar como void
leer_cadena(void). Lee una cadena por teclado y la guarda en la variable
global cadena1.(para no tener que pasar cadenas al programa).
PROGRAMA PROPUESTO :
#include "stdio.h"
#include "conio.h"
char cadena1[20]; /* cadena original*/
char cadena2[20]; /* cadena inversa*/
void leer_cadena(void)
……………………….
int medir_cadena(void)
…………………………
void invertir_cadena(int l)
/*AL INVERTIR LA CADENA NO COPIAR EL ELEMENTO '\0' EN LA 1ª
POSICION*/
……………………………
main(void)
{ int i, L;
leer_cadena();
L=medir_cadena();
invertir_cadena(L);
printf("La longitud es %i\n",L);
printf("La cadena original es |%s| \n", cadena1);
printf("La cadena inversa es |%s| \n", cadena2);
getch(); }
55
RESOLUCIÓN:
#include <stdio.h>
#include <conio.h>
void leer_cadena(void){
printf("Introduce una cadena de caracteres: \n");
gets(cadena1);}
int i=0;
while(cadena1[i]!='\0')
i++;
return(i);}
main(){
int i,L;
leer_cadena();
L=medir_cadena();
invertir_cadena(L); /* Toma como argumento la longitud de la cadena
original */
printf("La longitud de la cadena es: %i\n",L);
printf("La cadena original es: |%s| \n",cadena1);
printf("La cadena inversa es: |%s| \n",cadena2);
getch();
Archivo: inver_cadena. C
56
DIAGRAMA DE FLUJO ( facturacion.c)
INICIO
LLAMADA A:
1 leer_ cadena()
LLAMADA A:
2 L= medir_ cadena
LLAMADA A:
3 invertircadena(L)
FIN
return()
57
2
i=0
NO
MIENTRAS :
cadena1 [i]!='\0'
SI
i= i+1
RETURN (i)
i=0
NO
DESDE : i=0
HASTA :
i< medir _ cadena
SI
i= i+1
RETURN ()
58
PRÁCTICA PROPUESTA Nº 6
OBJETIVO:
Construir un programa que, para una masa (Mo) introducida por teclado,
genere una tabla entre 0 y 5000 años, en intervalos de un siglo, donde se
visualicen los valores de los años (A), de la masa restante por desintegrar (Mr)
y de la masa perdida (Mp) en cada intervalo.
REQUISITOS:
RESOLUCIÓN:
59
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define K 5700
main()
potencia=A/K;
Mr=M0*pow(0.5,potencia);
Mp=M0-Mr;
printf("\t%.2f\t%.2f\t%.2f\n",A,Mr,Mp);
getch();
getch();
Archivo: desintegracion1. C
Archivo: desintegracion1. C
60
DIAGRAMA DE FLUJO ( desintegracion1.c)
INICIO
IMPRIME : encabezamiento
de la tabla : Años , Mr, Mp
DESDE : A=0 NO
HASTA :
A<=5000
SI
potencia =A/K;
Mr= M0*pow(0.5, potencia );
Mp = M0 -Mr;
IMPRIME :
A , Mr , Mp
FIN
61
CODIGO FUENTE ( desintegracion3.c)
#include <stdio.h>
#include <math.h>
#include <conio.h>
#define K 5700
float Mr,potencia;
potencia= t/K;
Mr= m*pow(0.5,potencia);
return(Mr);
}
main(){
float A,Mo,Mp,Mr;
getch();
}
Archivo: desintegracion2. C
62
DIAGRAMA DE FLUJO ( desintegracion2.c)
INICIO
SI
1 LLAMA A:
funcion_MR(Mo,A);
Mp =Mo-Mr
IMPRIME :
A,Mr,Mp
FIN
63
1
DEFINO:
Mr , potencia :
real
potencia = t/K;
Mr= m*pow(0.5, potencia);
RETURN(Mr)
#include <stdio.h>
#include <math.h>
#include <conio.h>
#define K 5700
float Mr,potencia;
potencia= *t/K;
Mr= *m*pow(0.5,potencia);
return(Mr);
}
main(){
float A,Mo,Mp,Mr;
64
printf(" Masa original del elemento:\t");
scanf("%f",&Mo);
printf("\tAnos\t \t Mr\t \t Mp\n");
printf("\t_________________________________________________\n");
for(A=0;A<=5000;A=A+100)
{
Mr=funcion3(&Mo,&A);
Mp=Mo-Mr;
printf("\t%4.2f \t\t%4.2f \t\t %4.2f\t\n",A,Mr,Mp);
getch();
}
Archivo: desintegracion3. C
INICIO
SI
1 LLAMA A:
funcion3 (&Mo,&A);
Mp =Mo-Mr
IMPRIME :
A,Mr, Mp
FIN
65
1
DEFINO:
Mr , potencia :
real
potencia = *t/K;
Mr= *m*pow(0.5,potencia );
RETURN(Mr)
CUESTIONES ( calculos.c)
66
EJERCICIO B ): TÍTULO: Seguir la traza de operaciones con
Punteros
OBJETIVO:
Dado el siguiente programa, analizarlo, ejecutarlo, y rellenar en la memoria
una tabla similar a la adjunta con la traza (evolución) y los valores finales de
las variables ‘a’, ‘b’, ’*pa’, ‘*pb’ (cuando se conozcan). Los valores de las
cuatro variables deben indicarse inmediatamente después de ejecutarse las
instrucciones señaladas como (1),(2),(3),(4),(5), (6) en el listado.
No es imprescindible poner un printf en cada línea para saber los valores
intermedios.
Guardarlo como traza.c .
RESOLUCIÓN:
# include <stdio.h>
*pb = b + 2;
*pa = a*3;
pa = pb;
*pa = 2 * b;
printf("%i %i %i %i",a,b,*pa,*pb);
getch();
Archivo: traza. C
.a 3
*pa ----- 1 24
.b 24
67
*pb ----- 24
OBJETIVO:
El objetivo de este apartado es familiarizar al alumno con el paso de matrices a
funciones. El primer programa pasa un vector. El segundo pasa una matriz. La
función simplemente debe escribir el vector o la matriz en pantalla.
REQUISITOS:
a.- Observar la declaración y la llamada, y completar la función que aparece en
el programa Pruba
RESOLUCIÓN:
#include <stdio.h>
#include <conio.h>
printf ("%i\t",*(V+i));
}
main( )
{ escribir(matriz, 6);
getch(); }
Archivo: paso_vector. C
68
CODIGO FUENTE ( paso_matriz.c)
#include <stdio.h>
#include <conio.h>
{ int filas,columnas;
printf("La matriz es:");
for(filas=0;filas<Nf;filas++){
printf("\n");
for(columnas=0; columnas<Nc; columnas++){
printf("%i " ,matriz[filas][columnas]);
}
}
}
main( )
{ escribir(matriz,2,3);
getch(); }
Archivo: paso_vector. C
1 2 3
4 5 6
69
EJERCICIO C ): TÍTULO: Ordenación de números enteros
OBJETIVO:
Se desea ordenar de forma ascendente un conjunto de números enteros. Para
ello se ha escrito el siguiente programa en C, mostrado en las siguientes dos
columnas que utiliza cuatro funciones y que se deberá completar.
REQUISITOS:
Complete en el lenguaje de programación C, las partes que faltan en los puntos
a, b, c, d, esiguiendo
las siguientes especificaciones:
b) Añadir las instrucciones necesarias para que la función lee pueda leer los
elementos del vector.
RESOLUCIÓN:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h> /* Librería necesaria para usar la funcion malloc*/
/* La funcion malloc realiza una reserva dinamica de la memoria */
70
/* Función que imprime los valores de las posiciones del vector */
printf("\n");
for(i=0; i<tamano; i++)
printf("\na[%d]:%d ",i,a[i]);
}
aux=*x;
*x=*y;
*y=aux;
}
/* función Burbuja */
intercambio(&a[i],&a[j]);
}
main()
{
int *valores;
int tamano;
int j;
71
/* la función malloc reserva memoria */
lee(valores,tamano);
printf("\n\nLos valores desordenados son: ");
imprima(valores,tamano);
burbuja(valores,tamano);
printf("\n\nLos valores ordenados de forma ascendente son: ");
imprima(valores,tamano);
getch();
}
Archivo: ordenacion. C
72
PRÁCTICA PROPUESTA Nº 7
OBJETIVO:
El objetivo es familiarizarse con el manejo de matrices y punteros.
En el siguiente programa aparece un array unidimensional (datos) y una
funcion (cuadrado) que modifica el array.
REQUISITOS:
Probar y analizar el programa. Modificarlo creando una variante de la función
declarada como void cuadrado(int *p, int N). Es decir la función recibirá ahora
los mismos datos, pero a través del puntero a enteros (p). Deberá hacer lo
mismo pero utilizando notación de punteros {*(p+i) }.
Guardar el programa como cuadrado_vector.c
RESOLUCIÓN:
#include<stdio.h>
#include<math.h>
int datos[]={0,1,2,3,4,5,6,7};
void cuadrado (int V[],int N);
main (void)
{
int i,j;
/*llamada a la función*/
/*construccion de la funcion*/
int i;
for (i=0;i<N;i++)
V[i]=pow(V[i],2);
}
Archivo: cuadrado_vector. C
73
CUESTIONES ( cuadrado_vector.c)
Si ,los dos son arrays de vectores, solo que el vector unidimensional sol tiene
una dimensión ,mientras que el array bidimensional es un array bidimensional
es un array que contiene dos vectores unidimensionales.
OBJETIVO:
El programa adjunto calcula las potencias primera, segunda, tercera y cuarta
de los números del 1 al 10.
Funciona de la forma siguiente: Se genera primero un exponente n, y se llama
a la función crear tabla().
La función genera 10 enteros, los eleva al exponente indicado, y los guarda en
un vector V.
Cada vez que genera un vector, la función mostrar_tabla( ) visualiza el vector
en una línea de pantalla:
El programa tiene además la peculiaridad de que se reserva memoria para 10
elementos de forma dinámica (int *p), pero en las funciones se trabaja con
notación de matrices.
SE PIDE:
Respetando la estructura del programa completar la funcion mostrar_tabla( )
para que muestre la tabla de potencias guardada en V. Guardar el programa en
el fichero potencias_vector.c .
RESOLUCIÓN:
74
CODIGO FUENTE (potencias_vector.c)
/* potencias vector */
#include “stdio.h"
#include "stdlib.h"
/* programa principal */
main()
{
int n;
int *p; /* definimos un puntero */
p=malloc(10*sizeof(int)); /* reservamos espacio para 10 elementos (reserva
dinámica) */
system("cls");
for (n=1; n<5;n++) /* generamos cuatro esponentes posibles */
{
crear_tabla(p,n); /* llamamos a las funciones */
mostrar_tabla(p); /* con el puntero p obligamos a la función a usar la
zona de memoria reservada */
}
getch();
}
{
int j;
for(j=1; j<11; j++)
v[j]= pow(j,i);
}
75
/* Construimos una funcion para mostrar la lista de potencias guardada en V.
Utilizamos p a través del array V */
{
int j;
for(j=1;j<11;j++)
printf("%i ",v[j]);
printf("\n");
Archivo: potencias_vector. C
CUESTIONES ( potencias_vector.c)
El valor obtenido es 10* 4 bytes que ocupa una variable tipo int en el
compilador Dev-C++, es decir , 40 bytes.
76
EJERCICIO C ): TÍTULO: Comprobar si un numero es
Capicúa usando funciones
OBJETIVO:
Se desea escribir un programa en C que lea un número entero y determine si
es o no capicúa (sus cifras leídas de izquierda a derecha coinciden con sus
cifras leídas de derecha a izquierda).
Así el número 1221 es capicúa pero 122 no lo es.
REQUISITOS:
Complete las partes –a- , -b- , -c- y –d- del programa mostrado a continuación
del siguiente modo:
c) Añadir el código necesario para construir la función que extrae los dígitos a
partir del número. Para extraer los dígitos de una cifra se sugiere utilizar un
algoritmo similar al usado para dividir una cantidad de euros en monedas,
utilizando los operadores división entera (/) y resto (%), con un for decreciente.
Por ejemplo, para el número 123, sería: vector[0] = 123 % 10 =1, vector[1] = 12
%10 =2 …
RESOLUCIÓN:
#include<stdio.h>
#include<stdlib.h>
/* DECLARACION DE FUNCIONES */
77
main()
{
int numero;
int *vector;
int tamano;
printf("Numero: ");
scanf("%d", &numero);
tamano = ncifras(numero);
vector = malloc(tamano*sizeof(int)); /*…….. Parte –aconstruya_*/
construya_vector(vector, tamano, numero);
if (capicua(vector, tamano))
printf("El numero es capicua\n");
else
printf("El numero no es capicua\n");
getch();
}
/* DEFINICION DE FUNCIONES */
int ncifras(int n)
{ int nuevo=n, contador=0;
do
{ contador++;
nuevo=nuevo/10;
}
while(nuevo>=1);
printf("%d cifras\n",contador);
return contador;
}
78
/*{ ………… Parte –c- }*/
int capicua(int a[], int n)
{ int i;
for (i=n/2;i=0;i--)
{
if (a[i]== a[n-1-i])
return(1);
else
return(0);
}
}
Archivo: capicua. C
OBJETIVO:
Escribir un programa que lea una línea de texto, cuente el número de vocales
que tiene la línea y lo muestre por pantalla.
REQUISITOS:
Una forma de almacenar un texto consiste en partir de un puntero a carácter en
lugar de un vector de caracteres. Ese puntero, que en el programa se
denomina línea guarda el texto que el usuario haya introduciendo por teclado.
La línea (así se denominará en el programa) funcionará como un vector con la
ventaja de que tendrá sólo la longitud necesaria en cada ejecución, sin que se
desperdicie espacio de memoria. Para ello se utilizará la función malloc()
para reservar un nº de caracteres variables en cada caso (L en el listado). El
número de vocales que contiene la línea se calculará mediante una función, en
la que mediante una estructura case comparará cada posición p[i] con cada
vocal y incrementará un contador que se devolverá al programa principal.
SE PIDE:
Completar el programa y la función.
Guardar el programa en el fichero con el nombre de vocales.c.
79
RESOLUCIÓN:
#include <stdio.h>
#include <string.h>
#include <conio.h>
main()
{
char *linea;
int L,vocales;
printf("\n numero de letras: ");
scanf("%d",&L);
printf ("Introduzca la secuencia de letras:\n");
linea=malloc(L*sizeof(char)); /*reserve dinamica*/
scanf("%s",linea);
vocales = cuenta(linea, L);
printf ("La linea contiene %d vocales. \n", vocales);
getch();
}
}
}
return(vocales);
}
Archivo: vocales. C
80
EJERCICIO E ): TÍTULO: Paso de parámetros a main desde l
la línea de comandos
OBJETIVO:
En ANSI C se pueden pasar parámetros desde la línea de comandos del
sistema operativo a la función principal del programa (main). Esto es lo que
hacemos cuando ejecutamos un comando del antiguo MS-DOS, por ejemplo >
DIR A: /W
main esta preparada para recibir parámetros, pues esta declarada como main
(int argc, char *argv[ ]). Los parámetros que se deben utilizar son: a) argc
(variable entera que maneja el compilador y que cuenta el número de
parámetros especificado en la línea de comandos, considerando el nombre del
programa como el primer parámetro b) argv (tabla de punteros a cadenas)
donde se copian los parámetros tecleados. En el ejemplo citado argc guardaría
un 3. El nombre del programa “DIR”, se guarda en argv[0] , la cadena “A:” en
argv[1] y la cadena “ / W” en argv[1].
REQUISITOS:
1º.- El programa deberá visualizar por pantalla un mensaje de error en el caso
de que el usuario introduzca por error más o menos parámetros de los
necesarios: Con mas de 2 parámetros, (“Hay demasiados parámetros”).
Cuando falta el valor del lado del cuadrado o sea menos de 2 parámetros,
(“Falta el valor del lado del cuadrado”).
2º.- Se utilizaran las variables lado y area de tipo double para almacenar los
datos del lado del cuadrado y de su área.
81
RESOLUCIÓN:
#include <stdio.h>
#include <stdlib.h>
double area,lado;
{
if(argc>2)
printf("Hay demasiados parametros");
if(argc<2)
printf("Falta el valor del lado del cuadrado");
if(argc==2)
lado=atof(argv[1]);
/* Funcion que convierte una cadena de caracteres a un
valor numerico */
area=lado*lado;
printf("El area del cuadrado es %.2f",area);
getch();
Archivo: prueba. C
82
PRÁCTICA PROPUESTA Nº 8
OBJETIVO:
Una empresa necesita un programa para llevar el control del mantenimiento de
ASCENSORES. Para ello se utiliza un conjunto de estructuras anidadas donde
se almacenan la dirección de cada ascensor y los datos de las dos revisiones
que se efectúan anualmente (una por semestre).
Los campos de la estructura son los siguientes:
SE PIDE:
a) Copiar y Analizar el listado adjunto
c) Añadirle una función con un bucle para imprimir solo los datos generales
(codigo, calle y numero), de los 3 primeros ascensores almacenados en el
fichero.
d) Añadirle una función con un doble bucle para imprimir los datos generales
(codigo, calle y numero) de los 3 primeros ascensores, y para cada uno de
ellos, sólo el campo defecto de las dos revisiones.
83
RESOLUCIÓN:
# include <conio.h>
# include <stdio.h>
void leer(void);
void listado (void) ;
struct datos_revisiones
{ unsigned char DIA;
unsigned char MES;
unsigned char ANO;
char DEFECTO[20];
};
struct datos_ascensores
{ unsigned int CODIGO;
char CALLE[20];
unsigned int NUMERO;
struct datos_revisiones REVISIONES[2];
};
struct datos_ascensores TABLA[100];
main(void)
{
leer( );
listado();
getch();
}
void leer (void)
{ int na , nr; /*indices de los bucles: numero ascensores y numero revisiones */
for (na =0;na<3;na++)
{ printf ( "\n Introducir Datos del ascensor %i (Codigo,Calle,Numero) \n",na+1);
scanf(" \n %u",&TABLA[na].CODIGO);
scanf("\n %s", &TABLA[na].CALLE);
scanf("\n %u",&TABLA[na].NUMERO);
for (nr =0; nr<2; nr++)
{ printf("\n \t Introducir Datos de revision %i (dd,nn,aa,defecto) \n",nr+1);
scanf("\n %u",&TABLA[na].REVISIONES[nr].DIA);
scanf("\n %u",&TABLA[na].REVISIONES[nr].MES);
scanf("\n %u",&TABLA[na].REVISIONES[nr].ANO);
scanf("\n %s",&TABLA[na].REVISIONES[nr].DEFECTO);
}}}
void listado (void)
84
void listado (void)
{
{ int na , nr;
/*indices de los bucles: numero ascensores y numero revisiones */
for (na =0;na<31;na++)
{ printf ( "\n Los Datos del ascensor son %li (Codigo,Calle,Numero) \n",na+1);
printf(" \n %u",TABLA[na].CODIGO);
printf("\n %s", TABLA[na].CALLE);
printf("\n %u",TABLA[na].NUMERO);
for (nr =0; nr<2; nr++)
{
printf (" \nEl defecto en la revision %i es",nr+1);
printf("\n %s",TABLA[na].REVISIONES[nr].DEFECTO);
}}}}
Archivo: fichero_ascensores. C
OBJETIVO:
Se pretende implementar un sencillo programa de gestión de ventas de un
concesionario de automóviles.
La información se guarda en la siguiente estructura.
SE PIDE:
1º ) Construir la estructura.
2º) Escribir un primer programa que lea por teclado los datos de 3 vendedores
así como el número coches vendidos por cada vendedor durante cada uno de
los 4 trimestres del año. Para ello se necesitan dos bucles
anidados.
3º ).Copiar el modulo anterior y modificarlo para que se puedan listar a
continuación las 5 fichas de vendedores, y las ventas de cada uno en los 4
trimestres, por pantalla.
Guardar el programa como gestionventas1.c
ACLARACIONES:
Es deseable poder introducir apellidos compuestos. Para ello funciona mejor
gets que scanf.
85
RESOLUCIÓN:
#include <stdio.h>
#include <conio.h>
void leer(void);
void escribir(void);
struct reg_vendedor{
char nombre[20];
char apellidos[40];
int sueldo;
int ventas[4];};
struct reg_vendedor vendedores[5];
main(){
leer();
escribir();
getch();
}
void leer(void){
int i,j;
for(i=0;i<5;i++){
printf("Introduce los datos del vendeor %i
(nombre,apellidos,sueldo)\n",i+1);
scanf("%s",vendedores[i].nombre);
scanf("%s",vendedores[i].apellidos);
scanf("%i",&vendedores[i].sueldo);
for(j=0;j<4;j++){
printf("Introduce las ventas del trimestre %i\n",j+1);
scanf("%i",&vendedores[i].ventas[j]);
}}}
void escribir(void){
int i,j;
for(i=0;i<5;i++){
printf("Nombre:\n");
printf("%s\n",vendedores[i].nombre);
printf("Apellidos:\n");
printf("%s\n",vendedores[i].apellidos);
printf("Sueldo:\n");
printf("%i\n",vendedores[i].sueldo);
for(j=0;j<4;j++){
printf("Las ventas del trimestre %i\n",j+1);
printf("%i\n",vendedores[i].ventas[j]);
}}}
86
EJERCICIO C ): TÍTULO: Gestión de un fichero en disco
OBJETIVO:
Modificar el programa anterior de forma que mediante un menú de opciones se
pueda escoger entre las cinco posibilidades siguientes: 1) Cargar fichas por
teclado. 2) Visualizar las fichas 3) Grabar fichas en disco
4) Recuperar fichas del disco 5) Salir
REQUISITOS:
El programa se reordenará de la siguiente forma:
1.- En el programa principal main() seguirá la secuencia siguiente:
Escribir un menú con las cinco opciones citadas:
Leer la variable char opcion con getchar() o similar.
Construir una estructura case que decida en función de la variable opción
2.- Los dos módulos ya construidos en el programa anterior pasarán a ser dos
funciones definidas tal como void altas(void) y void listar (void).
3.- Se construirán dos nuevas funciones void grabar (void) , para grabar las 5
fichas en disco y void recuperar(void) para recuperar 5 fichas del disco.
87
RESOLUCIÓN:
#include <stdio.h>
#include <conio.h>
void altas(void);
void listado(void);
void grabar(void);
void recuperar(void);
struct reg_vendedor{
char nombre[20];
char apellidos[40];
int sueldo;
int ventas[4];};
struct reg_vendedor vendedores[5];
int opcion;
main(){
do{
printf("¿Que quieres hacer?:\n");
printf("\t 1)-Introducir datos\n");
printf("\t 2)-Presentar datos\n");
printf("\t 3)-Grabar datos a disco\n");
printf("\t 4)-Recuperar datos del disco\n");
printf("\t 5)-Salir del programa\n");
scanf("%i",&opcion);
switch(opcion){
case 1 :altas(); break;
case 2 :listado(); break;
case 3 :grabar(); break;
case 4 :recuperar(); break;
default: break;}
}while(opcion!=5);
getch();
}
void altas(void){
int i,j;
for(i=0;i<5;i++){
printf("Introduce los datos del vendeor %i
(nombre,apellidos,sueldo)\n",i+1);
scanf("%s",vendedores[i].nombre);
scanf("%s",vendedores[i].apellidos);
scanf("%i",&vendedores[i].sueldo);
for(j=0;j<4;j++){
printf("Introduce las ventas del trimestre
%i\n",j+1);
scanf("%i",&vendedores[i].ventas[j]);
}}}
88
void listado(void){
int i,j;
for(i=0;i<5;i++){
printf("%s\n",vendedores[i].nombre);
printf("%s\n",vendedores[i].apellidos);
printf("%i\n",vendedores[i].sueldo);
for(j=0;j<4;j++){
printf("Las ventas del trimestre %i\n",j+1);
printf("%i\n",vendedores[i].ventas[j]);
}}}
void grabar(void){
int i;
FILE *f;
f=fopen("c:\temp\datos.dat","w");
for(i=0;i<5;i++){
fwrite(vendedores,sizeof(vendedores),1,f);}
fclose(f);}
void recuperar(void){
int i;
FILE *f;
f=fopen("c:\temp\datos.dat","r");
for(i=0;i<5;i++){
fread(&vendedores[i],sizeof(vendedores[i]),1,f);
printf("%s",vendedores[i].nombre);
printf("%s",vendedores[i].apellidos);
printf("%i",vendedores[i].sueldo);}
fclose(f);}
Archivo: gestionventas2. C
OBJETIVO:
El programa de la página siguiente, crea un tipo estructurado (stack) y una
variable (pila) muy simple. Luego pretende apilar enteros de 0 hasta N-1 en la
pila. A continuación desapilarlos de N-1 hasta 0. Pero al programa le faltan las
funciones que realizan la tarea de apilar o desapilar en la posición adecuada, y
el número de elementos que se deben de almacenar.
UTILIDAD
Para programar a “bajo nivel” un Sistema de Adquisición de datos o un
Autómata Programable se debe de programar las llamadas a subrutinas. Desde
el programa principal se llama a una subrutina y cuando se ejecuta se precisa
almacenar valores de datos contenidos en registros de la CPU (como mínimo
Contador de Programa, Acumulador y Status) con el fin de que a la vuelta del
89
programa principal se reanude la ejecución en las mismas condiciones
existentes que en el momento de producirse el salto a la subrutina. Estos
valores se almacenan en una zona de memoria RAM denominada Pila o Stack.
En dicha zona de memoria se pueden almacenar todos los valores anteriores
(Contadores de programa, Acumulador, Status)
FUNCIONAMIENTO
Una pila (stack) es una estructura de datos en la que el modo de acceso a sus
elementos sigue un criterio LIFO (Last In First Out), es decir, el último elemento
insertado en la pila es el primero que se recupera. La estructura pila almacena
un conjunto de elementos del mismo tipo, donde la cima de la pila apunta a la
dirección del último elemento insertado en la pila.
La forma más simple de implementar una pila es, mediante un vector (V[i])
para guardar los elementos y una variable (cima) para conocer la posición del
último elemento. Sobre la pila se deben definir tres operaciones básicas:
inicializar , push (apilar) y pop (desapilar) que .manipulan los elementos de la
forma siguiente:
1.- Inicializar pila:
La variable cima debe apuntar al elemento o casilla 0, para meter nuevos datos
desde la base.
SE PIDE:
a) Implementar la sentencia para poder almacenar 10 elementos. ¿Habría otra
forma de implementarla?
b) Indicar para cada una de las funciones inicializar_pila( ), push( ), pop( ), cuyo
prototipo se ve en el listado.
b1) De qué tipo son los parámetros que recibe cada una (strings, punteros a
float, etc.).
b2) Con que método se realiza el paso de dichos parámetros (valor, etc)
b3) Justificar por qué en las llamadas a la funciones push() y pop() la variable
item aparece dentro y fuera respectivamente.
c) Completar la función push( ), que permite añadir un elemento en la pila, e
incrementar el campo cima, según se ha explicado anteriormente. Además la
función deberá evitar que se produzca un error por apilar mas elementos de los
previstos, controlando el valor del campo cima.
d) Completar la función pop() que permita recuperar un elemento de la pila
según se ha explicado anteriormente. Además la función deberá evitar que se
produzca un error por desapilar mas elementos de los existentes, controlando
el valor del campo cima.
Guardar el programa como stack1.c.
90
e) Construir una variante de las funciones push() que trabaje ahora con paso
de parámetros por valor.
Indicar también como quedaría la llamada al la función.
Guardar el programa como stack2.c.
RESOLUCIÓN:
int main( )
{ /* Variables locales*/
int i;
int item;
/* MODULO PARA APILAR (PUSH) */
pila.cima = 0; /* Para comenzar a apilar inicializamos cima a la 1º
posición */
for (i=0;i< N;i++)
{ item=i;
push(&pila, item);
printf(" Push (apilando) el elemento %d \n",item);
};
/* MODULO PARA DESAPILAR (POP) */
pila.cima = N-1; /* Para comenzar a desapilar inicializamos cima a la
ultima posición */
for (i=0;i<N;i++){
item = pop(&pila);
printf(" Pop (desapilando) el elemento %d \n",item);
};
getch();}
91
/* APILAR. EN LAS FUNCIONES P ES UN PUNTEROA ESTRUCTURA */
void push(struct stack *p, int elemento)
{ p->V[p->cima] = elemento;
p->cima++;
}
/* DESAPILAR. EN LAS FUNCIONES P ES UN PUNTEROA
ESTRUCTURA */
int pop(struct stack *p)
{ int elemento;
elemento = p->V[p->cima];
p->cima--;
return elemento;
}
Archivo: stack1. C
#include <stdio.h>
#include <stdlib.h>
#define N 10
/* ESTRUCTURA PILA */
struct stack
{ int V[N];
int cima;
};
/* VARIABLE GLOBAL PILA. AQUI ES UNA ESTRUCTURA*/
struct stack pila;
/* PROTOTIPOS DE FUNCIONES PARA APILAR Y DESAPILAR */
void push(struct stack dato, int elemento);
int pop(struct stack dato);
int main( )
{ /* Variables locales*/
int i;
int item;
/* MODULO PARA APILAR (PUSH) */
pila.cima = 0; /* Para comenzar a apilar inicializamos cima a la 1º
posición */
for (i=0;i< N;i++)
{ item=i;
push(pila, item);
printf(" Push (apilando) el elemento %d \n",item);
};
92
/* MODULO PARA DESAPILAR (POP) */
pila.cima = N-1; /* Para comenzar a desapilar inicializamos cima a la
ultima posición */
for (i=0;i<N;i++){
item = pop(pila);
printf(" Pop (desapilando) el elemento %d \n",item);
};
getch();
}
}
/* DESAPILAR. EN LAS FUNCIONES P ES UN PUNTEROA
ESTRUCTURA */
int pop(struct stack dato)
{ int elemento;
elemento = dato.V[dato.cima];
dato.cima--;
return (elemento);
}
Archivo: stack2 . C
OBJETIVO:
Vamos a simular el control de la Tª de un local mediante un PC con una tarjeta
de adquisición. Para ello usaremos la librería <simulacion.h>, que contiene las
siguientes funciones: medir_temp.( ), que devuelve la Tª simulada del local,
calentar( ) que simula el arranque de un calefactor, enfriar( ), que simula
el arranque de un refrigerador, y apagar_calentar( ) y apagar_enfriar( ), que
permiten apagar cualquiera de ellos.
REQUISITOS:
Vamos a simular el control de la Tª de un local mediante un PC con una tarjeta
de adquisición. Para
ello usaremos la librería <simulacion.h>, que contiene las siguientes funciones:
medir_temp.( ), que
devuelve la Tª simulada del local, calentar( ) que simula el arranque de un
calefactor, enfriar( ), que simula
93
el arranque de un refrigerador, y apagar_calentar( ) y apagar_enfriar( ), que
permiten apagar cualquiera de
ellos.
SE PIDE:
Construir un programa en C que permita:
Cargar por teclado la Tª deseada o de consigna [Tc], y el margen de
fluctuación admisible en dicha Tª.[M]
Construir un bucle infinito para repetir el proceso de medida y control [ej: .while
(1)]
Medir la temperatura del local [T=medir_Temp.()] e imprimirla en pantalla
Cuando la temperatura medida sobrepasa Tc+M , arrancar el proceso de
enfriar
Cuando la temperatura medida no alcanza Tc-M arrancar el proceso de
calentar
Cuando la temperatura medida sea > = que Tc, parar de calentar
Cuando la temperatura medida sea < = que Tc, parar de enfriar
Fin bucle.
Guardar el programa como control_temperatura.c.
RESOLUCIÓN:
#include <stdio.h>
#include "simulacion.h"
int Tc,M,T;
main(void){
printf("Introduce la temperatura deseada\n");
scanf("%i",&Tc);
printf("Introduce la fluctuacion maxima deseada\n");
scanf("%i",&M);
while(1){
T=medir_temp();
printf("\n La temperatura del local es %i ",T);
if(T>(Tc+M)){enfriar();}
if(T<(Tc-M)){calentar();}
if(T>=Tc && T<=(Tc+M)){apagar_calentar();}
if(T<=Tc && T>=(Tc-M)){apagar_enfriar();}
}
getch();
}
Archivo: control_temperatura. C
94
95