Está en la página 1de 95

 

MEMORIAS DE LAS 
PRACTICAS DE 
PROGAMACION 
INDUSTRIAL 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Índice

Práctica 1 ………………………………págs. 1-11

Tutorial………….págs. 7

Corrección de errores……….págs. 7

Mapa de memoria……………págs. 8-9

Tipos de datos………………..págs. 10-11

Práctica 2 …………………………………págs. 12-21

Área del triángulo(macro)……..págs. 12-14

División………………………….págs. 14-16

Tipos……………………págs. 16-18

Precisión……………..págs. 19-21

Práctica 3 ………………………………..págs. 22-30

Millas…………págs.22-24

Cambio de base ………….págs. 22-27

Nif ………………….págs. 28-29

Navegador………..págs. 29-30

Práctca 4 ………………………………….págs. 31-43

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

Práctica 5 ………………………………..págs. 44-59

Pofuente……….págs. 44-46

Facturación………….págs. 47-49

Calculos………………págs. 50-52

 
 

Recursiva………………págs. 52-55

Inver_cadena………….págs. 56-59

Práctica 6 ………………………………… págs. 60-73

Desintegración………págs. 60-67

Traza……………págs. 68-70

Paso_vector y Paso_matriz……….págs. 71-73

Práctica 7 ………………………………… págs. 74-83

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

Práctica 8 …………………………………págs. 84-86

Ascensores………………..págs. 86-87

Gestión ventas………………..págs. 88-90

Gestión ventas 2……………págs. 90-94

Stack……………………..págs. 94-95

Control de la tª……………págs. 132-140

 
 

 
 

PRÁCTICA Nº 1 : INTRODUCCIÓN AL COMPILADOR “Dev-C++”

OBJETIVO GENERAL:

Se trata de “FAMILIARIZARSE” con el manejo del “COMPILADOR DEV-


C++” disponible en el laboratorio y realizar los primeros programas.
El alumno deberá escribir, probar, depurar, y guardar los ejemplos que a
continuación se relacionan:

EJERCICIO A): TÍTULO: Tutorial auto aprendizaje manejo compilador


Dev C++.
OBJETIVO:
Se trata de que el alumno por medio de un tutorial on-line sigua por sus propios
medios el aprendizaje on line del manejo del Compilador DevC++.
Para ello conectarse con la facultad virtual de la U.D.C. en la Asignatura
de Programación Industrial (Electricidad) y dentro del bloque “Contenidos”
“Material Autoevaluación”, arrancar y seguir el video llamado
“Edicion_Programa_C.wmv”, para a continuación codificar y guardar el
programa que se propone.

 EJERCICIO B) : TÍTULO: Corrección de errores

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();

RESOLUCIÓN: CODIGO FUENTE (CORRECTO)

#include <stdio.h>

main( )
{ int numero;
numero = 2;
printf( "El valor es % i" ,numero );
getch();
}  Archivo: 1_errores.c

 
 

 EJERCICIO C) :TÍTULO: Estudiar el mapa de memoria.

OBJETIVO: Intentar estudiar el mapa de memoria de dos variables enteras.

REQUISITOS: Editar el siguiente programa:

#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

El programa se guardará en un archivo denominado memoria.c.

DIAGRAMA DE FLUJO: Memoria.c

Inicio

a , b:  Enteros 

a=0;
b=a+8; 

La  dirección de a: &a


La dirección  de b: &b 

Fin

   
 
 

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

Hemos definido dos enteros a y b (son de 4 bytes en Dev-C++). Veamos la


distribución de memoria:

3219265156 00101111 01101001 10101001 00101111


3219265152 00101111 00100000 00101111 00101111 a
3219265148 00101111 00000000 11101111 00101111 b
3219265144 00101111 00101100 00101111 00101111

En el momento en que hacemos a=0 lo que decimos es que asigne 0 a las


posiciones de memoria reservadas a la variable ‘a’. Como ‘a’ es un entero los 4
bytes quedaran de esta forma:

3219265156 00101111 01101001 10101001 00101111


3219265152 00000000 00000000 00000000 00000000 a
3219265148 00101111 00000000 11101111 00101111 b
3219265144 00101111 00101100 00101111 00101111

A continuación el programa asigna b=a+8. Es decir, lo que hay en las


posiciones de memoria de “a” le sumas 8 y lo guardas en las posiciones de
memoria reservadas a “b”.

El mapa de memoria quedaría ahora de la siguiente forma:

3219265156 00101111 01101001 10101001 00101111


3219265152 00000000 00000000 00000000 00000000 a
3219265148 00001000 00001000 00001000 00001000 b
3219265144 00101111 00101100 00101111 00101111

 
 

 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.

DIAGRAMA DE FLUJO: 1_desbordamiento. c .

Inicio

a , b:  Enteros 
c,d: Caracteres

a=2147483647; 
b=a+a;
c=127;
d=c+c;

a.
b. 
d. 

Fin 

 
 

RESOLUCIÓN:

La salida obtenida por pantalla es la siguiente:

 2147483647
 -2
 -2

El motive de que en la primera salida salga el numero 2147483647 es debido


a que este numero es almacenado en una variable tipo entera de 4 bytes cuyo
rango máximo es precisamente este numero, y por tanto sale por pantalla de
forma correcta.

La segunda salida es incorrrecta, ya que a una variable de 4 bytes entera se le


suma una vez mas su rango máximo y provoca un desbordamiento binario,
debido a esto, de los 32bits disponibles para almacenar, uno se rserva para el
signo, pues ocurre que el bit de signo positivo, que es cero, es acarreado y con
vertido en uno(numero negativo); de tal forma que el numero resultante en
binario para la variable “b” seria : 1… … 11111111111111110 , y esto en
complemento a dos es el numero decimal -2.

La tercera salida también es incorrecta debido al mismo motivo, solo que en


este caso al ser tipo char, solo ocupa 1 byte, pero el desbordamiento es
exactamente igual ,solo que con 8 bits, de ay que de el mismo resultado, -2.

 
 
10 
PRÁCTICA PROPUESTA Nº 2

 EJERCICIO A): TÍTULO: Área de un triangulo mediante


macro

OBJETIVO: Se trata de escribir una macro que calcule el área de un triángulo.

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:

 CODIGO FUENTE ( macro.c)

/* Macro de área de un triangulo */


