Beruflich Dokumente
Kultur Dokumente
Universidad Complutense
Fundamentos de la programación
1º curso
2013‐2014
Durante los tres primeros cursos en los que se ha impartido la asignatura, este
material ha sido sometido a continuas revisiones y contribuciones por parte de
los profesores que han impartido los distintos grupos
de la asignatura. Aunque el trabajo ha quedado bastante consolidado, estoy
seguro de que todavía contiene muchas erratas. Si encuentras alguna, no
dudes, por favor, en hacérmelo saber y conseguir así que la siguiente
versión esté mejor depurada.
TC
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
Fundamentos de la programación
Informática, computadoras y programación 3
Lenguaje máquina y ensamblador 12
Lenguajes de programación de alto nivel 15
Un poco de historia 19
Programación e Ingeniería del Software 24
El lenguaje de programación C++ 27
Sintaxis de los lenguajes de programación 30
Un primer programa en C++ 35
Herramientas de desarrollo 39
C++: Un mejor C 45
Luis Hernández Yáñez
Fundamentos de la programación
Constantes 167
La biblioteca cmath 171
Operaciones con caracteres 174
Fundamentos de la programación
int 214
float 216
Notación científica 217
double 218
char 220
bool 221
string 222
Literales con especificación de tipo 223
Luis Hernández Yáñez
Fundamentos de la programación
Fundamentos de la programación
El operador ternario ? 399
Recorridos 404
Un aparcamiento 405
¿Paréntesis bien emparejados? 409
¿Dos secuencias iguales? 412
Números primos menores que N 413
Búsquedas 417
Búsqueda de un número en un archivo 419
Búsquedas en secuencias ordenadas 420
Luis Hernández Yáñez
Fundamentos de la programación
Fundamentos de la programación
Archivos como parámetros 498
La función main() 501
Argumentos implícitos 504
Sobrecarga de subprogramas 508
Luis Hernández Yáñez
Fundamentos de la programación
Cadenas al estilo de C 582
E/S con cadenas al estilo de C 583
La biblioteca cstring 584
Ejemplo 585
Luis Hernández Yáñez
Fundamentos de la programación
Fundamentos de la programación
Algoritmos de ordenación 651
Algoritmo de ordenación por inserción 654
Ordenación de arrays por inserción 665
Algoritmo de ordenación por inserción
con intercambios 672
Claves de ordenación 680
Estabilidad de la ordenación 688
Complejidad y eficiencia 692
Ordenaciones naturales 694
Ordenación por selección directa 701
Método de la burbuja 716
Listas ordenadas 722
Búsquedas en listas ordenadas 729
Búsqueda binaria 731
Luis Hernández Yáñez
Fundamentos de la programación
Fundamentos de la programación
Programas multiarchivo y compilación separada 757
Interfaz frente a implementación 762
Uso de módulos de biblioteca 768
Ejemplo: Gestión de una lista ordenada I 770
Compilación de programas multiarchivo 778
El preprocesador 780
Cada cosa en su módulo 782
Ejemplo: Gestión de una lista ordenada II 784
El problema de las inclusiones múltiples 789
Compilación condicional 794
Protección frente a inclusiones múltiples 795
Ejemplo: Gestión de una lista ordenada III 796
Implementaciones alternativas 804
Espacios de nombres 808
Implementaciones alternativas 817
Luis Hernández Yáñez
Fundamentos de la programación
Fundamentos de la programación
Direcciones de memoria y punteros 849
Operadores de punteros 854
Punteros y direcciones válidas 864
Punteros no inicializados 866
Un valor seguro: NULL 867
Copia y comparación de punteros 868
Tipos puntero 873
Punteros a estructuras 875
Punteros a constantes y punteros constantes 877
Punteros y paso de parámetros 879
Punteros y arrays 883
Memoria y datos del programa 886
Memoria dinámica 891
Punteros y datos dinámicos 895
Gestión de la memoria 907
Luis Hernández Yáñez
Fundamentos de la programación
Fundamentos de la programación
Concepto de recursión 983
Algoritmos recursivos 986
Funciones recursivas 987
Diseño de funciones recursivas 989
Modelo de ejecución 990
La pila del sistema 992
La pila y las llamadas a función 994
Ejecución de la función factorial() 1005
Tipos de recursión 1018
Recursión simple 1019
Recursión múltiple 1020
Recursión anidada 1022
Recursión cruzada 1026
Código del subprograma recursivo 1027
Parámetros y recursión 1032
Ejemplos de algoritmos recursivos 1034
Búsqueda binaria 1035
Luis Hernández Yáñez
Fundamentos de la programación
Flujos 1051
Archivos binarios 1054
Tamaño de los datos: El operador sizeof() 1056
Apertura de archivos binarios 1059
Lectura de archivos binarios (acceso secuencial) 1061
Escritura en archivos binarios (acceso secuencial) 1066
Acceso directo o aleatorio 1070
Ejemplos de uso de archivos binarios 1078
Ordenación de los registros del archivo 1079
Búsqueda binaria 1085
Inserción en un archivo binario ordenado 1088
Carga de los registro de un archivo en una tabla 1092
Almacenamiento de una tabla en un archivo 1093
Luis Hernández Yáñez
Fundamentos de la programación
F
u
n
d
a
m
e
n
t
o
s
d
e
l
a
p
r
o
g
r
a
m
a
c
i
ó
n
Luis Hernández Yáñez
Funda
mento
s de
la
progra
mació
n
Fundamentos de la programación
1
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
Computadora
Maí quina electroí nica, analoí gica o digital,
dotada de una memoria de gran capacidad
y de meí todos de tratamiento de la informacioí n,
capaz de resolver problemas matemaí ticos y loí gicos
Luis Hernández Yáñez
Hardware
Componentes que integran
la parte material
de una computadora
Software
Programas, instrucciones
y reglas informaí ticas para
ejecutar tareas
en una computadora
Luis Hernández Yáñez
Programa
23 Secuencia de instrucciones
24 Instrucciones que entiende la computadora
25 Y que persiguen un objetivo: ¡resolver un problema!
Luis Hernández Yáñez
Trabajo en equipo
Muí ltiples roles...
0 Gestores
1 Analistas
Parque Jurásico 2 Disenñ adores
3 Programadores
4 Probadores
5 Administradores
de sistemas
...
Luis Hernández Yáñez
Táctil Almacenamiento …
… permanente
Dispositivos de E/S
C.P.U. (Procesador)
A.L.U.
Unidad Aritmeí tico‐Loí gica Memoria
Luis Hernández Yáñez
Unidad de Control
Dirección
10
2 = 1024 1000
Lenguaje máquina
Coí digos hexadecimales que representan instrucciones,
registros de la CPU, direcciones de memoria o datos
Lenguaje de bajo nivel
Instrucción Significado
A0 2F Dependiente de la máquina
Acceder a la celda de memoria 2F
3E 01 Copiarlo el registro 1 de la ALU Programación difícil
Luis Hernández Yáñez
F
u
n
d
a
m
e
n
t
o
s
d
e
l
a
p
r
o
g
r
a
m
a
c
i
ó
n
:
C
o
m
p
u
t
a
d
o
r
a
s
y
p
r
og
ra
m
ac
ió
n
Pá
gi
na
17
Prolog
1970 Java
COBOL PL/I C++
1959
1995
1964 1983
FORTRAN C#
1954 CPL C 2000
1963
1971
Python
ALGOL Pascal Modula 1991
1958 1970 1975
BASIC
1964 Ada Eiffel
1979 1986
Fuente: Simula
1964 Smalltalk
http://www.levenez.com/lang/ Ruby
1971
1993
Luis Hernández Yáñez
La prehistoria
El aí baco
Siglo XIX (Wikipedia)
es considerada
la primera
programadora
Luis Hernández Yáñez
Lenguaje de programacioí n C
1974 Protocolo TCP. Primera red local
IBM PC (Wikipedia)
1991 Sistema operativo Linux
Siglo XXI
2001 Windows XP
Mac OS X
2002 Mozilla Firefox
2007 iPhone
Luis Hernández Yáñez
P
r
o
g
r
a
m
a
:
T
r
a
n
s
f
o
r
m
a
e
n
t
r
a
d
a
e
n
s
La
programaci
ón
es
sól
o
un
a
eta
pa
del
pro
ces
o
de
Luis Hernández Yáñez
des
arr
ollo
Mo
del
Fu
nd
a
m
en
to
s
de
la
pr
og
ra
m
ac
ió
n:
Co
m
pu
ta
do
ra
sy
pr
og
ra
m
ac
ió
n
Pá
gi
na
26
Luis Hernández Yáñez
#include <iostream>
using namespace std;
int main()
{
cout << "Hola Mundo!" << endl;
0 Muestra Hola
Mundo! return 0;
Luis Hernández Yáñez
...
using namespace std;
Subprograma int main()
{ Dato
Instrucción cout << "Hola Mundo!" <<
endl; // Muestra Hola Mundo!
Comentario
Luis Hernández Yáñez
Instrucción
Dato
return 0;
}
Especificación
0 Lenguajes (BNF)
1 Diagramas
Ejemplo: Nuí meros enteros (sin decimales)
BNF
<numero entero> ::= <signo opcional><secuencia de dígitos>
<signo opcional> ::= +|‐|<nada>
<secuencia de dígitos> ::= <dígito>|<dígito><secuencia de dígitos>
<dígito> ::= 0|1|2|3|4|5|6|7|8|9 +23
<nada> ::= ‐159
1374
1‐34
+ 3.4
Luis Hernández Yáñez
0 .. 9 0
‐
+23
<numero entero> ::= <signo opcional><secuencia de dígitos> ::=
+<secuencia de dígitos> ::= +<dígito><secuencia de dígitos>
1‐34
<numero entero> ::= <signo opcional><secuencia de dígitos>
::= <secuencia de dígitos> ::= <dígito><secuencia de dígitos>
::= 1<secuencia de dígitos> ::= ERROR (‐ no es <dígito>)
Fundamentos de la programación: Computadoras y programación Página 33
+23 +
+223
1374 ‐
0 .. 9
+ 0 .. 9
1374
1‐34 ‐
+ 0 .. 9 ? 1‐
‐
Luis Hernández Yáñez
Hola Mundo!
Un programa que muestra un saludo en la pantalla:
#include <iostream>
using namespace std;
int main()
// main() es donde empieza la ejecución
{
cout << "Hola Mundo!" << endl; // Muestra Hola Mundo!
return 0;
Luis Hernández Yáñez
Hola Mundo!
Casi todo es infraestructura
Soí lo
cout << "Hola Mundo!" << endl
hace algo palpable
Editor
23 Bloc de notas, Wordpad, Word, Writer, Gedit, Kwrite, …
(texto simple, sin formatos)
24 Editores especííficos: coloreado sintaí ctico
25 Recomendacioí n: Notepad++
Instalacioí n y uso:
Seccioí n
Herramientas de desarrollo
en el Campus Virtual
Luis Hernández Yáñez
Hola Mundo!
Cargador hola.exe
(ejecutable)
Luis Hernández Yáñez
Compilador
5888 Importante: C++ estaí ndar
5889 Recomendacioí n: GNU G++ (MinGW en Windows)
Instalacioí n y uso:
Seccioí n
Herramientas de desarrollo
en el Campus Virtual
Luis Hernández Yáñez
Instalacioí n y uso:
Seccioí n
Herramientas de desarrollo
en el Campus Virtual
Luis Hernández Yáñez
Inicio
Pantalla (cout)
_ Hola Mundo!
cout << "Hola Mundo!" << endl; _
Muestra Hola Mundo!
en la pantalla y salta de líínea
return 0;
Devuelve 0 como coí digo
Yáñez
Fin
2
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
Constantes 167
La biblioteca cmath 171
Operaciones con caracteres 174
Stop;
avanzar
Go Blocks
avanzar dirección num
North 1
South
4
West
5
Fundamentos de la programación: Tipos e instrucciones I Página 52
N
El problema a resolver
Estando el coche en la posición A,
conseguir llegar al Cine Tívoli (B) B
1.‐ Arrancar
2.‐ Ir un bloque al Norte
3.‐ Ir dos bloques al Este
4.‐ Ir cinco bloques al Norte
5.‐ Ir dos bloques al Este
6.‐ Parar
Luis Hernández Yáñez
N
El programa
Instrucciones escritas en
el lenguaje de programacioí n B
Start;
Go North 1 Blocks;
Go East 2 Blocks;
Go North 5 Blocks; A
Go East 2 Blocks;
Stop;
Luis Hernández Yáñez
Stop;
La compilación
Introducimos la llave USB en el coche
y pulsamos el botoí n de ejecutar el programa:
Stat;
‐‐‐‐^ Unknown word.
Go North 1 Blocks
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐^ ; missing.
Go East Blocks;
Errores de
‐‐‐‐‐‐‐‐^ Number missing.
sintaxis
Go Noth 5 Blocks;
‐‐‐‐‐‐‐^ Unknown word.
Go West 2 Blocks;
Luis Hernández Yáñez
Stop;
There are errors. Impossible to run the program.
Stat; Start;
Go North 1 Blocks Go North 1 Blocks;
Go East Blocks; Go East 3 Blocks;
Go Noth 5 Blocks; Go North 5 Blocks;
Go West 2 Blocks; Go West 2 Blocks;
Stop; Stop;
Luis Hernández Yáñez
La ejecución N
cada instruccioí n: B
Start;
Go North 1 Blocks;
Go East 3 Blocks; !
Error de ejecucioí n
Luis Hernández Yáñez
Edita
mos
el
coí dig
o
para
arregl
ar
el
error
de
ejecuc
ioí n:
Start
;
Start
;
G
o
N
o
r
t
h
1
B
l
o
c
k
s
;
G
o
Luis Hernández Yáñez
Fu
nd
a
m
en
to
s
de
la
pr
og
ra
m
ac
ió
n:
Ti
po
s
e
in
str
uc
ci
on
es
I
Pá
gi
na
61
Depuración
Editamos el coí digo para arreglar el error loí gico:
Start; Start;
Go North 1 Blocks; Go North 1 Blocks;
Go East 2 Blocks; Go East 2 Blocks;
Go North 5 Blocks; Go North 5 Blocks;
Go West 2 Blocks; Go East 2 Blocks;
Stop; Stop;
Luis Hernández Yáñez
La ejecución N
Start;
Go North 1 Blocks;
Go East 2 Blocks;
Go North 5 Blocks;
Go East 2 Blocks;
Stop;
Luis Hernández Yáñez
¡Conseguido!
Hola Mundo!
De vuelta en el programa que muestra un saludo en la pantalla:
#include <iostream>
using namespace std;
return 0;
Luis Hernández Yáñez
return 0;
Luis Hernández Yáñez
Hola Mundo!
_
80 caracteres
Luis Hernández Yáñez
H o l a M u n d o !
...
Luis Hernández Yáñez
...
El programa principal
La funcioí n main():
La infraestructura
Coí digo para reutilizar:
#include <iostream> Una directiva: empieza por #
using namespace std;
Espacios de nombres
En iostream hay espacios de nombres; ¿cuaí l queremos?
#include <iostream>
using namespace std; Es una instruccioí n: termina en ;
Siempre usaremos el espacio de nombres estaí ndar (std)
Luis Hernández Yáñez
Hola Mundo!
Cargador hola.exe
Luis Hernández Yáñez
(ejecutable)
return 0;
}
int main()
{
return 0;
}
int main()
{
cout << "En un lugar de la Mancha," << endl;
cout << "de cuyo nombre no quiero acordarme," << endl;
cout << "no ha mucho tiempo que vivía un hidalgo de los
de lanza en astillero, ..." << endl;
Luis Hernández Yáñez
return 0;
}
return 0; ↲
} ↲
go
de
l
pr
og
ra
m
a
N
o
h
a
y
q
u
e
p
a
r
t
i
r
u
n
Luis Hernández Yáñez
M
an
te
ni
mi
en
to
y
re
us
ab
ili
da
d
Fu
nd
a
m
en
to
s
de
la
pr
og
ra
m
ac
ió
n:
Ti
po
s
e
in
str
uc
ci
on
es
I
Pá
gi
na
85
Luis Hernández Yáñez
Operadores aritméticos
23 Suma
‐ Resta
*
Multiplicacioí n /
Divisioí n
Operadores binarios
operando_izquierdo operador operando_derecho
Operacioí n Resultado
3 + 4 7
Luis Hernández Yáñez
2.56 ‐ 3 ‐0.44
143 * 2 286
45.45 / 3 15.15
Fundamentos de la programación: Tipos e instrucciones I Página 87
Números literales (concretos)
0 Enteros: sin parte decimal
Signo negativo (opcional) + secuencia de díígitos
3 143 ‐12 67321 ‐1234
cálculos.cpp
Ejemplo
#include <iostream>
using namespace std;
return 0;
}
Divisioí n real
...
LAS VARIABLES NO SE INICIALIZAN
No se deben usar hasta que se les haya dado alguí n valor
¿Dónde colocamos las declaraciones?
Siempre, antes del primer uso
Luis Hernández Yáñez
{
int cantidad; ...
double precio, total;
return 0; Podemos declarar varias de un mismo tipo
double
2,23 x 10‐308 ... 1,79 x 10+308 y sus negativos
cantidad 12
Expresiones
Secuencias de operandos y operadores
operando operador operando operador operando ...
total = cantidad * precio * 1.18;
Expresioí n
A igual prioridad se evaluí an de izquierda a derecha
Pareí ntesis para forzar ciertas operaciones
total = cantidad1 + cantidad2 * precio; total =
(cantidad1 + cantidad2) * precio;
Luis Hernández Yáñez
variables.cpp
int main()
{
int cantidad;
double precio, total;
cantidad = 12;
precio = 39.95;
total = cantidad * precio;
cout << cantidad << " x " << precio << " = "
23 total <<
Luis Hernández Yáñez
endl; return 0;
}
int main()
{ total ?
int cantidad;
double precio, total; ...
Luis Hernández Yáñez
int main()
{ total ?
int cantidad;
double precio, total;
cantidad = 12; ...
Luis Hernández Yáñez
int main()
{ total 479.4
int cantidad;
double precio, total;
cantidad = 12; ...
precio = 39.95;
total = cantidad * precio;
cout << cantidad << " x " << precio << " = "
<< total << endl;
Luis Hernández Yáñez
int main()
{
int cantidad;
double precio,
total; cantidad =
12; precio = 39.95;
total = cantidad * precio;
cout << cantidad << " x " << precio << " = "
5888 total <<
Luis Hernández Yáñez
endl; return 0;
}
1 2 ↲ 1 2
_
Luis Hernández Yáñez
Se asigna el valor 39,95 a la variable; el resto queda pendiente Recomendacioí n: Lee cada variable en una líínea
39.95↲
Página 111
se
eq
ui
vo
ca
?
12
para
cantidad
No se puede leer un real 0 para precio y Error
12
para
cantidad
.5
0,5
para
precio
Lo
demaí s
queda
pendiente
¡¡¡Lectura
correcta!!!
Funda
mento
s de la
Entrada‐Proceso‐Salida
Muchos programas se ajustan a un sencillo esquema:
0 Leer numerador
1 Leer denominador
3 Mostrar resultado
4. Mostrar resultado
Salida
endl; return 0;
}
Refinamiento
variable
Luis Hernández Yáñez
Operaciones (acciones)
#include <iostream>
using namespace std;
int main()
{
Declaraciones
1. Mostrar en la pantalla el texto que pida la base del triaí ngulo
Algoritmo 2. Leer del teclado el valor para la base del triaí ngulo
traducido 3. Mostrar en la pantalla el texto que pida la altura del triaí ngulo
a coí digo 4. Leer del teclado el valor para la altura del triaí ngulo
return 0;
Luis Hernández Yáñez
{
double base, altura, area; // Declaraciones
cout << "Introduzca la base del triángulo: "; // 1
cin >> base; // 2
cout << "Introduzca la altura del triángulo: "; // 3
cin >> altura; // 4
area = base * altura / 2; // 5
cout << "El área de un triángulo de base " << base // 6
<< " y altura " << altura << " es: " << area << endl;
Luis Hernández Yáñez
} return 0;
Recuerda: las instrucciones terminan en ;
Fundamentos de la programación: Tipos e instrucciones I Página 126
Luis Hernández Yáñez
Literales
Constantes
Pi = 3.141592653589
Variables
Luis Hernández Yáñez
Sintaxis:
a..z, A..Z, _
balance
interesAnual
_base_imponible años
EDAD12
salario_1_mes
__edad
cálculoNómina
valor%100
AlgunValor
100caracteres valor?
Luis Hernández Yáñez
____valor
_12_meses
Fundamentos de la programación: Tipos e instrucciones I Página 132
Luis Hernández Yáñez
int
Nuí meros enteros (sin decimales) 1363, ‐12, 49
float 12.45, ‐3.1932, 1.16E+02
Nuí meros reales
double
Nuí meros reales (mayores intervalo y precisioí n)
char 'a' , '{', '\t'
Caracteres
bool
Valores loí gicos (verdadero/falso) true, false
string
Luis Hernández Yáñez
ISO‐8859‐1
(ASCII extendido: coí digos 128..255)
Luis Hernández Yáñez
Valores lógicos
Soí lo dos valores posibles:
— Verdadero (true)
— Falso (false)
Literales:
true false
Cadenas de caracteres
"Hola" "Introduce el numerador: " "X142FG5TX?%A"
" "
char
Secuencias de caracteres
Programas con variables de tipo string:
#include <string>
using namespace std;
#include <iostream>
#include <string>
using namespace std; // Un solo using... para ambas bibliotecas
int main()
{
int entero = 3; // Podemos asignar (inicializar) al declarar
double real = 2.153;
char caracter = 'a';
bool cierto = true;
string cadena = "Hola";
cout << "Entero: " << entero << endl;
cout << "Real: " << real << endl;
cout << "Carácter: " << caracter << endl;
cout << "Booleano: " << cierto << endl;
Luis Hernández Yáñez
Tipo Intervalo
int ‐2147483648 .. 2147483647
unsigned int 0 .. 4294967295
short int ‐32768 .. 32768
unsigned short int 0 .. 65535
long int ‐2147483648 .. 2147483647
unsigned long int 0 .. 4294967295
double +|‐ 2.23e‐308 .. 1.79e+308
Luis Hernández Yáñez
double balance; 04
03
unidades 05
06
balance 07
08
09
10
11
12
13
14
Luis Hernández Yáñez
15
...
— Al declararla
Inicializacioí n en la propia declaracioí n:
int i, j = 2;
i = 23 + j * 5; // i toma el valor 33
Luis Hernández Yáñez
Errores
int a, b, c;
5 = a;
5888 ERROR: un literal no puede recibir un
valor a + 23 = 5;
5889 ERROR: no puede haber una expresión a la
izda. b = "abc";
5890 ERROR: un entero no puede guardar una cadena
c = 23 5;
// ERROR: expresión no válida (falta operador)
Luis Hernández Yáñez
Memoria Memoria
i
01 01
i 02 ? 23 + 2 * 5 02 33
03 03
04 04
j
05 05
j 06 2 06 2
07 07
08 08
09 09
10 10
... ...
Luis Hernández Yáñez
a 3.45 a 3.45
b 127.5 aux = a; b 127.5
aux ? aux 3.45
a 127.5
a = b; b 127.5
aux 3.45
a 127.5
Luis Hernández Yáñez
b = aux; b 3.45
aux 3.45
— Asignacioí n (=)
Operadores binarios
— Operando izquierdo operador operando derecho
Operandos: literales, constantes, variables o expresiones
Luis Hernández Yáñez
2 + 3 a * RATIO ‐a + b (a %
b) * (c / d)
Divisioí n entera:
No se obtienen decimales Queda un resto
5888 5
324
Luis Hernández Yáñez
123 % 5
int main() {
int entero1 = 15, entero2 = 4;
double real1 = 15.0, real2 = 4.0;
cout << "Operaciones entre los números 15 y 4:" << endl; cout
<< "División entera (/): " << entero1 / entero2 << endl;
cout << "Resto de la división (%): " << entero1 % entero2 << endl;
cout << "División real (/): " << real1 / real2 <<
endl; cout << "Num = " << real1 << endl; real1 = ‐
real1;
cout << "Cambia de signo (‐): " << real1 <<
endl; real1 = ‐real1;
cout << "Vuelve a cambiar (‐): " << real1 << endl;
cout << "Se incrementa antes (++ prefijo): " << ++real1 << endl;
cout << "Se muestra antes de incrementar (posfijo ++): "
Luis Hernández Yáñez
3 + 5 * 2 / 2 ‐ 1 3 + 10 / 2 ‐ 1 3 + 5 ‐ 1 8 ‐ 1 7
* antes que +
(32 + 12) / 4 ‐ 5
44 / 4 ‐ 5
/ antes que ‐
#include <iostream>
using namespace std;
int main()
{
double x, f;
cout << "Introduce el valor de X:
"; cin >> x;
f = 3 * x * x / 5 + 6 * x / 7 ‐ 3;
cout << "f(x) = " << f << endl;
return 0;
}
Luis Hernández Yáñez
Asignación Abreviatura
a = a + 12; a += 12;
Igual precedencia
a = a * 3; a *= 3; que la asignacioí n
a = a ‐ 5; a ‐= 5;
De momento,
a = a / 37; a /= 37;
mejor evitarlas
a %= b;
Luis Hernández Yáñez
a = a % b;
Bit de signo 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
32767
0 = positivo + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 + 1
1 = negativo
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ‐32768
Luis Hernández Yáñez
<< endl;
Página 169
cout << total << " (IVA: " << IVA << "%)" << endl;
#include <iostream>
using namespace std;
int main() {
const double Pi = 3.141592;
double radio = 12.2, circunferencia;
circunferencia = 2 * Pi * radio;
cout << "Circunferencia de un círculo de radio "
5888 radio << ": " << circunferencia <<
endl; const double Euler = 2.718281828459; //
Número e
cout << "Número e al cuadrado: " << Euler * Euler <<
endl; const int IVA = 21;
int cantidad = 12;
double precio = 39.95, neto, porIVA,
total; neto = cantidad * precio;
porIVA = neto * IVA / 100;
Luis Hernández Yáñez
pow(x, y) x elevado a y
sqrt(x) Raííz cuadrada de x
ceil(x) Menor entero que es mayor o igual que x
floor(x) Mayor entero que es menor o igual que x
exp(x) x
e
log(x) Ln x (logaritmo natural de x)
log10(x) Logaritmo en base 10 de x
sin(x) Seno de x
cos(x) Coseno de x
tan(x) Tangente de x
Luis Hernández Yáñez
mates.cpp
char
Asignacioí n, ++/‐‐ y operadores relacionales
tolower(c)
…
...
#include <cctype>
int main() {
char caracter1 = 'A', caracter2 = '1', caracter3 = '&';
cout << "Carácter 1 (" << caracter1 << ").‐" << endl;
cout << "Alfanumérico? " << isalnum(caracter1) << endl;
cout << "Alfabético? " << isalpha(caracter1) << endl;
cout << "Dígito? " << isdigit(caracter1) << endl;
cout << "Mayúscula? " << isupper(caracter1) << endl;
caracter1 = tolower(caracter1);
cout << "En minúscula: " << caracter1 << endl;
cout << "Carácter 2 (" << caracter2 << ").‐" << endl;
cout << "Alfabético? " << isalpha(caracter2) << endl;
cout << "Dígito? " << isdigit(caracter2) << endl;
cout << "Carácter 3 (" << caracter3 << ").‐" << endl;
cout << "Alfanumérico? " << isalnum(caracter3) << endl;
Luis Hernández Yáñez
Operadores (prioridad)
0AĀ ᜀAĀ ᜀAĀ ᜀAĀ ᜀAĀ ᜀAĀ ᜀAĀ ᜀAĀ ᜀAĀ AĀ AĀ AĀ
ᜀAĀ ᜀAĀ ᜀAĀ ᜀAĀ ᜀAĀ ᜀAĀ ᜀAĀ ᜀ m ...
enor que 0 / %
<= menor o igual que + ‐
0 mayor que < <= >
Luis Hernández Yáñez
else {
cout << num << " es impar";
}
Fundamentos de la programación: Tipos e instrucciones I Página 181
selección.cpp
#include <iostream>
using namespace std;
int main() {
int op1 = 13, op2 =
4; int opcion;
cout << "1 ‐ Sumar" << endl;
cout << "2 ‐ Restar" <<
endl; cout << "Opción: ";
cin >> opcion;
if (opcion == 1) {
cout << op1 + op2 << endl;
}
else {
cout << op1 ‐ op2 << endl;
Luis Hernández Yáñez
}
return 0;
}
{ instrucción }
{ intrucción1
Tab oí intrucción2
3 esp. ...
int num, total = } intrucciónN
0; cin >> num; if
(num > 0)
{
cout << "Positivo";
AÁ mbito local
total = total + num; (declaraciones locales)
Luis Hernández Yáñez
}
cout << endl;
cuerpo
Cuerpo
}
Luis Hernández Yáñez
#include <iostream>
using namespace std;
int main() {
int i = 1, n = 0, suma = 0;
while (n <= 0) { // Sólo n positivo
cout << "¿Cuántos números quieres sumar?
"; cin >> n;
}
while (i <= n)
{ suma = suma +
i; i++;
}
cout << "Sumatorio de i (1 a " << n << ") = "
Luis Hernández Yáñez
0 suma <<
endl; return 0;
}
Iteración condicional
while (i <= n) {
suma = suma + i;
i++;
}
0 5
i 654321
suma += i;
i++;
Luis Hernández Yáñez
#include <iostream>
Flujos de texto (streams) using namespace std;
cin cout
7 3 5 . Programa 1 6 = l a t o T
3 5 1
>>
Luis Hernández Yáñez
#include <string>
using namespace std;
cin >> cadena termina con el primer espacio en blanco
cin.sync() descarta la entrada pendiente
string nombre, apellidos; string nombre, apellidos;
Recuerda:
Espacios en blanco son espacios, tabuladores, saltos de líínea, ...
cout << d;
5 4 . 3 2 1
La biblioteca iostream
Luis Hernández Yáñez
¡Un texto!
define la constante endl
como un salto de líínea (secuencia de caracteres)
T o t a l : 1 2 3 . 4 5M e s e s : 7 Programa
cout
int meses = 7;
cout << "Total: " << 123.45 << endl << " Meses: " << meses;
cout << 123.45 << endl << " Meses: " << meses;
Meses: 7
#include <iomanip>
1 Instrucciones:
resultado = 2 * pow(x, 5) + sqrt(pow(x, 3)
23 pow(y, 2)) / abs(x * y) ‐
Luis Hernández Yáñez
Esta instruccioí n }
no se ejecutaraí nunca
Fundamentos de programación: Tipos e instrucciones I Página 204
int main() {
int numero, sum, x, y;
char caracter;
double f;
cout << "Entero: ";
cin >> numero;
if (par(numero)) {
Luis Hernández Yáñez
else {
cout << "Impar";
}
cout << endl;
if (numero > 1) {
cout << "Sumatorio de 1 a " << numero << ": "
<< suma(numero) << endl;
}
cout << "Carácter: ";
cin >> caracter;
if (!letra(caracter)) {
cout << "no ";
}
cout << "es una letra" << endl;
cout << "f(x, y) = " << formula(x, y) << endl;
Los argumentos pueden llamarse igual o no que los parámetros
Luis Hernández Yáñez
return 0;
}
...
if (num % 2 == 0) {
esPar = true;
}
else {
esPar = false;
}
return esPar;
}
Luis Hernández Yáñez
...
return sum;
}
...
2A
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
int 214
float 216
Notación científica 217
double 218
char 220
bool 221
string 222
Literales con especificación de tipo 223
Luis Hernández Yáñez
Números enteros
Nuí meros en notacioí n octal (base 8: díígitos entre 0 y 7):
‐010 = ‐8 en notacioí n decimal
1 0
10 = 1 x 8 + 0 x 8 = 1 x 8 + 0
0423 = 275 en notacioí n decimal
2 1 0
+ 16 +3 423 = 4 x 8 + 2 x 8 + 3 x 8 = 4 x 64 + 2 x 8 + 3 = 256
(*) sizeof(float)
Intervalo de valores:
01
+ /‐ 1.18e‐38 .. 3.40e+38 Bytes
de memoria: 4* 02
03
04
Punto flotante. Precisioí n: 7 díígitos 05
+ ...
0..9 . 0..9
‐
Luis Hernández Yáñez
Siempre un nuí mero (con o sin signo) con un solo díígito de parte
entera, seguido del exponente (potencia de 10):
‐5.23e‐2 ‐2 ‐0,0523
‐5,23 x 10
1.11e2 1,11 x 10
2 111,0
7.4523e‐04 7,4523 x 10‐4 0,00074523
‐3.3333e+06 ‐3,3333 x 106 ‐3.333.300
(*) sizeof(double)
Intervalo de valores:
01
+ /‐ 2.23e‐308 .. 1.79e+308 Bytes
de memoria: 8* 02
03
04
Punto flotante. Precisioí n: 15 díígitos 05
+ ...
0..9 . 0..9
‐
Luis Hernández Yáñez
Caracteres
Luis Hernández Yáñez
Intervalo de
valores:
J
u
e
g
o
d
e
c
a
r SCII) Bytes de memoria: 1
a (FC) Literales:
c 'a', '%', '\t'
t Constantes de barra invertida: 01
e (O secuencias de escape) 02
r Para caracteres de control 03
s 05
06
'
\ n, t, v, b, r, f, a, \ 07
( ' 08
A Carácter 09
...
Valores lógicos
— Falso (false) 01
02
Bytes de memoria: 1 (FC)
03
Literales: 04
05
true, false
06
En realidad, cualquier nuí mero 07
distinto de 0 es equivalente a true 08
09
y el nuí mero 0 es equivalente a false ...
Luis Hernández Yáñez
Secuencias de caracteres
Se asigna la memoria que se necesita para la secuencia concreta
Requieren la biblioteca string con el espacio de nombres std:
#include <string>
using namespace std;
¡Ojo!
Luis Hernández Yáñez
3
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
Tipo
Conjunto de valores con sus posibles operaciones
Valor
Conjunto de bits interpretados como de un tipo concreto
Variable (o constante)
Cierta memoria con nombre para valores de un tipo
Declaración
Instruccioí n que identifica un nombre
Definición
Declaracioí n que asigna memoria a una variable o constante
Luis Hernández Yáñez
Simples
Estaí ndar: int, float, double, char, bool
Conjunto de valores predeterminado
Definidos por el usuario: enumerados
Conjunto de valores definido por el programador
Estructurados (Tema 5)
Colecciones homogeí neas: arrays
Todos los elementos de la coleccioí n de un mismo tipo
Colecciones heterogeí neas: estructuras
Elementos de la coleccioí n de tipos distintos
Luis Hernández Yáñez
[long] double
char
bool
Definicioí n de variables:
tipo nombre [ = expresión] [, ...];
Luis Hernández Yáñez
long double
double
float long
int int
short int
Promoción de tipos
Dos operandos de tipos distintos:
b = a + 3 * 2;
El valor del tipo menor se promociona al
short int i = 3;
int j = 2;
double a = 1.5, b;
b = a + i * j;
float
long int
tipo mayor
short int
long double
double
Promoción
int
b = 1.5 + 6;
Valor 6 int (4 bytes) double (8 bytes)
Conversioí n segura:
De un tipo menor a un tipo mayor short
int int long int ...
Conversioí n no segura:
De un tipo mayor a un tipo menor
int entero = 1234;
char caracter;
caracter = entero; // Conversión no segura
Menor memoria: Peí rdida de informacioí n en la conversioí n
Luis Hernández Yáñez
int a = 3, b = 2;
cout << a / b; // Muestra 1 (división entera)
cout << double(a) / b; // Muestra 1.5 (división real)
Identificador válido
enum { Identificador }
,
enum { centimo, dos_centimos, cinco_centimos,
diez_centimos, veinte_centimos,
medio_euro, euro }
Valores literales que pueden tomar las variables (en amarillo)
Luis Hernández Yáñez
Mejoran la legibilidad
typedef descripción nombre _de_tipo;
Elegimos un nombre para el tipo: tMoneda descripción
moneda1 dos_centimos
moneda2
(Internamente se usan enteros) euro
int op;
cout << " 1 ‐ Enero" << endl;
cout << " 2 ‐ Febrero" << endl;
cout << " 3 ‐ Marzo" << endl;
cout << " 4 ‐ Abril" << endl;
cout << " 5 ‐ Mayo" << endl;
cout << " 6 ‐ Junio" << endl;
cout << " 7 ‐ Julio" << endl;
cout << " 8 ‐ Agosto" << endl;
cout << " 9 ‐ Septiembre" << endl;
cout << "10 ‐ Octubre" << endl;
cout << "11 ‐ Noviembre" << endl;
cout << "12 ‐ Diciembre" << endl;
Luis Hernández Yáñez
if (mes == enero) {
cout << "enero";
}
if (mes == febrero) {
cout << "febrero";
}
if (mes == marzo) {
cout << "marzo";
}
...
if (mes == diciembre) {
cout << "diciembre";
Luis Hernández Yáñez
domingo! i++;
dia = tDiaSemana(i);
int main() {
tDiaSemana hoy = lunes;
Luis Hernández Yáñez
// Mostramos la fecha
cout << "Hoy es: " << cadDia(hoy) << " " << dia
" de " << cadMes(mes) << " de " << anio
endl;
// Mostramos la fecha
cout << "Hoy es: " << cadDia(hoy) << " " << dia
" de " << cadMes(mes) << " de " << anio
endl;
Luis Hernández Yáñez
return 0;
}
} }
— Memorias USB
#include <fstream>
variabl
e
del
archiv
o
de
texto
del
dispos
itivo
flu
jo
.cl
ose
();
archivo.close();
Fundam
entos
de
la
progra
mación:
Tipos
e
instrucc
iones
II
Página
255
Fu
nd
am
en
tos
de
la
pr
og
ra
ma
ció
n:
Tip
os
e
ins
tru
cci
on
es
II
Pá
gin
a
25
6
¿Qué debo leer?
Un nuí mero
Usa el extractor archivo >> num;
Un caraí cter (sea el que sea)
Usa la funcioí n get() archivo.get(c);
Una cadena sin espacios
Usa el extractor archivo >> cad;
Una cadena posiblemente con espacios
Usa la funcioí n getline() getline(archivo, cad);
Luis Hernández Yáñez
Flujo de entrada
archivo.open("compras.txt"); // Apertura 5
4 archivo
archivo >> nif >> unidades >> precio; 3
2
getline(archivo, producto); 1
Programa
archivo.close(); // Cierre
Luis Hernández Yáñez
1
2
3
4
5
6
7
8
F
2
1
2
3
.
9
5
R
e
p
r
o
d
u
c
Luis Hernández Yáñez
Ca
da
líín
ea
da
to
de
un
co
pr
os
tr
ar
el
to
tal
de
ca
da
co
pr
un
id
ad
es
pr
ec
io
aí s
IV
(2
Fi
na
l:
"X
"
co
NI
Bucle
de
procesamiento:
Cad
a
p
a
s
o
#include <iostream> leer.cpp
#include <string>
using namespace std;
#include <fstream>
#include <iomanip> // Formato de salida
Fu int main() {
nd
am
en const int IVA = 21;
tos
de
s
la t
pr
og r
ra i
ma
ció n
n:
Tip
g
os
e
n
Luis Hernández Yáñez
ins
tru i
cci
on f
es
II
,
Pági
na
26 p
2
r
o
d
u
c
t
o
;
i
n
t
u
n
i
d
a
d
e
s
;
archivo.close(); // Cierre
}
else {
cout << "ERROR: No se ha podido abrir el archivo"
<< endl;
}
return 0;
}
Luis Hernández Yáñez
¡Atención!
Si el archivo ya existe, se borra todo lo que hubiera
Luis Hernández Yáñez
¡Atención!
Si no se cierra el archivo se puede perder informacioí n
2 archivo.open("output.txt"); // Apertura !
Flujo de salida
archivo
a
#include <iostream>
#include <string>
using namespace std;
#include <fstream>
int main() {
string nif, producto;
int unidades;
double precio;
char aux;
ofstream archivo;
return 0;
}
Luis Hernández Yáñez
return 0;
Luis Hernández Yáñez
Instrucción N
}
Fundamentos de la programación: Tipos e instrucciones II Página 273
true false
Condición false
true
false
Instrucción T Instrucción F
true
false
if true
if‐else‐if false
Luis Hernández Yáñez
switch
Diagramas de flujo
Inicialización
Sí ¿Iterar? No
Código
Luis Hernández Yáñez
while for
códigoT
} BloqueT BloqueF
[else { Opcional
códigoF
}]
condición: expresioí n bool
Claí usula else opcional
Luis Hernández Yáñez
signo.cpp
int num;
cin >> num;
if (num < 0) {
cout << "Negativo";
} cin >> num;
else { true false
cout << "Positivo"; num < 0
}
cout << "Negativo"; cout << "Positivo";
cout << endl;
Luis Hernández Yáñez
int num;
cin >> num; ‐5
if (num < 0) { Negativo
cout << "Negativo"; _
}
else {
cout << "Positivo"; cin >> num;
}
true
cout << endl; num < 0 num ‐?5
Divisioí n entre dos nuí meros protegida frente a intento de divisioí n por 0
#include <iostream>
using namespace std;
int main() {
double numerador, denominador,
resultado; cout << "Numerador: "; cin >>
numerador;
cout << "Denominador: ";
cin >> denominador;
if (denominador == 0) {
cout << "Imposible dividir entre 0!";
}
else {
resultado = numerador / denominador;
Luis Hernández Yáñez
Operadores (prioridad)
! NO Monario
...
&& Y Binario
!
|| O Binario
* / %
+ ‐
< <= > >=
== !=
&&
Luis Hernández Yáñez
||
int a = 2, b = 3, c = 4;
resultado = !(a < 5); // !(2 < 5) !true false
cond1 = (a * b + c) >= 12; // 10 >= 12 false
cond2 = (a * (b + c)) >= 12; // 14 >= 12 true
Luis Hernández Yáñez
#include <iostream>
using namespace std;
int main()
{
int num;
cout << "Introduce un número entre 1 y 10:
"; cin >> num;
if ((num >= 1) && (num <= 10)) {
cout << "Número dentro del intervalo de valores válidos";
}
else {
cout << "Número no válido!";
} Condiciones equivalentes
return 0;
} ((num >= 1) && (num <= 10))
Luis Hernández Yáñez
}
else {
dias = 30;
}
}
Fundamentos de la programación: Tipos e instrucciones II Página 287
esBisiesto = false;
}
return esBisiesto;
}
}
Luis Hernández Yáñez
else { ...
Condicioí n compuesta:
Combinacioí n de condiciones simples y operadores loí gicos
!isalpha(car)
(num < 0) || (car == 'a')
(num < 0) && ((car == 'a') || !isalpha(car))
Luis Hernández Yáñez
true
false
true
false
true
false
true
false
if‐else‐if
Luis Hernández Yáñez
switch
Ejemplo:
Calificacioí n (en letras) de
un estudiante en base a su
== 10 true
nota numeí rica (0‐10) cout << "MH"
false true
>= 9
cout << "SB"
Si nota == 10 entonces MH false
>= 7 true
si no, si nota >= 9 entonces SB cout << "NT"
false true
si no, si nota >= 7 entonces NT >= 5 cout << "AP"
false
si no, si nota >= 5 entonces AP
cout << "SS"
si no SS
Luis Hernández Yáñez
}
} cout << "SS";
} }
}
Fundamentos de la programación: Tipos e instrucciones II Página 297
cin >> nota;
Luis Hernández Yáñez
Soí lo muestra AP o SS
Página 298
if (nota < 5) { cout << "SS"; }
e else if (nota < 9) { cout << "NT"; }
l else if (nota < 10) { cout << "SB"; }
s else { cout << "MH"; }
e
i double nota;
f cin >> nota;
( if (nota >= 5) { cout << "AP"; }
n else if (nota >= 7) { cout << "NT"; }
o else if (nota >= 9) { cout << "SB"; }
t else if (nota == 10) { cout << "MH"; }
else { cout << "SS"; }
a
<
7 Fundamentos de la programación: Tipos e instrucciones II
)
{
c
o
u
t
<
<
"
A
P
"
;
}
Simplificación de las condiciones
SS AP
0 5 7 NT 9 SB 10
if (nota == 10) { cout << "MH"; } MH
else if ((nota < 10) && (nota >= 9)) { cout << "SB"; }
else if ((nota < 9) && (nota >= 7)) { cout << "NT"; }
else if ((nota < 7) && (nota >= 5)) { cout << "AP"; }
else if (nota < 5) { cout << "SS"; }
Siempre true: ramas else
if (nota == 10) { cout << "MH"; } Si no es 10, es menor que 10
else if (nota >= 7) { cout << "NT"; }
Si no es >= 9, es menor que 9
…Si no es >= 7, es menor que 7
nivel.cpp
#include <iostream> Si num == 4 entonces Muy alto
using namespace std; Si num == 3 entonces Alto
int main() { Si num == 2 entonces Medio
int num;
cout << "Introduce el nivel: "; Si num == 1 entonces Bajo
cin >> num;
if (num == 4) {
cout << "Muy alto" << endl;
}
else if (num == 3) {
cout << "Alto" << endl;
}
else if (num == 2) {
cout << "Medio" << endl;
}
else if (num == 1) {
cout << "Bajo" << endl;
}
else {
Luis Hernández Yáñez
} [break;]
[break;] [default:
case constante2: { códigoDefault
{ código2 }]
} }
[break;]
Luis Hernández Yáñez
...
nivel2.cpp
switch (num) { Si num == 4 Muy alto
case 4:
{ Si num == 3 Alto
cout << "Muy alto"; Si num == 2 Medio
}
break; Si num == 1 Bajo
case 3:
{
cout << "Alto";
}
break;
case 2:
{
default:
{
cout << "Valor no válido";
}
}
...
}
switch (num) {
...
case 3:
{
cout << "Alto";
}
case 2:
{ Num: 3
cout << "Medio"; Alto
} Medio
case 1: Bajo
{ Valor no válido
cout << "Bajo";
}
default:
Luis Hernández Yáñez
{
cout << "Valor no válido";
}
}
Fundamentos de la programación: Tipos e instrucciones II Página 306
true
num==4 Muy alto
false break;
Sin break;
true
num==3 Alto
false break;
Sin break;
true
num==2 Medio
false break;
Sin break;
true
num==1 Bajo break;
false Sin break;
No válido
default
Luis Hernández Yáñez
}
Luis Hernández
return op;
}
{
cout << "En la opción 4..." <<
endl; } // En la última no necesitamos
break
}
int opcion;
...
opcion = menu();
while (opcion != 0) {
switch (opcion) {
case 1:
{
cout << "En la opción 1..." << endl;
}
...break;
case 4:
{
cout << "En la opción 4..." << endl;
}
} // switch
...
opcion =
Luis Hernández Yáñez
menu(); } // while
break; // 5 o 6: AP
Fundamentos de la programación: Tipos e instrucciones II Página 311
{
cout << "diciembre";
}
}
Inicialización
Sí ¿Iterar? No
Cuerpo
int i = 1;
while (i <= 100) true Condición false
i 10239901?4
true 1
i <= 100 false 2
3
primero.cpp
} return 0;
Recorre la secuencia de números 1, 2, 3, 4, 5, ...
Recorre la secuencia
de nuí meros introducidos
#include <iostream>
using namespace
std; int main() {
Leemos el primero
Página 321
Luis Hernández Yáñez
Página 322
int cont = 0;
cout << "Introduce un número (0 para terminar): "; cin >> num;
cout << "Suma = " << suma << endl;
whil cout << "Media = " << media <<
e endl; return 0;
(n }
um
!=
Fundamentos de la programación: Tipos e instrucciones II
0)
{
//
0
pa
ra
te
rm
in
ar
su
ma
=
su
ma
+
nu
m;
cont
++;
cout
<<
"Intr
oduce
un
númer
o (0
para
termi
nar):
"; Fundamentos de la programación: Tipos e instrucciones II
cin
>>
num;
}
if
(c
on
t
>
0)
{
medi
a =
suma
/
cont
;
}
Número de iteraciones prefijado
Variable contadora que determina el nuí mero de iteraciones:
for ([int] var = ini; condición; paso) cuerpo
La condición compara el valor de var con un valor final
El paso incrementa o decrementa el valor de var
El valor de var debe ir aproximaí ndose al valor final
for (int i = 1; i <= 100; i++)... 1, 2, 3, 4, 5, ..., 100
for (int i = 100; i >= 1; i‐‐)... 100, 99, 98, 97, ..., 1
cout << i;
i++
Luis Hernández Yáñez
102?301
... i = 1 1
2
true 3
i <= 100 false
99
cout << i << endl; 100
_
i++
Luis Hernández Yáñez
Muy importante
El cuerpo del bucle NUNCA debe alterar el valor del contador
Garantía de terminación
Todo bucle debe terminar su ejecucioí n
Luis Hernández Yáñez
#include <iostream>
using namespace std;
long long int suma(int n);
int main() {
int num;
cout << "Número final: ";
cin >> num;
if (num > 0) { // El número debe ser positivo
cout << "La suma de los números entre 1 y "
<< num << " es: " << suma(num);
}
return 0;
}
long long int suma(int n) {
long long int total = 0;
for (int i = 1; i <= n; i++) {
Luis Hernández Yáñez
total = total + i;
}
return total;
}
Fundamentos de la programación: Tipos e instrucciones II Página 327
Luis Hernández Yáñez
¿Incremento/decremento prefijo o postfijo?
Es indiferente
Estos dos bucles producen el mismo resultado:
for (int i = 1; i <= 100; i++) ...
for (int i = 1; i <= 100; ++i) ...
Bucles infinitos
for (int i = 1; i <= 100; i‐‐) ...
0 ‐1 ‐2 ‐3 ‐4 ‐5 ‐6 ‐7 ‐8 ‐9 ‐10 ‐11 ...
Cada vez maí s lejos del valor final (100)
1
...
#include <iostream>
using namespace std; 1 x 1 = 1
#include <iomanip> 1 x 2 = 2
1 x 3 = 3
1 x 4 = 4
int main() {
...
for (int i = 1; i <= 10; i++) 1 x 10 = 10
{ for (int j = 1; j <= 10; j++) 2 x 1 = 2
{ 2 x 2 = 4
...
cout << setw(2) << i << " x "
10 x 7 = 70
setw(2) << j << " = " 10 x 8 = 80
setw(3) << i * j << endl; 10 x 9 = 90
} 10 x 10 = 100
}
Luis Hernández Yáñez
return 0;
}
Fundamentos de la programación: Tipos e instrucciones II Página 333
tablas2.cpp
#include <iostream>
using namespace std;
#include <iomanip>
int main() {
for (int i = 1; i <= 10; i++) {
cout << "Tabla del " << i << endl;
cout << "‐‐‐‐‐‐‐‐‐‐‐‐‐‐" << endl;
for (int j = 1; j <= 10; j++) {
cout << setw(2) << i << " x "
setw(2) << j << " = "
setw(3) << i * j << endl;
}
cout << endl;
Luis Hernández Yáñez
}
return 0;
}
Fundamentos de la programación: Tipos e instrucciones II Página 334
menú.cpp
#include <iostream>
using namespace std;
#include <iomanip>
int menu(); // 1: Tablas de multiplicación; 2:
Sumatorio long long int suma(int n); // Sumatorio
int main() {
int opcion = menu();
while (opcion != 0) {
switch (opcion) {
case 1:
{
for (int i = 1; i <= 10; i++) { for
(int j = 1; j <= 10; j++) {
cout << setw(2) << i << " x "
setw(2) << j << " = "
setw(3) << i * j << endl;
Luis Hernández Yáñez
}
}
}
break; ...
Fundamentos de la programación: Tipos e instrucciones II Página 335
case 2:
{
int num = 0;
while (num <= 0) {
cout << "Hasta (positivo)? ";
cin >> num;
}
cout << "La suma de los números del 1 al " <<
num << " es: " << suma(num) << endl;
}
} // switch
opcion = menu();
} // while (opcion != 0)
return 0;
}
Luis Hernández Yáñez
total = total + i;
}
return total;
}
Fundamentos de la programación: Tipos e instrucciones II Página 337
while (opcion != 0) {
...
for (int i = 1; i <= 10; i++)
{ for (int j = 1; j <= 10; j++)
{
...
}
}
while (num <= 0) {
...
} suma()
for (int i = 1; i <= n; i++) {
...
}
Luis Hernández Yáñez
return 0;
}
}
return 0;
}
Fundamentos de la programación: Tipos e instrucciones II Página 343
int main()
{ double
d; if
(...) {
int cont = 0; 0; i <= 10; i++) {
for (int i =
... AÁ mbito de la variable i
}
}
char c;
if (...) {
double x;
...
Luis Hernández Yáñez
}
return 0;
}
Fundamentos de la programación: Tipos e instrucciones II Página 344
int main() {
double d;
if (...) {
int cont = 0;
for (int i = 0; i <= 10; i++) {
...
}
}
char c;
if (...) { AÁ mbito de la variable c
double x;
...
}
Luis Hernández Yáñez
return 0;
}
Fundamentos de la programación: Tipos e instrucciones II Página 345
int main() {
double d;
if (...) {
int cont = 0;
for (int i = 0; i <= 10; i++) {
...
}
}
char c;
if (...) {
double x;
... AÁ mbito de la variable x
}
Luis Hernández Yáñez
return 0;
}
int main() {
int i, x; Oculta , en su ámbito, a la i anterior
if (...) {
}
return 0;
}
Fundamentos de la programación: Tipos e instrucciones II Página 348
Luis Hernández Yáñez
Fundamentos
de
la
programación:
Tipos
e
instrucciones
II
Página
349
Fu
nd
a
m
en
to
s
de
la
pr
og
ra
m
ac
ió
n:
Ti
po
s
e
in
str
uc
ci
on
es
II
Página
350
s l
e a
p
p o
e s
r i
m b
i l
t e
e
C
c a
u d
a e
l n
q a
u s
i d
e e
r c
a
n r
uí a
m c
e t
r e
o r
, e
s
n :
o
h
a
y
c
e
n
t
i
n
e
Luis Hernández Yáñez
true
¿Al final?
false No sabemos cuaí ntos
elementos hay
Obtener elemento
No podemos
Procesar elemento implementar con for
Luis Hernández Yáñez
Finalizacioí n
Obtener siguiente
Luis Hernández Yáñez
Finalizacioí n
int longitud() {
int l = 0;
char c;
cout << "Texto terminado en punto: ";
cin >> c; // Obtener primer carácter
while (c != '.') { // Mientras no el centinela
l++; // Procesar
cin >> c; // Obtener siguiente carácter
}
Luis Hernández Yáñez
return l;
}
char buscado, c;
int cont = 0;
cout << "Carácter a buscar: ";
cin >> buscado;
cout << "Cadena: ";
cin >> c; Primer elemento
while (c != '*') { Mientras no el centinela
if (c == buscado) {
cont++; Procesar elemento
Siguiente elemento
Luis Hernández Yáñez
}
cin >> c;
}
cout << buscado << " aparece " << cont
<< " veces.";
Fundamentos de la programación: Tipos e instrucciones II Página 361
Centinela: 0
int sumaSecuencia() {
double d, suma = 0;
ifstream archivo; // Archivo de entrada
(lectura) archivo.open("datos.txt"); if
(archivo.is_open()) {
archivo >> d; // Obtener el primero
while (d != 0) { // Mientras no sea el
centinela suma = suma + d; // Procesar el
dato archivo >> d; // Obtener el siguiente
}
archivo.close();
Luis Hernández Yáñez
}
return suma;
}
Fundamentos de la programación: Tipos e instrucciones II Página 362
Luis Hernández Yáñez
sumatorio.cpp
Recurrencia: ei+1 = ei + 1 e1 = 1
1 2 3 4 5 6 7 8 ...
Suma de los nuí meros de la secuencia calculada:
int main() {
int num;
cout << "N = ";
cin >> num;
cout << "Sumatorio:" <<
suma(num); return 0;
}
long long int suma(int n) {
int sumatorio = 0;
for (int i = 1; i <= n; i++) {
Luis Hernández Yáñez
sumatorio = sumatorio + i;
}
} return sumatorio; UÁ ltimo elemento de la secuencia: n
int i = 1;
?5
true
sumatorio += i;
Secuencia
Luis Hernández Yáñez
i = i + 1;
Definición
Fi = Fi‐1 + Fi‐2
F1 = 0
F2 = 1
0 1 1 2 3 5 8 13 21 34 55 89 ...
¿Fin de la secuencia?
Primer nuí mero de Fibonacci mayor que un nuí mero dado
Ese nuí mero de Fibonacci actuí a como centinela
Si num es 50, la secuencia seraí :
Luis Hernández Yáñez
0 1 1 2 3 5 8 13 21 34
}
¿Demasiados comentarios?
Para no oscurecer el coí digo, mejor una explicacioí n al principio
fibMenos1 123?
Luis Hernández Yáñez
fibMenos2 12?0
Obtener elemento
¿Encontrado?
Luis Hernández Yáñez
Finalizacioí n
Obtener siguiente
Luis Hernández Yáñez
Finalizacioí n
Centinela: ‐1
double d, num;
bool encontrado = false;
cout << "Encontrar primero mayor que: ";
cin >> num;
cout << "Siguiente (‐1 para terminar): ";
cin >> d; // Obtener el primer elemento
while ((d != ‐1) && !encontrado) {
Mientras no sea el centinela y no se encuentre
if (d > num) { // ¿Encontrado?
encontrado = true;
}
else {
Luis Hernández Yáñez
Colecciones homogéneas
Un mismo tipo de dato para varios elementos:
Notas de los estudiantes de una clase
Vent
as de
cada
díía
de la
sema
na
Tem
perat
uras
de
cada
díía
del
mes
...
En lugar de declarar N variables...
v
L
u
n
Luis Hernández Yáñez
v
M
a
r
v
M
i
e
v
J
u
e
v
V
i
e
v
S
a
b
v
D
o
m
125. 40 76. 95 328. 80 254. 62 435. 00 164. 29
0. 00
Ejemplos:
typedef do
typedef sh
tDiasMes[1
char tVoca
typedef do
tVentas[31
typedef tM
tMoneda
Fundamentos d
Declaraci
a
tipo nomb
Ejemplos:
tTemp temp
tDiasMes d
Luis Hernández Yáñez
nombre[índice]
Cada elemento se accede a traveí s de su ííndice (posicioí n en el array)
tVocales vocales; typedef char tVocales[5];
tTemp temp;
double media, total = 0; Memoria
... Dias 7
for (int i = 0; i < Dias; i++) temp[0] 12.40
{ total = total + temp[i]; temp[1] 10.96
} temp[2] 8.43
i = 0 temp[3] 11.65
temp[4] 13.70
temp[5] 13.41
true false
i<Dias temp[6] 14.07
media ?
total+=temp[i]
...
total 238412310.43679620040
Luis Hernández Yáñez
i++ i 3
42170
#include <iostream>
using namespace std;
int main() {
tTemp temp;
for (int i = 0; i < Dias; i++) { // Recorrido del
array cout << "Temperatura del día " << i + 1 << ":
"; cin >> temp[i];
}
cout << "Temperatura media: " << media(temp) << endl;
Luis Hernández Yáñez
return 0;
}
...
return med;
d }
o
u
b
l Los arrays se pasan a las funciones como constantes
e Las funciones no pueden devolver arrays
m
e
d
i
a
Fundamentos de la programación: Tipos e instrucciones II Página 386
(
c
o
n
s
t
t
T
e
m
p
t
e
m
p
)
{
d
o
u
b
l
e
m
e
d
,
t
o
t
a
l
=
0
;
const int Cuantas = 15;
typedef enum { centimo, dos_centimos, cinco_centimos,
diez_centimos, veinte_centimos, medio_euro, euro } tMoneda;
typedef tMoneda tCalderilla[Cuantas];
string aCadena(tMoneda moneda);
// Devuelve la cadena correspondiente al valor de moneda
if (!encontrado)
{ ind = ‐1;
}
return ind;
}
Fundamentos de la programación: Tipos e instrucciones II Página 389
Luis Hernández Yáñez
#include <iostream>
using namespace std;
#include <fstream>
const int Max = 100;
typedef double tArray[Max];
{ lista[contador] = valor;
contador++;
archivo >> valor;
} ...
Fundamentos de la programación: Tipos e instrucciones II Página 395
archivo.close();
med = media(lista, contador);
cout << "Media de los elementos de la lista: " << med << endl;
}
else {
cout << "¡No se pudo abrir el archivo!" << endl;
}
return 0;
}
3A
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
c = false ? 2 : 3; ?:
= += ‐= *= /= %=
c = 3;
Es equivalente a:
if (a + b == 10) c = 2;
else c = 3;
Se pueden concatenar:
cout << (nota == 10 ? "MH" : (nota >= 9 ? "SB" :
(nota >= 7 ? "NT" : (nota >= 5 ? "AP" : "SS"))))
"SS"
else if (nota >= 5) { cout << "AP"; }
else { cout << "SS"; }
3E
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
Recorridos 404
Un aparcamiento 405
¿Paréntesis bien emparejados? 409
¿Dos secuencias iguales? 412
Números primos menores que N 413
Búsquedas 417
Búsqueda de un número en un archivo 419
Búsquedas en secuencias ordenadas 420
Luis Hernández Yáñez
int main() {
int coches;
char c;
bool terminar = false;
ifstream archivo;
archivo.open("parking.txt");
if (!archivo.is_open()) {
cout << "¡No se ha podido abrir el archivo!" << endl;
}
else {
Recorrido...
archivo.close();
Luis Hernández Yáñez
}
return 0;
}
while (!terminar) {
archivo >> c;
if (c == '.') { // . como primer carácter? (centinela)
terminar = true;
}
else {
coches = 0;
while (c != '.') { // Recorrido de la
secuencia cout << c;
if (c == 'E') {
coches++;
}
else if (c == 'S') {
coches‐‐;
}
Luis Hernández Yáñez
archivo >> c;
}
...
if (coches >= 0) {
cout << endl << "Quedan " << coches << " coches.";
}
else {
cout << endl << "Error: Más salidas que entradas!";
}
cout << endl;
}
}
Luis Hernández Yáñez
if (!error) {
cin >> c;
}
}
Fundamentos de la programación: Tipos e instrucciones II (Anexo II) Página 410
parentesis.cpp
if (error) {
cout << "Error: cierre sin apertura (pos. " <<
pos << ")";
}
else if (anidamiento > 0) {
cout << "Error: Apertura sin cierre";
}
else {
cout << "Correcto";
}
cout << endl;
Luis Hernández Yáñez
bool iguales() {
bool sonIguales = true;
double d1, d2;
ifstream sec1, sec2;
bool final = false;
sec1.open("secuencia1.txt");
sec2.open("secuencia2.txt");
sec1 >> d1;
sec2 >> d2; // Al menos estarán los centinelas (0)
while (sonIguales && !final) {
sonIguales = (d1 == d2);
final = ((d1 == 0) || (d2 == 0));
if (!final) {
sec1 >> d1;
sec2 >> d2;
}
} Cambia secuencia2.txt por secuencia3.txt
Luis Hernández Yáñez
primos.cpp
Secuencia calculada: nuí meros divisibles soí lo por 1 y ellos mismos (< N)
#include <iostream>
using namespace std;
bool primo(int n);
int main() {
int num, candidato;
cout << "Entero en el que parar (>1): ";
cin >> num;
if (num > 1) {
candidato = 2; // El 1 no se considera un número
primo while (candidato < num) {
cout << candidato << " "; // Mostrar número
primo candidato++;
while (!primo(candidato)) { // Siguiente
primo candidato++;
}
Luis Hernández Yáñez
}
}
return 0;
}
return esPrimo;
}
Luis Hernández Yáñez
primos2.cpp
{ if (n % i == 0) {
esPrimo = false; // Es divisible por i
}
}...
Fundamentos de la programación: Tipos e instrucciones II (Anexo II) Página 415
primos3.cpp
bool primo(int n) {
bool esPrimo = true;
int i = 3;
while ((i <= n / 2) && esPrimo) {
if (n % i == 0) {
esPrimo = false;
}
i = i + 2;
}
return esPrimo;
}
Luis Hernández Yáñez
}
return 0;
}
int busca(int n) {
int i, linea = 0;
bool encontrado = false;
ifstream archivo;
archivo.open("enteros.txt");
if (!archivo.is_open()) {
linea = ‐1;
}
else {
archivo >> i;
while ((i != 0) && !encontrado) {
linea++;
if (i == n) {
encontrado = true;
}
archivo >> i; Centinela
}
if (!encontrado) {
linea = ‐1;
Luis Hernández Yáñez
}
archivo.close();
}
return linea;
}
Fundamentos de la programación: Tipos e instrucciones II (Anexo II) Página 419
Luis Hernández Yáñez
archivo >> i;
num ?9
(i != 0) false
&& (i < num)
i 95?2 true
cont++;
archivo >> i;
Luis Hernández Yáñez
No se
2 5 9 15 16 24 41 73 78 82 123 153 159 ... procesa el
resto
archivo >> i; de la secuencia
num 10?
(i != 0) false
159 && (i < num)
true
i ?2
cont++;
archivo >> i;
Luis Hernández Yáñez
4
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
Refinamientos sucesivos
Tareas que ha de realizar un programa:
Se pueden dividir en subtareas maí s sencillas
Subtareas:
Tambieí n se pueden dividir en otras maí s sencillas...
Refinamientos sucesivos
Disenñ o en sucesivos pasos en los se amplíía el detalle
Ejemplos:
Dibujar
Luis Hernández Yáñez
3. Dibujar 2. Dibujar
2.1. Dibujar
3. Dibujar
Luis Hernández Yáñez
Dibujar
Dibujar
2.1. Dibujar
4 tareas, pero dos de ellas son iguales
2.2. Dibujar Nos basta con saber cómo dibujar:
Dibujar
Luis Hernández Yáñez
{ ... }
Dibujar Dibujar Dibujar void dibujarTriangulo()
{
dibujarSecantes();
dibujarLinea();
Dibujar Dibujar }
int main() {
dibujarCirculo();
Luis Hernández Yáñez
dibujarTriangulo();
dibujarSecantes();
return 0;
}
Fundamentos de la programación: La abstracción procedimental Página 431
H O L A M A
H O L A Espacio en blanco M
{ ... } return 0;
void mostrarA()
}
{ ...}
Fundamentos de la programación: La abstracción procedimental Página 433
Luis Hernández Yáñez
Flujo de ejecución
int main()
{
mostrarH();
mostrarO();
...
}
void mostrarH()
{
...
}
void mostrarO()
{
Luis Hernández Yáñez
...
}
...
Fundamentos de la programación: La
abstracción procedimental Página 437
Procedimientos
Subprogramas de tipo void
...
void menu() int main()
{
{
int op;
cout << "1 – Editar" << endl; ...
cout << "2 – Combinar" << menu();
endl; cout << "0 – Cancelar" ...
<< endl; cout << "Opción: ";
cin >> op;
if (op == 1) {
editar();
}
else if (op == 2) {
Luis Hernández Yáñez
combinar();
}
}
Parámetros declarados en la
cabecera del subprograma
Comunicación del
subprograma con otros
subprogramas
Luis Hernández Yáñez
Fundamentos de la programación: La abstracción procedimental Página 442
Datos en los programas
Datos globales: declarados fuera de todos los subprogramas
Existen durante toda la ejecucioí n del programa
Datos locales: declarados en alguí n subprograma
Existen soí lo durante la ejecucioí n del subprograma
#include <iostream>
using namespace std;
int main() {
int op; Datos locales a main()
Luis Hernández Yáñez
Datos de entrada/salida:
Aceptados y modificados Subprograma
Subprograma que dada una variable x x
Luis Hernández Yáñez
Declaración de parámetros
Soí lo dos clases de paraí metros en C++:
— Soí lo de entrada (por valor)
& De salida
Luis Hernández Yáñez
&
Misma identidad que la variable pasada como argumento
void incrementa(int &x)
void intercambia(double &x, double &y)
void proc(char &c, int &x, double &a, bool &b)
Reciben las variables en la llamada del subprograma: ¡Variables!
Los argumentos pueden quedar modificados
¡No usaremos parámetros por valor en las funciones!
Soí lo en procedimientos
Puede haber tanto por valor como por referencia
nombre(argumentos)
— Tantos argumentos como paraí metros y en el mismo orden
— Concordancia de tipos argumento‐paraí metro
proc(12, d);
double d = 3;
int i = 124;
proc(i, 33 * d);
double d = 3;
int i = 124;
proc(cuad(20) * 34 + i, i * d);
Luis Hernández Yáñez
return 0;
Luis Hernández Yáñez
return 0;
Luis Hernández Yáñez
int main() {
int cociente, resto;
for (int j = 1; j <= 4; j++) {
for (int i = 1; i <= 4; i++) {
divide(i, j, cociente, resto);
cout << i << " entre " << j << " da un cociente de "
<< cociente << " y un resto de " << resto << endl;
}
}
Luis Hernández Yáñez
return 0;
}
...
void divide(int op1, int op2, int &div, int &rem) {
Divide op1 entre op2 y devuelve el cociente y el resto
div = op1 / op2;
rem = op1 % op2; Memoria
} cociente ?
resto ?
int main() {
int cociente, resto; i 1
for (int j = 1; j <= 4; j++) { for j 1
(int i = 1; i <= 4; i++) { ...
divide(i, j, cociente, resto);
...
}
}
Luis Hernández Yáñez
return 0;
}
...
return 0;
}
...
void divide(int op1, int op2, int &div, int &rem) {
Divide op1 entre op2 y devuelve el cociente y el resto
div = op1 / op2;
rem = op1 % op2; Memoria
} div cociente 1
rem resto 0
int main() {
i 1
int cociente, resto;
for (int j = 1; j <= 4; j++) { for j 1
(int i = 1; i <= 4; i++) { ...
divide(i, j, cociente, resto); op1 1
...
}
} op2 1
Luis Hernández Yáñez
...
return 0;
}
return 0;
}
...
void intercambia(double &valor1, double &valor2)
{ // Intercambia los valores
double tmp; // Variable local (temporal)
tmp = valor1; Memoria temporal
valor1 = valor2; del procedimiento
valor2 = tmp; tmp ?
}
...
int main() {
double num1, num2; Memoria de main()
cout << "Valor 1: ";
cin >> num1; valor1 num1 13.6
cout << "Valor 2: "; valor2 num2 317.14
cin >> num2;
...
intercambia(num1, num2);
cout << "Ahora el valor 1 es " << num1
Luis Hernández Yáñez
int main() {
double precio, pago;
int euros, cent50, cent20, cent10, cent5, cent2, cent1;
cout << "Precio: ";
cin >> precio;
cout << "Pago: ";
cin >> pago;
cambio(precio, pago, euros, cent50, cent20, cent10, cent5,
cent2, cent1);
cout << "Cambio: " << euros << " euros, " << cent50 << " x 50c., "
cent20 << " x 20c., " << cent10 << " x 10c., "
cent5 << " x 5c., " << cent2 << " x 2c. y "
Luis Hernández Yáñez
return 0;
}
cent1 = cantidad % 2;
}
}
}
else {
error = false;
...
cambio.cpp
Esta instruccioí n
Luis Hernández Yáñez
no se ejecutaraí nunca }
int main() {
int num;
cout << "Num: ";
cin >> num;
cout << "Factorial de " << num << ": " << factorial(num) <<
endl; return 0;
}
}
}
return fact;
}
}
else if (val1 < val2) {
return ‐1; ¡3 puntos de salida!
}
else {
return 1;
}
}
Luis Hernández Yáñez
resultado = 0;
}
else if (val1 < val2) {
resultado = ‐1;
}
else {
resultado = 1;
}
} return resultado; Punto de salida uí nico
Luis Hernández Yáñez
#include <iostream>
using namespace std;
>> num2;
intercambia(num1, num2);
cout << "Ahora el valor 1 es " << num1
" y el valor 2 es " << num2 << endl;
return 0;
}
mates.cpp
Luis Hernández Yáñez
Paso 2.‐
Desarrollar un programa que muestre al usuario un menú con
cuatro operaciones de conversión de medidas:
Pulgadas a centímetros
Libras a gramos
Grados Fahrenheit a centígrados
Galones a litros
Y lea la elección del usuario y proceda con la conversión, hasta que
el usuario decida que no quiere hacer más
6 grandes tareas:
Menuí , cuatro funciones de conversioí n y main()
Luis Hernández Yáñez
Conversiones
Paso 3.‐
Menú:
Mostrar las cuatro opciones maí s una para salir
Validar la entrada y devolver la elegida
Pulgadas a centímetros:
Devolver el equivalente en centíímetros del valor en pulgadas
Libras a gramos:
Devolver el equivalente en gramos del valor en libras
Grados Fahrenheit a centígrados:
Devolver el equivalente en centíígrados del valor en Fahrenheit
Galones a litros:
Devolver el equivalente en litros del valor en galones
Luis Hernández Yáñez
int main() {
double valor;
int op = ‐1;
while (op != 0) {
op = menu();
switch (op) {
case 1:
{
Luis Hernández Yáñez
break;
}
}
return 0; ...
int menu() {
int op = ‐1;
while ((op < 0) || (op > 4)) {
return op;
}
Luis Hernández Yáñez
...
Página 489
Funcioí n assert()
Precondiciones
Por ejemplo, no realizaremos conversiones de valores negativos:
double pulgACm(double pulg) {
assert(pulg > 0);
}
else { // Se cumple la precondición...
...
Postcondiciones
Un subprograma puede garantizar condiciones al terminar:
int menu() {
int op = ‐1;
while ((op < 0) || (op > 4)) {
...
cout << "Elige: ";
cin >> op;
if ((op < 0) || (op > 4)) {
cout << "Opción no válida" << endl;
}
}
assert ((op >= 0) && (op <= 4));
Luis Hernández Yáñez
return op;
}
El subprograma debe asegurarse de que se cumpla
4A
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
#include <iostream>
using namespace std;
#include <fstream>
void sumatorio_archivo(ifstream &arch, double &suma);
int main() {
double resultado;
ifstream archivo;
archivo.open("datos.txt");
if (!archivo.is_open()) {
cout << "ERROR DE APERTURA" << endl;
}
else {
sumatorio_archivo(archivo, resultado)
cout << "Suma = " << resultado <<
endl; archivo.close();
Luis Hernández Yáñez
return 0;
}
suma = 0;
arch >> dato;
#include <iostream>
using namespace std;
int main() {
double x, y;
cout << "X = "; No podemos dejar signo por
cin >> x; defecto y concretar delta
cout << "Y = ";
cin >> y;
cout << "signo y delta por defecto: " << f(x, y) << endl;
cout << "signo ‐1 y delta por defecto: " << f(x, y, ‐1) << endl;
cout << "signo y delta concretos: " << f(x, y, 1, 1.25) << endl;
return 0;
}
Luis Hernández Yáñez
5
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez/Pablo Moreno Ger
Facultad de Informaí tica
Universidad Complutense
Estructuras 543
Estructuras dentro de estructuras 549
Arrays de estructuras 550
Arrays dentro de estructuras 551
Listas de longitud variable 552
Un ejemplo completo 558
El bucle do..while 562
Clasificación de tipos
Simples
Estaí ndar: int, float, double, char, bool
Conjunto de valores predeterminado
Definidos por el usuario: enumerados
Conjunto de valores definido por el programador
Estructurados
Luis Hernández Yáñez/Pablo Moreno Ger
tVentas ventas;
double media, total = 0; Memoria
Dias 7
... ventas[0] 12.40
for (int i = 0; i < Dias; i++) {
ventas[1] 10.96
total = total + ventas[i];
} ventas[2] 8.43
ventas[3] 11.65
i = 0 ventas[4] 13.70
ventas[5] 13.41
Luis Hernández Yáñez/Pablo Moreno Ger
1º 2º 3º 4º 5º ... 10º
inicializa(array);
Si inicializa() modifica alguí n elemento de tabla,
automaí ticamente queda modificado ese elemento de array
¡Son el mismo array!
tTabla array;
inicializa(array); // array queda
modificado for (int i = 0; i < Dim; i++)
cout << array[i] << " ";
...
0 1 2 3 4 5 6 7 8 9
Recorrido de la lista:
for (int i = 0; i < NUM; i++) {
Luis Hernández Yáñez/Pablo Moreno Ger
...
Buí squeda en la lista:
while ((i < NUM) && !encontrado) {
...
...
Buí squeda en la lista:
while ((i < contador) && !encontrado) {
...
H o l a
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Longitud actual: 4
Longitud de la cadena
A d i ó s
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Longitud: 5
S u p e r c a l i f r a g i l í s t i c o
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Longitud: 21
Luis Hernández Yáñez/Pablo Moreno Ger
Tipo string
Cadenas maí s sofisticadas
Sin longitud maí xima (gestioí n automaí tica de la memoria)
Multitud de funciones de utilidad (biblioteca string)
string.cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
string cad1("Hola"); // inicialización
string cad2 = "amigo"; // inicialización
string cad3;
cad3 = cad1; // copia
cout << "cad3 = " << cad3 << endl;
cad3 = cad1 + " "; // concatenación
Luis Hernández Yáñez/Pablo Moreno Ger
return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main() {
string nombre, apellidos;
cout << "Introduzca un nombre: ";
cin >> nombre;
cout << "Introduzca los apellidos: ";
cin.sync();
getline(cin, apellidos);
cout << "Nombre completo: " << nombre << " "
Luis Hernández Yáñez/Pablo Moreno Ger
cadena.substr(posición, longitud)
Subcadena de longitud caracteres desde posición
string cad = "abcdefg";
cout << cad.substr(2, 3); // Muestra cde
cadena.find(subcadena)
Posicioí n de la primera ocurrencia de subcadena en cadena
string cad = "Olala";
cout << cad.find("la"); // Muestra 1
Luis Hernández Yáñez/Pablo Moreno Ger
http://www.cplusplus.com/reference/string/string/
typedef struct {
... // declaraciones de campos (como variables)
} tTipo; // nombre de tipo ‐ ¡al final!
typedef struct {
string nombre;
string apellidos;
int edad;
string nif;
} tPersona;
Luis Hernández Yáñez/Pablo Moreno Ger
Campos:
Tipos estaí ndar o previamente declarado
typedef struct {
string nombre;
string apellidos; Memoria
int edad;
string nif; Luis
} tPersona; persona.nombre
Antonio
tPersona persona;
persona persona.apellidos Hernández
Yáñez
nombre Luis Antonio
Luis Hernández Yáñez/Pablo Moreno Ger
persona.edad 22
apellidos Hernández Yáñez
persona.nif 00223344F
edad 22
nif 00223344F
apellidos
persona.nif // Otra estructura
edad tNif
Acceso a la letra del NIF: dni
Luis Hernández Yáñez/Pablo Moreno Ger
nif
persona.nif.letra letra
Acceso al DNI:
persona.nif.dni
edad
string apellidos; nif
nif
} tPersona; nombre
personal[11].edad edad
nif
int edad;
apellidos
edad
nif
tLista lista;
Luis Hernández Yáñez/Pablo
Fundamentos
de
la
programación:
Tipos
de
datos
estructurados
Página
552
Fu
nd
a
m
en
to
s
de
la
pr
og
ra
m
ac
ió
n:
Ti
po
s
de
da
to
s
estr
uct
ura
dos
Pá
gin
a
55
3
i la
izq
P uie
o rd
sia
de
ci
sd
oe
n el
e sig
s uie
v nte
aí ly
i de
d cre
a me
s:nta
0 r el
a co
c nta
do
o
r:
n
t
a
d
o
r
‐
1
D
e
s
p
la
z
a
r
a
Luis Hernández Yáñez/Pablo Moreno Ger
Descripción
Programa que mantenga una lista de los estudiantes de una clase
De cada estudiante: nombre, apellidos, edad, NIF y nota
Se desconoce el nuí mero total de estudiantes (maí ximo 100)
La informacioí n de la lista se mantiene en un archivo clase.txt
Se carga al empezar y se guarda al finalizar
El programa debe ofrecer estas opciones:
— Anñ adir un nuevo alumno
Luis Hernández Yáñez/Pablo Moreno Ger
#include <iostream>
#include <string>
using namespace std;
#include <fstream>
#include <iomanip>
double nota;
} tEstudiante; y tipos globales
typedef tEstudiante tArray[MAX]; Tras las bibliotecas
typedef struct {
tArray elementos;
int contador;
} tLista;
Fundamentos de la programación: Tipos de datos estructurados Página 560
// Prototipos
int menu(); // Menú del programa ‐ devuelve la opción elegida
void cargar(tLista &lista, bool &ok); // Carga del archivo void
guardar(const tLista &lista); // La guarda en el archivo void
leerEstudiante(tEstudiante &estudiante); // Lee los datos void
insertarEstudiante(tLista &lista, tEstudiante estudiante,
bool &ok); // Inserta un nuevo estudiante en la lista
void eliminarEstudiante(tLista &lista, int pos, bool &ok);
Elimina el estudiante en esa posición string
nombreCompleto(tEstudiante estudiante);
void calificar(tLista &lista); // Notas de los
estudiantes double mediaClase(const tLista &lista); //
Luis Hernández Yáñez/Pablo Moreno Ger
El bucle do..while
do cuerpo while (condición); Condicioí n al final del bucle
(
do cuerpo while condición ) ;
int i = 1;
do {
cout << i << endl;
i++;
Luis Hernández Yáñez/Pablo Moreno Ger
El cuerpo
Luis Hernández Yáñez/Pablo Moreno Ger
do {
cout << "1 ‐ Añadir un nuevo estudiante" << endl;
cout << "2 ‐ Eliminar un estudiante" << endl;
cout << "3 ‐ Calificar a los estudiantes" <<
endl; cout << "4 ‐ Listado de estudiantes" <<
endl; cout << "0 ‐ Salir" << endl; cout <<
"Opción: ";
cin >> op;
Luis Hernández Yáñez/Pablo Moreno Ger
El archivo clase.txt
Un dato en cada líínea ↲
↲
↲
Nombre (cadena) ↲ ↲
↲
Apellidos (cadena) ↲
↲ ↲ ↲
Edad (entero)
↲ ↲
NIF (cadena) ↲
↲ ↲
Luis Hernández Yáñez/Pablo Moreno Ger
↲ ↲
const tLista &lista Referencia constante Paso por referencia pero como
constante Paso por valor Evita la copia del argumento en el paraí metro (estructuras
grandes)
ok = true;
if (lista.contador == MAX) {
ok = false;
}
else {
lista.elementos[lista.contador] = estudiante;
Insertamos al final
lista.contador++;
Luis Hernández Yáñez/Pablo Moreno Ger
}
}
lista.contador‐‐;
}
}
int pos = 0;
for (int i = 0; i < lista.contador; i++) {
if (lista.elementos[i].nota > max) {
max = lista.elementos[i].nota;
pos = i;
}
}
return pos;
}
Fundamentos de la programación: Tipos de datos estructurados Página 575
void mostrarEstudiante(tEstudiante estudiante) {
cout << setw(35) << left << nombreCompleto(estudiante);
cout << estudiante.nif << " ";
cout << setw(2) << estudiante.edad << " años ";
cout << fixed << setprecision(1) << estudiante.nota;
}
if (i == mayor) {
cout << " <<< Mayor nota!";
}
cout << endl;
}
cout << "Media de la clase: " << fixed <<
setprecision(1) << media << endl << endl;
}
int main() {
tLista lista;
tEstudiante estudiante;
bool exito;
int op, pos;
cargar(lista, exito);
if (!exito) {
cout << "No se ha podido cargar la lista!" << endl;
}
else {
do { // El bucle do evita tener que leer antes la primera
opción op = menu();
switch (op) {
Luis Hernández Yáñez/Pablo Moreno Ger
case 1:
{
leerEstudiante(estudiante);
insertarEstudiante(lista, estudiante,
exito); if (!exito) {
cout << "Lista llena: imposible insertar" << endl;
}
}
break;
{ (
cout << l
"Pos i
ición: " s
; t
cin >> a
pos; )
eliminarE ,
studiante
(lista, m
pos a
‐ y
1, o
exito); r
Luis Hernández Yáñez/Pablo Moreno Ger
if (! N
exito) o
{ t
cout a
(
<< "l
Elemen i
to s
t
inexis a
tente! )
" )
;
<< }
}
endl; } while (op != 0);
} guardar(lista);
} }
break; return 0;
case 3: }
{
calificar(lista); Fundamentos de la
} programación:
estructurados
Tipos de datos
Página 578 Licen
break;
case 4: cia
l
{
CC
i (
s
t Creati
a ve
d
o Com
(
l
mons
i Luis )
s Hernández
t Este
Este tipo de licencia s ofrecen algunos derechos a terc eras personas bajo ciertas condiciones.
Yáñez/Pabl
o Moreno
a Ger documento
,
tie
m ne
e
d
i
est
a abl
C eci
l das
a
s las
imagen de
si
g arriba a
u la derecha
ie para saber
n maí s.
t
e
s:
Reconoci
miento
(
Attributi
on
):
En cualquier explotacioí n de la obra autorizad a por la licencia haraí falta reconocer la autoríía.
No
comercial
(
Non
commerc
ial
):
La
explotacioí n
de
la
obra
queda
limitada
a
usos
no
comercia
les.
Comparti
r
igual
(
Share
alike
):
La explotac ioí n autorizada incluye la cre acioí n de obras derivad as siemp re que mantengan la misma licencia al ser div ulgad as.
P
u
ls
a
e
Fundamentos de la programación: Tipos de datos
n estructurados
la Página 579
Fundamentos de la programación
5A
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez/Pablo Moreno Ger
Facultad de Informaí tica
Universidad Complutense
tCadena cadena;
cin >> cadena; // Se añade un nulo al final
cadenas.cpp
#include <iostream>
using namespace std;
#include <cstring>
int main() {
const int MAX = 20;
typedef char tCad[MAX];
tCad cadena = "Me gusta C++";
cout << cadena << endl;
cout << "Cadena: ";
cin >> cadena; // Lee hasta el primer espacio en
Luis Hernández Yáñez/Pablo Moreno Ger
c
a
d
e
n
a
2
Luis Hernández Yáñez/Pablo Moreno Ger
"
a
m
i
g
o
"
;
s
t
r
c
a
t
(
c
a
d
e
n
a
,
c
a
d
e
n
a
2
)
;
c
o
u
t
ut
<<
cade
na
<<
"
es
meno
r
que
"
<<
cade
na2;
}
c
o
u
t
<
<
e
n
d
l
;
r
e
t
u
r
n
0
;
}
Fundam
Luis Hernández Yáñez/Pablo Moreno Ger
entos
de
la
progra
mación:
Cadena
s
al
estilo
de
C
(Anexo)
Página
586
mento
s de la
progra
mació
n:
Caden
as al
estilo
de C
(Anexo
)
Página
587
Fu
nd
a
Fundamentos de la programación
6
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez / Pablo Moreno Ger
Facultad de Informaí tica
Universidad Complutense
Esquema de recorrido
Inicializacioí n Inicializacioí n
Mientras no al final de la secuencia:
Obtener el siguiente elemento ¿Al final? true
Procesar el elemento
false
Finalizacioí n
Obtener elemento
Procesar elemento
Luis Hernández Yáñez
Finalizacioí n
0 1 2 3 4 5 6 7 8 9
double elemento;
for (int i = 0; i < N; i++) {
elemento = ventas[i];
// Procesar el elemento ...
Luis Hernández Yáñez
int i = 0;
int i = 0; double elemento;
double elemento = datos[i]; do {
while (elemento != ‐1) { elemento = datos[i];
if (elemento != ‐1) {
Luis Hernández Yáñez
elementos
125.40 76.95 328.80 254.62 435.00 164.29 316.05
Luis Hernández Yáñez
0 1 2 3 4 5 6 7 8 9
contador 7
Nº de elementos (primer ííndice sin elemento)
0 1 2 3 4 5 6 7 99
numDig 0 0 0 0 0 0
0 1 2 3 4 5
Fundamentos de la programación: Recorrido y búsqueda en arrays Página 599
Cuenta de valores con k dígitos
Funcioí n que devuelve el nuí mero de díígitos de un entero:
int digitos(int dato) {
int n_digitos = 1; // Al menos tiene un dígito
Recorremos la secuencia de dígitos...
while (dato >= 10)
{ dato = dato /
10; n_digitos++;
}
return n_digitos;
}
Luis Hernández Yáñez
...
numeros[0] = rand(); // Entre 0 y 32766
int main() {
const int NUM = 100;
typedef int tNum[NUM]; // Exactamente 100 números
const int DIG = 5;
typedef int tDig[DIG];
tNum numeros;
tDig numDig = { 0 }; // Inicializa todo el array a 0
Luis Hernández Yáñez
Esquema de búsqueda
Inicializacioí n / encontrado = false;
Inicializacioí n
Mientras no se encuentre el elemento ¿Al final o true
y no se esteí al final de la secuencia:
encontrado?
Obtener el siguiente elemento false
Comprobar si el elemento
Obtener elemento
satisface la condicioí n
Finalizacioí n ¿Encontrado?
(tratar el elemento encontrado
o indicar que no se ha encontrado)
Luis Hernández Yáñez
Finalizacioí n
Página 606
Con centinela
int buscado;
cout << "Valor a buscar:
"; cin >> buscado; int pos
= 0;
bool encontrado = false;
while ((array[pos] != centinela) && !encontrado)
{ if (array[pos] == buscado) {
encontrado = true;
}
else {
pos++;
}
}
Luis Hernández Yáñez
if (encontrado) // ...
Con contador
int buscado;
cout << "Valor a buscar:
"; cin >> buscado; int pos
= 0;
bool encontrado = false;
Luis Hernández Yáñez
typedef struct {
tVentaMes ventas;
int dias;
} tMes;
typedef tMes tVentaAnual[MESES];
tVentaAnual anual;
V ntas del cuarto día del tercer mes en la primera sucursal:
e anual[2].ventas[3][0]
Fundamentos de la programación: Recorrido y búsqueda en arrays Página 609
Luis Hernández Yáñez
int main() {
tLista lista;
bool ok;
cargar(lista, ok);
Luis Hernández Yáñez
if (!ok) {
cout << "Error: no hay archivo o demasiados
datos" << endl;
}
Fundamentos de la programación: Recorrido y búsqueda en arrays Página 611
else {
double umbral;
cout << "Valor umbral: "; cin >>
umbral; bool encontrado = false; int
pos = 0;
while ((pos < lista.contador) && !encontrado)
{ if (lista.elementos[pos] > umbral) {
encontrado = true;
}
else {
pos++;
}
}
if (encontrado) {
cout << "Valor en pos. " << pos + 1 << " (" << lista.elementos[pos] << ")"
<< endl;
}
else { endl;
Luis Hernández Yáñez
}
archivo.close();
}
ok = abierto && !overflow;
}
inversa.cpp
pos++;
}
}
if (encontrado) // ...
vectores.cpp
void desplazar(tVector v) {
int aux = v[N ‐ 1];
return suma;
}
i++;
}
return !encontrado;
}
}
return i ‐ 1;
}
return encontrado;
}
Luis Hernández Yáñez
#include <iostream>
using namespace std;
const int N = 3;
const int M = 10;
typedef char tVector1[N];
typedef char tVector2[M];
int main() {
tVector1 v1 = { 'a', 'b', 'c' };
tVector2 v2 = { 'a', 'r', 'e', 't', 'z', 's', 'a', 'h', 'b', 'x' };
bool ok = vectorIncluido(v1, v2);
if (ok) {
cout << "OK: v1 esta incluido en v2" << endl;
}
else {
Luis Hernández Yáñez
return encontrado;
}
return encontrado;
}
anagramas.cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
string cad1, cad2;
bool sonAnagramas = true;
int numCar, posEnCad2;
else {
numCar = 0; // Contador de caracteres de la primera
cadena while (sonAnagramas && (numCar < cad1.length())) {
posEnCad2 = buscaCaracter(cad2, cad1.at(numCar));
if (sonAnagramas) {
cout << "Las palabras introducidas son anagramas" << endl;
}
else {
cout << "Las palabras introducidas NO son anagramas" << endl;
}
Luis Hernández Yáñez
return 0;
}
return pos;
Luis Hernández Yáñez
0 1 2 3 ... 98 99
0 ...
1 ...
2 ...
49 ...
temp.cpp
int main() {
const int MaxDias = 31;
const int MED = 2; // Nº de medidas
typedef double tTemp[MaxDias][MED]; // Día x mín./máx.
tTemp temp;
double tMaxMedia = 0, tMinMedia = 0,
tMaxAbs = ‐100, tMinAbs = 100;
int dia = 0;
double max, min;
ifstream archivo;
archivo.open("temp.txt");
if (!archivo.is_open()) {
cout << "No se ha podido abrir el archivo!" << endl;
}
Luis Hernández Yáñez
else {
archivo >> min >> max;
El archivo termina con ‐99 ‐99
...
}
}
...
return 0;
}
Luis Hernández Yáñez
Para cada valor del primer ííndice: todos los valores del segundo
Luis Hernández Yáñez
cuads[0][0] 1 0 1 1
cuads[0][1] 1 1 2 4
2 3 9
cuads[1][0] 2
3 4 16
cuads[1][1] 4
4 5 25
cuads[2][0] 3
cuads[2][1] 9
Si hay menos valores que elementos,
cuads[3][0] 4 el resto se inicializan a cero
cuads[3][1] 16 Inicializacioí n a cero de todo el array:
Luis Hernández Yáñez
matriz[0][1][1][2] 12
matriz[0][2][0][0] 0
... 0
Fundamentos de la programación: Recorrido y búsqueda en arrays Página 640
0 1 2 3 4 ... 28 29 30
0 201 125 234 112 156 ... 234 543 667
1 323 231 675 325 111 ...
2 523 417 327 333 324 ... 444 367 437
3 145 845 654 212 562 ... 354 548
4 327 652 555 222 777 ... 428 999 666 Celdas no
Meses 5 854 438 824 547 175 ... 321 356 utilizadas
tMatriz matriz;
// Procesar matriz[n1][n2][n3][n4]
}
}
}
}
double total = 0;
for (int mes = 0; mes < MESES; mes++) {
for (int dia = 0; dia < anual[mes].dias; dia++) {
for (int suc = 0; suc < SUCURSALES; suc++) {
Luis Hernández Yáñez
Página 646
7
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
Fundamentos
de
la
programación:
Algoritmos
de
ordenación
Página
651
Fu
nd
a
m
en
to
s
de
la
pr
og
ra
m
ac
ió
n:
Al
go
rit
m
os
de
or
de
na
ci
ón
Pá
gi
na
65
2
gad
a
P ele
a me
rtnt
io
men
o el
s lug
d ar
e qu
ue
n le
a co
li rre
s sp
t on
a da
v
a
cíí 1
a 6 Baraja de nueve cartas numeradas del 1 al 9
V 3
a 8
2 Las cartas estaí n desordenadas
m
o
9
4
s 7 Ordenaremos de menor a mayor (ascendente)
i
n 5
s
e
rtFundame
a ntos de la
programa
n ción:
Algoritmo
d s de
o ordenació
n
c Página 655
gLista
ordenada:
6
35 7
1
todos los elementos de
la lista
8
Lo
inse
rtam
os al
final
2 Fundame
ntos de la
9 programa
4 ción:
Algoritmo
7 s de
ordenació
n
Página 657
Al
g
or
it
m
o
d
e
or
d
e
n
ac
ió
n
p
or
gLista
ordenada:
6
34 5
1
todos los elementos de
la lista
7 9
8
Lo
inse
rtam
os al
final
2
9 Fundame
ntos de la
programa
ción:
Algoritmo
s de
ordenació
n
Página 659
Al
g
or
it
m
o
d
e
or
d
e
n
ac
ió
n
Algoritmo de ordenación por inserción
6
1
3 El 9 es el primer elemento mayor que el nuevo (8):
Lista ordenada:
42 4 5 7 89 9
Luis Hernández Yáñez
Lista ordenada:
42 43 54 57 78 98 9
Luis Hernández Yáñez
Lista ordenada:
21 32 43 45 57 87 98 9
Luis Hernández Yáñez
1 2 3 4 5 76 87 98 9
Luis Hernández Yáñez
7 14 20 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
Parte ya ordenada Elementos por insertar
Luis Hernández Yáñez
20 7 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
Luis Hernández Yáñez
nuevo 7
Primer elemento mayor o igual: ííndice 0
20 7 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
nuevo 7
7 20 14 32 5 14 27 12 13 15
Luis Hernández Yáñez
0 1 2 3 4 5 6 7 8 9
nuevo 7
Página 667
}
lista[pos] = nuevo;
}
i 1 pos 0 nuevo 7
20 7 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
20 20 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
7 20 14 32 5 14 27 12 13 15
Luis Hernández Yáñez
0 1 2 3 4 5 6 7 8 9
7 14 20 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
i 4 pos 0 nuevo 5
7 14 20 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
7 7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
14
Luis Hernández Yáñez
5 7 14 20 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9
i 5 pos 3 nuevo 14
5 7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
5 7 14 20 20 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9
14
Luis Hernández Yáñez
5 7 14 20 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9
5 7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
5 7 14 20 14 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9
Luis Hernández Yáñez
5 7 14 14 20 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9
Fundamentos de la programación: Algoritmos de ordenación Página 673
7 14 20 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
7 14 20 5 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
7 14 5 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
7 5 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
Luis Hernández Yáñez
5 7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
...
int tmp, pos;
Desde el segundo elemento hasta el último...
for (int i = 1; i < N; i++)
{ pos = i;
Mientras no al principio y anterior mayor...
while ((pos > 0) && (lista[pos ‐ 1] > lista[pos])) {
Intercambiar...
tmp = lista[pos];
lista[pos] = lista[pos ‐
1]; lista[pos ‐ 1] = tmp;
Luis Hernández Yáñez
int main() {
tLista lista;
#include ifstream archivo;
using namespace
int dato, std; pos, tmp;
#include lista.contador = 0;
...
c
o Fundamentos de la programación: Algoritmos de ordenación Página 676
n
s
t
i
n
t
N
=
1
0
0
;
t
y
p
e
d
e
f
i
n
t
t
A
r
r
a
y
[
N
]
;
archivo.open("insercion.txt");
if (!archivo.is_open()) {
cout << "Error de apertura de archivo!" << endl;
}
else {
archivo >> dato;
while ((lista.contador < N) && (dato != ‐1)) {
Centinela ‐1 al final
lista.elementos[lista.contador] =
dato; lista.contador++;
archivo >> dato;
}
archivo.close();
Si hay más de N ignoramos el resto
cout << "Antes de ordenar:" << endl;
Luis Hernández Yáñez
5 7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
5 7 14 20 14 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9
5 7 14 14 20 32 27 12 13 15
Luis Hernández Yáñez
0 1 2 3 4 5 6 7 8 9
Clave de ordenacioí n:
Luis Hernández Yáñez
Claves de ordenación
tDato tmp;
while ((pos > 0)
(lista[pos ‐ 1].nombre > lista[pos].nombre))
{ tmp = lista[pos];
lista[pos] = lista[pos ‐
1]; lista[pos ‐ 1] = tmp;
pos‐‐;
}
tDato tmp;
while ((pos > 0) && (lista[pos ‐ 1] > lista[pos]))
{ tmp = lista[pos];
lista[pos] = lista[pos ‐ 1];
lista[pos ‐ 1] = tmp;
pos‐‐;
Luis Hernández Yáñez
claves.cpp
Claves de ordenación
#include <iostream>
#include <string>
using namespace std;
#include <fstream>
#include <iomanip>
const int N = 15;
typedef struct {
int codigo;
string nombre;
double sueldo;
} tDato;
typedef tDato tArray[N];
typedef struct {
tArray datos;
Luis Hernández Yáñez
int cont;
} tLista;
...
endl; mostrar(lista);
}
return 0;
} ...
Fundamentos de la programación: Algoritmos de ordenación Página 686
void mostrar(tLista lista) {
for (int i = 0; i < lista.cont; i++)
{ cout << setw(10)
lista.datos[i].codigo
setw(20)
lista.datos[i].nombre
setw(12)
fixed
setprecision(2)
lista.datos[i].sueldo
endl;
}
}
No estable: Estable:
Luis Hernández Yáñez
Ordenaciones naturales
Si el algoritmo trabaja menos cuanto más ordenada estaí
inicialmente la lista, se dice que la ordenacioí n es natural
Ordenacioí n por insercioí n con la lista inicialmente ordenada:
Versioí n que busca el lugar primero y luego desplaza:
No hay desplazamientos; mismo nuí mero de comparaciones
Comportamiento no natural
Versioí n con intercambios:
Trabaja mucho menos; basta una comparacioí n cada vez
Comportamiento natural
Luis Hernández Yáñez
Intercambios
Asumimos que tardan un tiempo similar
Cálculo de la complejidad
Ordenacioí n por insercioí n (con intercambios):
...
for (int i = 1; i < N; i++) {
int pos = i;
while ((pos > 0) && (lista[pos ‐ 1] > lista[pos])) {
int tmp; Comparacioí n
tmp = lista[pos];
lista[pos] = lista[pos ‐ 1];
lista[pos ‐ 1] = tmp;
pos‐‐; Intercambio
}
}
Luis Hernández Yáñez
Intercambios y comparaciones:
Tantos como ciclos realicen los correspondientes bucles
... N ‐ 1 ciclos
for (int i = 1; i < N; i++) {
int pos = i; Nº variable de ciclos
while ((pos > 0) && (lista[pos ‐ 1] > lista[pos]))
{ int tmp;
tmp = lista[pos];
lista[pos] = lista[pos ‐ 1];
lista[pos ‐ 1] = tmp;
pos‐‐;
}
}
Luis Hernández Yáñez
Cálculo de la complejidad
Caso mejor: lista inicialmente ordenada
La primera comparacioí n falla: ninguí n intercambio
(N ‐ 1) * (1 comparacioí n + 0 intercambios) = N ‐ 1 O(N)
Caso peor: lista inicialmente ordenada al reveí s
Para cada pos, entre i y 1: 1 comparacioí n y 1 intercambio
1 + 2 + 3 + 4 + ... + (N ‐ 1)
((N ‐ 1) + 1) x (N ‐ 1) / 2
N * (N ‐ 1) / 2
(N2 ‐ N) / 2 O(N2)
Notacioí n O grande: orden de complejidad en base a N
El teí rmino en N que maí s raí pidamente crece al crecer N
Luis Hernández Yáñez
Órdenes de complejidad
O(log N) < O(N) < O(N log N) < O(N2) < O(N3) ...
N log2 N
N2
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
1 0 1
2 1 4
4 2 16
8 3 64
16 4 256
32 5 1024
64 6 4096
Luis Hernández Yáñez
128 7 16384
256 8 65536
...
Lista desordenada:
5 7 4 9 2 8 3 1 6
Lista ordenada:
Luis Hernández Yáñez
Lista desordenada:
5 7 4 9 2 8 3 6
Lista ordenada:
1
Luis Hernández Yáñez
Lista desordenada:
5 7 4 9 8 3 6
Lista ordenada:
1 2
Luis Hernández Yáñez
Lista desordenada:
5 7 4 9 8 6
Lista ordenada: 1 2 3
Luis Hernández Yáñez
Lista desordenada:
5 7 9 8 6
Lista ordenada: 1 2 3 4
Luis Hernández Yáñez
Lista desordenada:
7 9 8 6
Lista ordenada: 1 2 3 4 5
Luis Hernández Yáñez
Lista desordenada:
7 9 8
Lista ordenada: 1 2 3 4 5 6
Luis Hernández Yáñez
Lista desordenada:
9 8
Lista ordenada: 1 2 3 4 5 6 7
Luis Hernández Yáñez
Lista desordenada:
9
Lista ordenada: 1 2 3 4 5 6 7 8
Luis Hernández Yáñez
Lista desordenada:
i m
20 7 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
i m
5 7 14 32 20 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
5 7 14 32 20 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
i m
5 7 12 32 20 14 27 14 13 15
0 1 2 3 4 5 6 7 8 9
i m
Luis Hernández Yáñez
5 7 12 13 20 14 27 14 32 15
0 1 2 3 4 5 6 7 8 9
Fundamentos de la programación: Algoritmos de ordenación Página 713
Implementación seleccion.cpp
typedef int tLista[N];
const int N = 15;
tLista lista;
lista[i] = lista[menor];
lista[menor] = tmp;
}
}
Fundamentos de la programación: Algoritmos de ordenación Página 714
Complejidad de la ordenación por selección directa
¿Cuántas comparaciones se realizan?
Bucle externo: N ‐ 1 ciclos
Tantas comparaciones como elementos queden en la lista:
(N ‐ 1) + (N ‐ 2) + (N ‐ 3) + ... + 3 + 2 + 1 =
N x (N ‐ 1) / 2 = (N2 ‐ N) / 2 O(N2)
Mismo nuí mero de comparaciones en todos los casos
Complejidad: O(N2) Igual que el meí todo de insercioí n Algo
mejor (menos intercambios; uno en cada paso)
No es estable: intercambios “a larga distancia”
Luis Hernández Yáñez
9 9 9 9 1
4 4 4 1 9
3 3 1 4 4
6 1 3 3 3
Luis Hernández Yáñez
1 6 6 6 6
12 32 14 5 14 7
0 1 2 3 4 5
12 32 14 5 7 14
0 1 2 3 4 5
12 32 14 5 7 14
0 1 2 3 4 5
12 32 5 14 7 14
0 1 2 3 4 5
12 5 32 14 7 14
0 1 2 3 4 5
Luis Hernández Yáñez
5 12 32 14 7 14
0 1 2 3 4 5
...
int tmp;
// Del primero al penúltimo...
for (int i = 0; i < N ‐ 1; i++) {
Luis Hernández Yáñez
14 14 14 12
16 16 12 14 La lista ya estaí ordenada
35 12 16 16 No hace falta seguir
12 35 35 35
50 50 50 50
Fundamentos de la programación: Algoritmos de ordenación Página 720
burbuja2.cpp
} }
Esta variacioí n síí tiene un comportamiento natural
Fundamentos de la programación: Algoritmos de ordenación Página 721
Luis Hernández Yáñez
lista.cpp
typedef struct {
int codigo;
string nombre;
double sueldo;
} tRegistro;
typedef struct {
tArray registros;
int cont;
} tLista;
Luis Hernández Yáñez
Nuevas implementaciones:
Operadores relacionales
Insercioí n (mantener el orden)
Buí squeda (maí s eficiente)
Se guarda la lista en orden, por lo que cargar() no cambia
lista.registros[i] = registro;
lista.cont++;
}
}
5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9
5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9
Luis Hernández Yáñez
14
5 7 12 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9
5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9
Buscamos el 12
5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9
12 < lista[mitad] fin = mitad – 1
ini mitad fin
5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9
12 > lista[mitad] ini = mitad + 1
ini fin
Luis Hernández Yáñez
5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9
mitad ¡Encontrado!
5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9
5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9
Luis Hernández Yáñez
Página 735
#include <fstream>
int main() {
tLista lista;
ifstream archivo;
int dato;
Luis Hernández Yáñez
lista.cont = 0;
archivo.open("ordenados.txt"); // Existe y es correcto
archivo >> dato;
...
Fundamentos de la programación: Algoritmos de ordenación Página 737
}
return pos;
}
Complejidad
¿Qué orden de complejidad tiene la búsqueda binaria?
Caso peor:
No estaí o se encuentra en una sublista de 1 elemento
Nº de comparaciones = Nº de mitades que podemos hacer
N / 2, N / 4, N / 8, N / 16, ..., 8, 4, 2, 1
1, 2, 4, 8, ..., N / 16, N / 8, N / 4, N / 2
Si hacemos que N sea igual a 2k:
Nº de comparaciones = k N = 2k k = log2 N
Complejidad: O(log2 N) Mucho maí s raí pida que O(N)
7A
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
14 7 12 32 20 14 27 5 13 15
0 1 2 3 4 5 6 7 8 9
7 14 12 32 20 14 27 5 13 15
0 1 2 3 4 5 6 7 8 9
Luis Hernández Yáñez
5 14 12 32 20 14 27 7 13 15
0 1 2 3 4 5 6 7 8 9
}
...
mezcla2.cpp
archivo2.close();
archivo1.close();
mezcla << ‐1 << endl;
mezcla.close();
}
Luis Hernández Yáñez
8
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
Programas multiarchivo
Coí digo fuente repartido entre varios archivos (módulos)
Cada moí dulo con sus declaraciones y sus subprogramas
Moí dulo: Unidad funcional (estructura de datos, utilidades, ...)
Lista Principal Caí lculos Archivos
const int N = 10; int main() { double mean(tArray lista); bool cargar(tArray &lista,
typedef double tArray[N]; tArray lista; double min(tArray lists); string nombre);
typedef struct { bool ok; bool guardar(tArray lista,
tArray elem; init(lista);
int cont; cargar(lista, "bd.txt"); double max(tArray lista); string nombre);
} tArray; sort(lista); double desv(tArray lista); bool mezclar(string arch1,
double dato;
void init(tArray &lista); cout << "Dato: "; int minIndex(tArray lista); string arch2);
cin >> dato; int size(string nombre);
void insert(tArray &lista, insert(lista, dato, ok); int maxIndex(tArray lista);
double elem, bool &ok); cout << min(lista) << endl; bool exportar(string nombre);
cout << max(lista) << endl; double sum(tArray lista);
void remove(tArray &lista, cout << sum(lista) << endl;
int pos, bool &ok);
guardar(lista, "bd.txt");
...
return 0;
}
Luis Hernández Yáñez
Ejecutable
Caí lculos
int size(string nombre); 01010101001010000100111101001
10101010010101001010100101010
01010110010101010010101001010
bool exportar(string nombre); 10101010100101010010101010100
double mean(tArray lista); 01011001010010010101001010100 00101010111001010100101000111
10101011111010101000101001010 01010111010011010101001010101
double min(tArray lists); 10101010010101010101011001010 11111101010110011010101110000
10101010101010101001010101010 10010101001010101010101101111
double max(tArray lista); 10100000101010101101010010101
01010101000010101011110010101
Luis Hernández Yáñez
Compilación separada
Al compilar el programa principal, se adjuntan los moí dulos compilados
Principal
Moí dulos del programa int main() {
tArray lista;
Bibliotecas del sistema
bool ok;
init(lista);
cargar(lista, "bd.txt");
sort(lista);
lista.obj double dato; iostream.obj
cout << "Dato: ";
cin >> dato;
insert(lista, dato, ok);
calculos.obj cout << min(lista) << endl;
cout << max(lista) << endl;
fstream.obj
cout << sum(lista) << endl;
guardar(lista, "bd.txt");
archivos.obj .. }
return 0; math.obj ...
.
Luis Hernández Yáñez
Ejecutable
lista.cpp main.cpp
COMPILACIOÁ N
lista.obj iostream.obj
calculos.obj fstream.obj
Ejecutable
Fundamentos de la programación: Programación modular Página 761
Luis Hernández Yáñez
Etceí tera
+ Implementacioí n de los subprogramas (cómo se hace)
.cpp
lista.h
const int N = 10;
lista.cpp
#include "lista.h"
Moí dulo
typedef double tArray[N];
typedef struct {
} tArray;
tArray elem;
void init(tArray &lista) {
lista.cont = 0;
Unidad
Bibliotec a
int cont; }
void insert(tArray &lista,
main.cpp
#include "lista.h" Los nombres de archivos de cabecera
... propios (no del sistema) se encierran
entre dobles comillas, no entre aí ngulos
Fundamentos de la programación: Programación modular Página 765
lista.h
const int N = 10; typedef
double tArray[N]; typedef
struct {
tArray elem;
int cont;
} tArray;
lista.obj
00101110101011001010010010101
00101010010101011111010101000
10100101010101010010101010101
01100101010101010101010101001
01010101010100000101010101101
01001010101010101000010101011
11001010101010111100110010101
01101010101010010010101001111
00101010101001010100101010010
10100101010100101000010011110
10010101011001010101001010100
10101010101010010101001010101
01000010101011100101010010100
01110101011101001101010100101
01011111110101011001101010111
00001001010100101010101010110
} tLista;
const string BD = "bd.txt";
...
¡Documenta bien el coí digo!
Implementación lista.cpp
tRegistro nuevo() {
tRegistro registro;
cout << "Introduce el código: ";
cin >> registro.codigo;
cout << "Introduce el nombre: ";
cin >> registro.nombre;
cout << "Introduce el sueldo: ";
Luis Hernández Yáñez
lista.registros[i] = registro;
lista.cont++;
}
} ...
...
int menu();
int main() {
tLista lista;
bool ok;
int op, pos;
cargar(lista, ok);
if (!ok) {
cout << "No se ha podido abrir el archivo!" << endl;
}
Luis Hernández Yáñez
else {
do {
mostrar(lista);
op = menu(); ...
if (op == 1) {
tRegistro registro = nuevo();
insertar(lista, registro, ok);
if (!ok) {
cout << "Error: Lista llena!" << endl;
}
}
else if (op == 2) {
cout << "Posición: ";
cin >> pos;
eliminar(lista, pos, ok);
if (!ok) {
cout << "Error: Posicion inexistente!" << endl;
}
}
else if (op == 3) {
string nombre;
cin.sync();
cout << "Nombre: ";
Luis Hernández Yáñez
int menu() {
cout << endl;
cout << "1 ‐ Insertar" << endl;
cout << "2 ‐ Eliminar" << endl;
cout << "3 ‐ Buscar" << endl;
Luis Hernández Yáñez
Visual C++/Studio
Archivos de cabecera e implementacioí n en grupos distintos:
tArray[N]; tArray[N];
typedef struct { typedef struct {
Luis Hernández Yáñez
...
Fundamentos de la programación: Programación modular Página 781
Luis Hernández Yáñez
tArray registros;
int cont;
} tLista;
Fundamentos de la programación: Programación modular Página 783
Cabecera registro.h
typedef struct {
int codigo;
string nombre;
double sueldo;
} tRegistro;
tRegistro nuevo();
bool operator>(tRegistro opIzq, tRegistro opDer);
bool operator<(tRegistro opIzq, tRegistro opDer);
void mostrar(int pos, tRegistro registro);
Luis Hernández Yáñez
tRegistro nuevo() {
tRegistro registro;
cout << "Introduce el código: ";
cin >> registro.codigo;
cout << "Introduce el nombre: ";
cin >> registro.nombre;
cout << "Introduce el sueldo: ";
cin >> registro.sueldo;
return registro;
}
Luis Hernández Yáñez
Cabecera lista2.h
bd2.cpp
int menu();
int main() {
¡No intentes compilar este ejemplo!
tLista lista;
bool ok; Tiene errores
int op, pos;
cargar(lista, ok);
if (!ok) {
cout << "No se pudo abrir el archivo!" << endl;
}
Luis Hernández Yáñez
else {
do {
mostrar(lista);
op = menu();
...
Fundamentos de la programación: Programación modular Página 788
Luis Hernández Yáñez
...
registro.h #include "registro.h"
#include "lista2.h"
#include <string> ...
...
registro.cpp
...
#include "registro.h" lista2.h
...
...
#include "registro.h"
...
lista2.cpp
Luis Hernández Yáñez
...
Incluye... #include "lista2.h"
...
tArray registros;
int cont;
} tLista;
...
...
} tRegistro;
...
Compilación condicional
Directivas #ifdef, #ifndef, #else y #endif
Se usan en conjuncioí n con la directiva #define
#define X #define X
#ifdef X #ifndef X
... // Código if ... // Código if
[#else [#else
... // Código else ... // Código else
] ]
#endif #endif
La directiva #define define un síímbolo (identificador)
Izquierda: se compilaraí el “Coí digo if” y no el “Coí digo else”
Luis Hernández Yáñez
Cabecera registrofin.h
typedef struct {
int codigo;
string nombre;
double sueldo;
} tRegistro;
tRegistro nuevo();
bool operator>(tRegistro opIzq, tRegistro
Luis Hernández Yáñez
tRegistro nuevo() {
tRegistro registro;
cout << "Introduce el código: ";
cin >> registro.codigo;
cout << "Introduce el nombre: ";
cin >> registro.nombre;
cout << "Introduce el sueldo: ";
cin >> registro.sueldo;
return registro;
}
Luis Hernández Yáñez
Cabecera listafin.h
bdfin.cpp
int menu();
int main() {
bool ok;
¡Ahora ya puedes compilarlo!
tLista lista;
int op, pos;
cargar(lista, ok);
if (!ok) {
cout << "No se pudo abrir el archivo!" << endl;
}
Luis Hernández Yáñez
else {
do {
mostrar(lista);
op = menu();
...
Fundamentos de la programación: Programación modular Página 800
Gestión de una lista ordenada III
Preprocesamiento de #include en bdfin.cpp:
#include <iostream> #ifndef registrofin_h
using namespace std; #define registrofin_h
#include "registrofin.h" #include <string>
using namespace std;
#include "listafin.h" typedef struct {
...
int menu(); } tRegistro;
...
...
int menu();
... listafin_h no se ha definido todavíía
...
int menu(); ¡registrofin_h ya está definido!
...
Fundamentos de la programación: Programación modular Página 803
Luis Hernández Yáñez
tArray registros;
ordenada } tLista;
ok = true;
if (lista.cont == N) {
ok = false; // Lista llena
}
else { }
int i = 0;
while ((i < lista.cont) && (lista.registros[i]else {< registro)) {
} i++; lista.registros[lista.cont] = registro;
Luis Hernández Yáñez
lista.cont++;
// Insertamos en la posición i }
for (int j = lista.cont; j > i; j‐‐) { }
// Desplazamos a la derecha
lista.registros[j] = lista.registros[j ‐ 1];
...
listaORD.cpp: Lista ordenada void insertar(tLista &lista, tRegistro registro, bool &ok) {
if (lista.cont == N) {
ok = true;
... ok = false; // Lista llena
}
#include "lista.h"
else {
lista.registros[lista.cont] = registro;
void insertar(tLista &lista, tRegistro registro, bool &ok) {
ok = true; lista.cont++;
if (lista.cont == N) { }
ok = false; // Lista llena }
} ...
else {
int i = 0;
while ((i < lista.cont) && (lista.registros[i] < registro))
{ i++;
}
// Insertamos en la posición i
for (int j = lista.cont; j > i; j‐‐) {
// Desplazamos a la derecha
lista.registros[j] = lista.registros[j ‐ 1];
}
lista.registros[i] = registro;
...
ló
gi
ca
s
de
de
cl
ar
ac
io
Luis Hernández Yáñez
ne
s
Espacio de nombres :
agrupacioí n de
declaraciones (tipos,
datos, subprograma s)
bajo un nombre
distintivo Forma de un
espacio de nombre s:
n
a
m
e
s
p
a
c
e
n
o
m
b
r
e
{ //
Declara
ciones
}
P
o
r
e
Ac
ce
so
a
miemb
ros
de
un
es
pa
ci
Luis Hernández Yáñez
o
de
no
m
mento
s de la
progra
mació
n:
Progra
mació
n
modul
ar
Página
810
Fu
nd
a
#ifndef listaEN_h
#define listaEN_h
#include "registrofin.h"
namespace ord { // Lista ordenada
const int N = 100;
typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
} tLista;
const string BD = "bd.txt";
void mostrar(const tLista &lista);
void insertar(tLista &lista, tRegistro registro, bool
&ok); void eliminar(tLista &lista, int pos, bool &ok); //
1..N int buscar(tLista lista, string nombre);
void cargar(tLista &lista, bool
&ok); void guardar(tLista lista);
Luis Hernández Yáñez
} // namespace
#endif
Implementación
#include <iostream>
#include <fstream>
using namespace std;
#include "listaEN.h"
...
else {
ord::mostrar(lista);
...
int menu();
int main() {
tLista lista;
bool ok;
cargar(lista, ok);
if (!ok) {
cout << "No se pudo abrir el archivo!" << endl;
Luis Hernández Yáñez
}
else {
mostrar(lista);
...
Cabecera listaEN.h
Implementaciones alternativas
Todo lo comuí n puede estar fuera de la estructura namespace:
#ifndef listaEN_H
#define listaEN_H
#include "registrofin.h"
1..N ...
listaEN.cpp
#include <iostream>
using namespace std;
#include <fstream>
#include "listaEN.h"
int i = 0;
while ((i < lista.cont) && (lista.registros[i] < registro))
{ i++;
} ...
else {
ini = mitad + 1;
}
} ...
if (encontrado) {
mitad++;
}
else {
mitad = ‐1;
}
return mitad;
}
else {
pos++;
}
} ...
if (encontrado) {
pos++;
}
else {
pos = ‐1;
}
return pos;
}
Programa principal
#include <iostream> using
namespace std; #include
"registrofin.h" #include
"listaEN.h" using
namespace ord;
int menu();
int main() {
tLista lista;
bool ok;
...
tRegistro registro = nuevo();
insertar(lista, registro,
ok); if (!ok) {
Luis Hernández Yáñez
...
bdEN.cpp
Programa principal
#include <iostream> using
namespace std; #include
"registrofin.h" #include
"listaEN.h" using
namespace des;
int menu();
int main() {
tLista lista;
bool ok;
...
tRegistro registro = nuevo();
insertar(lista, registro,
ok); if (!ok) {
Luis Hernández Yáñez
...
Software de calidad
El software debe ser desarrollado con buenas praí cticas de
ingenieríía del software que aseguren un buen nivel de calidad
Los distintos moí dulos de la aplicacioí n deben ser probados
exhaustivamente, tanto de forma independiente como en su
relacioí n con los demaí s moí dulos
La prueba y depuracioí n es muy importante y todos los equipos
deberaí n seguir buenas pautas para asegurar la calidad
Los moí dulos deben ser igualmente bien documentados, de
forma que otros desarrolladores puedan aprovecharlos
Luis Hernández Yáñez
No reinventemos la rueda
Desarrollar el software pensando en su posible reutilizacioí n
Un software de calidad debe poder ser faí cilmente reutilizado
Nuestros moí dulos deben ser faí cilmente usados y modificados
8A
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
ventas.cpp
int menu();
int main() {
...
int cont;
typedef struct { Producto } tListaVentas;
int id_prod;
string codigo; ...
...
...
Luis Hernández Yáñez
Lista de ventas
void inicializar(tListaVentas &lista);
void cargar(tListaVentas &lista);
void insertar(tListaVentas &lista, tVenta venta, bool &ok);
void buscar(const tListaVentas &lista, int id, tVenta &venta, bool &ok);
void eliminar(tListaVentas &lista, int id, bool &ok);
void ventasPorClientes(const tListaVentas &lista);
void ventasPorProductos(const tListaVentas &lista);
double totalVentas(const tListaVentas &ventas, string nif,
const tListaClientes &clientes,
const tListaProductos &productos);
void stock(const tListaVentas &ventas, const tListaClientes &clientes,
const tListaProductos &productos);
int menu();
Luis Hernández Yáñez
int main() {
...
Ventas
main.cpp
typedef struct {
int id_prod;
string codigo;
#ifndef cliente_h
#define cliente_h
#include <string>
using namespace std;
typedef struct {
int id_cli;
string nif;
string nombre;
string telefono;
} tCliente;
tCliente nuevoCliente();
bool operator<(tCliente opIzq, tCliente opDer); // Por
Luis Hernández Yáñez
#endif
9
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
0F03:1A3A00
punt punt apunta a i
0F03:1A3B05
... i 5
punt 0F07:0417 0F
0F07:0418 03
Luis Hernández Yáñez
&
Obtener la dirección de memoria de ...
...
int i, j; i 0F03:1A38
0F03:1A39
... 0F03:1A3A
0F03:1A3B
int *punt;
j 0F03:1A3C
0F03:1A3D
0F03:1A3E
0F03:1A3F
...
punt 0F07:0417
0F07:0418
Luis Hernández Yáñez
0F07:0419
0F07:041A
...
int i, j; i 0F03:1A38 00
0F03:1A39 00
... 0F03:1A3A 00
int *punt; 0F03:1A3B 05
... j 0F03:1A3C
0F03:1A3D
i = 5;
0F03:1A3E
0F03:1A3F
...
punt 0F07:0417
0F07:0418
Luis Hernández Yáñez
i 5 0F07:0419
0F07:041A
...
&
Obtener la dirección de memoria de ...
...
int i, j; i 0F03:1A38 00
0F03:1A39 00
... 0F03:1A3A 00
int *punt; 0F03:1A3B 05
... j 0F03:1A3C
i = 5; 0F03:1A3D
0F03:1A3E
punt = &i; 0F03:1A3F
...
i 5 0F07:0419 1A
0F07:041A 38
...
*
Obtener lo que hay en la dirección ...
...
int i, j; i 0F03:1A38 00
0F03:1A39 00
... 0F03:1A3A 00
int *punt; 0F03:1A3B 05
... j 0F03:1A3C
i = 5; 0F03:1A3D
0F03:1A3E
punt = &i; 0F03:1A3F
j = *punt; ...
punt 0F07:0417 0F
0F07:0418 03
Luis Hernández Yáñez
punt: 0F07:0419 1A
0F07:041A 38
...
0F07:0418 03
Luis Hernández Yáñez
0F07:0419
*punt: 1A
0F07:041A
38
...
*
Obtener lo que hay en la dirección ...
...
int i, j; i 0F03:1A38 00
0F03:1A39 00
... 0F03:1A3A 00
int *punt; 0F03:1A3B 05
... j 0F03:1A3C 00
0F03:1A3D
i = 5; 00
0F03:1A3E 00
punt = &i; 0F03:1A3F 05
j = *punt; ...
punt 0F07:0417 0F
0F07:0418 03
Luis Hernández Yáñez
0F07:0419 1A
0F07:041A 38
...
int main() {
int i = 5;
int j = 13;
int *punt;
punt = &i;
cout << *punt << endl; // Muestra el valor de i
punt = &j;
cout << *punt << endl; // Ahora muestra el valor de j
int *otro = &i;
cout << *otro + *punt << endl; // i + j
int k = *punt;
Luis Hernández Yáñez
return 0;
}
int i;
int *q; // q no tiene aún una dirección válida
int *p = &i; // p toma una dirección válida
Luis Hernández Yáñez
punt1 X punt2
Luis Hernández Yáñez
punt1 punt2
Luis Hernández Yáñez
punt1 punt2
tipos.cpp
Con *puntero podemos hacer lo que con otros datos del tipo base
structPtr.cpp
Punteros a constantes:
typedef const int *tIntCtePtr; // Puntero a
constante int entero1 = 5, entero2 = 13; tIntCtePtr
punt_a_cte = &entero1;
constPtr.cpp
Punteros constantes:
typedef int *const tIntPtrCte; // Puntero
constante int entero1 = 5, entero2 = 13;
tIntPtrCte punt_cte = &entero1;
param.cpp
punt
(*punt)++;
} entero 6
Luis Hernández Yáñez
Prototipo equivalente:
void foo(int *param1, double *param2, char *param3);
void foo(int *param1, double *param2, char *param3) {
Al primer argumento se accede con *param1
Al segundo argumento se accede con *param2
Al tercer argumento se accede con *param3
}
¿Coí mo se llamaríía?
Luis Hernández Yáñez
Fundamentos
de
la
programación:
Punteros
y
memoria
dinámica
Página
883
Fu
nd
a
elot
a oti
r po
rs
a eq
y uiv
e ale
s nt
u es
n pa
p ra
u pa
n raí
t me
e tro
rs
o arr
: ay:
y
co
a ns
et
s in
ut
nN
=
p ..
a .;
s
o vo
id
p cu
o ad
r ra
r do
e (i
nt
f ar
e r[
r N]
e );
n
ci
a
P
r
Fundamentos
de la
programación:
Punteros y
memoria
dinámica
Página 888
S S
e G
M
l D
i
b c
e u
r e
a n
t
l a
a d
e
m n
e u
m e
o v
r o
i c
a o
n
y e
ll
e a
l
Fundamentos
de la
programación:
Punteros y
memoria
dinámica
Página 890
Luis Hernández Yáñez
Datos dinámicos
Se crean y se destruyen durante la ejecucioí n del programa
Se les asigna memoria del montoí n
Creacioí n Montón
Dato dinámico
Destruccioí n
Datos estáticos
Datos declarados como de un tipo concreto:
int i;
Se acceden directamente a traveí s del identificador:
cout << i;
Datos dinámicos
Datos accedidos a traveí s de su direccioí n de memoria Esa
direccioí n de memoria debe estar el alguí n puntero Los
punteros son la base del SGMD
Luis Hernández Yáñez
new tipo Reserva memoria del montoí n para una variable del
tipo y devuelve la primera direccioí n de memoria
utilizada, que debe ser asignada a un puntero
int *p; // Todavía sin una dirección válida
p = new int; // Ya tiene una dirección
válida *p = 12;
int main() {
tRegistro reg;
reg = nuevo();
Luis Hernández Yáñez
El operador delete
delete puntero; Devuelve al montoí n la memoria usada por la
variable dinaí mica apuntada por puntero
int *p;
p = new int;
*p = 12;
...
delete p; // Ya no se necesita el entero apuntado por p
#include <iostream>
using namespace std;
int main() {
double a = 1.5; Identificadores:
p1
double *p1, *p2,
*p3; p1 = &a; 4
p2 = new double; (a, p1, p2, p3)
a 1.5
*p2 = *p1;
p3 = new double; Variables:
*p3 = 123.45;
cout << *p1 << p2 1.5
endl; cout << *p2
<< endl; cout <<
*p3 << endl; delete
6
p3 (+ *p2 y *p3)
Luis Hernández Yáñez
#include <iostream>
using namespace std; PILA
1.5
int main() { double a = p1?
1.5; double *p1,
p2?
*p2, *p3;
p3?
Luis Hernández Yáñez
MONTÓN
MONTÓN
#include <iostream>
using namespace std; PILA
1.5
int main() { double a = p1
1.5; double *p1,
p2
*p2, *p3; p1 = &a;
p3?
p2 = new double;
Luis Hernández Yáñez
MONTÓN
1.5
MONTÓN
#include <iostream>
using namespace std; PILA
1.5
int main() { double a = p1
1.5; double *p1,
p2
*p2, *p3; p1 = &a;
p3
p2 = new double;
*p2 = *p1;
p3 = new double;
Luis Hernández Yáñez
1.5
MONTÓN
123.45
Luis Hernández Yáñez
1.5
MONTÓN
#include <iostream>
using namespace std; PILA
1.5
int main() { double a = p1
1.5; double *p1,
p2?
*p2, *p3; p1 = &a;
p3
p2 = new double;
*p2 = *p1;
p3 = new double;
*p3 = 123.45;
cout << *p1 << endl;
cout << *p2 << endl;
cout << *p3 << endl;
delete p2;
123.45
Luis Hernández Yáñez
MONTÓN
delete p3;
MONTÓN
Colisión pila‐montón
Los líímites de ambas regiones se encuentran
Se agota la memoria
Desbordamiento de la pila
Luis Hernández Yáñez
Fundamentos
de
la
programación:
Punteros
y
memoria
dinámica
Página
911
egis
tro
*p;
p
=
new
tRegi
stro;
*p
=
nuevo(
);
mostrar(*p);
Falta
delete
p;
retu
rn
0;
}
G++ no indica raí ninguí n error y el program a parece raí
una variable
delete p2;
Luis Hernández Yáñez
mostrar(*p);
delete p;
...
mostrar(*p); p ha dejado de apuntar
return 0; al dato dinaí mico destruido
Acceso a memoria inexistente
}
Luis Hernández Yáñez
tArray registros;
int cont;
} tLista;
Fundamentos de la programación: Punteros y memoria dinámica Página 917
tLista lista;
lista.cont = 0;
lista.cont 0
0 1 2 3 4 5 6 998 999
lista.registros
Luis Hernández Yáñez
lista.cont 1
0 1 2 3 4 5 6 998 999
lista.registros
Luis Hernández Yáñez
tLista lista;
lista.cont = 0;
lista.registros[lista.cont] = new
tRegistro(nuevo()); lista.cont++;
lista.registros[lista.cont] = new
tRegistro(nuevo()); lista.cont++;
lista.cont 2
0 1 2 3 4 5 6 998 999
lista.registros
Luis Hernández Yáñez
lista.cont 3
0 1 2 3 4 5 6 998 999
lista.registros
Luis Hernández Yáñez
lista.cont 3
0 1 2 3 4 5 6 998 999
lista.registros
Luis Hernández Yáñez
lista.cont 3
0 1 2 3 4 5 6 998 999
lista.registros
Luis Hernández Yáñez
lista.h
#endif
} lista.cont++;
}
void eliminar(tLista &lista, int code, bool &ok)
{ ok = true;
int ind = buscar(lista, code);
if (ind == ‐1) {
ok = false;
}
else {
delete lista.registros[ind];
for (int i = ind + 1; i < lista.cont; i++)
{ lista.registros[i ‐ 1] = lista.registros[i];
Luis Hernández Yáñez
} lista.cont‐‐;
}
delete lista.registros[i];
}
lista.cont = 0;
}
...
#include <iostream>
using namespace std;
#include "registro.h"
#include "lista.h"
int main() {
tLista lista;
bool ok;
cargar(lista, ok);
if (ok) {
mostrar(lista);
destruir(lista);
}
return 0;
Luis Hernández Yáñez
#include <iostream>
using namespace std;
const int N = 10;
int main() {
int *p = new int[N];
for (int i = 0; i < N; i++) {
p[i] = i;
}
for (int i = 0; i < N; i++) {
cout << p[i] << endl;
}
delete [] p;
¡No olvides destruir el array dinaí mico!
Luis Hernández Yáñez
return 0;
}
...
#include "registro.h"
...
Luis Hernández Yáñez
listaAD.cpp
No usamos new
Se han creado todo
el array al cargar
No usamos delete
Se destruye todo
el array al final
ok = true;
Luis Hernández Yáñez
if (lista.cont == N) {
ok = false;
}
else {
lista.registros[lista.cont] =
registro; lista.cont++;
}
}
voi uscar(lista, code); if (ind
d == ‐1) {
ok = false;
e }
l else {
i for (int i = ind + 1; i < lista.cont; i++) {
m lista.registros[i ‐ 1] = lista.registros[i];
i }
n lista.cont‐‐;
a }
r } ...
(
t
L Fundamentos de la programación: Punteros y memoria dinámica Página 932
i
s
t
a
&
l
i
s
t
a
,
i
n
t
c
o
d
e
,
b
o
o
l
&
o
k
)
o
k
t
r
u
e
;
i
n
t
i
n
d
=
b
int buscar(tLista lista, int code)
{ int ind = 0;
Luis Hernández Yáñez
Página 933
}
if (!encontrado) {
ind = ‐1;
}
return ind;
}
0 1 2 3 4 5 6 7
Luis Hernández Yáñez
Montón
9A
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
Fundamentos
de
la
programación:
Punteros
y
memoria
dinámica
(Anexo)
Página
940
Fu
nd
a
m
int dias[12] = { 31, 28, 31, 30, 31, 30,
...
dias[0]
31, 31, 30, 31, 30, 31 }; 0F03:1A38
0F03:1A41 31
0F03:1A42
0F03:1A43
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
Luis Hernández Yáñez
punt 0F07:041B 0F
0F07:041C 03
0F07:041D 1A
Restando pasamos a elementos anteriores 0F07:041E 40
...
28
dias[1] 0F03:1A3C
punt = punt + 2; 0F03:1A3D
0F03:1A3E
0F03:1A3F
int num = punt ‐ dias;
31
dias[2] 0F03:1A40
0F03:1A41
0F03:1A43
dias ...
0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
Luis Hernández Yáñez
punt 0F07:041B 0F
0F07:041C 03
0F07:041D 1A
0F07:041E 3C
...
dias[3] 0F03:1A3E 30
tSIPtr punt = dias; 0F03:1A3F
dias[4] 0F03:1A40
0F03:1A41
31
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
punt 0F07:041B 0F
0F07:041C 03
Luis Hernández Yáñez
0F07:041D 1A
0F07:041E 38
...
0F07:041D 1A
0F07:041E 3A
...
0F07:041D 1A
0F07:041E 40
...
dias[4] 0F03:1A40
0F03:1A41
31
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
punt 0F07:041B 0F
0F07:041C 03
Luis Hernández Yáñez
0F07:041D 1A
0F07:041E 3E
...
31
dias[0] 0F03:1A38
typedef short int* 0F03:1A39
28
dias[1] 0F03:1A3A
tSIPtr; tSIPtr punt = 0F03:1A3B
punt 0F07:041B 0F
0F07:041C 03
Luis Hernández Yáñez
0F07:041D 1A
0F07:041E 3E
punt2 0F07:041F ?
tSIPtr punt2;
dias[4] 0F03:1A40
0F03:1A41
31
...
punt2 = dias; dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
punt 0F07:041B 0F
0F07:041C 03
Luis Hernández Yáñez
0F07:041D 1A
0F07:041E 3E
punt2 0F07:041F 0F
28
dias[1] 0F03:1A3A
siPtr punt = dias;
3 0F03:1A3B
punt++; 0F03:1A3D 31
dias[2]
0F03:1A3C
punt = punt + 3; dias[3] 0F03:1A3E
punt‐‐; 0F03:1A3F 30
31
dias[4] 0F03:1A40
tSIPtr punt2; 0F03:1A41
punt 0F07:041B 0F
0F07:041C 03
Luis Hernández Yáñez
0F07:041D 1A
0F07:041E 3E
punt2 0F07:041F 0F
Fundamentos de la programación: Punteros y memoria dinámica (Anexo) Página 952
Luis Hernández Yáñez
punt++;
}
...
intPtr punt = lista.elementos;
punt
0 1 2 3 4 5 6 7 8... 9899
lista.elementos 4 13 3 47 53 19 7 48
lista.cont 8
Luis Hernández Yáñez
i 0 punt
0 1 2 3 4 5 6 7 8... 9899
lista.elementos 4 13 3 47 53 19 7 48
lista.cont 8
Luis Hernández Yáñez
...
for (int i = 0; i < lista.cont; i++) { 4
cout << *punt << endl;
punt++;
}
i 1 punt
0 1 2 3 4 5 6 7 8... 9899
lista.elementos 4 13 3 47 53 19 7 48
lista.cont 8
Luis Hernández Yáñez
i 2 punt
0 1 2 3 4 5 6 7 8 ... 98 99
lista.elementos 4 13 3 47 53 19 7 48
lista.cont 8
Luis Hernández Yáñez
...
for (int i = 0; i < lista.cont; i++) { 4
13
cout << *punt << endl;
3
punt++;
}
i 3 punt
0 1 2 3 4 5 6 7 8 ... 98 99
lista.elementos 4 13 3 47 53 19 7 48
lista.cont 8
Luis Hernández Yáñez
...
lista.elementos 4 13 3 47 53 19 7 48
lista.cont 8
Luis Hernández Yáñez
...
for (int i = 0; i < lista.cont; i++) { 4
cout << *punt << endl; 13
3
punt++; 47
} 53
19
7
i 8 punt 48
0 1 2 3 4 5 6 78 ... 9899
lista.elementos 4 13 3 47 53 19 7 48
lista.cont 8
Luis Hernández Yáñez
lista
struct tNodo;
typedef tNodo *tLista;
struct tNodo {
tRegistro reg;
tLista sig;
};
tLista lista = NULL; // Lista
vacía lista = new tNodo; lista‐
>reg = nuevo();
lista‐>sig = NULL;
Luis Hernández Yáñez
lista ítem1
lista ítem1
p
Luis Hernández Yáñez
struct tNodo;
typedef tNodo *tLista;
struct tNodo {
tRegistro reg;
tLista sig;
};
listaenlazada.cpp
tLista p = lista;
// Localizamos el último nodo...
while (p‐>sig != NULL) {
p = p‐>sig; nuevo
Luis Hernández Yáñez
} p
} p‐>sig = nuevo;
} lista
} ...
ant
lista
p = p‐>sig;
}
} ...
if (!encontrado) {
ok = false; // No existe ese código
}
else {
ant‐>sig = p‐>sig;
delete p;
}
}
}
...
ant p
lista
Luis Hernández Yáñez
mostrar(p‐>reg);
p = p‐>sig;
}
} ...
lista = lista‐>sig;
delete p;
}
}
10
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
(wikipedia.org)
Luis Hernández Yáñez
factorial.cpp
Funciones recursivas
long long int factorial(int n)
{ long long int resultado;
if (n == 0) { // Caso base
resultado = 1;
}
else {
resultado = n * factorial(n ‐ 1);
}
return resultado;
}
factorial(5) 5 x factorial(4) 5 x 4 x factorial(3)
5 x 4 x 3 x factorial(2) 5 x 4 x 3 x 2 x factorial(1)
Luis Hernández Yáñez
5 x 4 x 3 x 2 x 1 x factorial(0) 5 x 4 x 3 x 2 x 1 x 1
120 Caso base
S.O.
7 7 7
Luis Hernández Yáñez
4 4 4 4
... Pila
<DIR1> cout << funcA(4);
...
Fundamentos de la programación: Introducción a la recursión Página 995
... Pila
<DIR1> cout << funcA(4);
...
Pila
<DIR1> cout << funcA(4);
...
Fundamentos de la programación: Introducción a la recursión Página 997
... Pila
<DIR1> cout << funcA(4);
...
... Pila
<DIR1> cout << funcA(4);
...
Fundamentos de la programación: Introducción a la recursión Página 999
... Pila
<DIR1> cout << funcA(4);
...
... Pila
<DIR1> cout << funcA(4);
...
Fundamentos de la programación: Introducción a la recursión Página 1001
... Pila
<DIR1> cout << funcA(4);
...
... funcC(...)
LEUV T A S
}
int funcA(...) { funcC
...
... funcB(...) funcB
} funcA
int main() {
Luis Hernández Yáñez
...
cout << funcA(...); Pila
...
factorial(5)
resultado = ?
Luis Hernández Yáñez
n = 5
Pila
resultado = ?
n = 4
resultado = ?
Luis Hernández Yáñez
n = 5
Pila
factorial(5)
factorial(4)
factorial(3)
resultado = ?
n = 3
resultado = ?
n = 4
resultado = ?
Luis Hernández Yáñez
n = 5
Pila
resultado = ?
n = 2
resultado = ?
n = 3
resultado = ?
n = 4
resultado = ?
Luis Hernández Yáñez
n = 5
Pila
factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
resultado = ?
n = 1
resultado = ?
n = 2
resultado = ?
n = 3
resultado = ?
n = 4
resultado = ?
Luis Hernández Yáñez
n = 5
Pila
factorial(1) n = 0
factorial(0) resultado = ?
n = 1
resultado = ?
n = 2
resultado = ?
n = 3
resultado = ?
n = 4
resultado = ?
Luis Hernández Yáñez
n = 5
Pila
factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0) resultado = 1
n = 1
1 resultado = ?
n = 2
resultado = ?
n = 3
resultado = ?
n = 4
resultado = ?
Luis Hernández Yáñez
n = 5
Pila
1 n = 2
resultado = ?
n = 3
resultado = ?
n = 4
resultado = ?
Luis Hernández Yáñez
n = 5
Pila
factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)
1 1
2 resultado = 6
n = 3
resultado = ?
n = 4
resultado = ?
Luis Hernández Yáñez
n = 5
Pila
2 1 1
6 resultado = 24
n = 4
resultado = ?
Luis Hernández Yáñez
n = 5
Pila
factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)
24 6 2 1 1
resultado = 120
Luis Hernández Yáñez
n = 5
Pila
1
1
2
6
24
Luis Hernández Yáñez
120 Pila
0 si n = 0
Fib(n) 1 si n = 1
int fibonacci(int n) {
int resultado;
if (n == 0) {
resultado = 0;
}
else if (n == 1) {
resultado = 1;
}
else {
Luis Hernández Yáñez
n+1 si m = 0
}
Prueí balo con nuí meros muy bajos:
Se generan MUCHAS llamadas recursivas
Fundamentos de la programación: Introducción a la recursión Página 1023
2
3 ackermann(0, 1)
ackermann(0, 2)
ackermann(0, 3)
ackermann(0, 4)
Fundamentos de la programación: Introducción a la recursión Página 1025
Luis Hernández Yáñez
func(5);
int main() {
tLista lista;
lista.cont = 0;
Carga del array...
mostrar(lista, 0);
return 0;
}
inverso.cpp
int main() {
tLista lista;
lista.cont = 0;
Carga del array...
mostrar(lista, 0);
return 0;
}
a:
int buscar(tLista lista, int buscado, int ini, int fin) // Devuelve el índice (0, 1, ... ) o ‐ 1 si no está
¿Cuaí le
s
son
los
casos
base?
Que ya no quede sublista ( ini > fin ) No encontrado Que se encuentre el elemen to
Repas a en el Tema
7 coí mo funciona y
coí mo se
implemen toí
ite rat iv am ente la
buí squeda binaria
(compaíra la con
esta)
Fundam
entos
de
la
progra
mación:
Introdu
cción
a
la
recursió
n
Página
1035
entos de la
programació
n:
Introducción
a la
recursión
Página 1036
Fu
nd
am
Cuenta una leyenda que en un templo de Hanoi se dispusieron tres
pilares de diamante y en uno de ellos 64 discos de oro, de distintos
tamaños y colocados por orden de tamaño con el mayor debajo
A B C
Mover 3 discos de A a B
Mover N‐1 discos se hace igual, pero
usando ahora otros origen y destino
Mover N‐1 discos del pilar A al pilar B:
A B C
Mover N‐2 discos del pilar A al pilar C
Mover el disco del pilar A al pilar B
Mover N‐2 discos del pilar C al pilar B
A B C
Naturaleza recursiva de la solucioí n
A B C
Luis Hernández Yáñez
int main() {
int n;
cout << "Número de torres:
"; cin >> n;
hanoi(n, 'A', 'C',
Luis Hernández Yáñez
'B'); return 0;
}
return fact;
}
Luis Hernández Yáñez
¿Qué es preferible?
Cualquier algoritmo recursivo tiene uno iterativo equivalente
Los recursivos son menos eficientes que los iterativos:
Sobrecarga de las llamadas a subprograma
Si hay una versioí n iterativa sencilla, seraí preferible a la recursiva
En ocasiones la versioí n recursiva es mucho maí s simple
Seraí preferible si no hay requisitos de rendimiento Compara
las versiones recursivas del factorial o de los nuí meros de
Fibonacci con sus equivalentes iterativas
¿Y qué tal una versión iterativa para los números de Ackermann?
Luis Hernández Yáñez
AP
Grado en Ingenieríía Informaí tica
Grado en Ingenieríía del Software
Grado en Ingenieríía de Computadores
Luis Hernaí ndez Yaí nñ ez
Facultad de Informaí tica
Universidad Complutense
Flujos 1051
Archivos binarios 1054
Tamaño de los datos: El operador sizeof() 1056
Apertura de archivos binarios 1059
Lectura de archivos binarios (acceso secuencial) 1061
Escritura en archivos binarios (acceso secuencial) 1066
Acceso directo o aleatorio 1070
Ejemplos de uso de archivos binarios 1078
Ordenación de los registros del archivo 1079
Búsqueda binaria 1085
Inserción en un archivo binario ordenado 1088
Carga de los registro de un archivo en una tabla 1092
Almacenamiento de una tabla en un archivo 1093
Luis Hernández Yáñez
Flujos
Canalizan la E/S entre los dispositivos y el programa
En forma de secuencias de caracteres
La entrada puede proceder de un dispositivo o de un archivo
La salida puede dirigirse a un dispositivo o a un archivo
Dispositivos/archivos
de salida
Dispositivos/archivos
de entrada
Página 1052
rograma
Lo que signifiquen los coí digos dependeraí del programa que use el archivo
En ambos casos se trata de una secuencia de caracteres
En el segundo caso se interpretan como coí digos binarios
Luis Hernández Yáñez
Flujo de texto 1 2 4 5 6 7 8 9 4
El operador sizeof()
En los archivos binarios se manejan coí digos binarios (bytes)
sizeof() (palabra clave): bytes que ocupa en memoria algo
Se aplica a un dato o a un tipo char byte
const int Max = 80;
typedef char tCadena[Max];
typedef struct {
int codigo;
tCadena item;
double valor;
} tRegistro;
const int SIZE = sizeof(tRegistro);
Luis Hernández Yáñez
... 0F03:1A3C 0A
0F03:1A43 0E
Luis Hernández Yáñez
00 00 00 05 0A 37 1C DF 03 92 99 0E
Biblioteca fstream
archivo.read(puntero_al_búfer, número)
búfer: variable destino de los caracteres leíídos
Pasado como puntero a secuencia de caracteres
Referencia (&) a la variable destino
Molde de puntero a caraí cter (char *)
número: cantidad de caracteres a extraer del archivo
Operador sizeof()
Archivo abierto con los modos ios::in e ios::binary
archivo.read( (char *) ®istro, sizeof(tRegistro));
Luis Hernández Yáñez
else {
Lectura OK
...
leer.cpp
#include <iostream>
using namespace std;
#include <fstream>
#include "registro.h"
El tipo tRegistro
const int Max = 80;
typedef char tCadena[Max];
typedef struct {
int codigo;
tCadena item;
double valor;
} tRegistro;
const int SIZE = sizeof(tRegistro);
¿Por qué usamos cadenas al estilo de C?
string: tamanñ o variable en memoria
Requieren un proceso de serialización
Luis Hernández Yáñez
escribir.cpp
#include <iostream>
using namespace std;
#include <fstream>
#include "registro.h"
int main() {
tRegistro registro;
fstream archivo;
archivo.open("bd2.dat", ios::out | ios::binary);
bool seguir = true;
while (seguir) {
cout << "Código: ";
cin.sync();
cin >> registro.codigo;
cout << "Nombre: ";
Luis Hernández Yáñez
cin.sync();
cin.getline(registro.item, Max); // Máx: 80
...
cin >> c;
if ((c == 'n') || (c == 'N')) {
seguir = false;
}
}
archivo.close(); ¡No olvides cerrar el archivo!
(¡peí rdida de datos!)
return 0;
}
Luis Hernández Yáñez
ios::beg ios::end
0 SIZE 2*SIZE 3*SIZE 4*SIZE 5*SIZE 6*SIZE
Lecturas y escrituras
Una vez ubicado el puntero al principio de un registro, se
puede leer el registro o actualizar (escribir) el registro
Si se ubica al final, se puede anñ adir (escribir) un nuevo registro
Actualización de un registro
#include <iostream>
using namespace std;
#include <fstream>
#include "registro.h"
int main() {
tRegistro registro;
fstream archivo;
void mostrar();
...
Luis Hernández Yáñez
void mostrar() {
fstream archivo;
tRegistro registro;
int cuantos;
...
fstream archivo;
archivo.open(BD, ios::in | ios::out |
ios::binary); archivo.seekg(0, ios::end); int pos
Luis Hernández Yáñez
= archivo.tellg();
int numReg = pos / SIZE;
...
menor
i j
Luis Hernández Yáñez
Luis Hernández Yáñez
archivo.close();
return 0;
}
Luis Hernández Yáñez
void mostrar();
int main() {
mostrar();
tRegistro registro;
fstream archivo;
...
Luis Hernández Yáñez
archivo.open(BD, ios::in |
ios::binary); archivo.seekg(0,
ios::end); int pos = archivo.tellg();
int numReg = pos / SIZE;
int buscado;
cout << "Código a buscar: ";
cin >> buscado;
int ini = 0, fin = numReg ‐ 1,
mitad; bool encontrado = false;
while ((ini <= fin) && !encontrado) { mitad
= (ini + fin) / 2; archivo.seekg(mitad *
SIZE, ios::beg); archivo.read( (char *)
®istro, SIZE); if (buscado ==
registro.codigo) {
encontrado = true;
}
else if (buscado < registro.codigo)
Luis Hernández Yáñez
{ fin = mitad ‐ 1;
}
...
return 0;
Luis Hernández Yáñez
...
insertar.cpp
void mostrar();
int main() {
mostrar();
tRegistro nuevoRegistro = nuevo(),
registro; fstream archivo;
archivo.open(BD, ios::in | ios::out |
Luis Hernández Yáñez
mostrar(); nuevoRegistro
return 0;
Luis Hernández Yáñez
Por el medio
Luis Hernández Yáñez
Al final
tabla.cpp
registro; tabla.cont++;
}
archivo.close();
}
}
Fundamentos de programación: Archivos binarios Página 1092
tabla.cpp
bd.cpp
#include <iostream>
using namespace std;
#include "registro.h"
#include "tabla.h"
int main() {
tTabla tabla;
tTabla ok;
cargar(tabla, ok);
if (!ok) {
cout << "Error al abrir el archivo!" << endl;
}
else {
mostrar(tabla);
insertar(tabla, nuevo(), ok);
mostrar(tabla);
guardar(tabla);
Luis Hernández Yáñez
}
return 0;
}