APUNTES - Introducción A La Programación en C
APUNTES - Introducción A La Programación en C
APUNTES - Introducción A La Programación en C
INTRODUCCIÓN A LA PROGRAMACIÓN
1.1 INTRODUCCIÓN
Una breve definición de informática es la siguiente: «Ciencia del tratamiento racional,
mediante máquinas automáticas, de la información». De ella se derivan dos hechos importantes.
Por un lado, el tratamiento de la información es llevado a cabo mediante máquinas automáticas: los
ordenadores. Por otro lado, la racionalidad en dicho tratamiento introduce el componente humano
como elemento indispensable de cualquier proceso informático, ya que será el ser humano quien
determine el modo de tratar la información.
La informática es una disciplina académica relativamente joven. Baste con señalar que el
término Computer Science no fue acuñado hasta los años 60 por el matemático George Forsythe y
que el primer Departamento de Informática en una Universidad se formó en el año 1962. Sin
embargo, la vertiginosa evolución de las tecnologías de la información ha llevado a la informática a
estar presente en la actualidad en gran parte de los campos científico, económico y social.
La principal herramienta que emplea la informática para llevar a cabo las tareas relacionadas
anteriormente es el ordenador o computador. Su definición nos aporta nuevas claves:
«Máquina automática para el tratamiento de la información que ejecuta programas
formados por una sucesión de operaciones aritméticas y lógicas”
Es decir, para realizar el tratamiento de la información, el ordenador acepta una entrada (los
datos), que mediante un programa transforma para proporcionar una salida (el resultado). Es
precisamente en la determinación del programa que el ordenador debe ejecutar donde el ser humano
interviene de forma decisiva. La Ilustración 1 esquematiza este proceso para el tratamiento
programa
1
CURSO 2018/19 1. INTRODUCCIÓN A LA PROGRAMACIÓN
ALGORITMO PROGRAMA
2
CURSO 2018/19 1. INTRODUCCIÓN A LA PROGRAMACIÓN
3
CURSO 2018/19 1. INTRODUCCIÓN A LA PROGRAMACIÓN
EJEMPLO 1.1. Se desea realizar un programa que determine el precio de una llamada telefónica entre teléfonos fijos.
El precio de la llamada lo constituye el coste por establecimiento de llamada (0.10 euros) y un coste por paso (0.03
euros/paso). La duración de un paso depende del tramo horario en el que se efectúe la llamada, según la siguiente
tabla:
4
CURSO 2018/19 1. INTRODUCCIÓN A LA PROGRAMACIÓN
EJEMPLO 1.2. La fase de diseño del problema planteado en el Ejemplo 1.1, empleando pseudocódigo para la
representación algorítmica, sería la siguiente:
a) Parte declarativa:
CONSTANTES
EST_LLAM=0.10
PASO=0.03
DUR1=60
DUR2=20
DUR3=40
VARIABLES
duracion,tramo,numPasos: entero
precio: real
b) Representación algorítmica:
inicio
leer desde teclado duracion
mientras duracion ≤ 0 hacer
escribir mensaje de error
leer desde teclado duracion
leer desde teclado tramo
mientras tramo < 1 o tramo > 3 hacer
escribir mensaje de error
leer desde teclado tramo
si tramo=1 entonces
almacenar en numPasos el valor techo(duracion/DUR1)
sino (es tramo=1)
si tramo=2 entonces
almacenar en numPasos el valor techo(duracion/DUR2)
sino (es tramo=2)
almacenar en numPasos el valor techo(duracion/DUR3)
almacenar en precio el valor EST_LLAM+numPasos×PASO
escribir precio
fin
5
CURSO 2018/19 1. INTRODUCCIÓN A LA PROGRAMACIÓN
LENGUAJES MÁQUINA
El ordenador representa internamente la información que maneja utilizando código binario.
En los primeros tiempos, los programadores tenían que realizar la tediosa tarea de traducir sus
algoritmos directamente a las secuencias binarias que representaban las instrucciones y los datos
contenidos en el programa. Estas instrucciones, conocidas como instrucciones de código máquina,
constituyen el lenguaje máquina de un ordenador.
La ventaja de programar en lenguaje máquina es que el código generado puede ser muy
eficiente, es decir, emplear poca memoria y ser muy rápido, y, por tanto, utilizar la mínima cantidad
de recursos. Sin embargo, la importancia de sus inconvenientes ha acabado con el uso de este tipo
de lenguajes en la actualidad. Uno de estos inconvenientes es la dependencia respecto al hardware
del ordenador, ya que, el lenguaje máquina de una familia de microprocesadores (por ejemplo, Intel
Pentium) no tiene porqué ser compatible con el de otra. Otro inconveniente es la dificultad en la
codificación. Por ejemplo, la operación aritmética 4✶3+5 podría representarse esquemáticamente
en un hipotético lenguaje máquina como
multiplicación 4 3 dirección
0110 0100 0011 0001
suma 5 dirección
0101 0101 0001
donde puede observarse que tanto los códigos de operación como las direcciones de memoria y los
valores se representan mediante código binario. Obsérvese que la equivalencia real en instrucciones
máquina sería exclusivamente la cadena binaria 0110010000110001010101010001, difícilmente
comprensible de forma directa por el programador.
6
CURSO 2018/19 1. INTRODUCCIÓN A LA PROGRAMACIÓN
7
CURSO 2018/19 1. INTRODUCCIÓN A LA PROGRAMACIÓN
8
CURSO 2018/19 1. INTRODUCCIÓN A LA PROGRAMACIÓN
bibliotecas
9
2
TIPOS DE DATOS
Y EXPRESIONES
10
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
TIPO ENTERO
El tipo entero se representa en C mediante la palabra clave int y consiste en el subconjunto de
valores enteros contenido en el intervalo [-2147483648, 2147483647] (equivalente al intervalo
[-231, 231-1] que permite representar 232=4.294.967.296 valores distintos y ocupa 4 bytes 1). Un
literal entero es una secuencia de uno o más dígitos entre el 0 y el 9. Al literal puede añadírsele un
signo positivo o negativo (+ o −), aunque se asumirá el signo positivo cuando no se especifique
ningún signo. Sin embargo, no admite el uso de separadores de unidades de millar ni el empleo del
separador decimal aunque la parte decimal no sea significativa, debiendo por tanto aparecer
únicamente los dígitos que constituyen la cifra.
Ejemplos de literales válidos de tipo int son:
5 -15 2003
Ejemplos de literales no válidos como tipo int son:
-1050.0 3.456 3,200
TIPO REAL
El tipo real consiste en un subconjunto de los números reales. Un literal real consta de una parte
entera y una parte decimal, separadas por un punto decimal. En C, existen dos tipos básicos para
representar valores reales: simple precisión (float) y doble precisión (double). El tipo float
ocupa 4 bytes y permite representar valores en el rango [1.2×10 -38, 3.4×1038] (positivo y negativo),
además del cero. El tipo double ocupa 8 bytes y permite representar valores en el rango
[2.2×10-308, 1.8×10308] (también positivo y negativo), además del cero.
En aplicaciones científicas, a menudo se emplea una representación especial para manejar
números muy grandes o muy pequeños. Por ello, en C existe una representación denominada
notación exponencial donde cada literal consta de un número entero o real (mantisa) y de un
número entero (exponente), separados por la letra "e" (en minúscula o mayúscula). Por ejemplo, el
literal 1.345e2 es equivalente a 1.345×102 o 134.5, y el literal 2.058e-3 es equivalente a
2.058×10-3 o 0.002058. En el primer valor, el punto decimal se desplaza dos lugares hacia la
derecha porque el exponente es +2. En el segundo, el punto decimal se desplaza tres lugares hacia
la izquierda porque el exponente es -3.
Ejemplos de literales reales válidos en C son:
0.45 .23 1234. 1e10 -2e-3 0.2E4
Ejemplos de literales reales no válidos en C son:
1e0.1 12.0a10 1,345.5 1.345,5 2.3-e5 34
TIPO CARÁCTER
El tipo carácter se representa en C con la palabra clave char y consiste en el conjunto finito y
ordenado de los caracteres representables por el ordenador (en el caso de los PC's, consiste en el
conjunto de caracteres incluido en la tabla de códigos ASCII). Un literal de tipo carácter se
representa en C mediante un solo carácter encerrado entre comillas simples o apóstrofos.
1 Los intervalos de valores válidos y el número de bytes ocupados por los datos de cada tipo pueden variar según el
compilador y plataforma usadas.
11
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
subraya
letra
subraya
12
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
Algunas de las ventajas que puede proporcionar la definición de constantes simbólicas frente al
uso directo de literales son las siguientes:
Facilita la comprensión del programa: la elección de un identificador alusivo al
significado del valor que representa puede facilitar la comprensión del programa. Por
ejemplo, si en un programa hacemos referencia al porcentaje del IVA, será más
comprensible leer el identificador IVA que el literal 21.
Facilita la modificación del código del programa: si es necesario modificar un dato
considerado como constante en el programa, la definición de una constante simbólica
permite hacerlo en un solo paso en lugar de tener que explorar todo el código en busca
de literales que hagan referencia a ese dato. Por ejemplo, si el IVA variase, bastaría con
modificar el valor asociado a la constante simbólica en la definición para que dicha
modificación actuara sobre todas las referencias incluidas en el programa.
No obstante, antes de emplear una constante simbólica en lugar de un literal en un programa,
debe considerarse si alguna de las ventajas mencionadas va a ser aprovechada, pues en caso
contrario solo se conseguirá aumentar el tamaño del programa y hacerlo menos claro. Por ejemplo,
si en un programa quisiéramos contabilizar el número de valores que el usuario introduce por
teclado, no sería adecuado definir una constante simbólica para representar al literal 1 que debe
tomar el contador como valor inicial, ya que, por un lado, referirse a dicho valor mediante un
13
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
utilizando la palabra entero para hacer referencia al tipo int de C, la palabra real para los
diferentes tipos de reales y la palabra carácter para el tipo char.
En C, el diagrama sintáctico es el siguiente:
identificador ;
tipo
de variable
,
14
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
cadena).
Las variables de tipo cadena de caracteres permiten almacenar cadenas con una longitud máxima
que se indica en la declaración entre corchetes junto al identificador. Por ejemplo, para declarar una
variable frase de tipo cadena de caracteres con un máximo de 15 caracteres se utiliza la siguiente
sintaxis:
char frase[15];
que permitirá almacenar frases de hasta 14 caracteres significativos, pues el carácter nulo de fin de
cadena ocupará la última posición.
2.2 EXPRESIONES
Una expresión matemática tradicional está formada por una combinación de operandos,
operadores y paréntesis. Por ejemplo:
∑ x − x n 2
n−1
15
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
16
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
Los operadores lógicos son: ! (no-lógico), && (y-lógico) y || (o-lógico). Se aplican casi
siempre a operandos que son subexpresiones lógicas, aunque en general pueden aplicarse a
cualquier valor entero. En este sentido, el 0 se interpretará como falso y cualquier entero distinto de
0 (no solo el 1) se interpretará como verdadero. El resultado será 1 o 0 (verdadero o falso,
respectivamente). Los operadores && y || son operadores binarios, mientras que ! es unario.
Los operadores &&, || y ! vienen definidos por sus tablas de verdad:
a b a && b
distinto de 0 distinto de 0 1 Devuelve un resultado
distinto de 0 0 0 verdadero si y solo si los
0 distinto de 0 0 dos operandos son
0 0 0 verdadero
a b a || b
distinto de 0 distinto de 0 1 Devuelve un resultado
distinto de 0 0 1 verdadero si uno
0 distinto de 0 1 cualquiera de los
0 0 0 operandos es verdadero
a !a
distinto de 0 0 Devuelve un resultado
0 1 opuesto al del operando
17
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
Si aparecen dos o más operadores lógicos iguales en una expresión, los operadores ! se aplicarán
de derecha a izquierda y los operadores && y || de izquierda a derecha. Por ejemplo, si X=4 e
Y=3, la expresión lógica (X > 3) || (Y > 5) && !(X=4) será verdadero (1).
Los tipos de datos de los argumentos y del valor devuelto por algunas de las funciones internas
más usuales se muestran en la siguiente tabla. El tipo de los argumentos se representa entre los
paréntesis de las funciones (i=int, d=double, c=char), si bien los argumentos de tipo
double también admiten valores de cualquier otro tipo numérico (que será convertido a double).
Función Tipo Devuelto Cabecera Propósito
abs(i) int math.h Valor absoluto de i
fabs(d) double math.h Valor absoluto de d
ceil(d) double math.h Redondeo por exceso (el entero más pequeño mayor o igual a d)
floor(d) double math.h Redondeo por defecto (el entero más grande menor o igual a d)
cos(d) double math.h Coseno de d
sin(d) double math.h Seno de d
tan(d) double math.h Tangente de d
exp(d) double math.h Exponencial de d (ed)
log(d) double math.h Logarítmo neperiano de d
pow(d1,d2) double math.h Potencia de d1 elevado a d2
sqrt(d) double math.h Raíz cuadrada de d
tolower(c) char ctype.h Convertir c a minúsculas
toupper(c) char ctype.h Convertir c a mayúsculas
18
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
2.4 PUNTEROS
Un puntero es un dato que representa la dirección de memoria donde se almacena otro dato. Por
ello, se dice que el valor de un puntero apunta a otro valor. Los punteros son usados muy
frecuentemente en C y están relacionados con otros conceptos como los de arrays y modularidad
que se estudiarán en capítulos posteriores.
Para trabajar con punteros es necesario conocer los operadores de dirección e indirección. El
operador de dirección (&) permite obtener la dirección de memoria en la que se encuentra
almacenado un dato (es decir, la dirección de memoria asociada a una variable). El resultado de la
operación de dirección será, por tanto, de tipo puntero. Por ejemplo, si v es una variable declarada
de tipo real, en el siguiente esquema
&v 65522
v 3.154
v representa el contenido de la variable (el valor real 3.154) y &v representa la dirección de
memoria donde se almacena dicho valor (la posición 65522). Se dice que &v es un puntero a v.
El operador de indirección (*) permite obtener el valor al que apunta un puntero (es decir, el
valor contenido en la dirección de memoria que representa el puntero). Por ejemplo, si pv es una
variable puntero que apunta a la variable v (es decir, pv vale &v), entonces *pv representa el valor
al que apunta la variable puntero pv (es decir, *pv es igual a v).
En el siguiente esquema se representa la relación entre v y pv mediante los operadores de
dirección e indirección:
La declaración de una variable de tipo puntero requiere indicar el tipo del valor al que apuntará
el puntero y preceder al identificador del operador de indirección. En el ejemplo anterior, la
declaración de pv tanto en algoritmia como en C sería:
En algoritmia: En C:
VARIABLES float *pv;
*pv:real
19
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
4. + (suma), - (resta)
5. <, >, <=, >=
6. ==, !=
7. &&
8. ||
Los operadores de la misma prioridad se aplicarán de izquierda a derecha, exceptos los
operadores unarios (!, +, -, (tipo), & y *) que se aplicarán de derecha a izquierda.
20
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
EJERCICIOS
d)
a c2
a 2 b 2b
×
g)
q−2
k) 2
l
g
2 c b2 c h) b −4a c
2
l)
2cos
2a 1−tan 2
4º) Escribir las siguientes expresiones aritméticas en C como expresiones algebraicas:
a) sqrt(x/y+x/z)
b) x+3/y+2
c) exp(-pow(1-2*x/a,2))
5º) Determinar el valor y tipo del resultado de las siguientes expresiones o decir si no son válidas:
a) sqrt(25)/2
b) pow(sqrt(9),2)
c) 44%(6/3.0)
d) 44%6/3.0
e) 16/5%3
f) 16/5*5
g) 16/5*(double) 5
h) 16/(double)5*5
i) !(floor(6.6)==ceil(5.3)) || *&p==p && ceil(5./3)==5/3
j) 4/2*3/6+fabs(6/2-pow(3,2))*2
k) "A" <= "B"
l) 6>2 && 5<4 || !(toupper(tolower('A'))=='A')
21
CURSO 2018/19 2. TIPOS DE DATOS Y EXPRESIONES
22
3
REPRESENTACIÓN GRÁFICA
DE LOS ALGORITMOS
Y SU TRADUCCIÓN A C
En el Capítulo 1 estudiamos que un algoritmo nos permite describir paso a paso el proceso
necesario para resolver un problema. La representación de un algoritmo se hace bien mediante texto
(pseudocódigo), bien mediante fórmulas, o bien de forma gráfica utilizando símbolos geométricos
en lo que se denominan diagramas.
La representación de algoritmos mediante diagramas es una forma clara e intuitiva de describir
los distintos pasos del método de resolución, su orden y su estructura. En este capítulo se tratará la
representación de los distintos elementos de un algoritmo mediante diagramas. Paralelamente, se
irán introduciendo las reglas sintácticas para traducir a lenguaje C cada uno de esos elementos.
1 Edsger W. Dijkstra. Notes on structured programming, en Ole-Johan Dahl, Edsger W. Dijkstra y C. A. R. Hoare,
editores, Structured Programming. Academic Press, 1972.
2 Bohm, C. y Jacopini, G, Flow Diagrams, Turing Machines and Languages with Only Two Formation Rules,
Communications of the ACM, No. 5, Mayo 1966, págs. 366-371.
23
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
1 2 3 4
Los diagramas estructurados se emplean para representar algoritmos que respetan las reglas de la
programación estructurada. Aunque existen diferentes métodos, aquí nos centraremos en el método
de Tabourier (Ilustración 1), según el cual, todo diagrama estructurado comienza por un rectángulo
dividido horizontalmente, en cuya parte superior aparece el nombre del programa y en la inferior la
palabra BLOCK. De este rectángulo parten, unidos mediante líneas, los pasos que forman el
algoritmo encerrados en rectángulos y rombos. La estructura arborescente resultante se recorre en
preorden (de izquierda a derecha y de arriba a abajo) de forma que la operación situada a la derecha
de la actual se examina solo tras haber examinado todas las descendientes de dicha operación actual.
int main()
{
declaración de variables
24
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
EJEMPLO 3.1. El siguiente programa calcula y muestra la suma de dos números enteros leídos desde teclado.
#include <stdio.h>
int main()
{
int s1,s2,result;
25
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
Una instrucción de asignación en C utiliza como operador de asignación el carácter igual (=) y
finaliza en punto y coma (;). Por ejemplo, edad=25; correspondería a la operación de asignación
anterior. Adviértase la diferencia entre este operador y el operador relacional “igual que” (==)
estudiado en el capítulo anterior, ya que es habitual confundir ambos: el primero asigna un valor a
una variable y el segundo compara dos valores para determinar si son iguales.
En C, el tipo del valor obtenido al evaluar el lado derecho de una instrucción de asignación se
convertirá al tipo de la variable que se encuentra en el lado izquierdo, lo que puede provocar una
alteración del valor realmente almacenado (por ejemplo, al asignar el valor real 5.45 a una variable
de tipo entero, se almacenará el valor 5). Por ello, para evitar errores, es recomendable en general
que el dato que se asigna pueda almacenarse sin pérdidas en la variable especificada (por ejemplo,
el valor entero 5 podrá almacenarse sin pérdidas en una variable de tipo entero o de tipo real).
26
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
Obsérvese que cada identificador de variable viene precedido por el operador de dirección (&), es
decir, tras la cadena de control se indican las direcciones de memoria asociadas a las variables
donde se almacenarán los valores introducidos desde teclado.
Cuando se utiliza una misma instrucción para leer más de un valor numérico, estos deben
introducirse desde teclado separados por una pulsación de la tecla Intro o espacios. Para finalizar la
entrada se pulsará la tecla Intro.
EJEMPLO 3.2. Dadas las variables grupo, habitantes y masa, declaradas como char, int y double,
respectivamente, podrán recibir valores desde el teclado utilizando la siguiente instrucción de entrada:
scanf("%c %d %lf", &grupo, &habitantes, &masa);
Los valores deberán introducirse desde teclado separados entre sí mediante la tecla Intro o espacios y la introducción
deberá finalizar con la tecla Intro, por ejemplo:
B 146832 1.9891e30
o bien
B
146832
1.9891e30
Obsérvese que en la instrucción scanf las especificaciones de conversión van separadas entre sí por espacios y que
cada identificador va precedido del carácter ampersand (&). Por otro lado, los valores reales podrá introducirlos el
usuario indistintamente en notación clásica o en notación exponencial.
Para leer desde teclado cadenas de caracteres, emplearemos una función específica para este
propósito: la función gets, incluyendo entre paréntesis el identificador de la variable de tipo
cadena a la que se asignará el valor introducido desde teclado. Para evitar ciertos problemas cuando
se emplea en combinación con la función scanf, cada llamada a gets la precederemos de una
llamada a la función fflush(stdin);, que borra el buffer de teclado.
EJEMPLO 3.3. Dada la variable pelicula declarada como cadena de caracteres, podrá recibir una cadena desde
teclado utilizando la siguiente instrucción de entrada:
fflush(stdin); gets(pelicula);
Obsérvese que en la función gets el identificador ahora no va precedido del carácter ampersand (&).
27
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
En C, utilizaremos la función printf para mostrar por pantalla valores de cualquier tipo
(enteros, reales, caracteres y cadenas), cuyo archivo de cabecera es también stdio.h. Su diagrama
sintáctico es el siguiente:
printf( cadena de );
control
expresión ,
En la instrucción printf, la cadena de control deberá contener una especificación de
conversión por cada expresión y además podrá contener otros caracteres cualesquiera (incluidas las
secuencias de escape vistas en el capítulo anterior) que se mostrarán por pantalla. El valor de cada
expresión se insertará en la cadena de control allí donde aparezca su correspondiente especificación
de conversión.
Las especificaciones de conversión más habituales con la instrucción printf y sus formatos de
salida asociados se muestran en la siguiente tabla:
Especificación
de conversión Tipo
%d int
%f float, double
(notación clásica)
%e float, double
(notación exponencial)
%g float, double
(notación clasica/exponencial dependiendo de la precisión)
%c char
%s char []
EJEMPLO 3.4. Dadas las variables grupo, habitantes y masa declaradas como char, int y double,
respectivamente, y con los valores del Ejemplo 3.1, la siguiente instrucción de salida:
printf("Grupo=%c\nBadajoz=%d hab.\nMasa Sol=%e kg.\n",grupo,habitantes,masa);
generará las siguientes tres líneas en pantalla:
Grupo=B
Badajoz=146832 hab.
Masa Sol=1.989100e+030 kg.
Obsérvese que el valor de las variables se ha insertado en el lugar de las correspondientes especificaciones de
conversión dentro de la cadena de control.
En estas instrucciones los datos se visualizan con un determinado formato por defecto que
depende del tipo del dato. Por ejemplo, en el caso de los reales, las instrucciones
a=15.2;
printf("%f",a);
producirían el resultado
15.200000
28
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
mostrando por tanto el valor de la variable a con 6 dígitos decimales, aunque 5 de ellos no sean
significativos.
Para que la información pueda mostrarse de forma más clara, es posible añadir ciertos
modificadores a las especificaciones de conversión.
Uno de estos modificadores permite indicar el número mínimo de caracteres que ocupará en
pantalla el valor correspondiente. Cuando el valor a mostrar tenga menos caracteres que el número
de caracteres reservado, el valor será precedido de espacios hasta completar dicho número. Cuando
el valor tenga más caracteres que los reservados, el valor no aparecerá truncado, sino que se tomarán
los caracteres necesarios por la derecha. Este modificador se indica mediante un número situado
inmediatamente después del carácter % en la especificación de conversión correspondiente.
EJEMPLO 3.5. Dadas las variables grupo, habitantes y masa del ejemplo anterior, la siguiente instrucción de
salida:
printf("Grupo=%4c\nBadajoz=%5d hab.\nMasa Sol=%14e kg.\n",grupo,habitantes,masa);
generará las siguientes tres líneas en pantalla:
Grupo= B
Badajoz=146832 hab.
Masa Sol= 1.989100e+030 kg.
Obsérvese que el valor de grupo y de masa aparece precedido de 3 y 1 espacios para completar los 4 y 14
caracteres reservados, respectivamente. Sin embargo, aunque para habitantes se han reservado 5 caracteres y el valor
ocupa 6, se visualiza el dato completo.
En el caso de los valores reales, es posible indicar un modificador adicional que especifique el
número de dígitos decimales que se mostrarán por pantalla. El valor a mostrar se redondeará, si es
preciso, al número de decimales indicado por el modificador. Este modificador se incluirá en la
especificación de conversión mediante un punto seguido de un número entero, tras el carácter % (es
decir, %.entero) o, si se especifica el número mínimo de caracteres reservados, tras dicho número
(es decir, %entero.entero).
EJEMPLO 3.6. Dada la variable masa del ejemplo anterior y la variable numeroPi de tipo float y valor
3.14159265, la siguiente instrucción de salida:
printf("Masa Sol=%.2e kg.\nNúmero PI=%8.4f\n",masa,numeroPi);
mostrará en pantalla las siguientes líneas:
Masa Sol=1.99e+030 kg.
Número PI= 3.1416
29
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
BLOCK
1 2 3 ... n
EJEMPLO 3.7. Realizar un programa que calcule el perímetro y el área de un rectángulo a partir de la base y la
altura dadas por el usuario.
ANÁLISIS:
a) Datos de entrada:
bas: base del rectángulo. Teclado. (bas > 0)3
alt: altura del rectángulo. Teclado. (alt > 0)3
b) Datos de salida:
per: perímetro del rectángulo. Monitor.
area: área del rectángulo. Monitor.
DISEÑO:
a) Parte declarativa:
VARIABLES
bas,alt,per,area:real
b) Representación algorítmica:
rectangulo
BLOCK
CODIFICACIÓN:
/**************************************************/
/** Muestra el perímetro y área de un rectángulo **/
/**************************************************/
#include <stdio.h>
int main()
{
float bas,alt,per,area;
3 Dado que aún no se han estudiado las estructuras que permitirán realizar el control de entrada correspondiente a
estas restricciones, dicho control se omitirá excepcionalmente en la representación algorítmica de este ejemplo.
30
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
expresión acción
lógica
EJEMPLO 3.8. La siguiente porción de algoritmo expresa que la operación de asignación se ejecutará solo si la
variable x es mayor que 0.
if then
x>0 positivo ← 1
Es posible que la acción a realizar si se cumple la condición sea una acción compuesta, esto es,
que conste de varios pasos más simples. Una acción compuesta en un diagrama de Tabourier se
representará mediante una estructura secuencial:
BLOCK
31
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
Por tanto, una estructura selectiva simple cuando contiene una acción compuesta se representará
en un diagrama de Tabourier de la siguiente forma:
if then
expresión BLOCK
lógica
{ instrucción }
Por tanto, la estructura selectiva simple, cuando contiene una acción compuesta, utilizará el
diagrama sintáctico siguiente:
expresión
if ( ) { instrucción }
lógica
EJEMPLO 3.9. A partir de dos números reales introducidos por teclado, mostrar el resultado de la división si el
divisor es distinto de 0.
ANÁLISIS:
a) Datos de entrada:
ddo: Dividendo. Teclado.
dsor: Divisor. Teclado.
b) Datos de salida:
coc (solo si dsor ≠ 0): Cociente de la división. Monitor.
DISEÑO:
a) Parte declarativa:
VARIABLES
coc,ddo,dsor:real
b) Representación algorítmica:
division
BLOCK
32
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
CODIFICACIÓN:
/*****************************/
/** Cálculo de una división **/
/*****************************/
#include <stdio.h>
int main()
{
float ddo,dsor,coc;
if then else
Si la expresión lógica toma valor verdadero, se ejecutará la acción 1; si toma valor falso, se
ejecutará la acción 2. Al igual que en las estructuras selectivas simples, las acciones de una
estructura selectiva doble pueden ser compuestas, en cuyo caso se representarán del modo descrito
anteriormente para la estructura selectiva simple.
En C, el diagrama sintáctico correspondiente a la estructura selectiva doble es el siguiente:
expresión bloque de bloque de
if ( ) else
lógica sentencias sentencias
donde bloque de sentencias se refiere de forma genérica a una única acción simple o a una acción
compuesta, aplicándose en este último caso el diagrama sintáctico para acciones compuestas
estudiado anteriormente.
33
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
EJEMPLO 3.10. Indicar si, dado un número por teclado, este es par o impar.
ANÁLISIS:
a) Datos de entrada:
n: Número entero. Teclado.
b) Datos de salida:
paridad: Mensaje indicando la paridad del número n. Monitor
DISEÑO:
a) Parte declarativa:
VARIABLES
n: entero
paridad
BLOCK
CODIFICACIÓN:
/*****************************************/
/** Muestra si un número es par o impar **/
/*****************************************/
#include <stdio.h>
int main()
{
int n;
34
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
La estructura selectiva múltiple permite seleccionar una alternativa de entre varias posibles, en
función del resultado de una expresión de tipo entero o de tipo carácter. En un diagrama de
Tabourier, esta estructura se representa de la siguiente forma:
switch
Las listas lista 1, lista 2, ..., lista n contendrán el o los valores asociados a la alternativa
correspondiente, separados por comas si son varios. La cláusula default es opcional y se usará
cuando una alternativa englobe a los valores de la expresión que no se han indicado explícitamente.
En C, el diagrama sintáctico de la estructura selectiva múltiple es:
switch ( ) { : bloque de
expresión case expresión
sentencias
break;
bloque de }
default
sentencias
Cada valor de una misma lista se representa mediante un par case-expresión acabado en dos
puntos (:). Tras la lista, se sitúa el bloque de sentencias correspondiente a la acción asociada.
Obsérvese que se utiliza una instrucción break; para separar cada par lista-acción de la siguiente
y, si está presente, del par default-acción.
EJEMPLO 3.11. Se desea diseñar un algoritmo que escriba por pantalla la duración en días correspondiente al mes
cuyo número de orden se indique por teclado o un mensaje de error si dicho valor no está en el intervalo [1,12].
ANÁLISIS:
a) Datos de entrada:
mes: Número de orden del mes. Teclado.
b) Datos de salida:
dias: Mensaje indicando el número de días que tiene mes o un mensaje de error. Monitor
DISEÑO:
a) Parte declarativa:
VARIABLES
mes:entero
duracionMes
BLOCK
35
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
CODIFICACIÓN:
/******************************************************************************/
/** Muestra la duración en días correspondiente al número de orden de un mes **/
/******************************************************************************/
#include <stdio.h>
int main()
{
int mes;
expresión acción
lógica
36
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
EJEMPLO 3.12. Sumar una serie de números enteros no negativos introducidos por teclado hasta que se introduzca
uno negativo y mostrar el total por pantalla.
ANÁLISIS:
a) Datos de entrada:
n[1..k]: Secuencia de valores no negativos (excepto el último, que será negativo). Teclado.
b) Datos de salida:
tot: Suma de los valores no negativos de la secuencia. Monitor.
c) Comentarios:
Para realizar la suma no será necesario recordar todos los valores introducidos, sino que basta con ir
recordando el total acumulado. Por lo tanto, emplearemos una variable acumuladora para almacenar dicho
total y otra para almacenar el número actual.
DISEÑO:
a) Parte declarativa:
VARIABLES
n,tot:entero
b) Representación algorítmica:
contar
BLOCK
n≥0 BLOCK
37
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
CODIFICACIÓN:
/**************************************************************/
/** Muestra la suma de una secuencia de valores no negativos **/
/**************************************************************/
#include <stdio.h>
int main()
{
int n,tot;
tot=0;
printf("Introduzca un número: ");
scanf("%d",&n);
while (n >= 0)
{
tot=tot+n; /* Operación de acumulación */
printf("Introduzca otro número: ");
scanf("%d",&n);
}
printf("La suma es: %d\n",tot);
return 0;
}
acción expresión
lógica
Por tanto, una estructura do-while comienza ejecutando el cuerpo del bucle. A continuación se
evalúa la expresión lógica. Si el resultado es falso, el bucle termina; si es verdadero, el cuerpo del
bucle se ejecuta otra vez y a continuación la condición se evalúa de nuevo. La ejecución del cuerpo
del bucle se repetirá mientras la condición sea verdadera. Obsérvese que, en una estructura
do-while, el cuerpo del bucle se ejecuta al menos una vez.
La estructura repetitiva do-while deberá utilizarse cuando el número de iteraciones sea
desconocida a priori y se requiera ejecutar el cuerpo del bucle, al menos, una vez.
En C, la estructura do-while se implementa mediante el siguiente diagrama sintáctico:
bloque de expresión
do while ( ) ;
sentencias lógica
A diferencia del resto de instrucciones de control, la instrucción do-while acaba en punto y
coma.
EJEMPLO 3.13. Leer desde teclado una secuencia creciente de valores enteros. La secuencia finalizará cuando se
introduzca un valor menor que el anterior.
ANÁLISIS:
a) Datos de entrada:
n[1..k]: Secuencia de valores creciente, excepto el último valor, que será menor que el anterior. Teclado.
38
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
b) Datos de salida:
c) Comentarios:
Para comprobar si la secuencia es creciente no será necesario recordar todos los valores introducidos, sino
que basta con recordar el inmediatamente anterior y compararlo con el actual. Por lo tanto, emplearemos una
variable para almacenar el número actual y otra para almacenar el inmediatamente anterior.
DISEÑO:
a) Parte declarativa:
VARIABLES
n,ant:entero
creciente
BLOCK
CODIFICACIÓN:
/**********************************************************/
/** Lee desde teclado una secuencia de valores creciente **/
/**********************************************************/
#include <stdio.h>
int main()
{
int n,ant;
for do
39
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
En el diagrama, id es una variable que controla de modo automático el número de iteraciones del
bucle y se denomina variable índice. El valor inc podrá ser un entero positivo o negativo y
provocará, respectivamente, un incremento o decremento de la variable índice tras cada iteración.
La ejecución de la estructura for-do comienza asignando el valor inicial Vi a la variable índice. A
continuación comprueba si el valor de la variable índice supera al valor final Vf. Si es así, la
ejecución del bucle finaliza; en otro caso, la ejecución del cuerpo del bucle se repetirá hasta que la
variable índice sobrepase al valor final Vf, la cual se incrementará/decrementará automáticamente en
el valor de inc después de cada iteración.
El valor de la variable índice queda indefinido tras finalizar el bucle, por lo que no se deberá
suponer ningún valor para la misma en acciones posteriores al bucle.
En C, la estructura for-do se implementa con la instrucción for empleando el siguiente
diagrama sintáctico:
suma100
BLOCK
40
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
CODIFICACIÓN:
/***********************************************************/
/** Muestra la suma de los 100 primeros números naturales **/
/***********************************************************/
#include <stdio.h>
tot=0;
for (i=NUMMIN; i <= NUMMAX; i=i+1)
tot=tot+i;
printf("La suma es %d\n",tot);
return 0;
}
41
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
EJERCICIOS
1º) En el supermercado “El 13" las ventas no van muy bien. Por ello, han decidido lanzar una
campaña de captación de clientes consistente en aplicar un descuento de un 5% sobre el
importe de la compra si este supera los 60 euros y un 5% adicional si, además, dicho importe
(despreciando céntimos de euro) es divisible entre 13. Desarrollar un programa que lea por
teclado el importe inicial de una compra y calcule y muestre por pantalla el descuento
aplicado y el importe final.
2º) Calcular y mostrar por pantalla la estatura del individuo más alto y más bajo de una serie de
100 estaturas introducidas por teclado.
3º) Se proporcionan por teclado las calificaciones de un examen (entre 0 y 10). Desarrollar un
programa que muestre por pantalla la media de la clase y el número de aprobados
(calificaciones superiores o iguales a 5). La introducción de calificaciones terminará cuando se
teclee el valor -1.
4º) Calcular el producto de dos valores enteros no negativos introducidos por teclado, teniendo en
cuenta que solo podrá emplearse la operación de suma.
5º) Escribir en pantalla todos los números primos entre 2 y 10000, ambos inclusive.
6º) El desarrollo de la serie de Maclaurin para el logaritmo neperiano es:
( x−1)2 ( x−1)3 ( x−1)4 ( x−1)5
ln ( x ) = ( x−1) − + − + − ... , (0< x≤2)
2 3 4 5
Escribir un programa que evalúe y muestre por pantalla el valor de la serie con n términos,
donde x y n se introducen por teclado.
7º) Calcular la división entera de dos valores enteros no negativos introducidos por teclado
teniendo en cuenta que solo podrán emplearse las operaciones de suma y resta.
8º) El máximo común divisor de dos números es el mayor de sus divisores comunes. Realizar el
análisis, diseño y codificación de un programa C que, dados dos números enteros mayores que
0 introducidos por teclado, muestre en pantalla su máximo común divisor.
9º) Realizar el análisis, diseño y codificación en C de un programa que, a partir de cuatro
números enteros positivos a, b, c y d leídos desde teclado (siendo a<b y c<d), muestre en
pantalla la suma de los números comprendidos en el intervalo [c,d] y, a continuación, todos
los números dentro del intervalo [a,b] que sean mayores que dicha suma o, en el caso de que
no haya ningún número que cumpla la condición, un mensaje indicándolo.
10º) El tamaño de una población formada inicialmente por un número determinado de individuos
Tini evoluciona del siguiente modo:
a) cada día, se añaden dos individuos a la población
b) cada tres días, tras la aplicación del apartado a, hay un incremento extra del 50%
(despreciando decimales) de los individuos existentes en la población
c) cada cinco días, tras la aplicación del apartado a y, en su caso, del apartado b, hay una
pérdida de un cuarto (despreciando decimales) de los individuos existentes en la población
Realizar el análisis, diseño y codificación en C de un programa que, leyendo desde teclado dos
valores Tini y Tfin, muestre por pantalla la evolución del tamaño y el número de días necesarios
42
CURSO 2018/19 3. LA REPRESENTACIÓN GRÁFICA DE LOS ALGORITMOS Y SU TRADUCCIÓN A C
para que una población con un tamaño inicial Tini alcance o supere el tamaño Tfin. Al menos
deberá haber dos individuos en la población inicial y el tamaño de la población final deberá
ser siempre mayor que el de la inicial.
Así por ejemplo, dados los valores leídos desde teclado Tini=5 y Tfin=100, deberá mostrarse la
evolución del tamaño de la población
7 9 16 18 15 25 27 29 46 36 38 60 62 64 75 77 79 121
y el número de días 18, donde la aplicación del apartado b se indica en negrita y del apartado
c mediante subrayado
43
4
ESTRUCTURAS DE DATOS (I):
ARRAYS
4.1 INTRODUCCIÓN
Una estructura de datos es una colección de datos caracterizada por su organización y por las
operaciones definidas sobre ella. Los tipos de datos utilizados para declarar estructuras de datos se
denominan tipos compuestos y se construyen a partir de los tipos simples ya estudiados.
Distinguimos dos categorías de estructuras de datos:
Estáticas: su tamaño se determina a priori, antes del comienzo de la ejecución del programa,
y este no podrá incrementarse ni disminuirse en tiempo de ejecución. Esto implicará que
cuando se trabaje con una estructura de datos estática cuyo tamaño se desconoce en la fase de
diseño, será necesario establecer un tamaño máximo y reservar espacio en memoria para ese
máximo (con el posible desperdicio de memoria que esto pueda conllevar). Entre las
estructuras de datos estáticas distinguimos arrays, cadenas de caracteres y registros.
Dinámicas: su tamaño se determina en tiempo de ejecución, reservando y liberando espacio
en memoria en el momento que interese. Esto permitirá, por tanto, optimizar al máximo el
espacio de ocupación en memoria, aunque requiere una gestión de memoria más complicada.
Se distinguen listas, árboles y grafos.
En esta asignatura nos centraremos en las estructuras de datos estáticas, adecuadas como una
primera aproximación al manejo de estructuras de datos por ser más sencillas de gestionar.
Una característica común a todas las estructuras de datos es la existencia de un único
identificador que hace referencia a la misma en su conjunto. Además, cada tipo de estructura de
44
CURSO 2018/19 4. ESTRUCTURAS DE DATOS (I): ARRAYS
datos dispone de su propio mecanismo para hacer referencia de forma independiente a los elementos
que la integran.
4.2 ARRAYS
Un array es una colección de elementos de un mismo tipo, donde cada elemento puede
identificarse por su posición dentro de la estructura. Todo array posee un identificador que lo
designa y una serie de índices que toman valores enteros y permiten diferenciar por su posición a los
distintos elementos que lo constituyen.
Para hacer referencia a cada elemento del vector, tanto en algoritmia como en C, se utiliza la
siguiente sintaxis:
identificador[índice]
Por ejemplo, el número de habitantes de la tercera población se designa habitantes[2] y su
contenido es igual a 5.
En algoritmia, la declaración de estructuras de datos de tipo vector utiliza el siguiente diagrama
sintáctico:
identificador valor
VARIABLES [ ] : tipo
de variable entero
,
El valor entero representa el número de elementos del vector y, por tanto, determina el rango de
valores que puede tomar el índice (en C, desde 0 a valor entero – 1, ambos inclusive).
45
CURSO 2018/19 4. ESTRUCTURAS DE DATOS (I): ARRAYS
EJEMPLO 4.1. A partir de las edades de 10 individuos introducidas por teclado, calcular y mostrar cuántos
individuos son mayores y cuántos menores que la media.
ANÁLISIS:
a) Datos de entrada:
NUMIND=10. Número de individuos. Dato fijo.
edad[1..NUMIND]: Edades de los individuos. Teclado. (edad[i] ≥ 0, ∀i)
b) Datos de salida:
may: Número de individuos con edad superior a la media de edad[1..NUMIND]. Monitor.
men: Número de individuos con edad inferior a la media de edad[1..NUMIND]. Monitor.
c) Comentarios:
Dado que, una vez calculada la media de las edades, será necesario recorrer de nuevo la lista de edades, se
utilizará un vector para representar dicha lista.
Se utilizará una variable índice para recorrer el vector, en primer lugar, para almacenar los valores en él
durante la lectura desde teclado y el cálculo de la media y, en segundo lugar, para determinar cuántos de
esos valores son mayores y cuántos menores que la media.
Se utilizará una variable para acumular los valores del vector durante el cálculo de la media.
Se utilizará una variable para almacenar el resultado de la media.
DISEÑO:
a) Parte declarativa:
CONSTANTES
NUMIND=10
VARIABLES
edad[NUMIND]:entero
med:real
i,suma,may,men:entero
b) Representación algorítmica:
contar
BLOCK
46
CURSO 2018/19 4. ESTRUCTURAS DE DATOS (I): ARRAYS
CODIFICACIÓN:
/*************************/
/*** E D A D E S ***/
/*************************/
#include <stdio.h>
/* Visualización de resultados */
printf("Número de individuos mayores que la media: %d.\n",may);
printf("Número de individuos menores que la media: %d.\n",men);
return 0;
}
47
CURSO 2018/19 4. ESTRUCTURAS DE DATOS (I): ARRAYS
Para referenciar a cada elemento de un array bidimensional se utilizan dos índices. El primero se
refiere a la fila y el segundo a la columna que ocupa dicho elemento. Se utiliza la siguiente sintaxis:
identificador[fila][columna]
Por ejemplo, el número de habitantes de la segunda población en el censo de la primera década
se designa habitantes[1][0] y su contenido es igual a 10.
Análogamente, pueden declararse arrays de tantas dimensiones como se quiera, teniendo como
limitación el tamaño de la memoria del ordenador. El número total de elementos del array es el
producto del número de elementos de cada dimensión. Por ejemplo, un array de dimensión 3×10×2
tendrá 60 elementos. No obstante, a mayor número de dimensiones, menor será la legibilidad de la
solución y mayor la dificultad de su manejo, pues cada índice hará referencia a una característica de
los datos y debemos saber en qué orden debe situarse cada uno de los índices (por ejemplo, primero
el código de población, a continuación la década, etc.).
En general, un elemento de un array n-dimensional se referencia con la siguiente sintaxis:
identificador[índice1][índice2]...[índicen]
Al igual que en el caso de los vectores, todos los elementos de un array multidimensional deben
ser de igual tipo. Si junto con el número de habitantes del ejemplo anterior quisiéramos almacenar
el nombre de la entidad que realizó el censo (representado por un dato de tipo cadena de caracteres),
sería preciso declarar una nueva matriz de tamaño 100×3 en vez de añadir una nueva dimensión al
array original, ya que los datos a almacenar son de distinto tipo1.
En algoritmia, la declaración de una estructura de datos array multidimensional utiliza el
siguiente diagrama sintáctico:
identificador valor
VARIABLES [ ] : tipo
de variable entero
,
Ahora, cada valor entero representa el número de elementos de la dimensión correspondiente y,
por tanto, el rango de valores que puede tomar su índice (en C, desde 0 a valor entero – 1).
La traducción a C de esta declaración se realiza según el siguiente diagrama sintáctico:
identificador valor
tipo [ ] ;
de variable entero
,
Por ejemplo, la declaración de la matriz habitantes vista anteriormente emplearía la
siguiente sintaxis:
En algoritmia: En C:
VARIABLES int habitantes[100][3];
habitantes[100][3]:entero
1 Veremos en el Capítulo 6 que existe una alternativa más adecuada mediante el uso de registros.
48
CURSO 2018/19 4. ESTRUCTURAS DE DATOS (I): ARRAYS
EJEMPLO 4.2. Almacenar desde teclado valores reales en una matriz de dimensiones 20x20 por filas y mostrar por
pantalla la suma de sus columnas.
ANÁLISIS:
a) Datos de entrada:
NUMFIL=5. Número de filas. Dato fijo.
NUMCOL=5. Número de columnas. Dato fijo.
m[1..NUMFIL][1..NUMCOL]: Matriz de números reales. Teclado.
b) Datos de salida:
s[1..NUMCOL]: Sumas de las columnas de la matriz. Monitor.
c) Comentarios:
Se utilizarán dos variables índice para recorrer la matriz, en primer lugar, durante su lectura desde teclado y,
en segundo, durante el cálculo de la suma de cada columna.
Dado que se mostrará la suma de cada columna tras su cálculo, no es necesario recordar simultáneamente
cada una de ellas, por lo que solo se utilizará una variable para almacenarlas.
DISEÑO:
a) Parte declarativa:
CONSTANTES
NUMFIL=5
NUMCOL=5
VARIABLES
m[NUMFIL][NUMCOL]:real
i,j:entero
s:real
b) Representación algorítmica:
sumaColumnas
BLOCK
for do for do
CODIFICACIÓN:
/***************************************/
/*** S U M A C O L U M N A S ***/
/***************************************/
#include <stdio.h>
49
CURSO 2018/19 4. ESTRUCTURAS DE DATOS (I): ARRAYS
50
CURSO 2018/19 4. ESTRUCTURAS DE DATOS (I): ARRAYS
EJERCICIOS
1º) Leer desde teclado un vector con n números enteros y a continuación indicar por pantalla si este
es capicúa, siendo n un número entre 2 y 100, también leído desde teclado.
2º) Leer desde teclado un vector con 10 números enteros y a continuación indicar por pantalla si el
valor de algún elemento coincide con la suma de todos los que están a su izquierda en el vector.
3º) Leer desde teclado una matriz con 5×4 valores reales y a continuación mostrar su traspuesta.
4º) Leer desde teclado dos matrices A y B de dimensiones 5×4 y 4×6, respectivamente, con valores
reales y mostrar el resultado de A×B.
5º) Leer desde teclado una matriz con 6×6 valores reales positivos y dos valores a y b, y mostrar la
media de los elementos de la matriz que sean mayores que a y menores que b.
6º) Leer desde teclado un vector de 10 valores reales y mostrar la lista de índices de los elementos
del vector menores que la media del vector y el tamaño de dicha lista.
7º) Generar aleatoriamente un vector de m dígitos y leer desde teclado una lista con n índices del
vector, donde m y n se introducen por teclado y donde 10 ≤ m ≤ 30. A continuación, mostrar el
vector generado y el valor del vector que más se aproxima a la media de los elementos
apuntados por la lista de índices.
Nota: Para generar números aleatorios debe utilizarse la función interna rand(), que genera
un número aleatorio de tipo entero en el intervalo [0, 32767]. Antes de utilizar esta función en
el programa será necesario invocar una vez a la función interna srand(time(NULL)); que
inicializa el generador de números aleatorios a partir de la hora actual del sistema, para evitar
así que siempre se genere la misma secuencia de números aleatorios. Para el uso de ambas
funciones es necesario incluir los archivos de cabecera stdlib.h y time.h.
8º) Leer desde teclado y almacenar en una matriz una serie de temperaturas tomadas cada hora
durante una semana. A continuación, mostrar por pantalla la máxima de las temperaturas
mínimas diarias.
9º) Generar aleatoriamente un array tridimensional de 5×10×3 con valores entre el 1 y el 40 y
mostrar por pantalla el array generado, el valor del array que más veces se repite y el número de
repeticiones del mismo (si hay varios valores que se repiten el número máximo de veces,
devolver uno de ellos cualquiera).
10º) La distancia entre dos valores x e y se calcula como el valor absoluto de su diferencia |x-y|.
Realizar el análisis, diseño y codificación de un programa en C que lea desde teclado n valores
reales dentro del intervalo [1,n2], donde 5 ≤ n ≤ 30, y a continuación muestre por pantalla la
distancia mínima entre dos valores de posiciones distintas de entre todos los pares posibles.
11º) Realizar el análisis, diseño y codificación en C de un programa que muestre en pantalla 100
números enteros aleatorios que deberán estar entre dos números (el primero será un número
introducido por teclado que deberá estar entre el 5 y el 100, y el segundo será el 1000). Además
los números que aparezcan en pantalla no deberán estar repetidos.
12º) Realizar el análisis, diseño y codificación en C de un programa que genere aleatoriamente una
matriz de 5 filas y 10 columnas con valores enteros entre el 1 y el 5, lea un valor n desde
teclado y muestre por pantalla la matriz y un mensaje que indique si existe en ella alguna
51
CURSO 2018/19 4. ESTRUCTURAS DE DATOS (I): ARRAYS
columna que sume n y, en caso positivo, el índice de la primera columna que cumpla la
condición.
13º) Realizar el análisis, diseño y codificación en C de un programa que rellene un vector de 20
reales a partir de una secuencia de números organizados en pares (a,b). El primer número a de
cada par indica el valor que debe introducirse en el vector y será un número real mayor o igual
que cero introducido por teclado. El segundo número b de cada par especifica la cantidad de
valores que deben introducirse en el vector y será generado de manera aleatoria en el intervalo
[1,10]. Finalmente, una vez que el vector esté completamente relleno, su contenido deberá
mostrarse por pantalla.
14º) Realizar el análisis, diseño y codificación en C de un programa que:
a) en primer lugar, lea desde teclado un máximo de 30 valores reales entre 1 y 40,
almacenando los valores de nº de orden par (segundo, cuarto, sexto, etc.) en un vector y los
de orden impar (primero, tercero, quinto, etc.) en otro vector. La lectura de valores finalizará
cuando se llegue a 30 valores o se introduzcan dos valores iguales en la misma posición de
sendos vectores (sean iguales el primero y el segundo, o el tercero y el cuarto, o el quinto y
el sexto, etc).
b) en segundo lugar, una vez finalizada la lectura desde teclado, calcular y mostrar por pantalla
la distancia mayor entre pares de valores situados en la misma posición en sendos vectores.
Importante: el cálculo de la distancia descrito en el apartado b no deberá comenzar antes de
que haya finalizado la lectura descrita en el apartado a.
52
5
MODULARIDAD
Cálculo IRPF
53
CURSO 2018/19 5. MODULARIDAD
Además, la lectura de datos del contribuyente podría aún desglosarse, por ejemplo, en lectura de
datos personales y lectura de datos económicos:
Cálculo IRPF
Datos Datos
personales económicos
54
CURSO 2018/19 5. MODULARIDAD
datosEconomicos(...)
Re
. leerFecha(...) to
to
rn
to
verResultados(...) . . o
rn
rn
Re 1
o
o
. . . torn
. . . o2
55
CURSO 2018/19 5. MODULARIDAD
caso, en la especificación del dato de entrada se indicarán también las restricciones que se asume
que ya cumple dicho dato cuando llega a la función. Igualmente, los datos de salida pueden tener
como destino, no solamente el monitor, sino también el módulo llamador si son el resultado de la
función.
En la fase de diseño, en la parte declarativa y antes de la definición de constantes simbólicas y la
declaración de variables de que haga uso la función, deberá indicarse la cabecera de la función, que
contendrá los identificadores de los parámetros, el tipo asociado a cada uno de ellos y el tipo
asociado al valor devuelto por la función, utilizando el siguiente diagrama sintáctico:
identificador identificador
( : tipo ) : tipo
del módulo de parámetro
,
El identificador del módulo se refiere al nombre de la función. A continuación, entre paréntesis,
se incluirán los identificadores de los parámetros junto con sus tipos correspondientes (o
únicamente los paréntesis si la función careciera de parámetros). Por último, se indicará el tipo
devuelto por la función.
La representación algorítmica será muy similar a la vista en el Capítulo 3 para un algoritmo
completo. La única diferencia es que en un subalgoritmo, el primer símbolo del que parten el resto
de instrucciones será el que se indica a continuación:
identificador_módulo(lista de parámetros)
BLOCK
donde la lista de parámetros se refiere a los parámetros que utiliza la función y consistirá en una
lista de identificadores separados por comas (sin indicar tipos). En cuanto a identificador_módulo
será el nombre de la función.
Además, para expresar en el subalgoritmo el valor que finalmente devolverá la función como
resultado al módulo llamador, se empleará la siguiente representación:
devolver(expresión)
identificador identificador
tipo ( tipo )
de la función de parámetro
,
Las secciones de definición de constantes simbólicas y declaración de variables contendrán,
respectivamente, las constantes simbólicas y variables que la función utilice. El resto del cuerpo
estará formado por el conjunto de instrucciones que llevan a la obtención del valor que la función
debe devolver. La última instrucción del cuerpo de la función deberá ser de la forma:
return expresión;
indicando así el valor que esta devuelve como resultado al módulo llamador.
56
CURSO 2018/19 5. MODULARIDAD
EJEMPLO 5.1. Desarrollar un módulo que calcule y devuelva el factorial de un número recibido como parámetro.
ANÁLISIS:
a) Datos de entrada: M. llamador
n: Valor del que quiere calcularse el factorial. Módulo llamador. (n ≥ 0)
f n
b) Datos de salida:
factorial: Factorial de n. Módulo llamador. factorial
c) Comentarios:
Emplearemos una variable para contar el número de multiplicaciones efectuadas.
DISEÑO:
a) Parte declarativa:
factorial(n:entero):real
VARIABLES
i:entero
f:real
b) Representación algorítmica:
factorial(n)
BLOCK
i ← 2, n, 1 f ← fi
CODIFICACIÓN:
/** factorial(n) **/
/** Devuelve el factorial de un número n **/
double factorial(int n)
{
int i;
double f;
f=1;
for (i=2; i<=n; i=i+1)
f=f*i;
return f;
}
57
CURSO 2018/19 5. MODULARIDAD
identificador
( tipo ) : tipo
del módulo
,
y precediendo a toda la lista del epígrafe MÓDULOS LLAMADOS. En la representación
algorítmica, los pasos que contengan una invocación a un módulo definido por el programador
estarán encerrados en el siguiente símbolo:
identificador
tipo ( tipo ) ;
de la función
,
EJEMPLO 5.2. Calcular y mostrar por pantalla el número de combinaciones sin repetición de n elementos tomados de
m en m, solicitando n y m por teclado.
ANÁLISIS: M. P.
a) Datos de entrada: n
n: número total de elementos. Teclado. (n > 0) n
f
m: tamaño de cada grupo de elementos tomado. Teclado. (n ≥ m > 0)
leerEntPos factorial
b) Datos de salida:
result: número de combinaciones sin repetición de n elementos tomados de m en m. Monitor.
c) Comentarios:
Se utilizará un módulo para leer un número positivo desde teclado (sin mostrar ningún mensaje solicitando el
dato). Devolverá dicho número.
58
CURSO 2018/19 5. MODULARIDAD
Se utilizará un módulo para calcular el factorial de un número. Recibirá dicho número y devolverá el
factorial calculado.
DISEÑO:
a) Parte declarativa:
MÓDULOS LLAMADOS
leerEntPos():entero
factorial(entero):real
VARIABLES
n,m:entero
result:real
b) Representación algorítmica:
combinatorio
BLOCK
m>n BLOCK
CODIFICACIÓN:
/***********************************/
/*** C O M B I N A T O R I O ***/
/***********************************/
#include <stdio.h>
/* Prototipos de funciones */
int leerEntPos();
double factorial(int);
59
CURSO 2018/19 5. MODULARIDAD
EJEMPLO 5.3. Desarrollar un módulo que muestre por pantalla la tabla de multiplicar de un número entero
recibido como parámetro.
ANÁLISIS:
a) Datos de entrada: M. llamador
mult: valor del que se mostrará la tabla de multiplicar. Módulo llamador.
mult
b) Datos de salida:
tabla[1..10]: Valores de la tabla de multiplicar de mult. Monitor
tablaMultiplicar
c) Comentarios:
Utilizaremos una variable para contabilizar el número de multiplicaciones mostradas durante la visualización
de la tabla de multiplicar.
DISEÑO:
a) Parte declarativa:
tablaMultiplicar(mult:entero)
VARIABLES
i:entero
b) Representación algorítmica:
tablaMultiplicar(mult)
BLOCK
escribir for do
("Tabla",mult)
i ← 1, 10, 1 escribir
(i,mult,imult)
60
CURSO 2018/19 5. MODULARIDAD
CODIFICACIÓN:
/** tablaMultiplicar(mult) **/
/** Calcula y muestra la tabla de multiplicar de 'mult' **/
void tablaMultiplicar(int mult)
{
int i;
if (n < 2)
f=1;
else
{
f=n;
while (n > 2)
{
n=n-1;
f=f*n;
}
}
return f;
}
el resultado del cálculo combinatorio del Ejemplo 5.2 seguiría siendo correcto, ya que las
modificaciones que sufre el parámetro n dentro de la función no afectan al argumento con el que se
realiza cada llamada.
Cuando necesitemos definir un módulo que devuelva más de un valor al módulo llamador,
deberemos utilizar otro modo de transferir información entre módulos: el pase de argumentos por
referencia. Este modo permite establecer un canal de comunicación bidireccional entre el módulo
llamador y el módulo llamado. En concreto, consistirá en transferir al módulo llamado la dirección
del argumento (utilizando el operador de dirección, &), en lugar de transferir una copia de su valor.
Así, a diferencia de lo que ocurre con el pase de argumentos por valor, la información contenida en
61
CURSO 2018/19 5. MODULARIDAD
el parámetro, que será la dirección de memoria de una variable del módulo llamador, permite afectar
al valor del argumento en el módulo llamador. Un módulo puede pasar por referencia tantos
argumentos como se quiera, ampliando así el número de valores que el módulo puede «devolver» al
módulo llamador.1
Obsérvese que el parámetro correspondiente a un argumento pasado por referencia siempre
deberá actuar, al menos, como dato de salida del módulo (a veces, si interesa, podrá también actuar
como dato de entrada). En el caso de que el dato sea solo de entrada al módulo, el argumento
deberá pasarse siempre por valor.
EJEMPLO 5.4. Desarrollar un módulo que intercambie en el módulo llamador el valor de dos variables de tipo
entero.
ANÁLISIS:
a) Datos de entrada:
x: valor a intercambiar. Módulo llamador. M. llamador
y: valor a intercambiar. Módulo llamador.
x,y
b) Datos de salida:
x': valor intercambiado (la y original). Módulo llamador. intercambiar
y': valor intercambiado (la x original). Módulo llamador.
c) Comentarios:
Será necesario utilizar una variable auxiliar que mantenga uno de los valores iniciales temporalmente, con el
objetivo de que este no se pierda tras la primera asignación.
DISEÑO:
a) Parte declarativa:
intercambiar(*x:entero, *y:entero)
VARIABLES
aux:entero
b) Representación algorítmica:
intercambiar(x,y)
BLOCK
CODIFICACIÓN:
/** intercambiar(x,y) **/
/** Intercambia los valores de x e y **/
void intercambiar(int *x, int *y)
{
int aux;
aux=*x;
*x=*y;
*y=aux;
}
1 Si bien el lenguaje C permite que un mismo módulo devuelva un valor asociado al nombre de la función y otros
valores asociados a argumentos pasados por referencia, el uso simultáneo de ambos métodos no se considera una
buena práctica de programación. Por ello, emplearemos el primer método cuando el módulo devuelva un único valor
y el segundo cuando devuelva más de uno.
62
CURSO 2018/19 5. MODULARIDAD
63
CURSO 2018/19 5. MODULARIDAD
EJERCICIOS
1º) Calcular y mostrar por pantalla la edad de una persona a partir de la fecha actual y la de su
nacimiento con formato dd mm aaaa, introducidas ambas por teclado.
2º) El desarrollo de la serie de Maclaurin para la función seno es:
x3 x5 x7 x9
sen x = x − − −...
3! 5! 7! 9!
Evaluar y mostrar por pantalla el seno de x empleando n términos en el desarrollo, donde x y n
se introducen por teclado (x vendrá expresado en radianes).
3º) "¿Quién tiene menos?" es un juego de estrategia para dos jugadores en el que cada jugador
piensa un número entero entre el 1 y el 5 y a continuación los comparan. Si coinciden o se
diferencian en más de una unidad, cada jugador recibe un número de puntos igual al número
que pensó. Si por el contrario, los números se diferencian en una unidad, el jugador que pensó
el número menor recibe una cantidad de puntos igual a la suma de los dos números pensados.
El juego consta de 10 rondas y después de cada una de ellas se acumulan los puntos. Gana el
que alcance mayor número de puntos. Realizar un programa que permita jugar una partida entre
el usuario y el ordenador, solicitando para cada ronda la jugada al usuario desde teclado y
generándola aleatoriamente para el ordenador. Una vez finalizada la partida, se mostrará un
mensaje indicando quién ha sido el vencedor. Un ejemplo de ejecución sería:
RONDA 1:
Introduce tu jugada ([1,5]): 3
Humano: 3, Máquina: 5. Difieren en más de una unidad.
Marcador: HUMANO 3 - MAQUINA 5
RONDA 2:
Introduce tu jugada ([1,5]): 2
Humano: 2, Máquina: 2. Los números coinciden.
Marcador: HUMANO 5 - MAQUINA 7
...
RONDA 9:
Introduce tu jugada ([1,5]): 3
Humano: 3, Máquina: 5. Difieren en más de una unidad.
Marcador: HUMANO 28 - MAQUINA 24
RONDA 10:
Introduce tu jugada ([1,5]): 3
Humano: 3, Máquina: 4. Difieren en una unidad.
Marcador: HUMANO 35 - MAQUINA 24
Partida finalizada.
¡Enhorabuena!, has ganado.
4º) Desarrollar un módulo que reciba una lista de valores enteros y su tamaño y devuelva si está o
no ordenada crecientemente.
5º) Desarrollar un módulo que reciba una lista de valores enteros y su tamaño y la devuelva
ordenada ascendentemente empleando el método de inserción.
6º) Desarrollar un módulo que, recibiendo una matriz cuadrada de valores enteros y su dimensión
(10×10 como máximo), devuelva la suma de los valores situados por encima de la diagonal
principal, la suma de los valores de la diagonal principal y la suma de los valores por debajo de
la diagonal principal.
64
CURSO 2018/19 5. MODULARIDAD
7º) Desarrollar un módulo que inicialice y devuelva una matriz cuadrada de dimensiones n×n de la
siguiente forma: la diagonal principal deberá contener un determinado valor real v; las
diagonales adyacentes a la diagonal principal, un valor igual al doble de v; las diagonales aún
sin rellenar adyacentes a las dos anteriores, un valor igual al triple de v, y así sucesivamente
hasta rellenar completamente la matriz, resultando, por tanto, una matriz simétrica. El tamaño
máximo de la matriz será 15×15.
8º) Desarrollar un módulo que realice el cálculo de la diferencia entre dos conjuntos. Para ello,
recibiendo dos conjuntos de valores enteros y sus respectivos tamaños, deberá devolver el
conjunto diferencia (elementos del primer conjunto que no están en el segundo) y su tamaño.
Considérese que el tamaño máximo de cada conjunto recibido es igual a 100 elementos.
9º) Un punto en un espacio bidimensional se representa mediante el par de coordenadas (x,y). La
distancia entre dos puntos P=(x,y) y Q=(x’,y’) se calcula de la siguiente manera:
Desarrollar un módulo que recibiendo dos listas de puntos del mismo tamaño y dicho
tamaño, evalúe la distancia entre pares de puntos situados en la misma posición en sendos
vectores y devuelva el número de orden del par de puntos más alejados entre sí. En el caso de
que varios pares de puntos se encuentren a la máxima distancia, se devolverá el número de
orden del primer par encontrado.
10º) Desarrollar un módulo que evalúe si dos listas de valores enteros con el mismo tamaño superan
determinado grado de coincidencia. El grado de coincidencia se calculará como el porcentaje
de elementos que coinciden en posición y valor en sendos vectores. Para ello, el módulo
recibirá del módulo llamador las listas de valores, su tamaño y el grado de coincidencia, que
será un valor en el intervalo (0,1].
11º) Desarrollar un módulo que, recibiendo del módulo llamador una lista de valores enteros con al
menos 2 valores, su tamaño y una longitud l mayor que 0, devuelva la longitud (número de
elementos) de la primera secuencia de valores consecutivos iguales de longitud mayor o igual
que l, así como el valor que se repite en dicha secuencia. Si no existe ninguna secuencia de
valores consecutivos iguales de longitud mayor o igual que l, devolverá el valor 0.
12º) Desarrollar un módulo que, a partir de una lista de longitudes mayores o iguales que 1 y su
tamaño, devuelva una lista de secuencias binarias formadas alternativamente por ceros y por
unos y su tamaño. La lista de secuencias binarias deberá construirse según la lista de longitudes
recibida y comenzando por una secuencia de ceros.
13º) Con objeto de anticipar la intención de voto, una empresa de demoscopia selecciona muestras
de individuos del mismo tamaño en distintas poblaciones a los que les pregunta por su
intención de voto. Cada encuestado puede indicar el partido al que tiene intención de votar o no
indicar nada.
Desarrollar un módulo que, recibiendo el número de muestras consideradas, el número de
partidos políticos que se presentan a las elecciones y una matriz donde cada fila representa la
distribución de intención de voto de una muestra (porcentaje de individuos de la muestra que
votarán a cada partido), devuelva la distribución de intención de voto global y el número de
muestras erróneas (muestras donde la suma de porcentajes de los distintos partidos supere a
100). La distribución de intención de voto global será el porcentaje de individuos totales que
votarán a cada partido, calculado como será la media de los porcentajes de cada muestra (sin
considerar las muestras erróneas). El número máximo de partidos es 10.
65
CURSO 2018/19 5. MODULARIDAD
14º) Desarrollar un módulo que, recibiendo del módulo llamador la temperatura media diaria
durante una semana para p poblaciones (matriz de p filas y 7 columnas), el número p de
poblaciones y un valor real d, devuelva el resultado de comprobar si existe alguna población
para la cual la diferencia entre la máxima y mínima de sus temperaturas es mayor que d.
15º) Las localidades de un cine están dispuestas en f filas de c asientos cada una. Desarrollar el
análisis, diseño y codificación en C de un módulo para obtener la fila más lejana a la pantalla
en la que puedan sentarse n personas unas al lado de las otras en la misma fila. El módulo
recibirá tabla con información de la ocupación actual de las localidades (representada por los
caracteres L-libre, O-ocupado), el número de filas y columnas totales del cine y el número n de
asientos a ocupar consecutivamente, y deberá devolver el número de la fila más lejana a la
pantalla con un hueco de longitud mayor o igual a n. Si no existe tal hueco, devolverá el valor
-1. El número máximo de asientos en una fila será 50.
16º) Un número complejo es de la forma a+bi, donde a y b son números reales e i= −1 .
Desarrollar un programa dirigido por opciones de menú que lea dos números complejos (donde
a+bi se introduce como un par de números reales a y b), permita al usuario seleccionar la
ejecución de una operación (suma, resta, multiplicación o división) y muestre el resultado de la
forma a+bi. Las cuatro operaciones se definen de la siguiente manera:
(a+bi) + (c+di) = (a+c) + (b+d)i
(a+bi) - (c+di) = (a-c) + (b-d)i
(a+bi) · (c+di) = (ac-bd) + (ad+bc)i
(a+bi) / (c+di) = [(ac+bd)/(c2+d2) ] + [(bc-ad)/(c2+d2)]i
17º) Escribir los n primeros números de la serie de Fibonacci a partir de un número natural n
introducido por teclado.
Nota: La serie de Fibonacci es 0,1,1,2,3,5,8,13,... de acuerdo con la ley siguiente:
fibonacci(1) = 0
fibonacci(2) = 1
fibonacci(3) = 1 = fibonacci(2) + fibonacci(1)
fibonacci(4) = 2 = fibonacci(3) + fibonacci(2)
...
fibonacci(n) = fibonacci(n-1) + fibonacci(n-2)
18º) Escribir un programa que lea números enteros desde teclado hasta que el usuario acierte un
número secreto generado aleatoriamente entre 1 y 100. Cada vez que se introduzca un número
se debe indicar al usuario si es mayor o menor que el número secreto. Una vez acertado, se
mostrará el número de intentos que se han empleado.
19º) La distancia del punto de caída de un proyectil lanzado con un ángulo a (en grados) y una
velocidad inicial v (en metros por segundo), ignorando la resistencia del aire, viene dada por la
fórmula
v 2 × sen [ ×a/90 ]
distancia =
9,81
Suponiendo que la diana se encuentra a 100 metros de distancia, simular un juego en el que
el usuario introduce el ángulo y la velocidad de lanzamiento de un proyectil. Si el proyectil cae
a menos de un 1 metro de la distancia a la diana se considera que ha dado en el blanco y el
programa finaliza; en caso contrario, se le indica al usuario cuánto se ha alejado el proyectil del
punto de lanzamiento y se le permite intentar un nuevo lanzamiento. El usuario seguirá
lanzando hasta dar en el blanco, después de lo cual se mostrará el número de intentos
66
CURSO 2018/19 5. MODULARIDAD
21º) Existen muchas series infinitas que convergen a π o a fracciones de π. Dos de estas series son la
de Leibniz y la de Wallis. La serie de Leibniz viene dada por
n
1
4
= ∑ −1i1 2i−1
i=1
y la de Wallis por
n
u
4
= ∏ vi
i=1 i
donde ui = 2 + 2 × (i div 2)
vi = 1 + 2 × ((i+1) div 2)
Mostrar por pantalla una tabla con las aproximaciones a π mediante las series de Leibniz y
67
CURSO 2018/19 5. MODULARIDAD
de Wallis desde 10 hasta n términos, donde n es un número introducido por el usuario entre 20
y 999, ambos inclusive. En cada línea deberá aparecer, además de las dos aproximaciones
calculadas, el número de términos empleado, el error sobre el valor exacto de π y una
indicación (L, W o =) de cuál de las aproximaciones es la mejor.
22º) “Las 4 en raya” es un juego de mesa para 2 jugadores que emplea un tablero en disposición
vertical de f filas por c columnas. Los jugadores, alternativamente, van insertando fichas de su
color (blancas o negras) en las columnas del tablero, que caen situándose unas encima de las
otras. Gana el jugador que consigue formar una línea horizontal, vertical o diagonal de, al
menos, 4 fichas de su color. Los valores de f y c deben ser especificados por los jugadores antes
de comenzar cada partida y no deberán exceder de 20×20.
Desarrollar un módulo que procese y devuelva el efecto sobre el tablero de una jugada en
cualquier momento de la partida. En concreto, recibiendo la información referente al estado del
tablero antes de esa jugada (contenido y dimensiones) y la jugada a procesar (la columna donde
se inserta la ficha y el color de la ficha), deberá devolver el nuevo contenido del tablero y el
resultado de comprobar si la jugada fue válida o no (si la columna donde se intentaba insertar la
ficha estaba o no llena).
23º) En una versión electrónica del juego “Master Mind” el objetivo es averiguar una combinación
de 5 dígitos (entre el 0 y el 9) sin repetición. Para ello, el usuario va proporcionando
combinaciones y el ordenador responde informando sobre el número de JAQUES y de MATES
entre la combinación secreta y la especificada por el usuario. El número de MATES equivale al
número de dígitos entre ambas combinaciones que coinciden en valor y posición. El número de
JAQUES equivale al número de dígitos entre ambas combinaciones que coinciden solamente
en valor, pero no en posición.
Desarrollar un programa que simule el juego del “Master Mind”. Para ello, el ordenador
leerá en primer lugar la combinación secreta desde teclado y a continuación, tras borrar la
pantalla, el usuario deberá introducir combinaciones hasta averiguar la combinación secreta,
después de lo cual se mostrará el número de intentos empleados.
68