#include<stdio.h>
#define AREA(x,y) ((x)*(y)/2) /* Macro de sustitución AREA triangulo*/
main()
{
float a, b;
printf( "Introduzca el valor de la base: \n");
scanf( "%f", &a);
printf( "Introduzca el valor de la altura: \n" );
scanf( "%f", &b);
printf( "El resultado con precisión de centésimas es: %.2f \n" , AREA(a,b));
/* La macro AREA toma como argumentos los valores “a” y ”b” */
getch();
}

Archivo: macro. c

 DIAGRAMA DE FLUJO ( macro.c)

 
 
11 
INICIO

Introducir : base
Leer : base
Introducir : altura
leer: altura

Llamada a : 
1 AREA(B .A)

IMPRIMIR AREA 

FIN 

Diagrama flujo : macro. c

INICIO

Calcular  :
AREA =((X)*(Y))

RETURN (AREA) 

Diagrama flujo bloque 1 : macro. c

 
 
12 
 CUESTIONES ( macro.c)

Explicar cuál es el/los errores de las tres soluciones para la macro


propuestas a continuación:

a) AREA(x y) b*a/2 b) AREA(x y) x*y/2 c) AREA(x, y) = (x*y)/2

Solución a) : Los errores son :


 Debería llevar una coma entre la “x” y la “y”
 La expresión b*a/2 debería ir entre
paréntesis.

Solución b) : Los errores son :


 Debería llevar una coma entre la “x” y la “y”
 La expresión x*y/2 debería ir entre
paréntesis.

Solución c) : Los errores son :


 La expresión (x*y)/2 debería ir entre
paréntesis.

 EJERCICIO B ): TÍTULO: División entera y en punto flotante

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.

Se adjunta la codificación parcial de este programa.


El alumno deberá completarla El programa se deberá guardar con el nombre
division.c :

 
 
13 
/* fichero division.c */

# include <stdio.h>

void main (void)

{ 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”,...........);

getch();}  Archivo: division. C


(incompleto)

RESOLUCIÓN:

 CODIGO FUENTE COMPLETO ( division.c)

/* 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);

/* El operador " %" ,llamado modulo, devuelve


el resto de la división entera */
getch();
}
Archivo: division. C

 DIAGRAMA DE FLUJO ( division.c)

 
 
14 
INICIO

Borrar  pantalla : 
system (" cls") 

division  entera  5/4  es  : 1 


division  entera 6/3 es :2
division  entera 7/4 es :1
division flotante  7/4  es  :1.75
division mixta 7/4 es : 1.75
resto 7/4  es  : 3 

FIN 

Diagrama de flujo : division. C

 EJERCICIO C ): TÍTULO: Tipos de datos y valores máximos


y mínimos

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> .

Para mostrar números reales en notación exponencial usar el especificador de


formato “%ef ”.

Guardar el programa como tipos.c .

 
 
15 
RESOLUCIÓN:

 CODIGO FUENTE COMPLETO ( tipos.c)


/* Muestra las longitudes en longitudes en bytes
y los valores máximos y mínimos de los tipos básicos */

#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));

/* VALORES MÁXIMOS Y MÍNIMOS */


printf( "\n Valores Mínimos y máximos de cada uno de los tipos\n\n");
printf ( "Mínimo y máximo de char % i \t %i \n" ,CHAR_MIN,CHAR_MAX);
printf ( "Mínimo y máximo de short int %i \t %i \n" ,SHRT_MIN,SHRT_MAX);
printf ( "Mínimo y máximo de int %i \t %i \n" ,INT_MIN,INT_MAX);
printf ( "Mínimo y máximo de long int %li \t %li \n" ,LONG_MIN,LONG_MAX);
printf ( "Máximo de unsigned char %u \n" ,UCHAR_MAX);
printf ( "Máximo de unsigned int %u \n" ,UINT_MAX);
printf ( "Máximo de unsigned long int %lu \n" ,ULONG_MAX);
printf ( "Mínimo y máximo de float %ef \t %ef \n" ,FLT_MIN,FLT_MAX);
printf ( "Mínimo y máximo de double %ef \t %ef \n" ,DBL_MIN,DBL_MAX);
getchar();}

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)

Indica si encuentras alguna diferencia en el “tamaño” de alguna variable


respecto al habitualmente explicado para ANSI C.

Se han encontrado diferencias de tamaño , respecto al habitualmente explicado


en ANSI C, en los siguientes tipos de variables:

 Tipo int : En el compilador Dev-C++ este tipo de variable ocupa en


en memoria un espacio de 4 bytes , mientras que en ANSI C
ocuparía 2 bytes.

 Tipo unsigned int : En el compilador Dev-C++ este tipo de variable


reserva un espacio en memoria de 4 bytes ,
mientras que en ANSI C ocuparía 2 bytes.

 Tipo long double : En el compilador Dev-C++ este tipo de variable


ocupa 12 bytes, en cambio, en ANSI C reservaría
10 bytes.

 
 
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

Guardar el programa como precision.c

RESOLUCIÓN:

 DIAGRAMA DE FLUJO ( precision.c)

INICIO

DEFINE:
"a" y "b" : enteros 
"c" y "d" :caracteres
"decimal" : real

a = 512
b = 127
c = a 
d=b

 
 
18 
Buy SmartDraw!- purchased copies print this
document without a watermark .
Visit www.smartdraw.com or call 1-800-768-3729.

Diagrama de flujo : precision. C

 CUESTIONES ( precision.c)

Diga cuales son los resultados obtenidos. Explique el motivo por el cual
se obtienen dichos valores.

Los resultados obtenidos son :

Primera muestra por pantalla : c = 0 ; d= 127


Segunda muestra por pantalla : decimal = 0.000000 ; a =0
Tercera muestra por pantalla : decimal = 0.666667

 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

 EJERCICIO A ): TÍTULO: Sentencias de entrada-salida.


Definición de constantes

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:

 CODIGO FUENTE ( millas1.c)

/* Pasar de millas a kilometros*/

#include <stdio.h>
#define CONV_MILLAS 1.852

/* Macro de sustitución CONV_MILLAS */

main()
{
float millas , kilometros;

printf ( "introduzca el numero de millas: \n");


scanf ("%f", &millas);
kilometros = millas*CONV_MILLAS;

/* La Macro CONV_MILLAS es sustituida por el valor


asiganado : 1.852 */

printf("El numero de millas es:%.3f\n\n",millas);


printf ("El numero de kilometros equivalentes es:%.3f\n\n",kilometros);
getch();
}
Archivo: millas1. C

 
 
21 
 DIAGRAMA DE FLUJO ( millas.c)*
*El mismo para millas1, millas2 y
millas3

Buy SmartDraw!- purchased copies print this


document without a watermark .
Visit www.smartdraw.com or call 1-800-768-3729.

Diagrama de flujo : millas. C

 CODIGO FUENTE ( millas2.c)

/*Pasar de millas a kilometros*/

#include<stdio.h>

main()
{
float millas, kilometros, CONV_MILLAS=1.852 ;
/* Inicializamos CONV_MILLAS al valor 1.852 */

printf("Introduzca el numero de millas:\n");


scanf("%f", &millas);
kilometros=millas*CONV_MILLAS;
printf("El numero de millas es: %.3f\n\n", millas);
printf("El numero de kilometros es: %.3f\n\n", kilometros);
getch();
}

Archivo: millas2. C

 
 
22 
 CUESTIONES ( millas.c)

a) ¿Resulta la misma salida para millas1.c que para millas2.c ?.


Si es cierto indique el motivo y si es falso indique el motivo de la
disparidad.

Si resulta la misma salida , debido a que en el programa millas1.c se utiliza una


macro de sustitución, que lo que hace es sustituir en nombre de la macro por el
valor asignado a la macro en el inicio del programa y valido para todo él.

Mientras que en millas2.c se emplea una variable que se inicializa al valor


equivalente de cambio millas-kilometros y esta variable es sustituida por dicho
valor.

b) Dada la siguiente definición de la constante CONV_MILLAS:

const CONV_MILLAS=1.852;

Utilizando la definición anterior en la codificación del programa, ¿se


corresponde la salida del programa con la salida de los programas
millas1.c o millas2.c?.
Si es cierto Indique el motivo y si es falso proponga la codificación
alternativa para que las salidas sean idénticas.
Guardar el posible fichero como millas3.c.

La salida del programa no se corresponde con la de millas1.c y millas2.c.


El motivo es que además de decirle al compilador que CONV_MILLAS es una
constante simbólica , hay que decirle el tipo de dato que es.
En este caso sería un dato de tipo float: real.

CODIFICACIÓN ALTERNATIVA ( millas3.c)


/*Pasar de millas a kilometros*/

#include<stdio.h>

main()
{
float millas, kilometros ;
const float CONV_MILLAS=1.852 ;
/* Inicializamos CONV_MILLAS al valor 1.852 */

printf("Introduzca el numero de millas:\n");


scanf("%f", &millas);
kilometros=millas*CONV_MILLAS;
printf("El numero de millas es: %.3f\n\n", millas);
printf("El numero de kilometros es: %.3f\n\n", kilometros);
getch();
}
 
Archivo: millas3. C

 
 
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.

Algoritmo propuesto para el bloque de pasar a binario:

• Pseudocódigo:

Leer dato por teclado


Para valores de i = 7....0
Si dato & 2 i ¡= 0 Escribir un ‘1’
En otro caso Escribir un ‘0’
Siguiente i

• Explicación:

El algoritmo se basa en el funcionamiento del operador de bit “and binario” (&).


Supongamos que el número que queremos cambiar de base es el nº 13.
Usaremos el operador “&” de la forma siguiente:
13 & 20 00001101 & 00000001 = 00000001 Como es ≠ 0. => Imprimir 1
13 & 21 00001101 & 00000010 = 00000000 Como es = 0. => Imprimir 0
13 & 22 00001101 & 00000100 = 00000100 Como es ≠ 0. => Imprimir 1
...............................................................................................................................

RESOLUCIÓN:

 CODIGO FUENTE ( binario.c)

 
 
24 
/* Pasar a binarios ,hexadecimal y octal*/
#include <stdio.h>

unsigned int dato; /* unsigned ya que deben ser numeros positivos*/


int i;

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);

printf("El numero en binario es:\t");

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

 DIAGRAMA DE FLUJO ( binario.c)

Buy SmartDraw!- purchased copies print this


document without a watermark .
Visit www.smartdraw.com or call 1-800-768-3729.

 
 
25 

ERROR: SI  numero  <0


Introduzca  otro o 
numero numero >255

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 

imprime numero  octal 


imprime numero 
hexadecimal

FIN

Diagrama de flujo: binario. C

 
 
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:

Utilizar el siguiente algoritmo:


La letra de control se obtiene de la tabla siguiente:

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',..........};

- Leer el dni por teclado Ej :32000000


- Dividirlo por 23 y quitar decimales, es decir calcular el cociente entero
Ej: 1391304
- Multiplicar por 23 Ej: 31999992
- Restar al DNI original el nº obtenido anteriormente Ej.: 32000000-31999992=8
- Localizar en la tabla adjunta el carácter de control asociado. Ej: P

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:

 CODIGO FUENTE ( nif.c)

#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;

printf("Introduzca el numero de dni: ");


scanf("%i", &nif);
division=nif/23;
multiplicacion=division*23;
resta=nif-multiplicacion;
printf("La letra correspondiente es: %c", letra[resta]);

getch();
}

Archivo: nif. C
 
 
27 
 DIAGRAMA DE FLUJO ( nif.c)

Buy SmartDraw !- purchased copies print this


document without a watermark .
Visit www.smartdraw.com or call 1-800-768-3729.

Diagrama de flujo: nif. C

 EJERCICIO D ): TÍTULO: Programa mini navegador.

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:

 CODIGO FUENTE ( GPS.c)

 
 
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);

Lat_rad = (La_g +La_m/60)*2*Pi/360;


Dx = (Lo_g*60 + Lo_m)*cos(Lat_rad);
Dy = La_g*60 + La_m;
D=pow(((Dx*Dx)+(Dy*Dy)), 0.5);
A = atan(Dy/Dx)*360/(2*Pi);
printf ("\n Componentes de la distancia en millas:\n");
printf("\nDx: %f\t",Dx); printf ("Dy: %f\t",Dy);
printf("\n Distancia en millas: %f", D);
printf("\n El angulo en grados es: %f", A);

getch();
}

Archivo: GPS. C

 
 
29 
PRÁCTICA PROPUESTA Nº 4

 EJERCICIO A ): TÍTULO: Ordenación números

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:

 CODIGO FUENTE ( ordenar.c)


#include<stdio.h>
main(){
int a,b,c;
printf("Introduzca tres numeros a,b,c : \n");
scanf("%i",&a);
scanf("%i",&b);
scanf("%i",&c);
printf("Los numeros ordenados de mayor a menor son :\t");
if(a>b&&a>c)
{ /* Si a es mayor que b y mayor que c --> Imprime a ; y si
printf("%i\t",a); b es mayor que c -->Imprime b y c ;sino imprime c y b*/
if(b>c)
printf("%i\t,%i\t",b,c);
else
printf("%i\t,%i\t",c,b);
}
if(b>a&&b>c) /* Si b es mayor que a y mayor que c --> Imprime b ; y si
printf("%i\t",b); a es mayor que c -->Imprime a y c ;sino imprime c y a*/
{
if(a>c)
printf("%i\t,%i\t",a,c);
else
printf("%i\t,%i\t",c,a);
}
if(c>a&&c>b)
{ /* Si c es mayor que a y mayor que b --> Imprime c ; y si
printf("%i,\t",c); a es mayor que b -->Imprime a y b ;sino imprime b y a */
if(a>b)
printf("%i\t,%i\t",a,b);
else
printf("%i\t,%i\t",b,a); }
getch();
}

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 

Diagrama de flujo: ordenar. C

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

b) En una segunda versión, se deberá optimizar el algoritmo para no tener


que construir una estructura tipo if para cada tipo de
billete/moneda.
Esto se consigue trabajando con un vector.
Se deben guardar los distintos tipos de billetes/monedas, en un vector
inicializado. Guardar el programa como cambio2.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()

long int cantidad, billetes100,billetes50,billetes20;


long int sobrante,cantidad2,cantidad3,cantidad1;

printf ("Introduzca una cantidad de dinero\n");


scanf("%li",&cantidad);

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

PIDE UNA  CANTIDAD

LEE UNA  CANTIDAD

billetes100 = cantidad  /100;  si 


cantidad  >100 
cantidad1  = cantidad  -
-( billetes100 *100); 

NO 
IMPRIME  :
nº de  billetes de 
100 

billetes50  = cantidad1  /50; si 


cantidad  >50
cantidad2 = cantidad1 -
-( billetes50 *50); 

NO 

IMPRIME  : 
nº de  billetes  de 
50

billetes20  = cantidad2 /20; si


cantidad  >20
sobrante = cantidad2 -
-( billetes20 *20); 

NO
IMPRIME  :
nº de billetes de 20; 
Lo  que sobra ,

FIN

Diagrama de flujo: cambio1. C

 
 
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  

PIDE INTRODUCIR LA CANTIDAD    


LEE LA CANTIDAD  

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

Diagrama de flujo: cambio2. C

 
 
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:

 CODIGO FUENTE ( fibonaci.c)


#include<stdio.h>
main()
{
int n,i,aux,anterior=0,nuevo=1;
printf("Introduzca un numero: ");
scanf("%i",&n);
if(n==1)
printf("%i",anterior); /* Si n=1 solo imprime un 0*/
if(n>=2)
printf("%i, %i",anterior,nuevo); /* Si n es> o = que 2 imprime un cero y un uno*/
for(i=0;i<(n-2);i++)
{ /* Para seguir la serie fibonacci se crea un bucle que
proporciona el siguiente numero Fibonacci con la
suma
de los anteriores. */
aux=nuevo;
nuevo=anterior+nuevo;
anterior=aux;
printf(", %i",nuevo);
}
getch();
}
Archivo: fibonaci. C

 
 
36 
 DIAGRAMA DE FLUJO ( fibonaci.c)

INICIO 

DEFINO : 
n,i,aux,anterior=0, nuevo =1 :
como enteros 

PIDE UN NUMERO (n) 


LEE EL  NUMERO (n)

IMPRIME : 
SI 
n=1
un cero 

NO 
SI 
IMPRIME :
un cero y un  uno
n>2 ó n=2

NO 

aux= nuevo ; SI 


DESDE : i=0 
nuevo =anterior+ nuevo ;
HASTA : i<(n-2 )
anterior=aux;

IMPRIME : NO 
el valor de la variable
nuevo

i=i+1; 

FIN

Diagrama de flujo: fibonacci. C

 
 
37 
 CUESTIONES ( fibonaci.c)

Calcular y escribir en el papel la serie de Fibonacci para los dos valores


siguientes de n:

n=12 ====> 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89.

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.

 EJERCICIO D ): TÍTULO: Relación de transmisión


OBJETIVO:
La relación de transmisión de un engranaje se define como el número entero
‘n’ dado por el cociente n=n1/n2 siendo n1 y n2 los números de dientes de dos
ruedas dentadas. El siguiente programa, pide por teclado una relación de
transmisión n y genera posibles valores de dientes, comprendidos entre 20 y
50 que cumplan la relación.

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:

 CODIGO FUENTE ( engranajes.c)

#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  

Diagrama de flujo: engranajes. C

 CUESTIONES ( engranajes.c)

Completar una tabla similar a la adjunta, (traza de variables) con las


cuatro primeras soluciones que aparecen para el valor de N=2.Es decir,
indicar los valores que toman las variables N1,N2,C,R.

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:

Realizar un programa que lea un número y compruebe si es perfecto. Dado un


entero N mayor que 0 es perfecto, si la suma de sus divisores exactos, incluido
el 1, es igual a dicho número. Por ejemplo 6 es perfecto porque: 6 = 3 + 2 + 1.

REQUISITOS:

El programa se podrá ejecutar repetidamente, y que terminará sólo cuando el


número introducido sea un 0.
Guardar el programa fuente en el fichero con nombre perfecto.c.

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

Fin del programa.

 
 
40 
RESOLUCIÓN:

 CODIGO FUENTE ( perfecto.c)

#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();
}

Diagrama de flujo: engranajes. C

 
 
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  

Diagrama de flujo: perfecto. C

 
 
42 
PRÁCTICA PROPUESTA Nº 5

 EJERCICIO A ): TÍTULO: Potencia entregada por un


generador

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.

2) La declaración y definición de las funciones deberá ser coherente


con las llamadas que aparecen en el listado de la figura:

- La 1º función se declarará como void explicación_programa(void).


NO recibe ni devuelve parámetros. Solo presentará un texto que
explicará brevemente lo que hace el programa.

- La 2º función se declarará como void obtener_valores(void). Leerá


los valores de E, I por teclado. Para devolver dos valores al mismo
tiempo sin return, se deben utilizar las variables globales I y E

- Por último, la función flota calcular_y_presentar(float I_local,


float E_local,). recibirá los valores de I, y E en las variables locales
I_local y E_local , calculará la potencia P y la mostrará en pantalla.

3) Guardar el programa codificado en el fichero pofuente.c

EJEMPLO PROG. PRINCIPAL CON LLAMADAS A FUNCIONES:

float I,E,P;
main(void)
{ system (’’cls’’ );
explicacion_programa( );
obtener_valores( );
calcular_y_presentar(I, E);
getch(); }

 
 
43 
 CODIGO FUENTE ( pofuente.c)

/* potencia entregada por un generador (funciones) */

#include <stdio.h>

float I,E,P;

void explicacion_programa(void) { /* Funcion que explica lo que hace el


programa.
Tipo void:no devuelve ningun valor */
printf (" El programa calcula la potencia entregada por un generador.");
printf ("Para ello se deben introducir los datos de intensidad y tensión.\n");
}
void obtener_valores(void) { /* Funcion que pide y lee los valores de
intensidad y tensión necesarias para
calcular la potencia .
Tipo void: no devuelve nada */
printf ("\n Introduzca la intensidad en Amperios:\t");
scanf ("%f",&I);
printf ("\n Introduzca la tensión en voltios:\t");
scanf ("%f",&E);
}
float calcular_y_presentar( float I_local,float E_local){
/* Funcion que calcula la potencia mediante
la expresion P=IxE */
P=I_local*E_local;
printf ("\nLa potencia generada por el generador es:\t %.3f watios", 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

Diagrama de flujo: pofuente. C(modulo 1)

Diagrama de flujo: pofuente. C(principal)


2

P=I*E
Pide  el voltaje 
Lee el  voltaje 
Pide  la intensidad IMPRIME :
Lee la  intensidad POTENCIA DEL
GENERADOR 

FIN
FIN

Diagrama de flujo: pofuente. C(modulo 2) Diagrama de flujo: pofuente. C(modulo 3)


 
 
45 
 EJERCICIO B ): TÍTULO: Facturación de energía eléctrica

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:

 CODIGO FUENTE ( facturacion.c)

#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

PIDE  LOS KWH 


CONSUMIDOS
LEE LOS KWH

1  LLAMA A: 
pago(  k
  wh)

MUESTRA: 
la  cantidad  de la
factura

FIN

Diagrama de flujo: facturación.c (Prog. Principal)

 
 
47 
Facturacion. C (Modulo 1)

DEFINO :
tarifa1 ,tarifa2 ,tarifa
3 ,factura  , kwh :
COMO  REALES 

SI
factura =kwh *1.5 kwh <=200

NO 

tarifa1 =200*1.5  SI 


kwh = kwh -200;  kwh >200 Y
tarifa2 =kwh *1; kwh <=500
factura =tarifa1 +tarifa2 ;

NO 

tarifa1 =200*1.5  SI 


tarifa2 =300*1;  kwh =kwh -500; 
kwh >500 
tarifa3 =kwh *0.5; 
factura =tarifa1 + tarifa2 +tarifa3 ;

NO 

RETURN 
(factura )

Archivo: facturacion. C (MODULO 1)

 
 
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:

 CODIGO FUENTE ( calculos.c)

#include "C:\Temp\miscosas.h"

/* Declaramos este fichero que es donde se encuentra definida


la funcion area. */

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

Diagrama de flujo: calculos. C

 DIAGRAMA DE FLUJO ( miscosas.c)

Area= 3.14*x*x

return(Area) 

Diagrama de flujo: miscosas. C

 
 
50 
 CUESTIONES ( calculos.c)

Al compilar el programa cálculos.c :


1) ¿En que unidad o directorio busca el preprocesador el archivo de
cabecera “miscosas.h” cuando usamos la notación “……“ ?.
2) ¿Y cuando usamos < ……. > ?

1) Cuando usamos las comillas dobles “…..” el archivo mis cosas es


buscado en un directorio externo al compilador , por ejemplo en mis
documentos , o en cualquier otro directorio externo.
2) Mientras que cuando usamos <……> el archivo mis cosas es buscado
por el preprocesador en alguna de las librerías que tiene el propio
compilador.

 EJERCICIO D ): TÍTULO: Función recursiva

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

 DIAGRAMA DE FLUJO ( recursiva1.c)

Buy SmartDraw!- purchased copies print this


document without a watermark .
Visit www.smartdraw.com or call 1-800-768-3729.

Diagrama de flujo: recursiva1.c (PROG. PRINCIPAL)

 
 
52 

DEFINO : 
n , s : 
como  enteros

s=0 

SI 
s= n + func (n-1)  n    0

NO 

RETURN (s)

Diagrama de flujo: recursiva1.c (Modulo1)

 CODIGO FUENTE ( recursiva2.c)


/* recursiva2*/
#include <stdio.h>
int dato;
int func(int n);
main (void)

{
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

Diagrama de flujo: recursiva2.c (PROG. PRINCIPAL)

DEFINO  :
n , s : 
como enteros

s=1 

SI 
s= n * func (n-1) n  0 

NO 

RETURN (s)

Diagrama de flujo: recursiva2.c (MODULO 1)

 
 
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).

-La función para calcular la longitud se puede declarar como int


medir_cadena(void). Puede usar también la variable global cadena1.
Mediante un while y un contador, contará la letras hasta detectar ‘/0’ de fin de
cadena, y devolverá el valor del contador con return.

-La función para invertir la cadena. se puede declarar como void


invertir_cadena(void) y copiará los caracteres de cadena1 en cadena 2 en
orden inverso ( cadena2[i] = cadena1[L- (i+1)] )

Guardar el programa fuente con el nombre inver_cadena.c.

NOTA: Aunque se valora que el alumno construya por si mismo la función


medir_cadena( ), otra alternativa es la función strlen(<cadena>) que devuelve
la longitud de la cadena.

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:

 CODIGO FUENTE ( facturacion.c)

#include <stdio.h>
#include <conio.h>

char cadena1[20]; /* cadena original*/


char cadena2[20]; /* cadena inversa*/

void leer_cadena(void){
printf("Introduce una cadena de caracteres: \n");
gets(cadena1);}

int medir_cadena(void){ /* La funcion medir_cadena cuenta los caracteres


hasta que encuentre el valor NULL */

int i=0;
while(cadena1[i]!='\0')
i++;
return(i);}

void invertir_cadena(int L){ /* Esta funcion asigna la penultima posicion de la


cadena original(para no coger el retorno de carro)
a la primera de la cadena inversa */
int i=0;
for(i=0;i<medir_cadena();i++){
cadena2[i]=cadena1[L-(i+1)];}}

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

Diagrama de flujo: inver_cadena.c (PROG. PRINCIPAL)

PIDE  UNA CADENA  DE


CARACTERES
LEE LA  CADENA  DE
CARACTERES (cadena1)

return() 

Diagrama de flujo: inver_cadena.c (MODULO 1)

 
 
57 

i=0 

NO
MIENTRAS :
cadena1 [i]!='\0' 

SI 

i= i+1

RETURN (i)

Diagrama de flujo: inver_cadena.c (MODULO 2)

i=0 

NO
DESDE  : i=0 
HASTA  :
i< medir _ cadena 

SI 

cadena2  [i]= cadena1  [L-(i+1)] 

i= i+1 

RETURN ()

Diagrama de flujo: inver_cadena.c (MODULO 3)

 
 
58 
PRÁCTICA PROPUESTA Nº 6

 EJERCICIO A ): TÍTULO: Programa para calcular tiempo de


desintegración C14

OBJETIVO:

Aplicaciones, para tratar de datar la antigüedad de objetos, como sucedió con


la Sabana Santa de Turín.
El presente programa es una muestra de tales aplicaciones:

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.

La ecuación para calcular la masa que queda por desintegrar, en función de


la masa original, viene dada por la ecuación:

Mr = M0 *(0.5)A/k Mr : Masa restante


Mo: Masa original
K: Constante = 5700 años
A: Tiempo trascurrido en años

REQUISITOS:

a)Codificar el programa anteriormente indicado, sin crear funciones.


Guardar el programa como desintegracion1.c
Construir ahora una función para el cálculo de la masa restante (Mr). Se
realizarán dos versiones levemente diferentes del programa.

b) Codificar la función para calcular Mr, declarandola como float funcion2(int


m, int t ) que recibe las dos variables por valor.
Guardar el programa como desintegración2.c

c) Codificar la función para calcular Mr, delarandola como float funcion3(int


*m, int *t ) que recibe las dos variables por referencia. Indicar como sería la
llamada. Guardar el programa comodesintegración3.c .

RESOLUCIÓN:

 CODIGO FUENTE ( desintegracion1.c)

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

#define K 5700

float M0,Mr,Mp,A, potencia;

main()

printf("Dame la masa original del elemento: ");


scanf("%f",&M0);
printf("\tAnos\t Mr\t Mp\n");
printf("\t____________________\n");
for(A=0;A<=5000;A=A+100)

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

PIDE  MASA  DEL  ELEMENTO


LEE LA  MASA

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

Diagrama de flujo: desintegracion1.c

 
 
61 
 CODIGO FUENTE ( desintegracion3.c)

/* Codificar la función para calcular Mr, declarandola como float


función_MR(int m, int t ) que recibe las dos variables por valor. Guardar el
programa como desintegración2.c */

#include <stdio.h>
#include <math.h>
#include <conio.h>
#define K 5700

float funcion_MR(float m, float t ){ /* Funcion que calcula la masa


restante*/

float Mr,potencia;
potencia= t/K;
Mr= m*pow(0.5,potencia);

return(Mr);
}

main(){

float A,Mo,Mp,Mr;

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=funcion_MR(Mo,A); /* A la funcion que calcula la masa restante
toma como argumentos Mo y A */
Mp=Mo-Mr;
printf("\t%.2f \t%.2f \t %.2f\n",A,Mr,Mp);

getch();
}

 
Archivo: desintegracion2. C

 
 
62 
 DIAGRAMA DE FLUJO ( desintegracion2.c)

INICIO

PIDE  MASA  DEL 


ELEMENTO
LEE LA MASA 
PIDE  TIEMPO  INICIAL 
LEE EL  TIEMPO 
INICIAL 

DESDE : A=0 NO 


HASTA : 
A<=5000

SI 

1  LLAMA A: 
funcion_MR(Mo,A);

Mp =Mo-Mr 

IMPRIME :
A,Mr,Mp 

FIN

Diagrama de flujo: desintegracion2.c (PROG. PRINCIPAL)

 
 
63 

DEFINO:
Mr , potencia : 
real

potencia = t/K; 
Mr= m*pow(0.5, potencia);

RETURN(Mr)

Diagrama de flujo: desintegracion2.c (MODULO 2)

 CODIGO FUENTE ( desintegracion3.c)

#include <stdio.h>
#include <math.h>
#include <conio.h>
#define K 5700

float funcion3(float *m, float *t ){

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

 DIAGRAMA DE FLUJO ( desintegracion3.c)

INICIO

PIDE MASA  DEL


ELEMENTO
LEE LA  MASA 
PIDE TIEMPO  INICIAL
LEE EL  TIEMPO
INICIAL

DESDE : A=0  NO 


HASTA :
A<=5000

SI

1 LLAMA A: 
funcion3 (&Mo,&A);

Mp  =Mo-Mr

IMPRIME  : 
A,Mr, Mp 

FIN 

Diagrama de flujo: desintegracion3.c (PROG. PRINCIPAL)

 
 
65 
1

DEFINO:
Mr , potencia  : 
real 

potencia = *t/K; 
Mr= *m*pow(0.5,potencia ); 

RETURN(Mr)

Diagrama de flujo: desintegracion2.c (MODULO 1 )

 CUESTIONES ( calculos.c)

a) De todas las posibilidades de implementar el programa según los


apartados anteriores, indique cual a su juicio sería la más correcta.
Razone la respuesta.

La forma más correcta de las tres es utilizando la función y el paso por


referencia , ya que el proceso se realiza de forma separada y relativamente
rápida.

b) Indique cual de las soluciones implementadas en los apartados


anteriores sería la más eficaz en términos de ocupación de memoria y
tiempo de ejecución.

La más eficaz sería la primera , desintegracion1.c ya que ocupa menos espacio


de memoria y el proceso se realiza de forma rápida en un solo paso.

 
 
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:

 CODIGO FUENTE ( traza.c)

# include <stdio.h>

int a=1, b =10;

int *pa=&a, *pb=&b;

void main(void ) { /* Funcion principal y la primera que se ejecuta */

*pb = b + 2;

*pa = a*3;

pa = pb;

*pa = 2 * b;

printf("%i %i %i %i",a,b,*pa,*pb);

getch();

Archivo: traza. C

SOLUCIONES MOSTRADAS POR PANTALLA:

(1) (2) (3) (4) (5) (6)

.a 3

*pa ----- 1 24

.b 24

 
 
67 
*pb ----- 24

 EJERCICIO C ): TÍTULO: Paso de matrices a funciones

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

Paso Vector. Guardar el programa con nombre paso_vector.c

b.- Observar la declaración y la llamada, y completar la función que aparece en


el programa Pruba

Paso Matriz. Guardar el programa con nombre paso_matriz.c

RESOLUCIÓN:

 CODIGO FUENTE ( paso_vector.c)

/* Prueba Paso de vector */

#include <stdio.h>
#include <conio.h>

int matriz[6] = {1,2,3,4,5,6};


void escribir(int V[] , int N)
{ int i;
for(i=0;i<=5;i++)

printf ("%i\t",*(V+i));
}
main( )
{ escribir(matriz, 6);
getch(); }

Archivo: paso_vector. C

 
 
68 
 CODIGO FUENTE ( paso_matriz.c)

/* Prueba Paso de matriz */

#include <stdio.h>
#include <conio.h>

int matriz[2][3] = {{1,2,3},{4,5,6}};


void escribir(int V[][3] , int Nf, int Nc)

/* Funcion que recorre la matriz con un bucle for ,y va representando las


posiciones leidas */

{ 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);

/* A la funcion escribir se le pasan como argumentos la matriz, el nº de filas


y el nº de columnas */

getch(); }

Archivo: paso_vector. C

 SALIDA POR PANTALLA ( 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:

a) Se deberá añadir la instrucción para reservar el espacio de memoria


necesario para el vector valores declarado la principio del programa.

b) Añadir las instrucciones necesarias para que la función lee pueda leer los
elementos del vector.

c) Añadir instrucción para invocar la función intercambio. Como resultado de


la invocación sólo se intercambiarán los elementos i y j del vector a cuando la
llamada se produzca.

d) Añadir las instrucciones necesarias a la función intercambio para


intercambiar los parámetros actuales es decir los elementos i y j recibidos.

e) Añadir las instrucciones necesarias a la función imprima para imprimir los


elementos del vector.
Guardar el programa como ordenacion.c.

RESOLUCIÓN:

 CODIGO FUENTE ( ordenacion.c)

#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 */

void lee(int a[],int tamano)


/* Funcion que pide y lee el tamaño y las posiciones del array */
{int i;
printf("\nValores del vector a: ");
printf("\n");
for(i=0; i<tamano; i++)
{
printf("\na[%d]: ",i);
scanf("%d",&a[i]);
}
}

 
 
70 
/* Función que imprime los valores de las posiciones del vector */

void imprima(int a[], int tamano)


{int i;

printf("\n");
for(i=0; i<tamano; i++)
printf("\na[%d]:%d ",i,a[i]);
}

/* aptdo b función intercambio */

void intercambio(int *x, int *y)


/* Funcion que intercambia las posiciones del vector para ordenarlas */
{
int aux;

aux=*x;
*x=*y;
*y=aux;
}

/* función Burbuja */

void burbuja (int a[],int tamano)


/* Funcion que compara cada posicion del vector para ordenarlo */
{
int i, j;

for (i = 0; i < tamano; i++)


for (j = i+1; j < tamano; j++)
if (a[i] > a[j])

/* aptdo c función intercambio */

intercambio(&a[i],&a[j]);
}

main()
{
int *valores;
int tamano;
int j;

printf("\nDame la dimension del vector: ");


scanf("%d",&tamano);

 
 
71 
/* la función malloc reserva memoria */

valores=(int*)malloc(tamano*sizeof(int)); /* aptdo a*/

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

 EJERCICIO A ): TÍTULO: Cuadrado vector

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:

 CODIGO FUENTE ( cuadrado_vector.c)

#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*/

cuadrado(datos,8); /* La funcion cuadrado toma como argumentos el vector


y el numero de elementos del vector */
for(i=0;i<8;i++)
printf("\t %5d",datos[i]);
getch();

/*construccion de la funcion*/

void cuadrado (int V[],int N)

int i;
for (i=0;i<N;i++)
V[i]=pow(V[i],2);
}

Archivo: cuadrado_vector. C

 
 
73 
 CUESTIONES ( cuadrado_vector.c)

a) ¿Cuál de las dos versiones del programa será más eficaz?

La versión más eficaz es la de los punteros ya por este método el puntero te da


la dirección de memoria del primer elemento del vector siendo así mucho más
rápida la ejecución.

b) ¿Existe alguna diferencia entre el nombre de un vector unidimensional


y el nombre de un array bidimensional?

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.

c) Si datos estuviera declarada como un array datos [2][4]={{0,1,2,3},


{4,5,6,7} }, ¿Crees que la declaración de la función
podría ser igual?

No, habría que indicarle a la función la dimensión del vector.

 EJERCICIO B ): TÍTULO: Potencias vector

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"

/* declaracion de las funciones */

void crear_tabla(int v[], int i);


void mostrar_tabla(int v[]);

/* 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();
}

/* construimos una funcion para crear una lista de potencias y guardarla en V.


Utilizamos p a través del array V */

void crear_tabla (int v[], int i)

{
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 */

void mostrar_tabla(int v[])

{
int j;
for(j=1;j<11;j++)
printf("%i ",v[j]);
printf("\n");

Archivo: potencias_vector. C

 CUESTIONES ( potencias_vector.c)

a).- Cuando se realiza la reserva dinámica de memoria: ¿Qué valor


numérico en bytes se obtiene al ejecutar la función malloc(10*sizeof(int))
en el programa?

El valor obtenido es 10* 4 bytes que ocupa una variable tipo int en el
compilador Dev-C++, es decir , 40 bytes.

b).- ¿Funcionaria correctamente el programa si eliminamos la línea


anterior? ¿Qué puede suceder?

No tendría porque funcionar mal si se realiza una reserva de memoria estática


lo suficientemente amplia, pero si se realiza una reserva estática pequeña, es
decir ,si se necesita más memoria de la inicialmente prevista, se daría el caso
de una finalización anormal del programa, produciendo errores.

c).- Cuantas veces se ejecutan las funciones mostrar_tabla( )y crear


tabla()?

Las funciones mostrar_tabla y crear_tabla se ejecutan cuatro veces.

 
 
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:

a) Añada la instrucción para reservar, mediante reserva dinámica de memoria,


el espacio necesario en cada caso (depende de la longitud calculada en
tamano), para el vector declarado como int *vector.

b) Añadir el código necesario para construir la función que calcula el número de


dígitos del número introducido. Para contar el nº de dígitos de una cifra se
sugiere realizar divisiones enteras por 10 hasta que
el resultado sea <1 e ir contando. Por ejemplo, el número de dígitos del número
321 es 3 porque hasta la 3º división por 10 no se obtiene un número <1.

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 …

d) Añada el código necesario para construir la función que verifica si se cumple


o no la propiedad capicúa. Bastara que la función comprueba si existen dos
elementos a[i] y a[L-1-i] distintos, en cuyo caso devuelve un ‘0’ (falso), en caso
contrario un ‘1’ (correcto).
Guardar el programa como capicua.c

RESOLUCIÓN:

 CODIGO FUENTE ( capicua.c)

#include<stdio.h>
#include<stdlib.h>

/* DECLARACION DE FUNCIONES */

int ncifras(int n);


void construya_vector(int a[], int tamano, int numero);
int capicua(int a[], int n);

 
 
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;
}

/*{ ……….. Parte –b- }*/


void construya_vector(int a[], int tamano, int numero)
{
int i, nuevo;
nuevo=numero;
for ( i=tamano-1;i>=0;i--)
{ a[i]=nuevo % 10;
nuevo=nuevo/10;
}

for (i =0;i >tamano;i++)


printf ("%d ",a[i]);
printf ("\n ");
}

 
 
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);
}
}

/*{……… Parte –d- }*/

Archivo: capicua. C

 EJERCICIO D ): TÍTULO: Numero de vocales en una línea de


texto

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:

 CODIGO FUENTE ( vocales.c)

#include <stdio.h>
#include <string.h>
#include <conio.h>

int cuenta(char *p, int l);

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();
}

/*Aquí se comprueban las vocales que contienen la línea*/

int cuenta(char *p, int l)


{ int i, vocales = 0;

for (i=0; i <l ; i++)


{switch(p[i])
{
case 'a':case 'A':
case 'e': case 'E':
case 'i': case 'I':
case 'o': case 'O':
case 'u': case 'U':
vocales++;

}
}
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].

En el presente apartado se trata de escribir un programa que recibe como


parámetro desde la línea de comandos del DOS, el valor del lado de un
cuadrado y calcule y visualice en pantalla el área del mismo.

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.

3º.- Puesto que el parámetro argv[1] es un puntero a cadena de caracteres y la


variable lado es de tipo float (necesaria para calcular su cuadrado) necesitamos
la función de la librería stdlib.h declarada como float atof(const char *nptr), que
convierte una cadena de caracteres a un valor numérico, como su nombre
indica (Ascii To Float.=> atof).

4º.- El programa fuente se guardará en el fichero prueba.c Una vez compilado


se ejecutará el fichero ejecutable desde la línea de comandos del sistema
(accesorios_simbolo del sistema), o desde la opción ejecutar.

Entrada de datos: c:\temp\prueba 2


Y producirá la salida: El área del cuadrado es: 4.00

 
 
81 
RESOLUCIÓN:

 CODIGO FUENTE ( prueba.c)

/* parametros a main desde la linea de comandos */

#include <stdio.h>
#include <stdlib.h>

double area,lado;

main(int argc,char *argv[])

{
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

 EJERCICIO A ): TÍTULO: Construcción de un vector de


fichas

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:

DATOS_REVISIONES: Estructura para guardar la fecha y los datos de las


revisiones, con los campos:
DIA: para enteros sin signo. Máximo 1 byte
MES: para enteros sin signo. Máximo 1 byte
AÑO: para enteros sin signo. Máximo 1 bytes
DEFECTO: cadena de 20 caracteres máximo
DATOS_ASCENSORES: Estructura para guardar datos generales de los
vehículos con los campos
CODIGO: para enteros sin signo. Máximo 4 bytes
CALLE: cadena de caracteres de 15 caracteres máximo
NUMERO: para enteros sin signo. Máximo 1 bytes
REVISIONES: vector de 2 elementos tipo DATOS_REVISIONES
TABLA: Vector de 100 fichas del tipo estructura DATOS_ASCENSORES

SE PIDE:
a) Copiar y Analizar el listado adjunto

b) Completar las instrucciones para construir el conjunto de estructuras


descritas, concretamente: a1) Estructura tipo datos_revisiones. a2) Estructura
tipo datos_ascensores a3) Vector Tabla

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.

Guardar el programa como fichero_ascensores.c

 
 
83 
RESOLUCIÓN:

 CODIGO FUENTE ( Fichero_ascensores.c)

# 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

 EJERCICIO B): TÍTULO: Gestión de un fichero en memoria

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.

La interpretación de las estructuras es


la siguiente:
En la estructura reg_vendedor se almacenaeán el nombre y el apellido en dos
cadenas, el sueldo en un entero. Por último, para almacenar las ventas, se
usará ventas[], un array de 4 elementos del tipo entero para las ventas en los
cuatrotrimestres.
Finalmente construimos un array de estructuras denominado vendedores
cuyos elementos son 5 fichas tipo vendedor.

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:

 CODIGO FUENTE ( gestiónventas1.c)

#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.

Guardar el programa en el fichero llamado gestionventas2.c

 
 
87 
RESOLUCIÓN:

 CODIGO FUENTE ( gestiónventas2.c)

#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

 EJERCICIO D): TÍTULO: Manipulacion de una estructura tipo


pila

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.

2.- Insertar en pila (apilar):

Se incrementa la variable. cima y se inserta un elemento en la posición


apuntada por la cima.

3.- Recuperar de la pila (desapilar):

Se recupera de la pila el elemento apuntado por la cima y se decrementa la


variable cima.

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:

 CODIGO FUENTE ( stack1.c)

/* VERSION SIMPLE DEL PROGRAMA PARA APILAR-DESAPILAR N


ELEMENTOS */
/* SE DECLARAM 'PILA' COMO VARIABLE GLOBAL */
#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 *p, int elemento);
int pop(struct stack *p);

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

 CODIGO FUENTE ( stack2.c)

/* VERSION SIMPLE DEL PROGRAMA PARA APILAR-DESAPILAR N


ELEMENTOS */
/* SE DECLARAM 'PILA' COMO VARIABLE GLOBAL */

#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();
}

/* APILAR. EN LAS FUNCIONES P ES UN PUNTEROA ESTRUCTURA */


void push(struct stack dato, int elemento)
{ dato.V[dato.cima] = elemento;
dato.cima++;

}
/* 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

 EJERCICIO E ): TÍTULO: Simulacion del control de la


temperatura de un local

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:

 CODIGO FUENTE ( control_temperatura.c)

#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 

También podría gustarte