Está en la página 1de 568

FacultaddeInformtica

UniversidadComplutense

Apuntesdeclasedelaasignatura

Fundamentosdelaprogramacin

1curso
GradoenIngenieraenInformtica
GradoenIngenieradelSoftware
GradoenIngenieradeComputadores

20132014

LuisHernndezYez

LicenciaCreativeCommons:
Reconocimiento,NocomercialyCompartirigual.
http://creativecommons.org/licenses/byncsa/3.0/

Estapublicacincontienelosapuntesdeclasedelaasignatura
Fundamentosdelaprogramacin,asignaturade1cursodelosgrados
queseimpartenenlaFacultaddeInformticadelaUCM.

Durantelostresprimeroscursosenlosquesehaimpartidolaasignatura,
estematerialhasidosometidoacontinuasrevisionesycontribuciones
porpartedelosprofesoresquehanimpartidolosdistintosgrupos
delaasignatura.Aunqueeltrabajohaquedadobastanteconsolidado,
estoysegurodequetodavacontienemuchaserratas.Siencuentrasalguna,
nodudes,porfavor,enhacrmelosaberyconseguiras
quelasiguienteversinestmejordepurada.

Quieroagradeceratodoslosprofesoresquehanimpartidolaasignatura
sucontribucineneldesarrollodelmaterial,destacandoespecialmente
lalabordePabloMorenoGeryCarlosCervignRckauer.

LuisHernndezYez
ProfesordelaFacultaddeInformticadelaUCM

Fundamentosdelaprogramacin

TC
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

LuisHernndezYez

Tema1
Tema2

Computadorasyprogramacin
TiposeinstruccionesI
Anexo:Detallestcnicosdelostipos
Tema3 TiposeinstruccionesII
AnexoI:Eloperadorternario?
AnexoII:Ejemplosdesecuencias
Tema4 Laabstraccinprocedimental
Anexo:Mssobresubprogramas
Tema5 Tiposdedatosestructurados
Anexo:CadenasalestilodeC
Tema6 Recorridoybsquedaenarrays
Tema7 Algoritmosdeordenacin
Anexo:Mssobreordenacin
Tema8 Programacinmodular
Anexo:Ejemplodemodularizacin
Tema9 Punterosymemoriadinmica
Anexo:Punterosymemoriadinmica
Tema10 Introduccinalarecursin
Apndice:Archivosbinarios
Fundamentosdelaprogramacin

1
48
212
225
398
402
425
496
512
580
588
649
742
755
832
847
938
981
1049

3
12
15
19
24
27
30
35
39
45

LuisHernndezYez

Informtica,computadorasyprogramacin
Lenguajemquinayensamblador
Lenguajesdeprogramacindealtonivel
Unpocodehistoria
ProgramacineIngenieradelSoftware
EllenguajedeprogramacinC++
Sintaxisdeloslenguajesdeprogramacin
UnprimerprogramaenC++
Herramientasdedesarrollo
C++:UnmejorC

LuisHernndezYez

Fundamentosdelaprogramacin

Unejemplodeprogramacin
ElprimerprogramaenC++
Laslneasdecdigodelprograma
Clculosenlosprogramas
Variables
Expresiones
Lecturadedatosdesdeelteclado
Resolucindeproblemas
Losdatosdelosprogramas
Identificadores
Tiposdedatos
Declaracinyusodevariables
Instruccionesdeasignacin
Operadores
Mssobreexpresiones
Constantes
Labibliotecacmath
Operacionesconcaracteres

Fundamentosdelaprogramacin

50
64
80
86
92
98
108
119
127
129
133
142
147
152
160
167
171
174

Operadoresrelacionales
Tomadedecisiones(if)
Bloquesdecdigo
Bucles(while)
Entrada/salidaporconsola
Funcionesdefinidas
porelprogramador

177
180
183
186
190
199

214
216
217
218
220
221
222
223

LuisHernndezYez

int
float
Notacincientfica
double
char
bool
string
Literalesconespecificacindetipo

LuisHernndezYez

Fundamentosdelaprogramacin

Tipos,valoresyvariables
Conversindetipos
Tiposdeclaradosporelusuario
Tiposenumerados
Entrada/Salida
conarchivosdetexto
Lecturadearchivosdetexto
Escrituraenarchivosdetexto
Flujodeejecucin
Seleccinsimple
Operadoreslgicos
Anidamientodeif
Condiciones
Seleccinmltiple
Laescalaifelseif
Lainstruccinswitch
Repeticin
Elbuclewhile

Fundamentosdelaprogramacin

227
232
236
238
248
253
266
272
276
282
286
290
293
295
302
313
316

Elbuclefor
Buclesanidados
mbitoyvisibilidad
Secuencias
Recorridodesecuencias
Secuenciascalculadas
Bsquedaensecuencias
Arraysdedatossimples
Usodevariablesarrays
Recorridodearrays
Bsquedaenarrays
Arraysnocompletos

321
331
339
349
355
363
370
374
379
382
387
393

399

Recorridos
Unaparcamiento
Parntesisbienemparejados?
Dossecuenciasiguales?
NmerosprimosmenoresqueN
Bsquedas
Bsquedadeunnmeroenunarchivo
Bsquedasensecuenciasordenadas

404
405
409
412
413
417
419
420

LuisHernndezYez

Eloperadorternario?

Fundamentosdelaprogramacin

LuisHernndezYez

Diseodescendente:Tareasysubtareas
Subprogramas
Subprogramasydatos
Parmetros
Argumentos
Resultadodelafuncin
Prototipos
Ejemploscompletos
Funcionesdeoperador
Diseodescendente(unejemplo)
Precondicionesypostcondiciones

Fundamentosdelaprogramacin

427
434
441
446
451
467
473
475
477
480
490

498
501
504
508

LuisHernndezYez

Archivoscomoparmetros
Lafuncinmain()
Argumentosimplcitos
Sobrecargadesubprogramas

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Tiposdedatos
Arraysdenuevo
Arraysybuclesfor
Mssobrearrays
Inicializacindearrays
Enumeradoscomondices
Pasodearraysasubprogramas
Implementacindelistas
Cadenasdecaracteres
Cadenasdecaracteresdetipostring
Entrada/salidaconstring
Operacionesconstring
Estructuras
Estructurasdentrodeestructuras
Arraysdeestructuras
Arraysdentrodeestructuras
Listasdelongitudvariable
Unejemplocompleto
Elbucledo..while
Fundamentosdelaprogramacin

514
517
520
522
523
524
525
528
531
535
539
541
543
549
550
551
552
558
562

582
583
584
585

LuisHernndezYez

CadenasalestilodeC
E/SconcadenasalestilodeC
Labibliotecacstring
Ejemplo

LuisHernndezYez

Fundamentosdelaprogramacin

Recorridodearrays
Arrayscompletos
Arraysnocompletosconcentinela
Arraysnocompletosconcontador
Ejemplos
Generacindenmerosaleatorios
Bsquedasenarrays
Arrayscompletos
Arraysnocompletosconcentinela
Arraysnocompletosconcontador
Ejemplo
Recorridosybsquedasencadenas
Msejemplosdemanejodearrays
Arraysmultidimensionales
Inicializacindearraysmultidimensionales
Recorridodeunarraybidimensional
RecorridodeunarrayNdimensional
Bsquedaenunarraymultidimensional

Fundamentosdelaprogramacin

590
593
594
595
597
601
604
606
607
608
610
614
617
630
638
641
644
647

651
654
665
672
680
688
692
694
701
716
722
729
731

LuisHernndezYez

Algoritmosdeordenacin
Algoritmodeordenacinporinsercin
Ordenacindearraysporinsercin
Algoritmodeordenacinporinsercin
conintercambios
Clavesdeordenacin
Estabilidaddelaordenacin
Complejidadyeficiencia
Ordenacionesnaturales
Ordenacinporseleccindirecta
Mtododelaburbuja
Listasordenadas
Bsquedasenlistasordenadas
Bsquedabinaria

Fundamentosdelaprogramacin

LuisHernndezYez

Ordenacinporintercambio
Mezcladedoslistasordenadas

Fundamentosdelaprogramacin

744
747

LuisHernndezYez

Programasmultiarchivoycompilacinseparada
Interfazfrenteaimplementacin
Usodemdulosdebiblioteca
Ejemplo:GestindeunalistaordenadaI
Compilacindeprogramasmultiarchivo
Elpreprocesador
Cadacosaensumdulo
Ejemplo:GestindeunalistaordenadaII
Elproblemadelasinclusionesmltiples
Compilacincondicional
Proteccinfrenteainclusionesmltiples
Ejemplo:GestindeunalistaordenadaIII
Implementacionesalternativas
Espaciosdenombres
Implementacionesalternativas
Calidadyreutilizacindelsoftware

757
762
768
770
778
780
782
784
789
794
795
796
804
808
817
827

Fundamentosdelaprogramacin

LuisHernndezYez

Modularizacindeunprograma

Fundamentosdelaprogramacin

833

LuisHernndezYez

Direccionesdememoriaypunteros
Operadoresdepunteros
Punterosydireccionesvlidas
Punterosnoinicializados
Unvalorseguro:NULL
Copiaycomparacindepunteros
Tipospuntero
Punterosaestructuras
Punterosaconstantesypunterosconstantes
Punterosypasodeparmetros
Punterosyarrays
Memoriaydatosdelprograma
Memoriadinmica
Punterosydatosdinmicos
Gestindelamemoria
Errorescomunes
Arraysdedatosdinmicos
Arraysdinmicos

849
854
864
866
867
868
873
875
877
879
883
886
891
895
907
911
916
928

Fundamentosdelaprogramacin

LuisHernndezYez

Aritmticadepunteros
Recorridodearraysconpunteros
Referencias
Listasenlazadas

Fundamentosdelaprogramacin

940
953
962
964

LuisHernndezYez

Conceptoderecursin
Algoritmosrecursivos
Funcionesrecursivas
Diseodefuncionesrecursivas
Modelodeejecucin
Lapiladelsistema
Lapilaylasllamadasafuncin
Ejecucindelafuncinfactorial()
Tiposderecursin
Recursinsimple
Recursinmltiple
Recursinanidada
Recursincruzada
Cdigodelsubprogramarecursivo
Parmetrosyrecursin
Ejemplosdealgoritmosrecursivos
Bsquedabinaria
TorresdeHanoi
Recursinfrenteaiteracin
Estructurasdedatosrecursivas

983
986
987
989
990
992
994
1005
1018
1019
1020
1022
1026
1027
1032
1034
1035
1038
1043
1045

Fundamentosdelaprogramacin

LuisHernndezYez

Flujos
Archivosbinarios
Tamaodelosdatos:Eloperadorsizeof()
Aperturadearchivosbinarios
Lecturadearchivosbinarios(accesosecuencial)
Escrituraenarchivosbinarios(accesosecuencial)
Accesodirectooaleatorio
Ejemplosdeusodearchivosbinarios
Ordenacindelosregistrosdelarchivo
Bsquedabinaria
Insercinenunarchivobinarioordenado
Cargadelosregistrodeunarchivoenunatabla
Almacenamientodeunatablaenunarchivo

Fundamentosdelaprogramacin

1051
1054
1056
1059
1061
1066
1070
1078
1079
1085
1088
1092
1093

Fundamentosdelaprogramacin

RB
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

Programming. Principles and Practice Using C++


B. Stroustrup. Pearson Education, 2009
C++: An Introduction to Computing (2 edicin)
J. Adams, S. Leestma, L. Nyhoff. Prentice Hall, 1998
El lenguaje de programacin C++ (Edicin especial)
B. Stroustrup. AddisonWesley, 2002

LuisHernndezYez

Programacin y resolucin de problemas con C++


N. Dale, C. Weems. McGrawHill Interamericana, 2007
Problem Solving, Abstraction, Design Using C++ (3 edicin)
F.L. Friedman, E.B. Koffman. AddisonWesley, 2000.
Programacin en C++ para ingenieros
F. Xhafa et al. Thomson, 2006
Fundamentosdelaprogramacin

Programming. Principles and Practice Using C++


Del autor del lenguaje C++, un amplio tutorial que ensea a programar
en C++; hace un uso temprano de conceptos de orientacin a objetos y
de la STL, que quedan fuera del temario de este curso

C++: An Introduction to Computing (2 edicin)


Buena introduccin a la programacin en C++; buena organizacin de
los contenidos, bien desarrollado y con secciones prcticas

LuisHernndezYez

El lenguaje de programacin C++ (Edicin especial)


Del autor del lenguaje C++, la referencia absoluta sobre el lenguaje C++
en la que consultar dudas y detalles tcnicos sobre los elementos del
lenguaje

Fundamentosdelaprogramacin

Programacin y resolucin de problemas con C++


Un enfoque prctico al desarrollo de programas con C++ con
numerosos ejemplos

Problem Solving, Abstraction, Design Using C++ (3 edicin)


Introduccin a la programacin en C++ con un enfoque de desarrollo
de software y numerosos casos de estudio

Programacin en C++ para ingenieros

LuisHernndezYez

Introduccin a la programacin en C++ con explicaciones sencillas y


una organizacin clara

Fundamentosdelaprogramacin

Fundamentosdelaprogramacin

1
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

LuisHernndezYez

Informtica,computadorasyprogramacin
Lenguajemquinayensamblador
Lenguajesdeprogramacindealtonivel
Unpocodehistoria
ProgramacineIngenieradelSoftware
EllenguajedeprogramacinC++
Sintaxisdeloslenguajesdeprogramacin
UnprimerprogramaenC++
Herramientasdedesarrollo
C++:UnmejorC

Fundamentosdelaprogramacin:Computadorasyprogramacin

3
12
15
19
24
27
30
35
39
45

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 3

Informtica (Ciencia de la computacin)


Conjunto de conocimientos cientficos y tcnicas
que hacen posible el tratamiento automtico
de la informacin por medio de ordenadores

LuisHernndezYez

Computadora
Mquina electrnica, analgica o digital,
dotada de una memoria de gran capacidad
y de mtodos de tratamiento de la informacin,
capaz de resolver problemas matemticos y lgicos
mediante la ejecucin de programas informticos

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 4

LuisHernndezYez

En todas partes y con muchas formas

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 5

Hardware
Componentes que integran
la parte material
de una computadora

LuisHernndezYez

Software
Programas, instrucciones
y reglas informticas
para ejecutar tareas
en una computadora

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 6

Programar
Indicar a la computadora qu es lo que tiene que hacer

Programa

LuisHernndezYez

Secuencia de instrucciones
Instrucciones que entiende la computadora
Y que persiguen un objetivo: resolver un problema!

Fundamentosdelaprogramacin:Computadorasyprogramacin

LuisHernndezYez

ParqueJursico

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 7

Trabajo en equipo
Mltiples roles...
Gestores
Analistas
Diseadores
Programadores
Probadores
Administradores de
sistemas
...

Pgina 8

Esquema general
Memoria
temporal
UnidadCentraldeProceso
CentralProcessorUnit

LuisHernndezYez

Dispositivos
de entrada
Teclado
Ratn
Escner
Tctil

Dispositivos
de salida

C.P.U.

Almacenamiento
permanente

Fundamentosdelaprogramacin:Computadorasyprogramacin

Monitor
Impresora
Altavoz

Pgina 9

La arquitectura de Von Neumann


Dispositivos de E/S

UnaALUde2bits(Wikipedia)

C.P.U. (Procesador)

LuisHernndezYez

A.L.U.
Unidad AritmticoLgica

Memoria

Unidad de Control

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 10

La memoria
Memoria

Cada celda en una direccin

01

Celdas de 8 / 16 / 32 / 64 bits

02

Informacin voltil

03
04

Bus
de
datos

05
06
07
08

Direccin

210 =1024 1000

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 11

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 12

LuisHernndezYez

LuisHernndezYez

...

1 Bit = 0 / 1
1 Byte = 8 bits = 1 carcter
1 Kilobyte (KB) = 1024 Bytes
1 Megabyte (MB) = 1024 KB
1 Gigabyte (GB) = 1024 MB
1 Terabyte (TB) = 1024 GB
1 Petabyte (PB) = 1024 TB

Los procesadores trabajan con ceros y unos (bits)


Unidad de memoria bsica: Byte (8 bits)
(2 dgitos hexadecimales: 01011011 0101 1011 5B)

Lenguaje mquina
Cdigos hexadecimales que representan instrucciones,
registros de la CPU, direcciones de memoria o datos
Lenguajedebajonivel

LuisHernndezYez

Instruccin Significado
A02F
3E01
A030
3E02
1D
B331

Acceder a la celda de memoria 2F Dependientedelamquina


Programacindifcil
Copiarlo el registro 1 de la ALU
Acceder a la celda de memoria 30
Copiarlo en el registro 2 de la ALU
Sumar
Guardar el resultado en la celda de memoria 31

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 13

Nemotcnicos para los cdigos hexadecimales:


A0 READ3E REG1D ADD
Mayor legibilidad:
READ2F
REG01
READ30
REG02
ADD
WRITE31
LuisHernndezYez

Lenguaje de nivel medio

Cdigo fuente
(lenguaje ensamblador)
Programa
ensamblador

Cdigo objeto
(lenguaje mquina)

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 14

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 15

LuisHernndezYez

Ms cercanos a los lenguajes natural y matemtico


resultado=dato1+dato2;
Mayor legibilidad, mayor facilidad de codificacin
Estructuracin de datos / abstraccin procedimental

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 16

Traduccin

#include<iostream>
usingnamespacestd;

Cdigo fuente

intmain()
{
cout<<"HolaMundo!"<<endl;
return0;
}

Compiladores:
Compilan y enlazan
programas completos

Compilador

Cdigo objeto

Intrpretes:
Compilan, enlazan
y ejecutan instruccin
a instruccin

0100010100111010011100

Cdigo
objeto de
biblioteca

LuisHernndezYez

Enlazador

Programa
ejecutable

Paraunaarquitecturaconcreta
yunsistemaoperativo

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 17

Genealoga de lenguajes

Versiones/Estndares
Prolog

COBOL
1959

PL/I

1970

1964

1995

1983

FORTRAN
1954

Java

C++

C#

CPL

2000

1971

1963

Python
ALGOL

Pascal

Modula

1958

1970

1975

BASIC
1964

LuisHernndezYez

Fuente:
http://www.levenez.com/lang/

Simula
1964

1991

Ada

Eiffel

1979

1986

Smalltalk

Ruby

1971

1993

Haskell
Lisp

Scheme

1958

1975

1987

Logo
1968
Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 18

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 19

La prehistoria
El baco

Siglo XIX
Mquina analtica de Charles Babbage

(Wikipedia)

LuisHernndezYez

Lady Ada Lovelace


es considerada
la primera
programadora

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 20

LuisHernndezYez

Siglo XX
1936 Mquina de Turing
1946 ENIAC: Primera computadora digital
de propsito general
1947 El transistor
1953 IBM 650: Primera
computadora a gran escala
1966 ARPANET: Origen de Internet
1967 El disquete
1970 Sistema operativo UNIX
1972 Primer virus informtico (Creeper)
Lenguaje de programacin C
1974 Protocolo TCP. Primera red local

ENIAC(Wikipedia)

Fundamentosdelaprogramacin:Computadorasyprogramacin

1975
1976
1979
1981

LuisHernndezYez

1983
1984
1985
1990
1991

Se funda Microsoft
Se funda Apple
Juego Pacman
IBM PC
Sistema operativo MSDOS
Lenguaje de programacin C++
CDROM
Windows 1.0
Lenguaje HTML
World Wide Web
Sistema operativo Linux

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 21

AppleII(Wikipedia)

Linux

IBMPC(Wikipedia)

Pgina 22

1992 Windows 3.1


1995 Lenguaje de programacin Java
DVD
1998 Se funda Google
1999 MSN Messenger

2001 Windows XP
Mac OS X
2002 Mozilla Firefox
2007 iPhone
2008 Android ...

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 23

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 24

LuisHernndezYez

LuisHernndezYez

Siglo XXI

Qu es programar?
Decirle a un tonto muy rpido exactamente lo que tiene que hacer
Especificar la estructura y el comportamiento de un programa,
as como probar que el programa realiza su tarea
adecuadamente y con un rendimiento aceptable
Programa: Transforma entrada en salida

LuisHernndezYez

Entrada

Programa

Salida

Algoritmo: Secuencia de pasos y operaciones que debe realizar


el programa para resolver el problema
El programa implementa el algoritmo en un lenguaje concreto
Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 25

La programacin es slo una etapa del proceso de desarrollo


Modelo de desarrollo en cascada:
Planificacin

Recursos necesarios, presupuesto, plan,


Qu?

Anlisis
Diseo

Cmo?

LuisHernndezYez

Programacin

Implementacin

Prueba y depuracin
Mantenimiento
Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 26

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 27

Bjarne Stroustrup (1983)


HolaMundo!

#include<iostream>
usingnamespacestd;
int main()
{
cout<<"HolaMundo!"<<endl;

LuisHernndezYez

//MuestraHolaMundo!
return 0;
}

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 28

Instrucciones
Datos: literales, variables, tipos
Subprogramas (funciones)
Comentarios
Directivas
#include<iostream>
...

Directiva

usingnamespacestd;

int main()
Dato
{
Instruccin
cout<<"HolaMundo!"<<endl;
//MuestraHolaMundo!
Comentario

return 0;

Instruccin

Dato

}
Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina29

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 30

LuisHernndezYez

LuisHernndezYez

Subprograma

Sintaxis y semntica de los lenguajes


Sintaxis

Reglas que determinan cmo se pueden construir


y secuenciar los elementos del lenguaje

Semntica
Significado de cada elemento del lenguaje
Para qu sirve?

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 31

Especificacin
Lenguajes (BNF)
Diagramas
Ejemplo: Nmeros enteros (sin decimales)
BNF

LuisHernndezYez

<numeroentero>::=<signoopcional><secuenciadedgitos>
<signoopcional>::=+||<nada>
<secuenciadedgitos>::=<dgito>|<dgito><secuenciadedgitos>
<dgito>::=0|1|2|3|4|5|6|7|8|9
|significa
<nada>::=

+
0..9

Fundamentosdelaprogramacin:Computadorasyprogramacin

+23
159
1374
134
3.4
002

Pgina 32

<numeroentero>::=<signoopcional><secuenciadedgitos>
<signoopcional>::=+||<nada>
<secuenciadedgitos>::=<dgito>|<dgito><secuenciadedgitos>
<dgito>::=0|1|2|3|4|5|6|7|8|9
<nada>::=

LuisHernndezYez

+23
<numeroentero>::=<signoopcional><secuenciadedgitos>
::=+<secuenciadedgitos>::=+<dgito><secuenciadedgitos>
::=+2<secuenciadedgitos>::=+2<dgito> ::=+23
1374
<numeroentero>::=<signoopcional><secuenciadedgitos>
::=<secuenciadedgitos>::=<dgito><secuenciadedgitos>
::=1<secuenciadedgitos>::=1<dgito><secuenciadedgitos>
::=13<secuenciadedgitos>::=13<dgito><secuenciadedgitos>
::=137<secuenciadedgitos>::=137<dgito> ::=1374
134
<numeroentero>::=<signoopcional><secuenciadedgitos>
::=<secuenciadedgitos>::=<dgito><secuenciadedgitos>
::=1<secuenciadedgitos>::=ERROR ( noes<dgito>)
Fundamentosdelaprogramacin:Computadorasyprogramacin

+23

LuisHernndezYez

134

Pgina 33

+23

0..9

1374

0..9

1374

+
0..9

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 34

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 35

Hola Mundo!
Un programa que muestra un saludo en la pantalla:
#include<iostream>
usingnamespacestd;
int main()
//main()esdondeempiezalaejecucin

LuisHernndezYez

cout<<"HolaMundo!"<<endl;//MuestraHolaMundo!
return 0;
}

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 36

Anlisis del programa


Biblioteca
Directiva
Instruccin

Espaciodenombres

#include<iostream>
usingnamespacestd;

Coloreado sintctico
Tipo

Bloquedecdigo

LuisHernndezYez

Declaracin

Palabrasreservadas
Cabeceradelafuncin

int main()
{

Variable

Cadenadecaracteres

Constante

cout<<"HolaMundo!" <<endl;

Instruccin

Operador

Operador
Datosliterales

return0;

Instruccin

Nmero
Cuerpodelafuncin

Lasinstruccionesterminanen;
Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 37

Hola Mundo!
Casi todo es infraestructura
Slo
cout<<"HolaMundo!"<<endl
hace algo palpable

LuisHernndezYez

La infraestructura (notacin, bibliotecas y otro soporte)


hace nuestro cdigo simple, completo, confiable y eficiente

El estilo importa!

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 38

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 39

Editor
Bloc de notas, Wordpad, Word, Writer, Gedit, Kwrite,
(texto simple, sin formatos)
Editores especficos: coloreado sintctico
Recomendacin: Notepad++

LuisHernndezYez

Instalacin y uso:
Seccin
Herramientasdedesarrollo
en el Campus Virtual

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 40

hola.cpp
(cdigofuente)

Compilador

Cdigo objeto de
la biblioteca iostream

hola.obj
(cdigoobjeto)

Enlazador

HolaMundo!

LuisHernndezYez

Cargador

hola.exe
(ejecutable)

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 41

Compilador
Importante: C++ estndar
Recomendacin: GNU G++ (MinGW en Windows)

LuisHernndezYez

Instalacin y uso:
Seccin
Herramientasdedesarrollo
en el Campus Virtual

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 42

Entornos de desarrollo
Para editar, compilar y probar el cdigo del programa
Recomendaciones:
Windows: MS Visual Studio / C++ Express o Eclipse
Linux: Netbeans o Eclipse

LuisHernndezYez

Instalacin y uso:
Seccin
Herramientasdedesarrollo
en el Campus Virtual

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 43

Qu hace el programa?
La ejecucin del programa siempre empieza en main()
Se ejecutan las instrucciones en secuencia de principio a fin

LuisHernndezYez

Inicio

cout<<"HolaMundo!" <<endl;
Muestra HolaMundo!
en la pantalla y salta de lnea
return0;
Devuelve 0 como cdigo
de terminacin del programa

Pantalla(cout)
_ HolaMundo!
_

Fin

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 44

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 45

LuisHernndezYez

El lenguaje C
Lenguaje creado por Dennis M. Ritchie en 1972
Lenguaje de nivel medio:
Estructuras tpicas de los lenguajes de alto nivel
Construcciones para control a nivel de mquina
Lenguaje sencillo (pocas palabras reservadas)
Lenguaje estructurado (no estrictamente estructurado en bloques)
Compartimentalizacin de cdigo (funciones) y datos (mbitos)
Componente estructural bsico: la funcin (subprograma)
Programacin modular
Distingue entre maysculas y minsculas
Palabras reservadas (o clave): en minsculas
Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 46

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 47

Fundamentosdelaprogramacin

2
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

LuisHernndezYez

Facultad de Informtica
Universidad Complutense

Unejemplodeprogramacin
ElprimerprogramaenC++
Laslneasdecdigodelprograma
Clculosenlosprogramas
Variables
Expresiones
Lecturadedatosdesdeelteclado
Resolucindeproblemas
Losdatosdelosprogramas
Identificadores
Tiposdedatos
Declaracinyusodevariables
Instruccionesdeasignacin
Operadores
Mssobreexpresiones
Constantes
Labibliotecacmath
Operacionesconcaracteres

50
64
80
86
92
98
108
119
127
129
133
142
147
152
160
167
171
174

Fundamentosdelaprogramacin:TiposeinstruccionesI

Operadoresrelacionales
Tomadedecisiones(if)
Bloquesdecdigo
Bucles(while)
Entrada/salidaporconsola
Funcionesdefinidas
porelprogramador

177
180
183
186
190
199

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 50

Una computadora de un coche


Instrucciones que entiende:

<instruccin> ::= <inst> ;


<inst> ::= Start | Stop | <avanzar>
<avanzar> ::= Go <direccin> <num> Blocks
<direccin> ::= North | East | South | West
<num> ::= 1 | 2 | 3 | 4 | 5

LuisHernndezYez

Ejemplos:

Start;
Go North3Blocks;
Stop;
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 51

Sintaxis del lenguaje de programacin


= Literales

Start
instruccin

Stop
avanzar

LuisHernndezYez

avanzar

direccin

direccin

Go

num

Blocks

North

East

2
num

South

West

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 52

El problema a resolver

LuisHernndezYez

Estando el coche en la posicin A,


conseguir llegar al Cine Tvoli (B)
Qu pasos hay que seguir?
Arrancar
Ir un bloque al Norte
Ir dos bloques al Este
Ir cinco bloques al Norte
Ir dos bloques al Este
Parar

Fundamentosdelaprogramacin:TiposeinstruccionesI

A
Bloque:

Pgina 53

El algoritmo

Secuencia de pasos que hay que


seguir para resolver el problema

LuisHernndezYez

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
Esos pasos sirven tanto para
una persona como para una computadora.

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 54

El programa

LuisHernndezYez

Instrucciones escritas en
el lenguaje de programacin

Start;
Go North1Blocks;
Go East2Blocks;
Go North5Blocks;
Go East2Blocks;
Stop;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 55

El programa

LuisHernndezYez

Escribimos el cdigo del programa en un editor


y lo guardamos en un archivo:

Stat;
Go North1Blocks
Go EastBlocks;
Go Noth 5Blocks;
Go West2Blocks;
Stop;

Copiamos el archivo
en una llave USB
y lo llevamos al coche

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 56

La compilacin

LuisHernndezYez

Introducimos la llave USB en el coche


y pulsamos el botn de ejecutar el programa:
Stat;
^Unknown word.
Go North1Blocks
^;missing.
Go EastBlocks;
^Number missing.
Go Noth 5Blocks;
^Unknown word.
Go West2Blocks;
Stop;
There areerrors.Impossible to run the program.

Fundamentosdelaprogramacin:TiposeinstruccionesI

Errores
de sintaxis

Pgina 57

Depuracin
Editamos el cdigo para corregir los errores sintcticos:

Start;
Go North1Blocks;
Go East3 Blocks;
Go North5Blocks;
Go West2Blocks;
Stop;

LuisHernndezYez

Stat;
Go North1Blocks
Go EastBlocks;
Go Noth 5Blocks;
Go West2Blocks;
Stop;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 58

La ejecucin
Se realiza lo que pide
cada instruccin:

Start;
Go North1Blocks;

LuisHernndezYez

Go East3Blocks;

Error de ejecucin
Una instruccin no se puede ejecutar!

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 59

Depuracin
Editamos el cdigo para arreglar el error de ejecucin:

Start;
Go North1Blocks;
Go East2 Blocks;
Go North5Blocks;
Go West2Blocks;
Stop;

LuisHernndezYez

Start;
Go North1Blocks;
Go East3Blocks;
Go North5Blocks;
Go West2Blocks;
Stop;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 60

La ejecucin
Se realiza lo que pide
cada instruccin:

?
B

LuisHernndezYez

Start;
Go North1Blocks;
Go East2Blocks;
Go North5Blocks;
Go West2Blocks;
Stop;
Error lgico
El programa no llega al resultado deseado!
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 61

Depuracin
Editamos el cdigo para arreglar el error lgico:

Start;
Go North1Blocks;
Go East2Blocks;
Go North5Blocks;
Go East 2Blocks;
Stop;

LuisHernndezYez

Start;
Go North1Blocks;
Go East2Blocks;
Go North5Blocks;
Go West2Blocks;
Stop;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 62

La ejecucin

Se realiza lo que pide


cada instruccin:

LuisHernndezYez

Start;
Go North1Blocks;
Go East2Blocks;
Go North5Blocks;
Go East2Blocks;
Stop;

Conseguido!
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 63

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 64

Hola Mundo!
De vuelta en el programa que muestra un saludo en la pantalla:
#include<iostream>
usingnamespacestd;
int main() //main()esdondeempiezalaejecucin
{
cout<<"HolaMundo!"<<endl;

LuisHernndezYez

return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 65

Hola Mundo!
La nica instruccin que produce algo tangible:
#include<iostream>
usingnamespacestd;
intmain()//main()esdondeempiezalaejecucin
{
cout<<"HolaMundo!"<<endl;

LuisHernndezYez

return0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI

cout (iostream)

Pgina 66

character output stream

Visualizacin en la pantalla: operador << (insertor)

cout<<"HolaMundo!"<<endl;
cout <<"HolaMundo!" <<endl;
HolaMundo!

LuisHernndezYez

endl end line

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 67

Pantalla en modo texto


Lneas de 80 caracteres (textos)
Aplicacinenmodotexto

LuisHernndezYez

80caracteres

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 68

Ventanas de consola o terminal


Las aplicaciones en modo texto se ejecutan dentro de ventanas:
Windows: ventanas de consola (Smbolo del sistema)
Linux: ventanas de terminal

H o l a

M u n d o !

...

LuisHernndezYez

...

Cursor parpadeante: Donde se colocar el siguiente carcter.

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 69

El insertor <<

cout<<...;

Inserta textos en la pantalla de modo texto


Representacin textual de los datos
A partir de la posicin del cursor
Line wrap (contina en la siguiente lnea si no cabe)
Se pueden encadenar:
cout<<...<<...<<...;

LuisHernndezYez

Recuerda:lasinstruccionesterminanen;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 70

Con el insertor << podemos mostrar...


Cadenas de caracteres literales
Textos encerrados entre comillas dobles: "..."
cout<<"HolaMundo!";

Lascomillasnosemuestran!

LuisHernndezYez

Nmeros literales
Con o sin decimales, con signo o no: 123, 37, 3.1416, ...
cout<<"Pi=" <<3.1416;
Se muestran los caracteres que representan el nmero
endl

Fundamentosdelaprogramacin:TiposeinstruccionesI

Puntodecimal,NOcoma!

Pgina 71

El programa principal
La funcin main(): donde comienza la ejecucin...
#include<iostream>
usingnamespacestd;
int main()

//main()esdondeempiezalaejecucin

{
cout<<"HolaMundo!"<<endl;
return 0;
LuisHernndezYez

Contiene las instrucciones que hay que ejecutar

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 72

El programa principal
La funcin main():
Tipo de la funcin (int = entero): Tipo de valor que devuelve
Nombre de la funcin
int main()

Es una funcin!

{
...
return 0;

Cuerpo de la funcin (bloque de cdigo)

LuisHernndezYez

return 0;

Devuelve el resultado (0) de la funcin

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 73

Documentando el cdigo...
Comentarios (se ignoran):
#include<iostream>
usingnamespacestd;
intmain()//main()esdondeempiezalaejecucin
{
cout<<"HolaMundo!"<<endl;

LuisHernndezYez

...

Hasta el final de la lnea:


De varias lneas:

// Comentariodeunalnea
/* Comentariodevarias
lneasseguidas*/

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 74

La infraestructura
Cdigo para reutilizar:
#include<iostream>

Una directiva: empieza por #

usingnamespacestd;
intmain()//main()esdondeempiezalaejecucin
{
cout<<"HolaMundo!"<<endl;
return0;
LuisHernndezYez

Bibliotecas de funciones a nuestra disposicin

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 75

Bibliotecas
Se incluyen con la directiva #include:
#include<iostream>
(Utilidades de entrada/salida por consola)
Para mostrar o leer datos hay que incluir la biblioteca iostream

Espacios de nombres
En iostream hay espacios de nombres; cul queremos?

LuisHernndezYez

#include<iostream>
usingnamespacestd;

Es una instruccin: termina en ;

Siempre usaremos el espacio de nombres estndar (std)


Muchas bibliotecas no tienen espacios de nombres
Fundamentosdelaprogramacin:TiposeinstruccionesI

Compilacin y enlace
hola.cpp
(cdigofuente)

Pgina 76

Amenudoenunpaso
Compilador

Cdigo objeto de
la biblioteca iostream

hola.obj
(cdigoobjeto)

Enlazador

LuisHernndezYez

HolaMundo!

Cargador

Fundamentosdelaprogramacin:TiposeinstruccionesI

hola.exe
(ejecutable)

Pgina 77

Elementos del programa


Biblioteca
Directiva
Instruccin

Bloquedecdigo

LuisHernndezYez

Coloreadosintctico:

usingnamespacestd;

Tipo
Declaracin

Espaciodenombres

#include<iostream>

Palabrasreservadas

Cabeceradelafuncin

int main()
{

DirectivasTipos
Palabrasreservadasgenerales
DatosliteralesComentarios

Cadenadecaracteres

Variable

Constante

cout<<"HolaMundo!" <<endl;

Instruccin

Operador

Operador

Datosliterales

return0;

Instruccin

Nmero

Cuerpodelafuncin

Lasinstruccionesterminanen;
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 78

Uso de espacio en blanco


Separacin de elementos por uno o ms espacios en blanco
(espacios, tabuladores y saltos de lnea)
El compilador los ignora

LuisHernndezYez

#include<iostream>
usingnamespacestd;

#include<iostream>usingnamespacestd;
intmain(){cout<<"HolaMundo!"<<endl;
return0;}

intmain()
{
cout<<"HolaMundo!"<<endl;
return0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI

Cul se lee mejor?

Pgina 79

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 80

Programa con E/S por consola


Una plantilla para empezar:
#include<iostream>
usingnamespacestd;
int main()
{

LuisHernndezYez

Tu cdigo aqu!
return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 81

... recitado en la consola


Mostrar los textos con cout<<:
#include<iostream>
usingnamespacestd;
int main()
{
cout<<"EnunlugardelaMancha," <<endl;
cout<<"decuyonombrenoquieroacordarme," <<endl;

LuisHernndezYez

cout<<"nohamuchotiempoquevivaunhidalgodelosde
lanzaenastillero,..." <<endl;
return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 82

Introduccin del cdigo del programa


Terminamos cada lnea de cdigo con un salto de lnea ():
#include<iostream>
usingnamespacestd;

int main()
{
cout<<"EnunlugardelaMancha," <<endl;
cout<<"decuyonombrenoquieroacordarme," <<endl;

LuisHernndezYez

cout<<"nohamuchotiempoquevivaunhidalgodelosde
lanzaenastillero,..." <<endl;
return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 83

Introduccin del cdigo del programa


No hay que partir una cadena literal entre dos lneas:
cout<<"nohamuchotiempoquevivaunhidalgode
losde lanzaenastillero,..." <<endl;

La cadena no termina (1 lnea)!

LuisHernndezYez

No se entiende los (2 lnea)!

Veamos cmo nos muestra los errores el compilador...

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 84

Mantenimiento y reusabilidad
Usa espacio en blanco para separar los elementos:
cout<<"EnunlugardelaMancha," <<endl;

LuisHernndezYez

mejor que
cout<<"EnunlugardelaMancha,"<<endl;
Usa sangra (indentacin) para el cdigo de un bloque:
{
Tab
cout<<"EnunlugardelaMancha," <<endl;

...
3 esp.
return 0;
}

El estilo importa!
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 85

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 86

Operadores aritmticos
+

*
/

Suma
Resta
Multiplicacin
Divisin

LuisHernndezYez

Operadores binarios
operando_izquierdo
Operacin
3 +4
2.56 3
143 *2
45.45 /3

operadoroperando_derecho
Resultado
7
0.44
286
15.15

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 87

Nmeros literales (concretos)


Enteros: sin parte decimal
Signo negativo (opcional) + secuencia de dgitos
314312673211234

No se usan puntos de millares

LuisHernndezYez

Reales: con parte decimal


Signo negativo (opcional) + secuencia de dgitos
+ punto decimal + secuencia de dgitos
3.1416357.01.3332345.6789404.1

Punto decimal (3.1416), NO coma (3,1416)


Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 88

clculos.cpp

Ejemplo
#include<iostream>
usingnamespacestd;

LuisHernndezYez

int main()
Un texto
Un nmero
{
cout<<"133+1234=" <<133 +1234 <<endl;
cout<<"1234 111.5=" <<1234 111.5 <<endl;
cout<<"34*59=" <<34 *59 <<endl;
cout<<"3.4*5.93=" <<3.4 *5.93 <<endl;
cout<<"500/3=" <<500 /3 <<endl;//Div.entera
cout<<"500.0/3=" <<500.0 /3 <<endl;//Div.real
return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 89

LuisHernndezYez

Divisin entera

Divisin real

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 90

Divisin entera o divisin real?


Ambos operandos enteros Divisin entera
Algn operando real Divisin real

LuisHernndezYez

Divisin
500 /3
500.0 /3
500 /3.0
500.0 /3.0

Resultado
166
166.667
166.667
166.667

Comprueba siempre que el tipo de divisin sea el que quieres

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 91

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 92

Datos que se mantienen en memoria


Variable: dato que se accede por medio de un nombre
Dato literal: un valor concreto
Variable: puede cambiar de valor (variar)

LuisHernndezYez

edad=19;//variableedadyliteral19
Las variables deben ser declaradas
Qu tipo de dato queremos mantener?
Valor numrico sin decimales (entero): tipo int
Valor numrico con decimales (real): tipo double
Declaracin: tipo nombre;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 93

Declaracin de variables
int cantidad;
double precio;

tipo nombre;
Memoria

Se reserva espacio suficiente

cantidad

precio

?
...

LuisHernndezYez

LAS VARIABLES NO SE INICIALIZAN


No se deben usar hasta que se les haya dado algn valor
Dnde colocamos las declaraciones?
Siempre, antes del primer uso
Habitualmente al principio de la funcin

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 94

Declaracin de variables
#include<iostream>
usingnamespacestd;
int main()
{

Memoria
cantidad

precio

total

?
...

int cantidad;

LuisHernndezYez

double precio,total;

return 0;

Podemos declarar varias de un mismo tipo


separando los nombres con comas

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 95

Capacidad de las variables


int
2.147.483.648 ... 2.147.483.647
2147483648 .. 2147483647
double
2,23 x10308 ... 1,79 x 10+308 y sus negativos

LuisHernndezYez

[+|] 2.23e308 .. 1.79e+308

Notacin cientfica

Problemas de precisin

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 96

Asignacin de valores a las variables (operador =)


variable = expresin;

Instruccin: termina en ;

cantidad 12
cantidad=12; //int
precio=39.95; //double
total=cantidad*precio;//Asigna479.4

LuisHernndezYez

Concordancia de tipos:

cantidad=12.5;

A la izquierda del = debe ir siempre una variable!!!

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 97

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 98

Expresiones
Secuencias de operandos y operadores
operando operador operandooperador operando...
total=cantidad*precio*1.18;

Expresin

LuisHernndezYez

A igual prioridad se evalan de izquierda a derecha


Parntesis para forzar ciertas operaciones
total=cantidad1+cantidad2*precio;
total=(cantidad1+cantidad2)*precio;

Unos operadores se evalan antes que otros


Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 99

Precedencia de los operadores


cantidad1=10;
cantidad2=2;
precio=40.0;
* y /

se evalan antes que

+ y

LuisHernndezYez

total=cantidad1+cantidad2*precio;
* antes que + 10 + 2 * 40,0 10 + 80,0 90,0
total=(cantidad1+cantidad2)*precio;
+ antes que * (10 + 2) * 40,0 12 * 40,0 480,0

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 100

variables.cpp

Ejemplo de uso de variables y expresiones

LuisHernndezYez

#include<iostream>
usingnamespacestd;
int main()
{
int cantidad;
double precio,total;
cantidad=12;
precio=39.95;
total=cantidad*precio;
cout<<cantidad<<"x"<<precio<<"="
<<total<<endl;
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 101

Ejemplo de uso de variables


#include<iostream>
usingnamespacestd;
intmain()
{
int cantidad;
double precio,total;

Memoria
cantidad

precio

total

LuisHernndezYez

...

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 102

Ejemplo de uso de variables


#include<iostream>
usingnamespacestd;

cantidad

12

precio

total

?
...

LuisHernndezYez

intmain()
{
intcantidad;
doubleprecio,total;
cantidad=12;

Memoria

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 103

Ejemplo de uso de variables


#include<iostream>
usingnamespacestd;

cantidad
precio

12
39.95

total

?
...

LuisHernndezYez

intmain()
{
intcantidad;
doubleprecio,total;
cantidad=12;
precio=39.95;

Memoria

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 104

Ejemplo de uso de variables


#include<iostream>
usingnamespacestd;

cantidad

12

precio

39.95

total

479.4
...

LuisHernndezYez

intmain()
{
intcantidad;
doubleprecio,total;
cantidad=12;
precio=39.95;
total=cantidad*precio;

Memoria

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 105

Ejemplo de uso de variables

LuisHernndezYez

#include<iostream>
usingnamespacestd;

Memoria
cantidad

12

precio

39.95

intmain()
{
479.4
total
intcantidad;
doubleprecio,total;
...
cantidad=12;
precio=39.95;
total=cantidad*precio;
cout<<cantidad<<"x"<<precio<<"="
<<total<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 106

Ejemplo de uso de variables

LuisHernndezYez

#include<iostream>
usingnamespacestd;
intmain()
{
intcantidad;
doubleprecio,total;
cantidad=12;
precio=39.95;
total=cantidad*precio;
cout<<cantidad<<"x"<<precio<<"="
<<total<<endl;
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 107

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

cin (iostream)

Pgina 108

character input stream

Lectura de valores de variables: operador >> (extractor)

cin>>cantidad;
Memoria

cin

>>cantidad;

cantidad

12
?
...

12
_

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 109

El extractor >>

cin>>variable;

Transforma los caracteres introducidos en datos


Cursor parpadeante: lugar de lectura del siguiente carcter
La entrada termina con Intro (cursor a la siguiente lnea)
El destino del extractor debe ser SIEMPRE una variable!

LuisHernndezYez

Se ignoran los espacios en blanco iniciales

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 110

Lectura de valores enteros (int)


Se leen dgitos hasta encontrar un carcter que no lo sea
12abc
12abc
12abc
12
Se asigna el valor 12 a la variable
El resto queda pendiente para la siguiente lectura
Recomendacin: Lee cada variable en una lnea
12

Lectura de valores reales (double)


Se leen dgitos, el punto decimal y otros dgitos
LuisHernndezYez

39.95.5abc

39.95abc

39.95

Se asigna el valor 39,95 a la variable; el resto queda pendiente


Recomendacin: Lee cada variable en una lnea
39.95
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 111

Qu pasa si el usuario se equivoca?


El dato no ser correcto
Aplicacin profesional: cdigo de comprobacin y ayuda
Aqu supondremos que los usuarios no se equivocan
En ocasiones aadiremos comprobaciones sencillas

LuisHernndezYez

Para evitar errores, lee cada dato en una instruccin aparte

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 112

Qu pasa si el usuario se equivoca?

LuisHernndezYez

int cantidad;
Amigable con el usuario!
double precio,total;
Qu tiene que introducir?
cout<<"Introducelacantidad:";
cin>>cantidad;
cout<<"Introduceelprecio:";
cin>>precio;
cout<<"Cantidad:" <<cantidad<<endl;
cout<<"Precio:" <<precio<<endl;

No se puede leer un entero 0 para cantidad y Error


La lectura del precio falla: precio no toma valor (basura)

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 113

Qu pasa si el usuario se equivoca?


12 para cantidad
No se puede leer un real
0 para precio y Error
12 para cantidad
.5 0,5 para precio
Lo dems queda pendiente

LuisHernndezYez

Lectura correcta!!!

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 114

Divisin de dos nmeros


Pedir al usuario dos nmeros y mostrarle el resultado
de dividir el primero entre el segundo
Algoritmo.

Datos/clculos

1. Pedir el numerador
Variablenumerador (double)

2. Pedir el denominador

Variabledenominador (double)

LuisHernndezYez

3. Realizar la divisin, guardando el resultado


Variableresultado (double)
resultado=numerador/denominador

4. Mostrar el resultado
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 115

EntradaProcesoSalida
Muchos programas se ajustan a un sencillo esquema:

Declaraciones

Entrada

Procesamiento

Salida

1. Leer numerador
2. Leer denominador
LuisHernndezYez

3. Calcular divisin en resultado


4. Mostrar resultado

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 116

Divisin de dos nmeros


Pedir al usuario dos nmeros y mostrarle el resultado de dividir el
primero entre el segundo.
1.

Leer numerador
cin>>numerador;

2.

Leer denominador
cin>>denominador;

LuisHernndezYez

3.
4.

Calcular divisin en resultado


Mostrar resultado

resultado=numerador/denominador;

cout<<resultado;
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 117

Divisin de dos nmeros


#include<iostream>
usingnamespacestd;

divisin.cpp
Numerador:_129

_
Denominador:_
2

_
int main()
{
Declaraciones double numerador,denominador,resultado;
cout<<"Numerador:";
cin>>numerador;
Entrada
cout<<"Denominador:";
cin>>denominador;
Procesamiento resultado=numerador/denominador;
cout<<"Resultado:" <<resultado<<endl;
Salida
return0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 118

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 119

LuisHernndezYez

LuisHernndezYez

_
Resultado:_
64.5
64.5

Problema
Dadas la base y la altura de un tringulo, mostrar su rea

Refinamiento

LuisHernndezYez

Mostrar en la pantalla un texto que pida la base del tringulo. El usuario


introducir el valor con el teclado. Mostrar en la pantalla un texto que
pida la altura del tringulo. El usuario introducir el valor con el teclado.
Se calcular el rea del tringulo y se mostrar en la pantalla.

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 120

Objetos: Datos que maneja el programa


variable

cin
cadena literal

cout

Mostrar en la pantalla un texto que pida la base del tringulo. El usuario


introducir la base con el teclado. Mostrar en la pantalla un texto que
pida la altura del tringulo. El usuario introducir la altura con el
teclado. Se calcular el rea del tringulo y se mostrar en la pantalla.

LuisHernndezYez

cadena literal

variable
variable

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 121

Datos que maneja el programa: tipos


Objeto

Vara?

Nombre

Pantalla

Variable

cout

"Introduzcalabasedeltringulo:"

Constante

ninguno

Variable

base

Teclado

Variable

cin

"Introduzcalaalturadeltringulo:"

Constante

ninguno

Basedeltringulo

Tipo

double

double

Variable

altura

readeltringulo

double

Variable

area

LuisHernndezYez

Alturadeltringulo

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 122

Operaciones (acciones)
cout<<...

cin>>...

LuisHernndezYez

Mostrar en la pantalla un texto que pida la base del tringulo. El usuario


introducir la base con el teclado. Mostrar en la pantalla un texto que
pida la altura del tringulo. El usuario introducir la altura con el
teclado. Se calcular el rea del tringulo y se mostrar en la pantalla.

area =base*altura/2

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 123

Secuencia de acciones que ha de realizar el programa


para conseguir resolver el problema
1. Mostrar en la pantalla el texto que pida la base del tringulo
2. Leer del teclado el valor para la base del tringulo
3. Mostrar en la pantalla el texto que pida la altura
4. Leer del teclado el valor para la altura del tringulo
5. Calcular el rea del tringulo

LuisHernndezYez

6. Mostrar el rea del tringulo

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 124

#include<iostream>
usingnamespacestd;
int main()
{
Declaraciones
1. Mostrar en la pantalla el texto que pida la base del tringulo

Algoritmo
traducido
a cdigo
en C++

2. Leer del teclado el valor para la base del tringulo


3. Mostrar en la pantalla el texto que pida la altura del tringulo
4. Leer del teclado el valor para la altura del tringulo
5. Calcular el rea del tringulo

LuisHernndezYez

6. Mostrar el rea del tringulo

return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 125

tringulo.cpp

El programa: implementacin
tringulo?

int main()
{
double base,altura,area;//Declaraciones
cout<<"Introduzcalabasedeltringulo:";//1
cin>>base;//2
cout<<"Introduzcalaalturadeltringulo:";//3
cin>>altura;//4
area =base*altura/2;//5
//6
cout<<"Elreadeuntringulodebase" <<base
<<"yaltura"<<altura<<"es:" <<area <<endl;
return 0;
}

Recuerda: las instrucciones terminan en ;


Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 126

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 127

LuisHernndezYez

LuisHernndezYez

#include<iostream>
usingnamespacestd;

Variabilidad de los datos


"Introduzcalabasedeltringulo:"
3.141592653589

Literales
Constantes
Con nombre

Datos

base,altura,area

Identificadores

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 128

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 129

LuisHernndezYez

LuisHernndezYez

Variables

Pi=3.141592653589

palabras reservadas
Para variables y constantes con nombre
Nombre de un dato (para accederlo/modificarlo)
Deben ser descriptivos
Sintaxis:
a..z,A..Z,_
0..9,a..z,A..Z,_

LuisHernndezYez

cantidadprrecio

totalbasealturaarea

numerador

Al menos 32 caracteres significativos


Ni ees ni vocales acentuadas!
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 130

Palabras reservadas del lenguaje C++


asm

autoboolbreakcasecatchcharclassconst

const_cast

continuedefaultdeletedodouble

dynamic_cast

elseenumexplicitexternfalse

floatforfriendgoto

ifinlineintlong

mutablenamespacenewoperatorprivateprotected
publicregisterreinterpret_cast

LuisHernndezYez

signedsizeofstaticstatic_cast

returnshort
structswitch

templatethisthrowtruetrytypedeftypeid
typename

unionunsignedusingvirtualvoid

volatilewhile
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 131

a..z,A..Z,_

Qu identificadores son vlidos?


balance

_base_imponible

__edad

valor%100

interesAnual

EDAD12

_12_meses

clculoNmina
AlgunValor
valor?
____valor

salario_1_mes

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 132

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 133

LuisHernndezYez

LuisHernndezYez

100caracteres

aos

0..9,a..z,A..Z,_

Tipos
Cada dato, de un tipo concreto
Cada tipo establece:

125
true
'a'
3.14159
"Hola"

El conjunto (intervalo) de valores vlidos

El conjunto de operaciones que se pueden realizar

LuisHernndezYez

Expresiones con datos de distintos tipos (compatibles):


Transformacin automtica de tipos (promocin de tipo)

Anexo del Tema 2: detalles tcnicos

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 134

int
Nmeros enteros (sin decimales)
1363, 12, 49
float
Nmeros reales
12.45, 3.1932, 1.16E+02
double
Nmeros reales (mayores intervalo y precisin)
char
Caracteres
'a' , '{', '\t'
bool
Valores lgicos (verdadero/falso)
true, false
string
Cadenas de caracteres (biblioteca string) "HolaMundo!"
void
Nada, ausencia de tipo, ausencia de dato (funciones)
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 135

Caracteres
Intervalo de valores: Juego de caracteres (ASCII)
Literales:
'a''%''\t'

1 byte

LuisHernndezYez

Constantes de barra invertida (o secuencias de escape):


Caracteres de control
'\t' = tabulador '\n' = salto de lnea

ISO88591
(ASCII extendido: cdigos 128..255)
ASCII (cdigos 32..127)

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 136

Valores lgicos
Slo dos valores posibles:
Verdadero (true)
Falso (false)
Literales:
truefalse

LuisHernndezYez

Cualquier nmero distinto de 0 es equivalente a true


El 0 es equivalente a false

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 137

C++ distingue entre maysculas y minsculas


int: palabra reservada de C++ para declarar datos enteros
Int, INT o inT no son palabras reservadas de C++
true: palabra reservada de C++ para el valor verdadero

LuisHernndezYez

True o TRUE no son palabras reservadas de C++

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 138

Cadenas de caracteres
"Hola""Introduceelnumerador:""X142FG5TX?%A"

"

"
char

LuisHernndezYez

Secuencias de caracteres
Programas con variables de tipo string:
#include<string>
usingnamespacestd;

Las comillas tipogrficas (apertura/cierre) NO sirven


Asegrate de utilizar comillas rectas: ""

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 139

tipos.cpp

LuisHernndezYez

#include<iostream>
#include<string>
usingnamespacestd;//Unsolousing...paraambasbibliotecas
int main()
{
int entero=3;//Podemosasignar(inicializar)aldeclarar
double real=2.153;
char caracter ='a';
bool cierto=true;
string cadena="Hola";
cout<<"Entero:" <<entero<<endl;
cout<<"Real:" <<real<<endl;
cout<<"Carcter:" <<caracter <<endl;
cout<<"Booleano:" <<cierto<<endl;
cout<<"Cadena:" <<cadena<<endl;
return 0;
}

Cuntos nmeros hay en total en el programa?


Y caracteres? Y cadenas? Y booleanos?

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 140

signed / unsigned : con signo (por defecto) / sin signo


short / long : menor / mayor intervalo de valores

Tipo

Intervalo

int

2147483648 .. 2147483647

unsignedint

0 .. 4294967295

shortint

32768 .. 32768

LuisHernndezYez

unsignedshortint 0 .. 65535
longint

2147483648 .. 2147483647

unsignedlongint

0 .. 4294967295

double

+| 2.23e308 .. 1.79e+308

longdouble

+| 3.37E4932 .. 1.18E+4932

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 141

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 142

[modificadores]tipo lista_de_variables;
Opcional

lista_de_variables

Identificador

LuisHernndezYez

,
int i,j,l;
shortintunidades;
unsignedshortintmonedas;
double balance,beneficio,perdida;

Programacin con buen estilo:


Identificadores descriptivos
Espacio tras cada coma
Nombres de las variables en minsculas
(Varias palabras: capitaliza cada inicial: interesPorMes)

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 143

Se reserva memoria suficiente para cada tipo de dato


Memoria

int inicio;
shortintunidades;
double balance;

inicio

01
02
03
04

unidades

05
06

balance

07
08
09
10
11
12

LuisHernndezYez

13
14
15
...

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 144

En C++ las variables no se inicializan automticamente!


Una variable debe ser haber sido inicializada antes de ser accedida!
Cmo se inicializa una variable?
Al leer su valor (cin>>)
Al asignarle un valor (instruccin de asignacin)
Al declararla
Inicializacin en la propia declaracin:

LuisHernndezYez

Identificador

Expresin

int i=0,j,l=26;
shortintunidades=100;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Expresin: valor compatible

Enparticular,unaexpresin
puedeserunliteral

Pgina 145

Obtencin del valor de una variable


Nombre de la variable en una expresin
cout<<balance;
cout<<interesPorMes *meses /100;

Modificacin del valor de una variable

Las variables han de haber sido previamente declaradas

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 146

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 147

LuisHernndezYez

LuisHernndezYez

Nombre de la variable a la izquierda del =


balance =1214;
porcentaje =valor/30;

El operador =
Variable

Expresin

A la izquierda, SIEMPRE una variable

int i,j=2;

LuisHernndezYez

i=23 +j*5;//itomaelvalor33

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 148

Errores
int a,b,c;
5 =a;
//ERROR:unliteralnopuederecibirunvalor
a+23 =5;
//ERROR:nopuedehaberunaexpresinalaizda.
b="abc";
//ERROR:unenteronopuedeguardarunacadena

LuisHernndezYez

c=23

5;

//ERROR:expresinnovlida(faltaoperador)

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 149

int i,j=2;
i=23 +j*5;
Memoria

01

02
03
04

Memoria

i
23 +2 *5

08

03

07

33

02

04

05
06

01

05

06
07
08

09

09

10

10
...

LuisHernndezYez

...

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 150

Necesitamos una variable auxiliar


double a=3.45,b=127.5,aux;
a

3.45

127.5

aux

aux=a;

LuisHernndezYez

a=b;

b=aux;

Fundamentosdelaprogramacin:TiposeinstruccionesI

3.45

127.5

aux

3.45

127.5

127.5

aux

3.45

127.5

3.45

aux

3.45

Pgina 151

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 152

LuisHernndezYez

Operaciones sobre valores de los tipos


Cada tipo determina las operaciones posibles
Tipos de datos numricos (int, float y double):
Asignacin (=)
Operadores aritmticos
Operadores relacionales (menor, mayor, igual, ...)
Tipo de datos bool:
Asignacin (=)
Operadores lgicos (Y, O, NO)
Tipos de datos char y string:
Asignacin (=)
Operadores relacionales (menor, mayor, igual, ...)
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 153

Operadores para tipos de datos numricos

LuisHernndezYez

Operador Operandos Posicin

float / double

int

1(monario) Prefijo

2(binario)

Infijo

Suma

2(binario)

Infijo

Resta

2(binario)

Infijo

Producto

2(binario)

Infijo

Div.entera

Divisinreal

2(binario)

Infijo

Mdulo

Noaplicable

Cambiodesigno

++

1(monario) Prefijo/postfijo

Incremento

1(monario) Prefijo/postfijo

Decremento

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 154

Operadores monarios y operadores binarios


Operadores monarios (unarios)
Cambio de signo ():
Delante de variable, constante o expresin entre parntesis
saldoRATIO(3 *a b)

Incremento/decremento (slo variables) (prefijo/postfijo):

LuisHernndezYez

++interes

mesesj++

//1ms1menos

Operadores binarios
Operando izquierdo operador operando derecho
Operandos: literales, constantes, variables o expresiones
2 +3

a*RATIOa+b

(a%b)*(c/d)
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 155

Divisin entera o divisin real?

Ambos operandos enteros: divisin entera


int i=23,j=2;
cout<<i/j;//Muestra11

LuisHernndezYez

Algn operando real: divisin real


int i=23;
double j=2;
cout<<i/j;//Muestra11.5

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 156

Mdulo (resto de la divisin entera)

Ambos operandos han de ser enteros


int i=123,j=5;
cout<<i%j;//Muestra3

LuisHernndezYez

Divisin entera:
No se obtienen decimales Queda un resto
123

24

123 %5

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 157

Operadores de incremento y decremento

++/

Incremento/decremento de la variable numrica en una unidad


Prefijo: Antes de acceder
i=i+1;
j=i;

int i=10,j;
j=++i;//Incrementaantesdecopiar
cout<<i<<" "<<j;//Muestra11 11

Postfijo: Despus de acceder

LuisHernndezYez

j=i;
i=i+1;

int i=10,j;
j=i++;//Copiaydespusincrementa
cout<<i<<" "<<j;//Muestra11 10
No mezcles ++ y con otros operadores

Fundamentosdelaprogramacin:TiposeinstruccionesI

LuisHernndezYez

#include<iostream>
usingnamespacestd;

Pgina 158

operadores.cpp

int main(){
int entero1=15,entero2=4;
double real1=15.0,real2=4.0;
cout<<"Operacionesentrelosnmeros15y4:"<<endl;
cout<<"Divisinentera(/):"<<entero1/entero2<<endl;
cout<<"Restodeladivisin(%):"<<entero1%entero2<<endl;
cout<<"Divisinreal(/):"<<real1/real2<<endl;
cout<<"Num="<<real1<<endl;
real1=real1;
cout<<"Cambiadesigno():"<<real1<<endl;
real1=real1;
cout<<"Vuelveacambiar():"<<real1<<endl;
cout<<"Seincrementaantes(++prefijo):"<<++real1<<endl;
cout<<"Semuestraantesdeincrementar(posfijo++):"
<<real1++<<endl;
cout<<"Yaincrementado:" <<real1<<endl;
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 159

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 160

En qu orden se evalan los operadores?


3 +5 *2 /2 1
De izquierda a derecha?
De derecha a izquierda?
Unos antes que otros?

LuisHernndezYez

Precedencia de los operadores (prioridad):


Se evalan antes los de mayor precedencia
Y si tienen igual prioridad?
Normalmente, de izquierda a derecha
Parntesis: fuerzan a evaluar su subexpresin

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 161

Precedencia

Operadores

Mayor prioridad

++ (postfijos)
++ (prefijos)
(cambio de signo)
*/%

Menor prioridad

LuisHernndezYez

3 +5 *2 /2 1 3 +10 /2 1 3 +5 1 8 1 7

Misma precedencia:
Izquierda antes

Mayor
precedencia

Misma precedencia:
Izquierda antes

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 162

((3 + 5)*4 +12)/4 (3 * 2 1)


(8 *4 +12)/4

Primero, los parntesis...

* antes que
(6 1)

* antes que +
(32 +12)/4

44 /4 5
/ antes que
LuisHernndezYez

11 5

Pon espacio antes y despus


de cada operador binario

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 163

frmula.cpp

#include<iostream>
usingnamespacestd;

LuisHernndezYez

int main()
{
double x,f;
cout<<"IntroduceelvalordeX:";
cin>>x;
f=3 *x*x/5 +6 *x/7 3;
cout<<"f(x)=" <<f<<endl;
return 0;
}
Usa parntesis para mejorar la legibilidad:
f=(3 *x*x/5)+(6 *x/7) 3;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 164

variable =variable operador op_derecho;

La misma

LuisHernndezYez

variable operador=op_derecho;
Asignacin
a=a+12;
a=a*3;
a=a 5;
a=a/37;
a=a%b;

Abreviatura
a+=12;
a*=3;
a=5;
a/=37;
a%=b;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Igual precedencia
que la asignacin
De momento,
mejor evitarlas

Pgina 165

Valor siguiente al mximo?


Valor mayor del mximo (o menor del mnimo) del tipo
shortinti=32767;//Valormximoparashortint
i++;//32768nocabe enunshortint
cout<<i;//Muestra 32768

Bit de signo
0 1 1 1 1 1 1 1
0 = positivo
+ 0 0 0 0 0 0 0 0
1 = negativo

32767

+ 1

0 0 0 0 0 0 0 0

32768

LuisHernndezYez

1 0 0 0 0 0 0 0

1 1 1 1 1 1 1 1

Pgina 166

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 167

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Declaracin de constantes Modificador de acceso const


Variables inicializadas a las que no dejamos variar

const

Declaracindevariableconinicializador

constshortintMeses=12;
constdouble Pi=3.141592,

LuisHernndezYez

RATIO=2.179 *Pi;

La constante no podr volver a


aparecer a la izquierda de un =

Programacin con buen estilo:


Pon en mayscula la primera letra
de una constante o todo su nombre

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 168

Aumentan la legibilidad del cdigo

vs.

cambioPoblacion =(0.1758 0.1257)*poblacion;

cambioPoblacion =(RatioNacimientos RatioMuertes)*poblacion;

Facilitan la modificacin del cdigo

LuisHernndezYez

double compra1=bruto1*18 /100;


3 cambios
double compra2=bruto2*18 /100;
double total=compra1+compra2;
cout<<total<<"(IVA:"<<18 <<"%)" <<endl;
Cambio del IVA al 21%?
constint IVA=18;
double compra1=bruto1*IVA/100;
double compra2=bruto2*IVA/100;
1 cambio
double total=compra1+compra2;
cout<<total<<"(IVA:"<<IVA<<"%)" <<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 169

constantes.cpp

int main(){
const double Pi=3.141592;
double radio=12.2,circunferencia;
circunferencia=2 *Pi*radio;
cout<<"Circunferenciadeuncrculoderadio"
<<radio<<":" <<circunferencia<<endl;
const double Euler =2.718281828459;//Nmeroe
cout<<"Nmeroealcuadrado:"<<Euler *Euler <<endl;
const int IVA=21;
int cantidad=12;
double precio=39.95,neto,porIVA,total;
neto=cantidad*precio;
porIVA =neto*IVA/100;
total=neto+porIVA;
cout<<"Totalcompra:"<<total<<endl;
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 170

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 171

LuisHernndezYez

LuisHernndezYez

#include<iostream>
usingnamespacestd;

#include<cmath>
Algunas ...

abs(x)

Valor absoluto de x

LuisHernndezYez

pow(x,y) x elevado a y
sqrt(x)

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

ex

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

round(x)

Redondeo al entero ms prximo

trunc(x)

Prdida de la parte decimal (entero)

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 172

mates.cpp

LuisHernndezYez

#include<iostream>
usingnamespacestd;
#include<cmath>
int main(){
double x,y,f;
pow() con argumento entero:
cout<<"ValordeX:";
Usa el molde double():
cin>>x;
pow(double(i),5)
cout<<"ValordeY:";
cin>>y;
f=2 *pow(x,5) +sqrt(pow(x,3) /pow(y,2))
/abs(x*y) cos(y);
cout<<"f(x,y)=" <<f<<endl;
return 0;
}
Pon un espacio detrs de cada coma en las listas de argumentos
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 173

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 174

char
Asignacin, ++/ y operadores relacionales

Funciones para caracteres (biblioteca cctype)


isalnum(c)
isalpha(c)
isdigit(c)
islower(c)
isupper(c)

true si c es una letra o un dgito


true si c es una letra
true si c es un dgito
true si c es una letra minscula
true si c es una letra mayscula

LuisHernndezYez

false en caso contrario


toupper(c)
tolower(c)

devuelve la mayscula de c
devuelve la minscula de c

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 175

caracteres.cpp

int main(){
char caracter1='A',caracter2='1',caracter3='&';
cout<<"Carcter1(" <<caracter1<<")."<<endl;
cout<<"Alfanumrico?"<<isalnum(caracter1)<<endl;
cout<<"Alfabtico?"<<isalpha(caracter1)<<endl;
cout<<"Dgito?"<<isdigit(caracter1)<<endl;
cout<<"Mayscula?"<<isupper(caracter1)<<endl;
caracter1=tolower(caracter1);
cout<<"Enminscula:"<<caracter1<<endl;
cout<<"Carcter2(" <<caracter2<<")."<<endl;
cout<<"Alfabtico?"<<isalpha(caracter2)<<endl;
cout<<"Dgito?"<<isdigit(caracter2)<<endl;
cout<<"Carcter3(" <<caracter3<<")."<<endl;
cout<<"Alfanumrico?"<<isalnum(caracter3)<<endl;
cout<<"Alfabtico?"<<isalpha(caracter3)<<endl;
cout<<"Dgito?"<<isdigit(caracter3)<<endl;
return 0;
1 true / 0 false
}
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 176

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 177

LuisHernndezYez

LuisHernndezYez

...
#include<cctype>

Operadores relacionales
Comparaciones (condiciones)
Condicin simple ::= Expresin Operador_relacional Expresin

Concordancia de tipo entre las expresiones

LuisHernndezYez

Resultado: bool (true o false)


<

menor que

<=

menor o igual que

>

mayor que

>=

mayor o igual que

==

igual que

!=

distinto de

Fundamentosdelaprogramacin:TiposeinstruccionesI

Operadores(prioridad)
...
*/%
+
< <=>>=
==!=
=+==*=/=%=
Pgina 178

Menor prioridad que los operadores aditivos y multiplicativos


bool resultado;
int a=2,b=3,c=4;
resultado=a< 5;//2<5 true
resultado=a*b+c>= 12;//10>=12 false
resultado=a*(b+c)>= 12;//14>=12 true
resultado=a!= b;//2!=3 true
resultado=a*b> c+5;//6>9 false

LuisHernndezYez

resultado=a+b== c+1;//5==5 true


No confundas el operador de igualdad (==)
con el operador de asignacin (=)

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 179

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 180

Seleccin: bifurcacin condicional


true

LuisHernndezYez

cdigoT

Condicin

false
cdigoF

if (condicin) {
cdigoT
}
else{
cdigoF
}

int num;
cout<<"Nmero:";
Opcional:puedenohaberelse
cin>>num;
if (num%2 ==0){
cout<<num<<"espar";
}
else {
cout<<num<<"esimpar";
}
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 181

seleccin.cpp

int main(){
intop1=13,op2=4;
intopcion;
cout<<"1 Sumar"<<endl;
cout<<"2 Restar"<<endl;
cout<<"Opcin:";
cin>>opcion;
if (opcion ==1){
cout<<op1+op2<<endl;
}
else {
cout<<op1 op2<<endl;
}
return0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 182

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 183

LuisHernndezYez

LuisHernndezYez

#include<iostream>
usingnamespacestd;

Agrupacin de instrucciones
Grupo de instrucciones a ejecutar en una rama del if
{

instruccin

Tab

LuisHernndezYez

3 esp.

int num,total=0;
cin>>num;
if (num>0)
{
cout<<"Positivo";
total=total+num;
}
cout<<endl;

intruccin1
intruccin2
...
intruccinN

mbito local
(declaraciones locales)

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 184

Posicin de las llaves: cuestin de estilo


if (num>0)
{
cout<<"Positivo";
total=total+num;
}
cout<<endl;

if (num>0){
cout<<"Positivo";
total=total+num;
}
cout<<endl;

No necesitamos las llaves si slo hay una instruccin

LuisHernndezYez

if (num>0){
cout<<"Positivo";
}

if (num>0)
cout<<"Positivo";

Usaremos siempre llaves por simplicidad...


Evita poner el if y la instruccin objetivo en la misma lnea:
if (num>0)cout<<"Positivo";
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 185

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 186

Repeticin o iteracin condicional


while

condicin

cuerpo
Bloque
de cdigo

true

Condicin

false

LuisHernndezYez

Cuerpo

while (condicin) {
cuerpo
}

Si la condicin es false al empezar,


no se ejecuta el cuerpo ninguna vez
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 187

serie.cpp

LuisHernndezYez

#include<iostream>
usingnamespacestd;
int main(){
inti=1,n=0,suma=0;
while (n<=0){//Slonpositivo
cout<<"Cuntosnmerosquieressumar?";
cin>>n;
}
while(i<=n){
suma=suma+i;
i++;
}
cout<<"Sumatoriodei(1a" <<n <<")="
<<suma<<endl;
return0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 188

Iteracin condicional
while(i<=n){
suma=suma+i;
i++;
}

true

i<=n

false

6
2
3
4
5
1

suma

15
10
1
3
6
0

LuisHernndezYez

suma+=i;
i++;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 189

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 190

#include<iostream>
usingnamespacestd;

Flujos de texto (streams)

Conectan la ejecucin del programa con los dispositivos de E/S


Son secuencias de caracteres
Entrada por teclado: flujo de entrada cin (tipo istream)
Salida por pantalla: flujo de salida cout (tipo ostream)

cin
7

cout
5

Programa 1

= l a t o T

LuisHernndezYez

Biblioteca iostream con espacio de nombres std


Extractor

Flujodeentrada

>>

Variable

Insertor

Flujodesalida

<<

Expresin

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 191

cin

>>

Variable

LuisHernndezYez

Salta los espacios en blanco (espacios, tabuladores o saltos de lnea)


char
Se lee un carcter en la variable
int
Se leen dgitos y se transforman en el valor a asignar
float/double:
Se leen dgitos (quiz el punto y ms dgitos) y se asigna el valor
bool:
Si se lee 1, se asigna true; con cualquier otro valor se asigna false
Se amigable con el usuario
Lee cada dato en una lnea
cout<<"Introducetuedad:";
cin>>edad;
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 192

#include<string>
usingnamespacestd;

cin>>cadena
cin.sync()

termina con el primer espacio en blanco


descarta la entrada pendiente

string nombre,apellidos;
cout<<"Nombre:";
cin>>nombre;
cout<<"Apellidos:";
cin>>apellidos;
cout<<"Nombrecompleto:"
<<nombre<<""
<<apellidos<<endl;

string nombre,apellidos;
cout<<"Nombre:";
cin>>nombre;
cin.sync();
cout<<"Apellidos:";
cin>>apellidos;
cout<<...

LuisHernndezYez

apellidos recibe "Antonio"

Cmo leer varias palabras?


Siguiente pgina...
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 193

Lectura sin saltar los espacios en blanco iniciales


Llamada a funciones con el operador punto (.) :
El operador punto permite llamar a una funcin sobre una variable
variable.funcin(argumentos)

Lectura de un carcter sin saltar espacios en blanco:


cin.get(c);//Leeelsiguientecarcter

Lectura de cadenas sin saltar los espacios en blanco:


getline(cin,cad);
LuisHernndezYez

Lee todo lo que haya hasta el final de la lnea (Intro)


Recuerda:
Espacios en blanco son espacios, tabuladores, saltos de lnea, ...
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 194

cout

Expresin

<<

Representacin textual de los datos


int meses=7;
cout<<"Total:"<<123.45 <<endl<<"Meses:"<<meses;

El valor double 123.45 se guarda en memoria en binario


Su representacin textual es:'1''2''3''.''4''5'
double d=123.45;
d

123.45

Un nmero real!

LuisHernndezYez

cout<<d;
La biblioteca iostream
define la constante endl
como un salto de lnea

5 4 . 3 2 1
Un texto!
(secuencia de caracteres)

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 195

Expresin

<<

cout

Programa

cout
int meses=7;
cout<<"Total:"<<123.45 <<endl<<"Meses:"<<meses;
cout<<123.45 <<endl<<"Meses:"<<meses;
cout<<endl<<"Meses:"<<meses;

LuisHernndezYez

cout<<"Meses:"<<meses;
Total: 123.45
Meses: 7

cout<<meses;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 196

#include<iomanip>
Constantes y funciones a enviar a cout para ajustar el formato de salida
Biblioteca Constante/funcin
iostream

LuisHernndezYez

iomanip

Propsito

showpoint/
noshowpoint

Mostrar o no el punto decimal para reales sin


decimales (34.0)

fixed

Notacin de punto fijo (reales) (123.5)

scientific

Notacin cientfica (reales) (1.235E+2)

boolalpha

Valores bool como true / false

left/right

Ajustar a la izquierda/derecha (por defecto)

setw(anchura)*

N de caracteres (anchura) para el dato

setprecision(p)

Precisin: N de dgitos (en total)


Con fixed o scientific, n de decimales

*setw() slo afecta al siguiente dato que se escriba,


mientras que los otros afectan a todos
Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 197

bool fin=false;
cout<<fin<<">" <<boolalpha <<fin<<endl;

0>false

double d=123.45;
char c='x';
int i=62;
cout<<d<<c<<i<<endl;

123.45x62

cout<<"|" <<setw(8)<<d<<"|"<<endl;

|123.45|

cout<<"|" <<left<<setw(8)<<d<<"|"<<endl;

|123.45|

cout<<"|" <<setw(4)<<c<<"|"<<endl;

|x|

cout<<"|" <<right<<setw(5)<<i<<"|"<<endl;

|62|

cout<<e<<" "<<showpoint<<e<<endl;

96 96.0000

cout<<scientific<<d<<endl;

1.234500e+002

cout<<fixed<<setprecision(8)<<d<<endl;

123.45000000

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 198

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 199

LuisHernndezYez

LuisHernndezYez

double e=96;

Los programas pueden incluir otras funciones adems de main()


Forma general de una funcin en C++:

LuisHernndezYez

tipo nombre(parmetros)//Cabecera
{
//Cuerpo
}

Tipo de dato que devuelve la funcin como resultado


Parmetros para proporcionar datos a la funcin
Declaraciones de variables separadas por comas
Cuerpo: secuencia de declaraciones e instrucciones
Un bloque de cdigo!

Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 200

Datos locales: declarados en el cuerpo de la funcin


Datos auxiliares que utiliza la funcin (puede no haber)
Parmetros: declarados en la cabecera de la funcin
Datos de entrada de la funcin (puede no haber)
Ambos son de uso exclusivo de la funcin y no se conocen fuera

LuisHernndezYez

double f(intx,int y){


//Declaracindedatoslocales:
double resultado;
//Instrucciones:
resultado=2 *pow(x,5) +sqrt(pow(x,3)
/pow(y,2)) /abs(x*y) cos(y);
return resultado;//Devolucindelresultado
}
Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 201

Llamada a una funcin con parmetros


Nombre(Argumentos)
Al llamar a la funcin:
Tantos argumentos entre los parntesis como parmetros
Orden de declaracin de los parmetros
Cada argumento: mismo tipo que su parmetro
Cada argumento: expresin vlida (se pasa el resultado)

LuisHernndezYez

Se copian los valores resultantes de las expresiones


en los correspondientes parmetros
Llamadas a la funcin: en expresiones de otras funciones
int valor=f(2,3);

Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 202

Se copian los argumentos en los parmetros


int funcion(int x,double a){
...
}

Memoria
i

124

3.0
...

int main(){
int i=124;

...

double d=3;

124

funcion(i,33 *d);

99.0

LuisHernndezYez

...

...

return0;//main()devuelve0alS.O.
}

Los argumentos no se modifican

Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 203

La funcin ha de devolver un resultado


La funcin termina su ejecucin devolviendo un resultado
La instruccin return (slo una en cada funcin)
Devuelve el dato que se pone a continuacin (tipo de la funcin)
Termina la ejecucin de la funcin
El dato devuelto sustituye a la llamada de la funcin:
int cuad(int x){

int main(){

return x*x;

cout<<2 *cuad(16);

LuisHernndezYez

x=x*x;
}

return 0;
Esta instruccin
no se ejecutar nunca

256

Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 204

Qu funciones hay en el programa?


Colocaremos las funciones despus de main()
Son correctas las llamadas a funciones del programa?
Existe la funcin?
Concuerdan los argumentos con los parmetros?
Prototipos tras las inclusiones de bibliotecas

LuisHernndezYez

Prototipo de funcin: Cabecera de la funcin terminada en ;


double f(intx,int y);
int funcion(int x,double a)
int cuad(int x);
...
main() es la nica funcin
que no hay que prototipar
Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 205

#include<iostream>
usingnamespacestd;
#include<cmath>

LuisHernndezYez

//Prototiposdelasfunciones(exceptomain())
bool par(int num);
boolletra(char car);
intsuma(int num);
double formula(int x,inty);
int main(){
intnumero,sum,x,y;
char caracter;
double f;
cout<<"Entero:";
cin>>numero;
if (par(numero)){
cout<<"Par";
}
...
Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 206

LuisHernndezYez

else{
cout<<"Impar";
}
cout<<endl;
if (numero>1){
cout<<"Sumatoriode1a" <<numero<<":"
<<suma(numero)<<endl;
}
cout<<"Carcter:";
cin>>caracter;
if(!letra(caracter)){
cout<<"no";
}
cout<<"esunaletra" <<endl;
cout<<"f(x,y)=" <<formula(x,y)<<endl;
//Losargumentospuedenllamarseigualonoquelosparmetros
return 0;
}
...
Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 207

//Implementacindelasfuncionespropias
boolpar(int num){
bool esPar;
if (num%2==0){
esPar =true;
}
else {
esPar =false;
}

LuisHernndezYez

return esPar;
}
...

Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 208

LuisHernndezYez

bool letra(char car){


bool esLetra;
if ((car>='a')&&(car<='z')||(car>='A')&&(car<='Z')){
esLetra =true;
}
else {
esLetra =false;
}
return esLetra;
}
int suma(int num){
int sum =0,i=1;
while (i<num){
sum =sum +i;
i++;
}
return sum;
}
...
Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 209

funciones.cpp

double formula(int x,inty){


double f;
f=2 *pow(x,5)+sqrt(pow(x,3)/pow(y,2))
/abs(x*y) cos(y);
return f;

LuisHernndezYez

Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 210

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 211

Fundamentosdelaprogramacin

2A
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

LuisHernndezYez

int
float
Notacincientfica
double
char
bool
string
Literalesconespecificacindetipo

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

214
216
217
218
220
221
222
223

Nmeros enteros
Intervalo de valores:
2147483648 .. 2147483647
(*) Depende de la mquina
Bytes de memoria: 4*
4 bytes es lo ms habitual
Literales:
Se puede saber cuntos
se usan con la funcin
1363, 12, 010 , 0x1A
sizeof(int)

01
02
03
04
05
06

07

0..9
0..9

LuisHernndezYez

Notacin octal

08
09
...

Notacin hexadecimal

0..7
x

0..9,A..F

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 214

Nmeros enteros

LuisHernndezYez

Nmeros en notacin octal (base 8: dgitos entre 0 y 7):


010 = 8 en notacin decimal
10 = 1 x 81 + 0 x 80 = 1 x 8 + 0
0423 = 275 en notacin decimal
423 = 4 x 82 + 2 x 81 + 3 x 80 = 4 x 64 + 2 x 8 + 3 = 256
+ 16 +3
Nmeros en notacin hexadecimal (base 16):
Dgitos posibles: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
0x1F = 31 en notacin decimal
1F = 1 x 161 + F x 160 = 1 x 16 + 15
0xAD = 173 en notacin decimal
AD = A x 161 + D x 160 = 10 x 16 + 13 = 160 + 13

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 215

Nmeros reales (con decimales)


Intervalo de valores:
+/ 1.18e38 .. 3.40e+38
(*) sizeof(float)
Bytes de memoria: 4*
Punto flotante. Precisin: 7 dgitos
Literales (punto decimal):
Notacin normal: 134.45, 1.1764

01
02
03
04
05
06
07

+
0..9

08

0..9

09

...

LuisHernndezYez

Notacin cientfica: 1.4E2, 5.23e02


+

+
0..9

0..9

e,E

0..9

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 216

Siempre un nmero (con o sin signo) con un solo dgito de parte


entera, seguido del exponente (potencia de 10):
5.23e2

5,23 x 102

0,0523

1.11e2

1,11 x 102

111,0

7.4523e04

7,4523 x 104

0,00074523
3.333.300

LuisHernndezYez

3.3333e+06 3,3333 x 106

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 217

Nmeros reales (con decimales)


Intervalo de valores:
+/ 2.23e308 .. 1.79e+308
(*) sizeof(double)
Bytes de memoria: 8*
Punto flotante. Precisin: 15 dgitos
Literales (punto decimal):
Notacin normal: 134.45, 1.1764

01
02
03
04
05
06
07

+
0..9

08

0..9

09

...

LuisHernndezYez

Notacin cientfica: 1.4E2, 5.23e02


+

+
0..9

0..9

e,E

0..9

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 218

Caracteres
Intervalo de valores:
Juego de caracteres (ASCII)
Bytes de memoria: 1 (FC)
Literales:
'a', '%', '\t'
Constantes de barra invertida:
(O secuencias de escape)
Para caracteres de control
'\t' = tabulador, '\n' = salto de lnea,
\

02
03
04
05
06
07
08
09
...

n,t,v,b,r,f,a,\

'
LuisHernndezYez

01

'
Carcter

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 219

LuisHernndezYez

Juego de caracteres ASCII:


American Standard Code for Information Interchange (1963)
Caracteres con cdigos entre 0 y 127 (7 bits)
Caracteres de control:
Cdigos del 0 al 31 y 127
Tabulacin, salto de lnea,...
Caracteres imprimibles:
Cdigos del 32 al 126
Juego de caracteres ASCII extendido (8 bits):
ISO88591
Multitud de codificaciones:
+ Cdigos entre 128 y 255
EBCDIC, UNICODE, UTF8, ...

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 220

Valores lgicos

01
02
03
04
05
06
07
08
09
...

LuisHernndezYez

Slo dos valores posibles:


Verdadero (true)
Falso (false)
Bytes de memoria: 1 (FC)
Literales:
true, false
En realidad, cualquier nmero
distinto de 0 es equivalente a true
y el nmero 0 es equivalente a false

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 221

Cadenas de caracteres
"Hola", "Introduceelnumerador:", "X142FG5TX?%A"
"

Carcter

"

LuisHernndezYez

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>
usingnamespacestd;
Ojo!
Las comillas tipogrficas (apertura/cierre) te darn problemas
al compilar. Asegrate de utilizar comillas rectas: ""

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 222

Por defecto un literal entero se considera un dato int


longint: 35L, 1546l
unsignedint: 35U, 1546u
unsignedlongint: 35UL, 1546ul
Por defecto un literal real se considera un dato double
float: 1.35F, 15.46f
longdouble: 1.35L, 15.46l

LuisHernndezYez

Abreviaturas para modificadores de tipos


short shortint
long longint
Es preferible evitar el uso de tales abreviaturas:
Minimizar la cantidad de informacin a recordar
sobre el lenguaje
Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 223

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 224

Fundamentosdelaprogramacin

3
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

LuisHernndezYez

Facultad de Informtica
Universidad Complutense

Tipos,valoresyvariables
Conversindetipos
Tiposdeclaradosporelusuario
Tiposenumerados
Entrada/Salida
conarchivosdetexto
Lecturadearchivosdetexto
Escrituraenarchivosdetexto
Flujodeejecucin
Seleccinsimple
Operadoreslgicos
Anidamientodeif
Condiciones
Seleccinmltiple
Laescalaifelseif
Lainstruccinswitch
Repeticin
Elbuclewhile

227
232
236
238
248
253
266
272
276
282
286
290
293
295
302
313
316

Fundamentosdelaprogramacin:TiposeinstruccionesII

Elbuclefor
Buclesanidados
mbitoyvisibilidad
Secuencias
Recorridodesecuencias
Secuenciascalculadas
Bsquedaensecuencias
Arraysdedatossimples
Usodevariablesarrays
Recorridodearrays
Bsquedaenarrays
Arraysnocompletos

321
331
339
349
355
363
370
374
379
382
387
393

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 227

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

LuisHernndezYez

Declaracin
Instruccin que identifica un nombre
Definicin
Declaracin que asigna memoria a una variable o constante

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 228

LuisHernndezYez

Memoria suficiente para su tipo de valores


shortinti=3;

int j=9;

char c='a';

c a

double x=1.5;

3
9

1.5

El significado de los bits depende del tipo de la variable:


00000000000000000000000001111000
Interpretado como int es el entero 120
Interpretado como char (slo 01111000) es el carcter 'x'

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 229

Simples

Estndar: int, float, double, char, bool


Conjunto de valores predeterminado

Definidos por el usuario: enumerados


Conjunto de valores definido por el programador

LuisHernndezYez

Estructurados (Tema 5)

Colecciones homogneas: arrays


Todos los elementos de la coleccin de un mismo tipo

Colecciones heterogneas: estructuras


Elementos de la coleccin de tipos distintos

Fundamentosdeprogramacin:TiposeinstruccionesII

Pgina 230

Con sus posibles modificadores:


[unsigned][short] int
longlong int

longint int

float
[long] double
char
Definicin de variables:
tipo nombre [=expresin][,...];
Definicin de constantes con nombre:
consttipo nombre =expresin;
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 231

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 232

LuisHernndezYez

LuisHernndezYez

bool

Promocin de tipos
Dos operandos de tipos distintos:
El valor del tipo menor se promociona al tipo mayor

LuisHernndezYez

b=a+3 *2;

long double

Promocin

shortinti=3;
int j=2;
double a=1.5,b;
b=a+i*j;

double
float
long int
int
short int

Valor 3 shortint (2 bytes) int (4 bytes)

b=1.5 +6;
Valor 6 int (4 bytes) double (8 bytes)
Fundamentosdelaprogramacin:TiposeinstruccionesII

Conversin segura:
De un tipo menor a un tipo mayor
shortint int longint ...

Pgina 233

long double
double
float
long int

Conversin no segura:
int
De un tipo mayor a un tipo menor
short int
intentero=1234;
char caracter;
caracter =entero;//Conversinnosegura

LuisHernndezYez

Menor memoria: Prdida de informacin en la conversin

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 234

Fuerzan una conversin de tipo:


tipo(expresin)
El valor resultante de la expresin se trata como un valor del tipo
int a=3,b=2;
cout<<a/b;//Muestra1(divisinentera)
cout<<double(a)/b;//Muestra1.5(divisinreal)

LuisHernndezYez

Tienen la mayor prioridad

Pgina 235

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 236

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Describimos los valores de las variables del tipo


typedefdescripcinnombre_de_tipo;
Identificador vlido
Nombres de tipos propios:
t minscula seguida de una o varias palabras capitalizadas

typedefdescripcintMiTipo;
typedefdescripcintMoneda;
typedefdescripcintTiposDeCalificacion;

Declaracin de tipo frente a definicin de variable


Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 237

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 238

LuisHernndezYez

LuisHernndezYez

Los colorearemos en naranja, para remarcar que son tipos

Enumeracin del conjunto de valores posibles para las variables:


enum {smbolo1,smbolo2,...,smboloN }
enum

Identificador

enum {centimo,dos_centimos,cinco_centimos,
diez_centimos,veinte_centimos,
medio_euro,euro }

LuisHernndezYez

Valores literales que pueden tomar las variables (en amarillo)

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 239

Mejoran la legibilidad
typedefdescripcinnombre_de_tipo;
Elegimos un nombre para el tipo: tMoneda

LuisHernndezYez

descripcin
typedefenum {centimo,dos_centimos,cinco_centimos,
diez_centimos,veinte_centimos,
medio_euro,euro }tMoneda;

En el mbito de la declaracin, se reconoce un nuevo tipo tMoneda


tMoneda moneda1,moneda2;
Cada variable de ese tipo contendr alguno de los smbolos
moneda1=dos_centimos;
moneda2=euro;
(Internamente se usan enteros)
Fundamentosdelaprogramacin:TiposeinstruccionesII

moneda1

dos_centimos

moneda2

euro
Pgina 240

typedefenum{enero,febrero,marzo,abril,mayo,
junio,julio,agosto,septiembre,octubre,
noviembre,diciembre}tMes;
tMes mes;

Lectura de la variable mes:


cin>>mes;
Se espera un valor entero
No se puede escribir directamente enero o junio

LuisHernndezYez

Y si se escribe la variable en la pantalla:


cout<<mes;
Se ver un nmero entero
Cdigo de entrada/salida especfico
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 241

LuisHernndezYez

typedefenum {enero,febrero,marzo,abril,mayo,junio,julio,
agosto,septiembre,octubre,noviembre,diciembre} tMes;
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;
cout<<"Numerodemes:";
cin>>op;
tMes mes=tMes(op 1);
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 242

typedefenum {enero,febrero,marzo,abril,mayo,junio,julio,
agosto,septiembre,octubre,noviembre,diciembre} tMes;

LuisHernndezYez

if (mes==enero){
cout<<"enero";
}
if (mes==febrero){
cout<<"febrero";
}
if (mes==marzo){
cout<<"marzo";
}
...
if (mes==diciembre){
cout<<"diciembre";
}

Tambin podemos utilizar una instruccin switch


Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 243

Conjunto de valores ordenado (posicin en la enumeracin)


typedefenum{lunes,martes,miercoles,jueves,
viernes,sabado,domingo}tDiaSemana;
tDiaSemana dia;
...

lunes <martes <miercoles <jueves


<viernes <sabado <domingo

if(dia ==jueves)...
bool noLaborable =(dia >=sabado);

LuisHernndezYez

No admiten operadores de incremento y decremento


Emulacin con moldes:
int i=int(dia);//dia nohadevalerdomingo!
i++;
dia =tDiaSemana(i);
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 244

#include<iostream>
usingnamespacestd;

Si los tipos se usan en varias funciones,


los declaramos antes de los prototipos

typedef enum{enero,febrero,marzo,abril,mayo,
junio,julio,agosto,septiembre,octubre,
noviembre,diciembre }tMes;
typedef enum {lunes,martes,miercoles,jueves,
viernes,sabado,domingo }tDiaSemana;

LuisHernndezYez

string cadMes(tMes mes);


string cadDia(tDiaSemana dia);
int main(){
tDiaSemana hoy=lunes;
int dia =21;
tMes mes=octubre;
int anio =2013;
...
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 245

//Mostramoslafecha
cout<<"Hoyes:" <<cadDia(hoy)<<"" <<dia
<<"de" <<cadMes(mes)<<"de"<<anio
<<endl;

LuisHernndezYez

cout<<"Pasadalamedianoche..."<<endl;
dia++;
inti=int(hoy);
i++;
hoy=tDiaSemana(i);
//Mostramoslafecha
cout<<"Hoyes:" <<cadDia(hoy)<<"" <<dia
<<"de" <<cadMes(mes)<<"de"<<anio
<<endl;
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 246

fechas.cpp
string cadMes(tMes mes){
string cad;

string cadDia(tDiaSemana dia);


string cad;
if (dia ==lunes){
cad ="lunes";
}
if (dia ==martes){
cad ="martes";
}
...
if (dia ==domingo){
cad ="domingo";
}

return cad;
}

return cad;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 247

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 248

LuisHernndezYez

LuisHernndezYez

if (mes==enero){
cad ="enero";
}
if (mes==febrero){
cad ="febrero";
}
...
if (mes==diciembre){
cad ="diciembre";
}

Datos del programa: en la memoria principal (voltil)


Medios (dispositivos) de almacenamiento permanente:
Discos magnticos fijos (internos) o porttiles (externos)
Cintas magnticas
Discos pticos (CD, DVD, BlueRay)
Memorias USB

LuisHernndezYez

Mantienen la informacin en archivos


Secuencias de datos

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 249

Archivo de texto: secuencia de caracteres


T

Archivo binario: contiene una secuencia de cdigos binarios


A0

25

2F

04

D6

FF

00

27

6C

CA

49

07

5F

A4

(Cdigos representados en notacin hexadecimal)

LuisHernndezYez

Los archivos se manejan en los programas por medio de flujos


Archivos de texto: flujos de texto
Similar a la E/S por consola
(Ms adelante veremos el uso de archivos binarios)

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 250

LuisHernndezYez

Textos dispuestos en sucesivas lneas


Carcter de fin de lnea entre lnea y lnea (Intro)
Posiblemente varios datos en cada lnea
Ejemplo: Compras de los clientes
En cada lnea, NIF del cliente, unidades compradas, precio
unitario y descripcin de producto, separados por espacio
12345678F2123.95ReproductordeDVD
00112233A1218.4Discoporttil
32143567J332MemoriaUSB16Gb
76329845H1134.5ModemADSL
...
Normalmente terminan con un dato especial (centinela)
Por ejemplo, un NIF que sea X
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 251

#include<fstream>

Lectura del archivo: flujo de entrada


Escritura en el archivo: flujo de salida
No podemos leer y escribir en un mismo flujo
Un flujo de texto se puede utilizar para lectura o para escritura:

Flujos (archivos) de entrada: variables de tipo ifstream

Flujos (archivos) de salida : variables de tipo ofstream

LuisHernndezYez

Biblioteca fstream (sin espacio de nombres)

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 252

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Flujos de texto de entrada

Pgina 253

ifstream

Para leer de un archivo de texto:


1 Declara una variable de tipo ifstream
2 Asocia la variable con el archivo de texto (apertura del archivo)
3 Realiza las operaciones de lectura

LuisHernndezYez

4 Desliga la variable del archivo de texto (cierre el archivo)

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 254

Apertura del archivo


Conecta la variable con el archivo de texto del dispositivo
flujo.open(cadena_literal);
ifstream archivo;
archivo.open("abc.txt");
if(archivo.is_open())...

Cierre del archivo

El archivo debe existir!


is_open():
true si el archivo
se ha podido abrir
false en caso contrario

Desconecta la variable del archivo de texto del dispositivo


LuisHernndezYez

flujo.close();
archivo.close();

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 255

Operaciones de lectura

LuisHernndezYez

Extractor (>>)
archivo>>variable;
Salta primero los espacios en blanco (espacio, tab, Intro, ...)
Datos numricos: lee hasta el primer carcter no vlido
Cadenas (string): lee hasta el siguiente espacio en blanco
archivo.get(c)
Lee el siguiente carcter en la variable c, sea el que sea
getline(archivo,cadena)
Lee en la cadena todos los caracteres que queden en la lnea
Incluidos los espacios en blanco
Hasta el siguiente salto de lnea (descartndolo)
Con los archivos no tiene efecto la funcin sync()
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 256

LuisHernndezYez

Qu debo leer?
Un nmero
Usa el extractor

archivo>>num;

Un carcter (sea el que sea)


Usa la funcin get()

archivo.get(c);

Una cadena sin espacios


Usa el extractor

archivo>>cad;

Una cadena posiblemente con espacios


Usa la funcin getline()
getline(archivo,cad);

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 257

Dnde queda pendiente la entrada?


Nmero ledo con el extractor
En el primer carcter no vlido (inc. espacios en blanco)
Carcter ledo con get()
En el siguiente carcter (inc. espacios en blanco)

LuisHernndezYez

Una cadena leda con el extractor


En el siguiente espacio en blanco
Una cadena leda con la funcin getline()
Al principio de la siguiente lnea

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 258

string nif,producto;
int unidades;
double precio;
char aux;
1 ifstream archivo;

2 archivo.open("compras.txt");//Apertura

3 archivo>>nif >>unidades>>precio;
getline(archivo,producto);

3
2
1

Programa

LuisHernndezYez

4 archivo.close();//Cierre

Flujo de entrada
archivo

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 259

archivo>>nif;
archivo>>unidades;
archivo>>precio;
getline(archivo,producto);
getline() no salta espacios

12345678F2123.95ReproductordeDVD
El extractor salta los espacios

LuisHernndezYez

nif 12345678F
producto

ReproductordeDVD

unidades 2
precio 123.95

Espacio
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 260

archivo>>nif;
archivo>>unidades;
archivo>>precio;
archivo.get(aux);//Saltaelespacioenblanco
getline(archivo,producto);

12345678F2123.95ReproductordeDVD
Leemos el espacio
(no hacemos nada con l)

LuisHernndezYez

nif 12345678F
producto ReproductordeDVD

unidades 2
precio 123.95

Sin espacio
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 261

LuisHernndezYez

Cada lnea, datos de una compra


Mostrar el total de cada compra
unidades x precio ms IVA (21%)
Final: "X" como NIF
Bucle de procesamiento:
Cada paso del bucle (ciclo) procesa una lnea (compra)
Podemos usar las mismas variables en cada ciclo
Leer primer NIF
Mientras el NIF no sea X:
Leer unidades, precio y descripcin
Calcular y mostrar el total
Leer el siguiente NIF
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 262

LuisHernndezYez

#include<iostream>
#include<string>
usingnamespacestd;
#include<fstream>
#include<iomanip>//Formatodesalida
int main(){
const int IVA=21;
string nif,producto;
int unidades;
double precio,neto,total,iva;
char aux;
ifstream archivo;
int contador=0;
archivo.open("compras.txt");//Apertura
...
Fundamentosdelaprogramacin:TiposeinstruccionesII

LuisHernndezYez

leer.cpp

Pgina 263

if (archivo.is_open()){//Existeelarchivo
archivo>>nif;//PrimerNIF
while (nif !="X"){
archivo>>unidades>>precio;
archivo.get(aux);//Saltaelespacio
getline(archivo,producto);
contador++;
neto=unidades*precio;
iva =neto*IVA/100;
total=neto+iva;
cout<<"Compra" <<contador<<"." <<endl;
cout<<"" <<producto<<":" <<unidades
<<"x" <<fixed <<setprecision(2)
<<precio<<"=" <<neto<<" I.V.A.:"
<<iva <<" Total:" <<total<<endl;
archivo>>nif;//SiguienteNIF
}...
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 264

archivo.close();//Cierre
}
else {
cout<<"ERROR:Nosehapodidoabrirelarchivo"
<<endl;
}
return 0;

LuisHernndezYez

Pgina 265

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 266

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

ofstream

Flujos de texto de salida


Para crear un archivo de texto y escribir en l:
1 Declara una variable de tipo ofstream

2 Asocia la variable con el archivo de texto (crea el archivo)


3 Realiza las escrituras por medio del operador << (insertor)
4 Desliga la variable del archivo de texto (cierra el archivo)

LuisHernndezYez

Atencin!
Si el archivo ya existe, se borra todo lo que hubiera
Atencin!
Si no se cierra el archivo se puede perder informacin
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 267

int valor=999;
Programa

1 ofstream archivo;
2 archivo.open("output.txt");//Apertura

2
1

Flujo de salida
archivo

LuisHernndezYez

3 archivo<<'X' <<"Hola!" <<123.45


<<endl<<valor<<"Bye!";

4 archivo.close();//Cierre

Fundamentosdelaprogramacin:TiposeinstruccionesII

o
H

Pgina 268

escribir.cpp

#include<iostream>
#include<string>
usingnamespacestd;
#include<fstream>
int main(){
string nif,producto;
int unidades;
double precio;
char aux;
ofstream archivo;

LuisHernndezYez

archivo.open("output.txt");//Apertura(creacin)
cout<<"NIFdelcliente(Xparaterminar):";
cin>>nif;
...

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 269

while (nif !="X"){


//QuedapendienteelIntroanterior...
cin.get(aux);//LeemoselIntro
cout<<"Producto:";
getline(cin,producto);
cout<<"Unidades:";
cin>>unidades;
cout<<"Precio:";
cin>>precio;
//Escribimoslosdatosenunalneadelarchivo...
//Conunespaciodeseparacinentreellos
archivo<<nif <<"" <<unidades<<""
<<precio<<"" <<producto<<endl;
cout<<"NIFdelcliente(Xparaterminar):";
cin>>nif;
}
...
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 270

//Escribimoselcentinelafinal...
archivo<<"X";
archivo.close();//Cierredelarchivo
return 0;

LuisHernndezYez

Pgina 271

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 272

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Flujo de ejecucin

LuisHernndezYez

double oper1,oper2,prod;
Instruccin1

cout<<"Operando1:";

Instruccin2

cin>>oper1;

Instruccin3

cout<<"Operando2:";
...
cout<<"Producto:" <<prod;
return 0;

InstruccinN

}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 273

Uno entre dos o ms caminos de ejecucin


Seleccin simple (2 caminos)

Seleccin mltiple (> 2 caminos)


true

true

InstruccinT

Condicin

false

false
true

InstruccinF

false
true
false

LuisHernndezYez

if
ifelseif
switch
Diagramasdeflujo
Fundamentosdelaprogramacin:TiposeinstruccionesII

true
false

Pgina 274

Repetir la ejecucin de una o ms instrucciones


Acumular, procesar colecciones, ...

Inicializacin

No

Iterar?

while

for

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 275

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 276

LuisHernndezYez

LuisHernndezYez

Cdigo

La instruccin if

LuisHernndezYez

if (condicin){
cdigoT
}
[else {
cdigoF
}]

true
BloqueT

Condicin

false
BloqueF
Opcional

condicin: expresin bool


Clusula else opcional

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 277

signo.cpp

LuisHernndezYez

int num;
cin>>num;
if (num<0){
cout<<"Negativo";
}
cin>>num;
else{
false
true
cout<<"Positivo";
num<0
}
cout<<"Negativo";
cout<<"Positivo";
cout<<endl;
cout<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 278

int num;
cin>>num;

1_29
129

if (num<0){

_
Positivo
_

cout<<"Negativo";
}
else{
cout<<"Positivo";

cin>>num;

false

cout<<endl;

num<0

num

129
?

LuisHernndezYez

cout<<"Positivo";

cout<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 279

int num;
cin>>num;

if (num<0){

Negativo

cout<<"Negativo";
}
else{
cout<<"Positivo";

cin>>num;

}
cout<<endl;

true

num<0

num

LuisHernndezYez

cout<<"Negativo";

cout<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 280

5
?

divisin.cpp

Divisin entre dos nmeros protegida frente a intento de divisin por 0

int main(){
double numerador,denominador,resultado;
cout<<"Numerador:";
cin>>numerador;
cout<<"Denominador:";
cin>>denominador;
if (denominador==0){
cout<<"Imposibledividirentre0!";
}
else{
resultado=numerador/denominador;
cout<<"Resultado:" <<resultado<<endl;
}
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 281

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 282

LuisHernndezYez

LuisHernndezYez

#include<iostream>
usingnamespacestd;

Se aplican a valores bool (condiciones)


El resultado es de tipo bool

NO

Monario

&&

Binario

||

Binario

Operadores(prioridad)
...
!
*/%
+
< <=>>=

LuisHernndezYez

==!=
&&
||

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 283

&&

true

false

||

true

false

true

false

true

true

false

true

true

true

false

true

false

false

false

false

true

false

NO (Not)

Y (And)

O (Or)

bool cond1,cond2,resultado;
int a=2,b=3,c=4;
resultado=!(a<5);//!(2<5) !true false

LuisHernndezYez

cond1=(a*b+c)>=12;//10>=12 false
cond2=(a*(b+c))>=12;//14>=12 true
resultado=cond1&&cond2;//false&&true false
resultado=cond1||cond2;//false||true true

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 284

condiciones.cpp

int main()
{
int num;
cout<<"Introduceunnmeroentre1y10:";
cin>>num;
if ((num>=1)&&(num<=10)){
cout<<"Nmerodentrodelintervalodevaloresvlidos";
}
else{
cout<<"Nmeronovlido!";
}
Condiciones equivalentes
return 0;
((num >=1)&&(num <=10))
}

Encierra las condiciones


simples entre parntesis!

((num >0)&&(num <11))


((num >=1)&&(num <11))
((num >0)&&(num <=10))

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 285

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 286

LuisHernndezYez

LuisHernndezYez

#include<iostream>
usingnamespacestd;

LuisHernndezYez

diasmes.cpp
int mes,anio,dias;
cout<<"Nmerodemes:";
cin>>mes;
cout<<"Ao:";
cin>>anio;
if (mes==2){
if (bisiesto(mes,anio)){
dias =29;
}
else {
dias =28;
}
}
else{
if ((mes==1)||(mes==3)||(mes==5)||(mes==7)
||(mes==8)||(mes==10)||(mes==12)){
dias =31;
}
else{
dias =30;
}
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 287

LuisHernndezYez

Calendario Gregoriano: bisiesto si divisible por 4, excepto el ltimo


de cada siglo (divisible por 100), salvo que sea divisible por 400
bool bisiesto(int mes,int anio){
bool esBisiesto;
if ((anio %4)==0){//Divisiblepor4
if (((anio %100)==0)&&((anio %400)!=0)){
//Peroltimodesigloynomltiplode400
esBisiesto =false;
}
else {
esBisiesto =true;//Aobisiesto
}
}
else {
esBisiesto =false;
}
return esBisiesto;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 288

if (condicin1){
if (condicin2){...}
else {...}
}
else{
if (condicin3){
if (condicin4){...}
if (condicin5){...}
else {...}
}
else {...

Una mala sangra puede confundir


if (x>0){
if (y>0){...}
else {...}

if (x>0){
if (y>0){...}
else {...}

La sangra ayuda a asociar los else con sus if


Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 289

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 290

LuisHernndezYez

LuisHernndezYez

Cada else se asocia al if anterior ms cercano sin asociar (mismo bloque)

Condicin simple:
num<0
car=='a'
isalpha(car)
12

Expresin lgica (true/false)


Sin operadores lgicos

Compatibilidad con el lenguaje C:


0 es equivalente a false
Cualquier valor distinto de 0 es equivalente a true

LuisHernndezYez

Condicin compuesta:
Combinacin de condiciones simples y operadores lgicos
!isalpha(car)
(num<0)|| (car=='a')
(num<0)&& ((car=='a')||!isalpha(car))
No confundas el operador de igualdad (==)
con el operador de asignacin (=).
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 291

Shortcut Boolean Evaluation


true || X true
(n==0)||(x>=1.0 /n)
Si n es 0: divisin por cero? (segunda condicin)
Como la primera sera true: no se evala la segunda!

LuisHernndezYez

false && X false


(n!=0)&&(x<1.0 /n)
Si n es 0: divisin por cero? (segunda condicin)
Como la primera sera false: no se evala la segunda!

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 292

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 293

true
false
true
false
true
false
true

LuisHernndezYez

false

ifelseif
switch
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 294

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Ejemplo:
Calificacin (en letras)
de un estudiante en base
a su nota numrica (010)

Pgina 295

true
==10

cout<<"MH"

false
true

Si nota==10 entonces MH
si no, si nota>=9 entonces SB
si no, si nota>=7 entonces NT

LuisHernndezYez

si no, si nota>=5 entonces AP


si no SS

Fundamentosdelaprogramacin:TiposeinstruccionesII

>=9
false

cout<<"SB"
true

>=7
false

cout<<"NT"
true

>=5

cout<<"AP"

false
cout<<"SS"

Pgina 296

LuisHernndezYez

nota.cpp
double nota;
cin>>nota;
if (nota==10){
cout<<"MH";
}
else {
if (nota>=9){
cout<<"SB";
}
else {
if (nota>=7){
cout<<"NT";
}
else {
if (nota>=5){
cout<<"AP";
}
else {
cout<<"SS";
}
}
}
}

double nota;
cin>>nota;
if (nota==10){
cout<<"MH";
}
else if (nota>=9){
cout<<"SB";
}
else if (nota>=7){
cout<<"NT";
}
else if (nota>=5){
cout<<"AP";
}
else{
cout<<"SS";
}

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 297

Cuidado con el orden de las condiciones!

LuisHernndezYez

double nota;
cin>>nota;
if (nota<5){cout<<"SS";}
else if (nota<7){cout<<"AP";}
else if (nota<9){cout<<"NT";}
else if (nota<10){cout<<"SB";}
else {cout<<"MH";}

No se ejecutan nunca!
double nota;
cin>>nota;
if (nota>=5){cout<<"AP";}
else if (nota>=7){cout<<"NT";}
else if (nota>=9){cout<<"SB";}
else if (nota==10){cout<<"MH";}
else {cout<<"SS";}

Slo muestra AP o SS

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 298

Simplificacin de las condiciones


0

SS

AP

NT

9 SB 10
MH

LuisHernndezYez

if (nota==10){cout<<"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
Si no es 10, es menor que 10
if (nota==10){cout<<"MH";}
Si no es >= 9, es menor que 9
else if (nota>=9){cout<<"SB";} Si no es >= 7, es menor que 7
else if (nota>=7){cout<<"NT";}

else if (nota>=5){cout<<"AP";} true &&X X


else {cout<<"SS";}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 299

LuisHernndezYez

nivel.cpp
#include<iostream>
Sinum==4 entoncesMuyalto
usingnamespacestd;
Sinum==3 entoncesAlto
int main(){
Sinum==2 entoncesMedio
int num;
cout<<"Introduceelnivel:"; Sinum==1 entoncesBajo
cin>>num;
if (num==4){
cout<<"Muyalto" <<endl;
}
elseif (num==3){
cout<<"Alto" <<endl;
}
elseif (num==2){
cout<<"Medio" <<endl;
}
elseif (num==1){
cout<<"Bajo" <<endl;
}
else{
cout<<"Valornovlido" <<endl;
}
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 300

if (num==4)cout<<"Muyalto";
elseif (num==3)cout<<"Alto";
elseif (num==2)cout<<"Medio";
elseif (num==1)cout<<"Bajo";
elsecout<<"Valornovlido";
cout<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 301

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 302

LuisHernndezYez

LuisHernndezYez

if (num==4){cout<<"Muyalto" <<endl;}
elseif (num==3){cout<<"Alto" <<endl;}
elseif (num==2){cout<<"Medio" <<endl;}
elseif (num==1){cout<<"Bajo" <<endl;}
elsecout<<"Valornovlido" <<endl;}

LuisHernndezYez

Seleccin entre valores posibles de una expresin


switch (expresin){
case constante1:
{
cdigo1
}
[break;]
case constante2:
{
cdigo2
}
[break;]
...

Fundamentosdelaprogramacin:TiposeinstruccionesII

case constanteN:
{
cdigoN
}
[break;]
[default:
{
cdigoDefault
}]
}

Pgina 303

LuisHernndezYez

nivel2.cpp
switch (num){
case 4:
{
cout<<"Muyalto";
}
break;
case 3:
{
cout<<"Alto";
}
break;
case 2:
{
cout<<"Medio";
}
break;
case 1:
{
cout<<"Bajo";
}
break;
default:
{
cout<<"Valornovlido";
}
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Si num==4 Muy alto


Si num==3 Alto
Si num==2 Medio
Si num==1 Bajo

Pgina 304

LuisHernndezYez

Interrumpe el switch; contina en la instruccin que le siga


switch (num){
...
case 3:
{
cout<<"Alto";
}
break;
case 2:
{
cout<<"Medio";
}
break;
...
}

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

switch (num){
...
case 3:
{
cout<<"Alto";
}
case 2:
{
cout<<"Medio";
}
case 1:
{
cout<<"Bajo";
}
default:
{
cout<<"Valornovlido";
}
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Num:3
Alto

Pgina 305

Num:3
Alto
Medio
Bajo
Valornovlido

Pgina 306

true
num==4

Muyalto
break;

false

Sin break;

true
num==3

Alto
break;

false

Sin break;

true
num==2

Medio
break;

false

Sin break;

true
num==1

LuisHernndezYez

false

Bajo

break;

Sin break;

default

Novlido

Fundamentosdelaprogramacin:TiposeinstruccionesII

int menu(){
int op =1;//Cualquieranovlida

LuisHernndezYez

while ((op <0)||(op >4)){


cout<<"1 Nuevocliente" <<endl;
cout<<"2 Editarcliente" <<endl;
cout<<"3 Bajacliente" <<endl;
cout<<"4 Vercliente" <<endl;
cout<<"0 Salir" <<endl;
cout<<"Opcin:";
cin>>op;

Pgina 307

1 Nuevocliente
2 Editarcliente
3 Bajacliente
4 Vercliente
0 Salir
Opcin:5
Opcinnovlida!
1 Nuevocliente
2 Editarcliente
3 Bajacliente
4 Vercliente
0 Salir
Opcin:3

if ((op <0)||(op >4)){


cout<<"Opcinnovlida!"<<endl;
}
}
return op;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 308

LuisHernndezYez

int opcion;
...
opcion =menu();
switch (opcion){
case 1:
{
cout<<"Enlaopcin1..." <<endl;
}
break;
case 2:
{
cout<<"Enlaopcin2..." <<endl;
}
break;
case 3:
{
cout<<"Enlaopcin3..." <<endl;
}
break;
case 4:
{
cout<<"Enlaopcin4..." <<endl;
}//Enlaltimanonecesitamosbreak
}

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 309

int opcion;
...
opcion =menu();
while (opcion!=0){
switch (opcion){
case 1:
{
cout<<"Enlaopcin1..." <<endl;
}
break;
...
case 4:
{
cout<<"Enlaopcin4..." <<endl;
}
} //switch
...
opcion =menu();
} //while

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 310

LuisHernndezYez

nota2.cpp
int nota;//Sindecimales
cout<<"Nota(010):";
cin>>nota;
switch (nota){
case 0:
case 1:
case 2:
case 3:
case 4:
{
cout<<"Suspenso";
}
break;//De0a4:SS
case 5:
case 6:
{
cout<<"Aprobado";
}
break; //5o6:AP

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

case
case
{

7:
8:

cout<<"Notable";
}
break;//7u8:NT
case 9:
case 10:
{
cout<<"Sobresaliente";
}
break;//9o10:SB
default:
{
cout<<"Novlida!";
}
}

Pgina 311

typedefenum {enero,febrero,marzo,abril,mayo,junio,
julio,agosto,septiembre,octubre,noviembre,diciembre}
tMes;
tMes mes;
...
switch (mes){
case enero:
{
cout<<"enero";
}
break;
case febrero:
{
cout<<"febrero";
}
break;
...
case diciembre:
{
cout<<"diciembre";
}
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 312

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 313

Inicializacin

Iterar?

No

LuisHernndezYez

Cuerpo

Bucles while y for

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 314

Nmero de iteraciones condicionado (recorrido variable):

Bucle while
while(condicin)cuerpo
Ejecuta el cuerpo mientras la condicin sea true
Bucle dowhile
Comprueba la condicin al final (lo veremos ms adelante)

Nmero de iteraciones prefijado (recorrido fijo):


Bucle for
for(inicializacin;condicin;paso)cuerpo
Ejecuta el cuerpo mientras la condicin sea true
Se usa una variable contadora entera

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 315

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 316

LuisHernndezYez

LuisHernndezYez

while.cpp

Mientras la condicin sea cierta, ejecuta el cuerpo


while(condicin){
cuerpo
}

Condicin al principio del bucle

int i=1;//Inicializacindelavariablei
while(i<=100){
cout<<i<<endl;
i++;
}
LuisHernndezYez

Muestra los nmeros del 1 al 100

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 317

int i=1;
while(i<=100){
cout<<i<<endl;
i++;
}

true

Condicin

Cuerpo

i=1

100
101
99
?
3
2
1
4

_
1

true

i<=100

LuisHernndezYez

cout<<i<<endl;

i++

Fundamentosdelaprogramacin:TiposeinstruccionesII

false

2
3
99
100

Pgina 318

false

Y si la condicin es falsa al comenzar?


No se ejecuta el cuerpo del bucle ninguna vez

LuisHernndezYez

int op;
cout<<"Introducelaopcin:";
cin>>op;
while((op <0)||(op >4)){
cout<<"Novlida!Intntalootravez" <<endl;
cout<<"Introducelaopcin:";
cin>>op;
}

Si el usuario introduce un nmero entre 0 y 4:


No se ejecuta el cuerpo del bucle

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 319

primero.cpp

Primer entero cuyo cuadrado es mayor que 1.000


#include<iostream>
usingnamespacestd;
int main(){
int num=1;

LuisHernndezYez

while(num*num<=1000){
num++;
}

Ejecuta el programa para


saber cul es ese nmero!

Empezamosen1
Incrementamosen1

cout<<"1er.enteroconcuadradomayorque1.000:"
<<num<<endl;
return 0;
}

Recorre la secuencia de nmeros 1, 2, 3, 4, 5, ...


Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 320

#include<iostream>
Recorre la secuencia
usingnamespacestd;
de nmeros introducidos
int main(){
double num,suma=0,media=0;
int cont =0;
cout<<"Introduceunnmero(0paraterminar):";
cin>>num;
Leemoselprimero
while(num!=0){//0paraterminar
suma=suma+num;
cont++;
cout<<"Introduceunnmero(0paraterminar):";
cin>>num;
Leemoselsiguiente
}
if (cont >0){
media=suma/cont;
}
cout<<"Suma="<<suma<<endl;
cout<<"Media="<<media<<endl;
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 321

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 322

LuisHernndezYez

LuisHernndezYez

sumamedia.cpp

Nmero de iteraciones prefijado


Variable contadora que determina el nmero de iteraciones:
for ([int]var =ini;condicin;paso)cuerpo

LuisHernndezYez

La condicin compara el valor de var con un valor final


El paso incrementa o decrementa el valor de var
El valor de var debe ir aproximndose 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

Tantos ciclos como valores toma la variable contadora

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 323

for(inicializacin;condicin;paso)cuerpo

for(int i=1;i<=100;i++){
cout<<i;
}
i=1

true

i<=100

false

LuisHernndezYez

cout<<i;
i++

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 324

for1.cpp

for(int i=1;i<=100;i++){
cout<<i<<endl;
}
i

100
101
2?3
1

...

1
2

i=1

3
true

i<=100

cout<<i<<endl;

99
100

LuisHernndezYez

i++

false

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 325

La variable contadora

for2.cpp

El paso no tiene porqu ir de uno en uno:


for(int i=1;i<=100;i=i+2)
cout<<i<<endl;
Este bucle for muestra los nmeros impares de 1 a 99
Muy importante
El cuerpo del bucle NUNCA debe alterar el valor del contador

LuisHernndezYez

Garanta de terminacin
Todo bucle debe terminar su ejecucin
Bucles for: la variable contadora debe converger al valor final

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 326

suma.cpp
#include<iostream>
usingnamespacestd;
longlong int suma(intn);

LuisHernndezYez

int main(){
int num;
cout<<"Nmerofinal:";
cin>>num;
if (num>0){//Elnmerodebeserpositivo
cout<<"Lasumadelosnmerosentre1y"
<<num<<"es:" <<suma(num);
}
return 0;
}
longlong int suma(int n){
longlong int total=0;
for(int i=1;i<=n;i++){
total=total+i;
}
Recorre la secuencia de nmeros
return total;
1, 2, 3, 4, 5, ..., n
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 327

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

LuisHernndezYez

Bucles infinitos
for(int i=1;i<=100;i)...
101234567891011...
Cada vez ms lejos del valor final (100)
Es un error de diseo/programacin
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 328

Declarada en el propio bucle


for(int i=1;...)
Slo se conoce en el cuerpo del bucle (su mbito)
No se puede usar en instrucciones que sigan al bucle

Declarada antes del bucle

LuisHernndezYez

int i;
for(i=1;...)
Se conoce en el cuerpo del bucle y despus del mismo
mbito externo al bucle

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 329

Los bucles for se pueden reescribir como bucles condicionados


for(int i=1;i<=100;i++)cuerpo
Es equivalente a:
int i=1;
while(i<=100){
cuerpo
i++;
}

LuisHernndezYez

La inversa no es siempre posible:


int i;
cin>>i;
while(i!=0){
cuerpo
cin>>i;
}

Bucle for equivalente?


No sabemos cuntos nmeros
introducir el usuario!

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 330

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

LuisHernndezYez

Un bucle for en el cuerpo de otro bucle for


Cada uno con su propia variable contadora:
for(int i=1;i<=100;i++){
for(int j=1;j<=5;j++){
cuerpo
}
}
Para cada valor de i
el valor de j vara entre 1 y 5
j vara ms rpido que i

Pgina 331

i
1
1
1
1
1
2
2
2
2
2
3

j
1
2
3
4
5
1
2
3
4
5
1
...

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 332

tablas.cpp

#include<iostream>
usingnamespacestd;
#include<iomanip>

LuisHernndezYez

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

1x1=1
1x2=2
1x3=3
1x4=4
...
1x10=10
2x1=2
2x2=4
...
10x7=70
10x8=80
10x9=90
10x10=100

return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 333

tablas2.cpp

LuisHernndezYez

#include<iostream>
usingnamespacestd;
#include<iomanip>
int main(){
for(int i=1;i<=10;i++){
cout<<"Tabladel"<<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;
}
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 334

men.cpp
#include<iostream>
usingnamespacestd;
#include<iomanip>

LuisHernndezYez

int menu();//1:Tablasdemultiplicacin;2:Sumatorio
longlong intsuma(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;
}
}
}
break;...
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 335

case 2:
{
int num=0;
while (num<=0){
cout<<"Hasta(positivo)?";
cin>>num;
}
cout<<"Lasumadelosnmerosdel1al"
<<num<<"es:"<<suma(num)<<endl;
}
}//switch
opcion =menu();
}//while(opcion!=0)
return 0;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 336

LuisHernndezYez

int menu(){
int op =1;
while ((op <0)||(op >2)){
cout<<"1 Tablasdemultiplicar" <<endl;
cout<<"2 Sumatorio" <<endl;
cout<<"0 Salir" <<endl;
cout<<"Opcin:" <<endl;
cin>>op;
if ((op <0)||(op >2)){
cout<<"Opcinnovlida!"<<endl;
}
}
return op;
}
longlong int suma(int n){
longlong int total=0;
for(int i=1;i<=n;i++){
total=total+i;
}
return total;
}

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 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++){
...
}
while ((op <0)||(op >2)){
...
}
menu()
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 338

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 339

LuisHernndezYez

Cada bloque crea un nuevo mbito:


int main(){
double d=1,suma=0;
3 mbitos anidados
int cont=0;
while(d!=0) {
cin>>d;
if(d!=0){
suma=suma+d;
cont++;
}
}
cout<<"Suma="<<suma<<endl;
cout<<"Media="<<suma/cont<<endl;
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 340

LuisHernndezYez

Un identificador se conoce
en el mbito en el que est declarado
(a partir de su instruccin de declaracin)
y en los submbitos posteriores

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 341

int main(){
mbito de la variable d
double d;
if(...){
int cont=0;
for(int i=0;i<=10;i++){
...
}
}
char c;
if(...){
double x;
...
}
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 342

LuisHernndezYez

int main(){
double d;
if(...){
mbito de la variable cont
int cont=0;
for(int i=0;i<=10;i++){
...
}
}
char c;
if(...){
double x;
...
}
return 0;
}

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 343

int main(){
double d;
if(...){
int cont=0;
for(int i=0;i<=10;i++){
...
}
mbito de la variable i
}
char c;
if(...){
double x;
...
}
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 344

LuisHernndezYez

int main(){
double d;
if(...){
int cont=0;
for(int i=0;i<=10;i++){
...
}
}
char c;
if(...){
mbito de la variable c
double x;
...
}
return 0;
}

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 345

int main(){
double d;
if(...){
int cont=0;
for(int i=0;i<=10;i++){
...
}
}
char c;
if(...){
double x;
...
mbito de la variable x
}
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 346

LuisHernndezYez

Si en un submbito se declara
un identificador con idntico nombre
que uno ya declarado en el mbito,
el del submbito oculta al del mbito
(no es visible)

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 347

int main(){
Oculta , en su mbito, a la i anterior
int i,x;
if(...){
Oculta , en su mbito, a la i anterior
int i=0;
for(int i=0;i<=10;i++){
...
}
}
char c;
if(...){
Oculta , en su mbito, a la x anterior
double x;
...
}
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 348

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 349

Sucesin de elementos de un mismo tipo que se acceden linealmente


elemento

secuencia

secuencia

(Secuencia vaca)

elemento

LuisHernndezYez

134122648718452
Comienza en un primer elemento (si no est vaca)
A cada elemento le sigue otra secuencia (vaca, si es el ltimo)
Acceso secuencial (lineal)
Se comienza siempre accediendo al primer elemento
Desde un elemento slo se puede acceder a su elemento siguiente
(sucesor), si es que existe
Todos los elementos, de un mismo tipo
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 350

No tratamos secuencias infinitas: siempre hay un ltimo elemento


Secuencias explcitas:

Sucesin de datos de un dispositivo (teclado, disco, sensor, ...)

Secuencias calculadas:

Frmula de recurrencia que determina el elemento siguiente

Listas (ms adelante)


Secuencias explcitas que manejaremos:

LuisHernndezYez

Datos introducidos por el teclado o ledos de un archivo


Con un elemento especial al final de la secuencia (centinela)
1341226487184521

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 351

Secuencia explcita leda de archivo:


Detectar la marca de final de archivo (Eof End of file)
Detectar un valor centinela al final

LuisHernndezYez

Secuencia explcita leda del teclado:


Preguntar al usuario si quiere introducir un nuevo dato
Preguntar al usuario primero cuntos datos va a introducir
Detectar un valor centinela al final
Valor centinela:
Valor especial al final que no puede darse en la secuencia
(Secuencia de nmeros positivos centinela: cualquier negativo)
12

37 23

19 83 63

Fundamentosdelaprogramacin:TiposeinstruccionesII

35 17 76 15 1
Pgina 352

Debe haber algn valor que no sea un elemento vlido


Secuencias numricas:
Si se permite cualquier nmero, no hay centinela posible
Cadenas de caracteres:
Caracteres especiales (no imprimibles)?
En realidad el valor centinela es parte de la secuencia,
pero su significado es especial y no se procesa como el resto
Significa que se ha alcanzado el final de la secuencia
(Incluso aunque haya elementos posteriores)
LuisHernndezYez

ltimo elemento
12

37 23

19 83 63 1 35 17 76 15
No se procesan

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 353

Tratamiento de los elementos uno a uno desde el primero

Recorrido
Un mismo tratamiento para todos los elementos de la secuencia
Ej. Mostrar los elementos de una secuencia, sumar los nmeros
de una secuencia, par o impar cada nmero de una secuencia?, ...
Termina al llegar al final de la secuencia

LuisHernndezYez

Bsqueda
Recorrido de la secuencia hasta encontrar un elemento buscado
Ej. Localizar el primer nmero que sea mayor que 1.000
Termina al localizar el primer elemento que cumple la condicin
o al llegar al final de la secuencia (no encontrado)

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 354

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 355

Un mismo tratamiento a todos los elementos

LuisHernndezYez

Inicializacin
Mientras no se llegue al final de la secuencia:
Obtener el siguiente elemento
Procesar el elemento
Finalizacin
Al empezar se obtiene el primer elemento de la secuencia
En los siguientes pasos del bucle se van obteniendo
los siguientes elementos de la secuencia

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 356

Inicializacin

Al final?

true

false
Obtener elemento

LuisHernndezYez

Procesar elemento

No sabemos cuntos
elementos hay
No podemos
implementar con for

Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 357

Implementacin con while


Inicializacin
Obtener el primer elemento
Mientras no sea el centinela:
Procesar el elemento
Obtener el siguiente elemento
Finalizacin

Inicializacin
Obtener 1

Centinela?

true

false
Procesar elemento

LuisHernndezYez

Obtener siguiente

Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 358

Secuencia de nmeros positivos

LuisHernndezYez

Siempre se realiza al menos una lectura


Centinela: 1
double d,suma=0;
Inicializacin
cout<<"Valor(1termina):";
Primer elemento
cin>>d;
while(d!=1){
Mientras no el centinela
suma=suma+d;
Procesar elemento
cout<<"Valor(1termina):";
Siguiente elemento
cin>>d;
}
cout<<"Suma="<<suma<<endl;
Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII

Longitud de una secuencia de caracteres

Pgina 359

longitud.cpp

LuisHernndezYez

Centinela: carcter punto (.)


int longitud(){
int l=0;
char c;
cout<<"Textoterminadoenpunto:";
cin>>c;//Obtenerprimercarcter
while(c!='.'){//Mientrasnoelcentinela
l++;//Procesar
cin>>c;//Obtenersiguientecarcter
}
return l;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 360

Cuntas veces aparece un carcter en una cadena?

LuisHernndezYez

Centinela: asterisco (*)

cont.cpp

charbuscado,c;
intcont =0;
cout<<"Carcterabuscar:";
cin>>buscado;
cout<<"Cadena:";
cin>>c;
Primer elemento
while(c!='*'){
Mientras no el centinela
if(c==buscado){
Procesar elemento
cont++;
}
Siguiente elemento
cin>>c;
}
cout<<buscado<<"aparece" <<cont
<<"veces.";
Fundamentosdelaprogramacin:TiposeinstruccionesII

Suma de los nmeros de la secuencia

Pgina 361

suma2.cpp

LuisHernndezYez

Centinela: 0
intsumaSecuencia(){
doubled,suma=0;
ifstreamarchivo;//Archivodeentrada(lectura)
archivo.open("datos.txt");
if (archivo.is_open()){
archivo>>d;//Obtenerelprimero
while(d!=0){//Mientrasnoseaelcentinela
suma=suma+d; //Procesareldato
archivo>>d;//Obtenerelsiguiente
}
archivo.close();
}
return suma;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 362

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 363

sumatorio.cpp

Recurrencia:

ei+1 = ei + 1

e1 = 1

12345678...

LuisHernndezYez

Suma de los nmeros de la secuencia calculada:


intmain(){
intnum;
cout<<"N=";
cin>>num;
cout<<"Sumatorio:" <<suma(num);
return 0;
}
longlong intsuma(intn){
intsumatorio=0;
for(int i=1;i<=n;i++){
sumatorio=sumatorio+i;
}
return sumatorio;
ltimo elemento de la secuencia: n
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 364

longlong intsuma(intn){
intsumatorio=0;
for(int i=1;i<=n;i++){
sumatorio=sumatorio+i;
}
...

sumatorio=0;
int i=1;

5
?

sumatorio

15
10
01
3
6

false

i<=n
i

2
51
4
3
6

21
1
54321
4321
321

LuisHernndezYez

Secuencia

true
sumatorio+=i;
i=i+1;

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 365

Definicin
Fi = Fi1 + Fi2
F1 = 0
F2 = 1
01123581321345589...

LuisHernndezYez

Fin de la secuencia?
Primer nmero de Fibonacci mayor que un nmero dado
Ese nmero de Fibonacci acta como centinela
Si num es 50, la secuencia ser:
0112358132134

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 366

fibonacci.cpp

LuisHernndezYez

Recorrido de la secuencia calculada


int num,fib,fibMenos2=0,fibMenos1=1;//1y2
fib =fibMenos2+fibMenos1;//Calculamoseltercero
cout<<"Hasta:";
cin>>num;
if (num >=1){//Hadeserenteropositivo
cout<<"01";//Losdosprimerosson<=num
while(fib <=num){//Mientrasnomayorquenum
cout<<fib <<"";
fibMenos2=fibMenos1;//Actualizamosanteriores
fibMenos1=fib;//paraobtener...
fib =fibMenos2+fibMenos1;//...elsiguiente
}
}
Demasiados comentarios?
Para no oscurecer el cdigo, mejor una explicacin al principio
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 367

El bucle calcula adecuadamente la secuencia:


while(fib <=num){
cout<<fib<<"";
fibMenos2=fibMenos1;
fibMenos1=fib;
fib =fibMenos2+fibMenos1;
}

LuisHernndezYez

num 100
?
fib

5
2
3
1
?

fibMenos1

3
1
2
?

fibMenos2

2
1
0
?

Fundamentosdelaprogramacin:TiposeinstruccionesII

01 1 2 3 5 ...

Pgina 368

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 369

Localizacin del primer elemento con una propiedad

LuisHernndezYez

Inicializacin
Mientras no se encuentre el elemento
y no se est al final de la secuencia:
Obtener el siguiente elemento
Comprobar si el elemento satisface la condicin
Finalizacin
(tratar el elemento encontrado o indicar que no se ha encontrado)
Elemento que se busca: satisfar una condicin
Dos condiciones de terminacin del bucle: se encuentra / al final
Variable lgica que indique si se ha encontrado

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 370

Localizacin del primer elemento con una propiedad


Inicializacin / encontrado=false;

Al final o
encontrado?

true

false

Obtener elemento

LuisHernndezYez

Encontrado?

Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 371

Implementacin con while


Inicializacin
Obtener el primer elemento
Mientras ni encontrado ni el centinela:
Obtener el siguiente elemento
Finalizacin (encontrado?)

Inicializacin
Obtener 1

Encontrado
o centinela?

false

LuisHernndezYez

Obtener siguiente

Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 372

true

Primer nmero mayor que uno dado

busca.cpp

doubled,num;
boolencontrado=false;
cout<<"Encontrarprimeromayorque:";
cin>>num;
cout<<"Siguiente(1paraterminar):";
cin>>d; //Obtenerelprimerelemento
while((d!=1)&&!encontrado){
//Mientrasnoseaelcentinelaynoseencuentre
if(d>num){ //Encontrado?
encontrado=true;
}
else{
cout<<"Siguiente(1paraterminar):";
cin>>d; //Obtenerelsiguienteelemento
}
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 373

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 374

LuisHernndezYez

LuisHernndezYez

Centinela: 1

Colecciones homogneas
Un mismo tipo de dato para varios elementos:
Notas de los estudiantes de una clase
Ventas de cada da de la semana
Temperaturas de cada da del mes
...
En lugar de declarar N variables...

LuisHernndezYez

vLun
125.40

vMar
76.95

vMie
328.80

vJue
254.62

vVie
435.00

vSab
164.29

vDom
0.00

... declaramos una tabla de N valores:


ventas 125.40
ndices
0

76.95
1

328.80 254.62 435.00 164.29


2

Fundamentosdelaprogramacin:TiposeinstruccionesII

0.00
6

Pgina 375

Estructura secuencial
Cada elemento se encuentra en una posicin (ndice):
Los ndices son enteros positivos
El ndice del primer elemento siempre es 0
Los ndices se incrementan de uno en uno
ventas 125.40

LuisHernndezYez

76.95
1

328.80 254.62 435.00 164.29


2

0.00

Acceso directo
A cada elemento se accede a travs de su ndice:
ventas[4] accede al 5 elemento (contiene el valor 435.00)
cout<<ventas[4];
ventas[4]=442.75;

Datos de un mismo tipo base:


Se usan como cualquier variable

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 376

Declaracin de tipos de arrays


typedef tipo_base nombre_tipo[tamao];
Ejemplos:

LuisHernndezYez

typedef
typedef
typedef
typedef
typedef

double tTemp[7];
shortint tDiasMes[12];
char tVocales[5];
double tVentas[31];
tMoneda tCalderilla[15];//EnumeradotMoneda
Recuerda: Adoptamos el convenio de comenzar
los nombres de tipo con una t minscula, seguida
de una o varias palabras, cada una con su inicial en mayscula

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 377

Declaracin de variables arrays

typedef
typedef
typedef
typedef

tipo nombre;

double tTemp[7];
shortint tDiasMes[12];
char tVocales[5];
double tVentas[31];

Ejemplos:
tempMax ? ? ? ? ? ? ?

tTemp tempMax;

tDiasMes diasMes;

10

11

vocales ? ? ? ? ?

tVocales vocales;

LuisHernndezYez

diasMes ? ? ? ? ? ? ? ? ? ? ? ?
0

tVentas ventasFeb;

ventasFeb ? ? ? ? ? ? ? ? ? ? ? ? ?
0

9 10 11 12

NO se inicializan los elementos automticamente


Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 378

3
...

?
30

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 379

nombre[ndice]
Cada elemento se accede a travs de su ndice (posicin en el array)
tVocales vocales;
vocales

typedef char tVocales[5];

'a'

'e'

'i'

'o'

'u'

5 elementos, ndices de 0 a 4:
vocales[0]vocales[1]vocales[2]vocales[3]vocales[4]

Procesamiento de cada elemento:


Como cualquier otra variable del tipo base
LuisHernndezYez

cout<<vocales[4];
vocales[3]='o';
if(vocales[i]=='e')...

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 380

IMPORTANTE!
No se comprueba si el ndice es correcto!
Es responsabilidad del programador!
const int Dim =100;
typedef double tVentas[Dim];
tVentas ventas;

ndices vlidos: enteros entre 0 y Dim1


Qu es ventas[100]? O ventas[1]? O ventas[132]?
Memoria de alguna otra variable del programa!
Define los tamaos de los arrays con constantes
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 381

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 382

LuisHernndezYez

LuisHernndezYez

ventas[0]ventas[1]ventas[2]...ventas[98]ventas[99]

Arrays: tamao fijo Bucle de recorrido fijo (for)


Ejemplo: Media de un array de temperaturas

LuisHernndezYez

const int Dias =7;


typedef double tTemp[Dias];
tTemp temp;
double media,total=0;
...
for(int i=0;i<Dias;i++){
total=total+temp[i];
}
media=total/Dias;

Fundamentosdelaprogramacin:TiposeinstruccionesII

12.40

10.96

8.43

11.65

13.70

13.41

14.07

tTemp temp;
double media,total=0;
...
for(int i=0;i<Dias;i++){
total=total+temp[i];
}

Memoria

i=0

true
i<Dias
total+=temp[i]

LuisHernndezYez

Pgina 383

false

...

i++

Fundamentosdelaprogramacin:TiposeinstruccionesII

Dias

temp[0]

12.40

temp[1]

10.96

temp[2]

8.43

temp[3]

11.65

temp[4]

13.70

temp[5]

13.41

temp[6]

14.07

media

total

23.36
31.79
84.62
12.40
0.00
43.44

3
2
70
4
1

Pgina 384

mediatemp.cpp
#include<iostream>
usingnamespacestd;
const int Dias =7;
typedef double tTemp[Dias];

LuisHernndezYez

double media(const tTemp temp);


int main(){
tTemp temp;
for (int i=0;i<Dias;i++){//Recorridodelarray
cout<<"Temperaturadelda"<<i+1<<":";
cin>>temp[i];
}
cout<<"Temperaturamedia:"<<media(temp)<<endl;
return0;
}
Los usuarios usan de 1 a 7 para numerar los das
...
La interfaz debe aproximarse a los usuarios,
aunque internamente se usen los ndices de 0 a 6
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 385

double media(consttTemp temp){


double med,total=0;
for (int i=0;i<Dias;i++){//Recorridodelarray
total=total+temp[i];
}
med =total/Dias;
returnmed;
}

LuisHernndezYez

Los arrays se pasan a las funciones como constantes


Las funciones no pueden devolver arrays

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 386

constint Cuantas=15;
typedefenum {centimo,dos_centimos,cinco_centimos,
diez_centimos,veinte_centimos,medio_euro,euro }tMoneda;
typedef tMoneda tCalderilla[Cuantas];

tCalderilla bolsillo;//ExactamentellevoCuantasmonedas
bolsillo[0]=euro;
bolsillo[1]=cinco_centimos;
bolsillo[2]=medio_euro;
bolsillo[3]=euro;
bolsillo[4]=centimo;
...
for(int moneda=0;moneda<Cuantas;moneda++)
cout<<aCadena(bolsillo[moneda])<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 387

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 388

LuisHernndezYez

LuisHernndezYez

string aCadena(tMoneda moneda);


//Devuelvelacadenacorrespondientealvalordemoneda

buscaarray.cpp

Qu da las ventas superaron los 1.000 ?


int busca(const tVentas ventas){
//ndicedelprimerelementomayorque1000(1sinohay)
bool encontrado=false;
int ind =0;
while ((ind <Dias)&&!encontrado){//Esquemadebsqueda
if (ventas[ind]>1000){
encontrado=true;
}
else {
ind++;
}
}
if (!encontrado){
ind =1;
}
returnind;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 389

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 390

LuisHernndezYez

LuisHernndezYez

constint Dias =365;//Aonobisiesto


typedef doubletVentas[Dias];

LuisHernndezYez

La capacidad de un array no puede ser alterada en la ejecucin


El tamao de un array es una decisin de diseo:
En ocasiones ser fcil (das de la semana)
Cuando pueda variar ha de estimarse un tamao
Ni corto ni con mucho desperdicio (posiciones sin usar)
STL (Standard Template Library) de C++:
Colecciones ms eficientes cuyo tamao puede variar

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 391

No se pueden copiar dos arrays (del mismo tipo) con asignacin:


array2=array1;//NOCOPIALOSELEMENTOS!!!

LuisHernndezYez

Han de copiarse los elementos uno a uno:


for(int i=0;i<N;i++){
array2[i]=array1[i];
}

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 392

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 393

Puede que no necesitemos todas las posiciones de un array...


La dimensin del array ser el mximo de elementos
Pero podremos tener menos elementos del mximo
Necesitamos un contador de elementos...

LuisHernndezYez

constint Max=100;
typedef doubletArray[Max];
tArray lista;
int contador=0;

contador: indica cuntas posiciones del array se utilizan


Slo accederemos a las posiciones entre 0 y contador1
Las dems posiciones no contienen informacin del programa

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 394

lista.cpp
#include<iostream>
usingnamespacestd;
#include<fstream>
const int Max=100;
typedef double tArray[Max];

LuisHernndezYez

double media(const tArray lista,int cont);


int main(){
tArray lista;
int contador=0;
double valor,med;
ifstream archivo;
archivo.open("lista.txt");
if (archivo.is_open()){
archivo>>valor;
while ((valor!=1)&&(contador<Max)){
lista[contador]=valor;
contador++;
archivo>>valor;
}...
Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 395

archivo.close();
med =media(lista,contador);
cout<<"Mediadeloselementosdelalista:"<<med <<endl;
}
else {
cout<<"Nosepudoabrirelarchivo!" <<endl;
}
return 0;

LuisHernndezYez

}
double media(const tArray lista,int cont){
double med,total=0;
for (int ind =0;ind <cont;ind++){
total=total+lista[ind];
}
med =total/cont;
Slo recorremos hasta cont1
return med;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 396

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 397

Fundamentosdelaprogramacin

3A
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

LuisHernndezYez

Expresin condicional

Condicin

Exp1

Dos alternativas
Condicin: Expresin lgica
Exp1 y Exp2: Expresiones
Si Condicin se evala a true,
el resultado es Exp1;
si Condicin se evala a false,
el resultado es Exp2.

int a=5,b=3,c;

< <=>>=

c=(a+b==10)?2 :3;

==!=

c=(8

||

==10)?2 :3;

c=false

?2 :3;

Exp2

Operadores(prioridad)
++ (postfijos)
Llamadas a funciones
Moldes
++ (prefijos) !
(cambio de signo)
*/%

&&
?:
=+==*=/=%=

c=3;
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoI)

Pgina 399

Equivalencia con un ifelse


c=(a+b==10)?2 :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"))))
LuisHernndezYez

Esto es equivalente a la escala ifelseif de la siguiente seccin.

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoI)

Pgina 400

Escala if ... elseif ... equivalente


cout<<(nota==10 ?"MH" :(nota>=9 ?"SB" :
(nota>=7 ?"NT" :(nota>=5 ?"AP" :"SS"))))

LuisHernndezYez

Si nota==10 entonces MH
si no, si nota>=9 entonces SB
si no, si nota>=7 entonces NT
si no, si nota>=5 entonces AP
si no SS
double nota;
cin>>nota;
if (nota==10){cout<<"MH";}
else if (nota>=9){cout<<"SB";}
else if (nota>=7){cout<<"NT";}
else if (nota>=5){cout<<"AP";}
else {cout<<"SS";}

true
"MH"

==10

false
true
"SB"

>=9

false
true
"NT"

>=7

false
true
>=5

"AP"

false

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoI)

"SS"

Pgina 401

Fundamentosdelaprogramacin

3E
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

LuisHernndezYez

Recorridos
Unaparcamiento
Parntesisbienemparejados?
Dossecuenciasiguales?
NmerosprimosmenoresqueN
Bsquedas
Bsquedadeunnmeroenunarchivo
Bsquedasensecuenciasordenadas

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

404
405
409
412
413
417
419
420

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 404

LuisHernndezYez

Secuencia de caracteres E y S en archivo


E = Entra un coche; S = Sale un coche
Cuntos coches quedan al final de la jornada?
Varios casos, cada uno en una lnea y terminado en punto
Final: lnea slo con punto

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 405

LuisHernndezYez

#include<iostream>
usingnamespacestd;
#include<fstream>
int main(){
int coches;
char c;
bool terminar=false;
ifstream archivo;
archivo.open("parking.txt");
if (!archivo.is_open()){
cout<<"Nosehapodidoabrirelarchivo!"<<endl;
}
else {
//Recorrido...
archivo.close();
}
return 0;
}

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina406

while (!terminar){
archivo>>c;
if (c=='.'){//.comoprimercarcter?(centinela)
terminar=true;
}
else {
coches=0;
while (c!='.'){//Recorridodelasecuencia
cout<<c;
if (c=='E'){
coches++;
}
elseif(c=='S'){
coches;
}
archivo>>c;
}
...

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina407

parking.cpp
if (coches>=0){
cout<<endl<<"Quedan" <<coches<<"coches.";
}
else {
cout<<endl<<"Error:Mssalidasqueentradas!";
}
cout<<endl;
}

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina408

Cada parntesis, con su pareja


Secuencia de caracteres terminada en # y con parejas de parntesis:
ab(c(de)fgh((i(jk))lmn)op)(rs)#

Contador del nivel de anidamiento:


Al encontrar '(' incrementamos Al encontrar ')' decrementamos
Al terminar, el contador deber tener el valor 0

LuisHernndezYez

Errores:
Contador 1: parntesis de cierre sin uno de apertura pendiente
abc)de(fgh(ij))#

Contador termina con un valor positivo


Ms parntesis de apertura que de cierre
Algn parntesis sin cerrar: (a(b(cd(e)f)gh(i))jk#
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 409

LuisHernndezYez

Un error puede interrumpir el recorrido:


char c;
int anidamiento=0,pos=0;
bool error=false;
cin>>c;
while((c!='#')&&!error){
pos++;
if (c=='('){
anidamiento++;
}
elseif (c==')'){
anidamiento;
}
if (anidamiento<0){
error=true;
}
if (!error){
cin>>c;
}
}
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 410

parentesis.cpp

LuisHernndezYez

if (error){
cout<<"Error:cierresinapertura(pos." <<pos
<<")";
}
elseif(anidamiento>0){
cout<<"Error:Aperturasincierre";
}
else {
cout<<"Correcto";
}
cout<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 411

LuisHernndezYez

iguales.cpp
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;//Almenosestarnloscentinelas(0)
while (sonIguales &&!final){
sonIguales =(d1==d2);
final=((d1==0)||(d2==0));
if (!final){
sec1>>d1;
sec2>>d2;
}
}
Cambia secuencia2.txt por secuencia3.txt
sec1.close();
y por secuencia4.txt para comprobar otros casos
sec2.close();
return sonIguales;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 412

primos.cpp

LuisHernndezYez

Secuencia calculada: nmeros divisibles slo por 1 y ellos mismos (< N)


#include<iostream>
usingnamespacestd;
bool primo(int n);
int main(){
int num,candidato;
cout<<"Enteroenelqueparar(>1):";
cin>>num;
if (num>1){
candidato=2;//El1noseconsideraunnmeroprimo
while (candidato<num){
cout<<candidato<<"";//Mostrarnmeroprimo
candidato++;
while (!primo(candidato)){//Siguienteprimo
candidato++;
}
}
}
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 413

bool primo(int n){


bool esPrimo =true;
for (inti=2;i<=n 1;i++){
if (n%i==0){
esPrimo =false;//Esdivisiblepori
}
}
return esPrimo;

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 414

primos2.cpp

Mejoras: probar slo impares; slo pueden ser divisibles por impares;
no pueden ser divisibles por ninguno mayor que su mitad

LuisHernndezYez

candidato=2;
cout<<candidato<<"";//Mostrarelnmeroprimo2
candidato++;//Seguimosconel3,queesprimo
while (candidato<num){
cout<<candidato<<"";//Mostrarnmeroprimo
candidato=candidato+2;//Sloprobamosimpares
while (!primo(candidato)){//Siguientenmeroprimo
candidato=candidato+2;
}
}...
bool primo(int n){
bool esPrimo =true;
for (int i=3;i<=n/2;i=i+2){
if (n%i==0){
esPrimo =false;//Esdivisiblepori
}
}...
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 415

primos3.cpp

Otra mejora ms: Paramos al encontrar el primer divisor


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

Pgina 416

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 417

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

#include<iostream>
usingnamespacestd;
#include<fstream>

buscaarch.cpp

int busca(int n);


//Devuelvelalneaenlaqueseencuentrao1sinoest

LuisHernndezYez

intmain(){
intnum,linea;
cout<<"Valoralocalizar:";
cin>>num;
linea =busca(num);
if(linea !=1){
cout<<"Encontrado(lnea" <<linea <<")" <<endl;
}
else{
cout<<"Noencontrado" <<endl;
}
return 0;
}

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

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;
}
if (!encontrado){
linea =1;
}
archivo.close();
}
return linea;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 418

Centinela

Pgina 419

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Secuencia ordenada de menor a mayor:


paramos al encontrar uno mayor o igual al buscado

Pgina 420

buscaord.cpp

LuisHernndezYez

Los que resten sern seguro mayores: no puede estar el buscado!


cout<<"Valoralocalizar:";
cin>>num;
archivo>>i;
while ((i!=0)&&(i<num)){
cont++;
archivo>>i;
}
if (i==num){
cout<<"Encontrado(pos.:" <<cont <<")";
}
else {
cout<<"Noencontrado";
}
cout<<endl;
archivo.close();
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 421

Si el elemento est: procesamiento similar a secuencias desordenadas

15

16

24

41

73

78

82

123

153

159

...

archivo>>i;

num

9
?

false

(i!=0)
&&(i<num)

true

9
5
?
2

LuisHernndezYez

cont++;
archivo>>i;

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 422

Si el elemento no est: evitamos buscar en el resto de la secuencia

15

16

24

41

73

78

82

123

153

159

archivo>>i;

num

No se procesa
el resto
de la secuencia

10
?
(i!=0)
&&(i<num)

...

5
2
9
?
15

false

true

LuisHernndezYez

cont++;
archivo>>i;

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 423

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 424

Fundamentosdelaprogramacin

4
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

LuisHernndezYez

Diseodescendente:Tareasysubtareas
Subprogramas
Subprogramasydatos
Parmetros
Argumentos
Resultadodelafuncin
Prototipos
Ejemploscompletos
Funcionesdeoperador
Diseodescendente(unejemplo)
Precondicionesypostcondiciones

Fundamentosdelaprogramacin:Laabstraccinprocedimental

427
434
441
446
451
467
473
475
477
480
490

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 427

Refinamientos sucesivos
Tareas que ha de realizar un programa:
Se pueden dividir en subtareas ms sencillas
Subtareas:
Tambin se pueden dividir en otras ms sencillas...
Refinamientos sucesivos
Diseo en sucesivos pasos en los se ampla el detalle

LuisHernndezYez

Ejemplos:
Dibujar
Mostrar la cadena HOLA MAMA en letras gigantes

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 428

1. Dibujar
2. Dibujar

1. Dibujar

3. Dibujar

2. Dibujar

Misma tarea

2.1. Dibujar

LuisHernndezYez

REFINAMIENTO

2.2. Dibujar
3. Dibujar

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 429

1. Dibujar
2. Dibujar
2.1. Dibujar
4tareas,perodosdeellassoniguales

LuisHernndezYez

2.2. Dibujar

Nosbastaconsabercmodibujar:

3. Dibujar

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 430

void dibujarCirculo()
{...}
void dibujarSecantes()
{...}

Dibujar

void dibujarLinea()
{...}

Dibujar

Dibujar

Dibujar

Dibujar

Dibujar

void dibujarTriangulo()
{
dibujarSecantes();
dibujarLinea();
}

LuisHernndezYez

int main(){
dibujarCirculo();
dibujarTriangulo();
dibujarSecantes();
return 0;
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 431

Mostrar la cadena HOLA MAMA en letras gigantes


MostrarHOLAMAMA

MostrarHOLA

LuisHernndezYez

Espacioenblanco

MostrarMAMA

Tareas bsicas
H

Espacioenblanco

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 432

void mostrarH(){
cout<<"**"
cout<<"**"
cout<<"*****"
cout<<"**"
cout<<"**"
}

void mostrarL()
{...}

<<endl;
<<endl;
<<endl;
<<endl;
<<endl<<endl;

void espaciosEnBlanco(){
cout<<endl<<endl<<endl;
}
void mostrarM()
{...}
int main(){
mostrarH();
mostrarO();
mostrarL();
mostrarA();
espaciosEnBlanco();
mostrarM();
mostrarA();
mostrarM();
mostrarA();
return0;

void mostrarA()
{...}

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 433

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 434

LuisHernndezYez

LuisHernndezYez

void mostrarO(){
cout<<"*****"
cout<<"**"
cout<<"**"
cout<<"**"
cout<<"*****"
}

<<endl;
<<endl;
<<endl;
<<endl;
<<endl<<endl;

Subprogramas
Pequeos programas dentro de otros programas
Unidades de ejecucin independientes
Encapsulan cdigo y datos
Se comunican con otros subprogramas (datos)

LuisHernndezYez

Subrutinas, procedimientos, funciones, acciones, ...

Realizan tareas individuales del programa


Funcionalidad concreta, identificable y coherente (diseo)
Se ejecutan de principio a fin cuando se llaman (invocan)
Terminan devolviendo el control al punto de llamada
Aumentan el nivel de abstraccin del programa
Facilitan la prueba, la depuracin y el mantenimiento
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 435

Flujo de ejecucin
int main()
{

mostrarH();
mostrarO();

...
}

LuisHernndezYez

void mostrarH()
{
...

void mostrarO()
{
...
}
...

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 436

Subprogramas en C++
Forma general de un subprograma en C++:
tipo nombre(parmetros)//Cabecera
{
//Cuerpo
}

Tipo de dato que devuelve el subprograma como resultado


Parmetros para la comunicacin con el exterior
LuisHernndezYez

Cuerpo: Un bloque de cdigo!

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 437

Tipos de subprogramas

LuisHernndezYez

Procedimientos (acciones):
NO devuelven ningn resultado de su ejecucin con return
Tipo: void
Llamada: instruccin independiente
mostrarH();
Funciones:
S devuelven un resultado con la instruccin return
Tipo distinto de void
Llamada: dentro de cualquier expresin
x=12*y+cuadrado(20) 3;
Se sustituye en la expresin por el valor que devuelve
Ya venimos utilizando funciones desde el Tema 2!
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 438

Funciones
Subprogramas de tipo distinto de void
intmain()
{
...
int opcion;
opcion =menu();
...

LuisHernndezYez

...
int menu()
{
int op;
cout<<"1 Editar"<<endl;
cout<<"2 Combinar"<<endl;
cout<<"3 Publicar"<<endl;
cout<<"0 Cancelar"<<endl;
cout<<"Elija:";
cin>>op;
returnop;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 439

Procedimientos

LuisHernndezYez

Subprogramas de tipo void


...
void menu()
{
int op;
cout<<"1 Editar"<<endl;
cout<<"2 Combinar"<<endl;
cout<<"0 Cancelar"<<endl;
cout<<"Opcin:";
cin>>op;
if(op ==1){
editar();
}
elseif(op ==2){
combinar();
}
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental

intmain()
{
...
menu();
...

Pgina 440

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 441

De uso exclusivo del subprograma


tipo nombre(parmetros)//Cabecera
{
Declaracioneslocales//Cuerpo
}

LuisHernndezYez

Declaraciones locales de tipos, constantes y variables


Dentro del cuerpo del subprograma
Parmetros declarados en la cabecera del subprograma
Comunicacin del subprograma con otros subprogramas

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 442

Datos en los programas


Datos globales: declarados fuera de todos los subprogramas
Existen durante toda la ejecucin del programa

Datos locales: declarados en algn subprograma


Existen slo durante la ejecucin del subprograma

mbito y visibilidad de los datos

Tema 3

mbito de los datos globales: resto del programa


Se conocen dentro de los subprogramas que siguen

LuisHernndezYez

mbito de los datos locales: resto del subprograma


No se conocen fuera del subprograma

Visibilidad de los datos


Datos locales a un bloque ocultan otros externos homnimos
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 443

#include<iostream>
usingnamespace std;
const int MAX=100;
double ingresos;

LuisHernndezYez

...
void proc(){
int op;
double ingresos;
...
}
int main(){
int op;
...
return 0;
}

Datos globales

op de proc()
es distinta
de op de main()

Datos locales a proc()


Se conocen MAX (global), op (local)
e ingresos (local que oculta la global)

Datos locales a main()


Se conocen MAX (global), op (local)
e ingresos (global)

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 444

Sobre el uso de datos globales en los subprogramas

Excepciones:
Constantes globales (valores inalterables)
Tipos globales (necesarios en varios subprogramas)

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 445

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 446

LuisHernndezYez

LuisHernndezYez

NO SE DEBEN USAR datos globales en subprogramas


Necesidad de datos externos?
Define parmetros en el subprograma
Los datos externos se pasan como argumentos en la llamada
Uso de datos globales en los subprogramas:
Riesgo de efectos laterales
Modificacin inadvertida de esos datos afectando otros sitios

Datos de entrada, datos de salida y datos de entrada/salida


Datos de entrada: Aceptados

Subprograma

Subprograma que dado un nmero


muestra en la pantalla su cuadrado:

x
5

Datos de salida: Devueltos

Subprograma

Subprograma que dado un nmero


devuelve su cuadrado:

x
5

Datos de entrada/salida:
Aceptados y modificados
LuisHernndezYez

cuadrado()

cuadrado()

y (=x2)

Subprograma

Subprograma que dada una variable


numrica la eleva al cuadrado:

cuadrado()

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 447

Declaracin de parmetros
Slo dos clases de parmetros en C++:
Slo de entrada (por valor)
De salida (slo salida o E/S) (por referencia / por variable)

Lista de parmetros formales


Entre los parntesis de la cabecera del subprograma
tipo nombre(parmetros)

LuisHernndezYez

&

parmetros

De salida
identificador

tipo
,

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 448

Reciben copias de los argumentos usados en la llamada


int cuadrado(int num)
double potencia(double base,int exp)
void muestra(string nombre,int edad,string nif)
void proc(char c,int x,double a,bool b)

LuisHernndezYez

Reciben sus valores en la llamada del subprograma


Argumentos: Expresiones en general
Variables, constantes, literales, llamadas a funcin, operaciones
Se destruyen al terminar la ejecucin del subprograma
Atencin! Los arrays se pasan por valor como constantes:
double media(const tArray lista)

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 449

&
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 parmetros por valor en las funciones!
Slo en procedimientos
LuisHernndezYez

Puede haber tanto por valor como por referencia

Atencin! Los arrays se pasan por referencia sin utilizar &


void insertar(tArray lista,int&contador,doubleitem)

El argumento de lista (variable tArray) quedar modificado


Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 450

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 451

nombre(argumentos)

Tantos argumentos como parmetros y en el mismo orden


Concordancia de tipos argumentoparmetro
Por valor: Expresiones vlidas (se pasa el resultado)
Por referencia: Slo variables!
Se copian los valores de las expresiones pasadas por valor
en los correspondientes parmetros

LuisHernndezYez

Se hacen corresponder los argumentos pasados por referencia


(variables) con sus correspondientes parmetros

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 452

Expresiones vlidas con concordancia de tipo:


void proc(int x,double a)

proc(23 *4 /7,13.5);
double d=3;
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);

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 453

Memoria

void proc(int x,double a)


{...}

124

3.0

int main()

...

{
int i=124;
double d=3;
proc(i,33 *d);

LuisHernndezYez

...

...
x

124

99.0
...

return0;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 454

Memoria

void proc(int&x,double&a)
{...}

124

3.0

int main()

...

{
int i=124;
double d=3;
proc(i,d);

LuisHernndezYez

...
return0;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 455

Dadas las siguientes declaraciones:


int i;
doubled;
void proc(int x,double&a);

Qu pasos de argumentos son correctos? Por qu no?

proc(i,d);

proc(3*i+12,d);
proc(i,23);

proc(d,i);

proc(3.5,d);

proc(i);

LuisHernndezYez

proc(3,i,d);

N de argumentos N de para metros

Parmetro por referencia variable!


Argumento double para parmetro int!
Argumento double para parmetro int!
N de argumentos N de para metros

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 456

LuisHernndezYez

...
void divide(int op1,int op2,int&div,int&rem){
//Divideop1entreop2ydevuelveelcocienteyelresto
div =op1/op2;
rem=op1%op2;
}
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<<"dauncocientede"
<<cociente<<"yunrestode" <<resto<<endl;
}
}
return 0;
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 457

...
void divide(int op1,int op2,int&div,int&rem){
//Divideop1entreop2ydevuelveelcocienteyelresto
div =op1/op2;
Memoria
rem=op1%op2;
}
cociente
?

LuisHernndezYez

int main(){
int cociente,resto;
for (int j=1;j<=4;j++){
for (int i=1;i<=4;i++){
divide(i,j,cociente,resto);
...
}
}

resto

1
...

return 0;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 458

...
void divide(int op1,int op2,int&div,int&rem){
//Divideop1entreop2ydevuelveelcocienteyelresto
div =op1/op2;
Memoria
rem=op1%op2;
}
?
div cociente

LuisHernndezYez

int main(){
int cociente,resto;
for (int j=1;j<=4;j++){
for (int i=1;i<=4;i++){
divide(i,j,cociente,resto);
...
}
}

rem

resto

1
...

op1

op2

1
...

return 0;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 459

...
void divide(int op1,int op2,int&div,int&rem){
//Divideop1entreop2ydevuelveelcocienteyelresto
div =op1/op2;
Memoria
rem=op1%op2;
}
1
div cociente

LuisHernndezYez

int main(){
int cociente,resto;
for (int j=1;j<=4;j++){
for (int i=1;i<=4;i++){
divide(i,j,cociente,resto);
...
}
}

rem

resto

1
...

op1

op2

1
...

return 0;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 460

...
void divide(int op1,int op2,int&div,int&rem){
//Divideop1entreop2ydevuelveelcocienteyelresto
div =op1/op2;
Memoria
rem=op1%op2;
}
cociente
1

LuisHernndezYez

int main(){
int cociente,resto;
for (int j=1;j<=4;j++){
for (int i=1;i<=4;i++){
divide(i,j,cociente,resto);
...
}
}

resto

1
...

return 0;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 461

...
void intercambia(double&valor1,double&valor2){
//Intercambialosvalores
double tmp;//Variablelocal(temporal)
tmp=valor1;
Memoriatemporal
valor1=valor2;
delprocedimiento
valor2=tmp;
tmp
?
}

LuisHernndezYez

...

int main(){
double num1,num2;
Memoriademain()
cout<<"Valor1:";
cin>>num1;
valor1 num1
13.6
cout<<"Valor2:";
valor2 num2
317.14
cin>>num2;
...
intercambia(num1,num2);
cout<<"Ahoraelvalor1es" <<num1
<<"yelvalor2es" <<num2<<endl;
return 0;
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 462

LuisHernndezYez

...
//Prototipo
void cambio(double precio,double pago,int&euros,int&cent50,
int&cent20, int&cent10,int&cent5,int&cent2,int&cent1);
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<<"x50c.,"
<<cent20<<"x20c.," <<cent10<<"x10c.,"
<<cent5<<"x5c.," <<cent2<<"x2c.y"
<<cent1<<"x1c." <<endl;
return 0;
}

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 463

void cambio(double precio,double pago,int&euros,int&cent50,


int&cent20,int&cent10,int&cent5,int&cent2,int&cent1){
if (pago<precio){//Cantidadinsuficiente
cout<<"Error:Elpagoesinferioralprecio" <<endl;
}
else {
int cantidad=int(100.0 *(pago precio)+0.5);
euros=cantidad/100;
cantidad=cambio%100;
cent50=cantidad/50;
cantidad=cantidad%50;
Explicacin en el libro de
cent20=cantidad/20;
Adams/Leestma/Nyhoff
cantidad=cantidad%20;
cent10=cantidad/10;
cantidad=cantidad%10;
cent5=cantidad/5;
cantidad=cantidad%5;
cent2=cantidad/2;
cent1=cantidad%2;
}
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 464

En los subprogramas se pueden detectar errores


Errores que impiden realizar los clculos:
void cambio(double precio,double pago,int&euros,int&cent50,
int&cent20,int&cent10,int&cent5,int&cent2,int&cent1){
if (pago<precio){//Cantidadinsuficiente
cout<<"Error:Elpagoesinferioralprecio" <<endl;
}
...

LuisHernndezYez

Debe el subprograma notificar al usuario o al programa?


Mejor notificarlo al punto de llamada y all decidir qu hacer
void cambio(double precio,double pago,int&euros,int&cent50,
int&cent20,int&cent10,int&cent5,int&cent2,int&cent1,
bool&error){
if (pago<precio){//Cantidadinsuficiente
error=true;
}
else{
error=false;
...
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 465

cambio.cpp

LuisHernndezYez

Al volver de la llamada se decide qu hacer si ha habido error...


Informar al usuario?
Volver a pedir los datos?
Etctera
int main(){
double precio,pago;
int euros,cent50,cent20,cent10,cent5,cent2,cent1;
bool error;
cout<<"Precio:";
cin>>precio;
cout<<"Pago:";
cin>>pago;
cambio(precio,pago,euros,cent50,cent20,cent10,cent5,cent2,
cent1,error);
if (error){
cout<<"Error:Elpagoesinferioralprecio" <<endl;
}
else {
...
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 466

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 467

Una funcin ha de devolver un resultado


La funcin ha de terminar su ejecucin devolviendo el resultado
La instruccin return:
Devuelve el dato que se indica a continuacin como resultado
Termina la ejecucin de la funcin
El dato devuelto sustituye a la llamada de la funcin en la expresin
int cuad(int x){

int main(){

return x*x;

cout<<2 *cuad(16);

LuisHernndezYez

x=x*x;
}

Esta instruccin
no se ejecutar nunca

return 0;

256

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 468

factorial.cpp

Factorial(N)=1x2x3x...x(N2)x(N1)xN
longlong int factorial(int n);//Prototipo

LuisHernndezYez

int main(){
intnum;
cout<<"Num:";
cin>>num;
cout<<"Factorialde" <<num<<":" <<factorial(num)<<endl;
return 0;
}
longlong int factorial(int n){
longlong int fact =1;
if (n<0){
fact =0;
}
else{
for (inti=1;i<=n;i++){
fact =fact *i;
}
}
return fact;
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 469

LuisHernndezYez

int compara(int val1,int val2){


//1sival1<val2,0siiguales,+1sival1>val2
if (val1==val2){
return 0;
}
elseif (val1<val2){
return 1;
3 puntos de salida!
}
else{
return 1;
}
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 470

int compara(int val1,int val2){


//1sival1<val2,0siiguales,+1sival1>val2
int resultado;

LuisHernndezYez

if (val1==val2){
resultado=0;
}
elseif (val1<val2){
resultado=1;
}
else{
resultado=1;
}
return resultado;
}

Punto de salida nico

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 471

Procedimientos (tipo void):


Al encontrar la llave de cierre que termina el subprograma o
Al encontrar una instruccin return (sin resultado)
Funciones (tipo distinto de void):
SLO al encontrar una instruccin return (con resultado)

LuisHernndezYez

Nuestros subprogramas siempre terminarn al final:


No usaremos return en los procedimientos
Funciones: slo un return y estar al final
Para facilitar la depuracin y el mantenimiento,
codifica los subprogramas con un nico punto de salida

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 472

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 473

Dnde los ponemos? Antes de main()? Despus de main()?


Los pondremos despus de main()
Son correctas las llamadas a subprogramas?
En main() o en otros subprogramas
Existe el subprograma?
Concuerdan los argumentos con los parmetros?

LuisHernndezYez

Deben estar los prototipos de los subprogramas antes de main()


Prototipo: cabecera del subprograma terminada en ;
void dibujarCirculo();
void mostrarM();
void proc(double&a);
int cuad(int x);
...

main() es el nico subprograma


que no hay que prototipar

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 474

intercambia.cpp
#include<iostream>
usingnamespace std;
void intercambia(double&valor1,double&valor2);//Prototipo
int main(){
double num1,num2;
Asegrate de que los prototipos
cout<<"Valor1:";
cin>>num1;
coincidan con las implementaciones
cout<<"Valor2:";
cin>>num2;
intercambia(num1,num2);
cout<<"Ahoraelvalor1es" <<num1
<<"yelvalor2es" <<num2<<endl;
return 0;
}
LuisHernndezYez

void intercambia(double&valor1,double&valor2){
double tmp;//Variablelocal(temporal)
tmp=valor1;
valor1=valor2;
valor2=tmp;
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 475

mates.cpp
#include<iostream>
usingnamespace std;

longlong int factorial(int n){


longlong int fact =1;
if (n<0){
fact =0;
}
else{
for (inti=1;i<=n;i++){
fact =fact *i;
}
}

LuisHernndezYez

//Prototipos
longlong int factorial(int n);
int sumatorio(int n);
int main(){
intnum;
cout<<"Num:";
cin>>num;
cout<<"Factorialde"
<<num<<":"
<<factorial(num)
<<endl
<<"Sumatoriode1a"
<<num<<":"
<<sumatorio(num)
<<endl;

return fact;
}
int sumatorio(int n){
int sum =0;
for (inti=1;i<=n;i++){
sum =sum +i;
}

return 0;
}

return sum;
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 476

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 477

Notacin infija (de operador)


operandoIzquierdo operador operandoDerecho
a+b
Se ejecuta el operador con los operandos como argumentos
Los operadores se implementan como funciones:

LuisHernndezYez

tipo operatorsmbolo(parmetros)
Si es un operador monario slo habr un parmetro
Si es binario habr dos parmetros
El smbolo es un smbolo de operador (uno o dos caracteres):
+, , *, /, , <<, %, ...

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 478

tMatriz suma(tMatriz a,tMatriz b);


tMatriz a,b,c;
c=suma(a,b);
tMatriz operator+(tMatriz a,tMatriz b);
tMatriz a,b,c;
c=a+b;

Mayor aproximacin al lenguaje matemtico

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 479

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 480

LuisHernndezYez

LuisHernndezYez

La implementacin ser exactamente la misma!

Especificacin inicial (Paso 0).


Desarrollar un programa que haga operaciones de conversin
de medidas hasta que el usuario decida que no quiere hacer ms

LuisHernndezYez

Anlisis y diseo aumentando el nivel de detalle en cada paso


Qu operaciones de conversin?
Paso 1.
Desarrollar un programa que haga operaciones de conversin
de medidas hasta que el usuario decida que no quiere hacer ms
Pulgadas a centmetros
Libras a gramos
Grados Fahrenheit a centgrados
Galones a litros
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 481

LuisHernndezYez

Paso 2.
Desarrollar un programa que muestre al usuario un men con
cuatro operaciones de conversin de medidas:
Pulgadas a centmetros
Libras a gramos
Grados Fahrenheit a centgrados
Galones a litros
Y lea la eleccin del usuario y proceda con la conversin, hasta que
el usuario decida que no quiere hacer ms
6 grandes tareas:
Men, cuatro funciones de conversin y main()

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 482

Paso 2.

Conversiones

Pulgadasacm.

Librasagr.

FaC

Galonesal.

main()

LuisHernndezYez

Men

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 483

Paso 3.
Men:
Mostrar las cuatro opciones ms una para salir
Validar la entrada y devolver la elegida
Pulgadas a centmetros:
Devolver el equivalente en centmetros del valor en pulgadas
Libras a gramos:
Devolver el equivalente en gramos del valor en libras
Grados Fahrenheit a centgrados:
Devolver el equivalente en centgrados del valor en Fahrenheit
Galones a litros:
Devolver el equivalente en litros del valor en galones
Programa principal (main())

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 484

Paso 3. Cada tarea, un subprograma


Comunicacin entre los subprogramas:
Entrada

Salida

Valordevuelto

menu()

int

pulgACm()

double pulg

double

lbAGr()

double libras

double

grFAGrC()

double grF

double

galALtr()

double galones

double

main()

int

LuisHernndezYez

Funcin

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 485

Paso 4. Algoritmos detallados de cada subprograma Programar

LuisHernndezYez

#include<iostream>
usingnamespace std;
//Prototipos
int menu();
double pulgACm(double pulg);
double lbAGr(double libras);
double grFAGrC(double grF);
double galALtr(double galones);
int main(){
double valor;
int op =1;
while(op !=0){
op =menu();
switch(op){
case 1:
{
cout<<"Pulgadas:";
cin>>valor;
cout<<"Son" <<pulgACm(valor)<<"cm." <<endl;
}
. . .
break;
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 486

LuisHernndezYez

case 2:
{
cout<<"Libras:";
cin>>valor;
cout<<"Son" <<lbAGr(valor)<<"gr." <<endl;
}
break;
case 3:
{
cout<<"GradosFahrenheit:";
cin>>valor;
cout<<"Son" <<grFAGrC(valor)<<"C" <<endl;
}
break;
case 4:
{
cout<<"Galones:";
cin>>valor;
cout<<"Son" <<galALtr(valor)<<"l." <<endl;
}
break;
}
}
return 0;
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental

. . .
Pgina 487

int menu(){
int op =1;
while ((op <0)||(op >4)){
cout<<"1 PulgadasaCm."<<endl;
cout<<"2 LibrasaGr."<<endl;
cout<<"3 FahrenheitaC"<<endl;
cout<<"4 GalonesaL."<<endl;
cout<<"0 Salir"<<endl;
cout<<"Elige:";
cin>>op;
if ((op <0)||(op >4)){
cout<<"Opcinnovlida"<<endl;
}
}
returnop;
LuisHernndezYez

}
double pulgACm(double pulg){
const double cmPorPulg =2.54;
return pulg *cmPorPulg;
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental

. . .
Pgina 488

conversiones.cpp
double lbAGr(double libras){
constdouble grPorLb =453.6;
return libras*grPorLb;
}
double grFAGrC(double grF){
return ((grF 32)*5 /9);
}

LuisHernndezYez

double galALtr(double galones){


constdouble ltrPorGal =4.54609;
return galones*ltrPorGal;
}

. . .
Pgina 489

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 490

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Integridad de los subprogramas


Condiciones que se deben dar antes de comenzar su ejecucin
Precondiciones
Quien llame al subprograma debe garantizar que se satisfacen
Condiciones que se darn cuando termine su ejecucin
Postcondiciones
En el punto de llamada se pueden dar por garantizadas

LuisHernndezYez

Aserciones:
Condiciones que si no se cumplen interrumpen la ejecucin
Funcin assert()

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 491

Precondiciones
Por ejemplo, no realizaremos conversiones de valores negativos:
double pulgACm(double pulg){
assert(pulg >0);
double cmPorPulg =2.54;
return pulg *cmPorPulg;
}

LuisHernndezYez

La funcin tiene una precondicin: pulg debe ser positivo


assert(pulg >0); interrumpir la ejecucin si no es cierto

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 492

Precondiciones

LuisHernndezYez

Es responsabilidad del punto de llamada garantizar la precondicin:


int main(){
double valor;
int op =1;
while(op !=0){
op =menu();
switch(op){
case 1:
{
cout<<"Pulgadas:";
cin>>valor;
if (valor<0){
cout<<"Novlido!" <<endl;
}
else{ //Secumplelaprecondicin...
...
Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 493

Postcondiciones

LuisHernndezYez

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<<"Opcinnovlida"<<endl;
}
}
assert ((op >=0)&&(op <=4));
returnop;
}

El subprograma debe asegurarse de que se cumpla


Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 494

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 495

Fundamentosdelaprogramacin

4A
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

LuisHernndezYez

Archivoscomoparmetros
Lafuncinmain()
Argumentosimplcitos
Sobrecargadesubprogramas

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

498
501
504
508

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 498

#include<iostream>
usingnamespacestd;
#include<fstream>

LuisHernndezYez

voidsumatorio_archivo(ifstream&arch,double&suma);
int main(){
double resultado;
ifstream archivo;
archivo.open("datos.txt");
if (!archivo.is_open()){
cout<<"ERRORDEAPERTURA" <<endl;
}
else{
sumatorio_archivo(archivo,resultado)
cout<<"Suma=" <<resultado <<endl;
archivo.close();
}
return0;
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 499

void sumatorio_archivo(ifstream&arch,double&suma){
double dato;
suma =0;
arch>>dato;
while (dato !=1){
suma =suma +dato;
arch>>dato;
}
}

LuisHernndezYez

Los archivos siempre se pasan por referencia

Pgina 500

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 501

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Comunicacin con el sistema operativo


Parmetros opcionales de la funcin main():
int main(int argc,char*argv[])

LuisHernndezYez

Para obtener datos proporcionados al ejecutar el programa:


C:\>pruebacad1cad2cad3
Ejecuta prueba.exe con tres argumentos (cadenas)
Parmetros de main():
argc: nmero de argumentos que se proporcionan
4 en el ejemplo (primero: nombre del programa con su ruta)
argv: array con las cadenas proporcionadas como argumentos

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 502

Cmo ha ido la funcin?


La funcin main() devuelve al S.O. un cdigo de terminacin
0: Todo OK
Distinto de 0: Ha habido un error!
Si la ejecucin llega al final de la funcin main(), todo OK:
...
return 0;//Findelprograma

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 503

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 504

Valores predeterminados para parmetros por valor


Valor por defecto para un parmetro:
Tras un = a continuacin del nombre del parmetro:
void proc(int i=1);

Si no se proporciona argumento, el parmetro toma ese valor


proc(12);
i toma el valor explcito 12
proc();
i toma el valor implcito (1)
Slo puede haber argumentos implcitos en los parmetros finales:
LuisHernndezYez

void p(int i,int j=2,int k=3);//CORRECTO


void p(int i=1,int j,int k=3);//INCORRECTO
Unavezasignadounvalorimplcito,todoslosquesiguen
handetenertambinvalorimplcito
Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 505

Parmetros y argumentos implcitos


void p(int i,int j=2,int k=3);

Se copian los argumentos en los parmetros del primero al ltimo


los que no tengan correspondencia tomarn los implcitos
void p(int i,int j=2,int k=3);
...
p(13);//itoma13,jyksusvaloresimplcitos
p(5,7);//itoma5,jtoma7yksuvalorimplcito
LuisHernndezYez

p(3,9,12);//itoma3,jtoma9yktoma12
Los argumentos implcitos se declaran en el prototipo
(preferible) o en la cabecera del subprograma, pero NO en ambos
Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 506

Por defecto, signo +


Por defecto, es 1
#include<iostream>
usingnamespace std;
double f(double x,double y,int signo=1,double delta=1.0);
int main(){
double x,y;
No podemos dejar signo por defecto
cout<<"X=";
y concretar delta
cin>>x;
cout<<"Y=";
cin>>y;
cout<<"signoydeltapordefecto:" <<f(x,y)<<endl;
cout<<"signo1ydeltapordefecto:" <<f(x,y,1)<<endl;
cout<<"signoydeltaconcretos:" <<f(x,y,1,1.25)<<endl;

LuisHernndezYez

return 0;
}
double f(double x,double y,int signo,double delta){
return signo*delta*x/y;
}
Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 507

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 508

Igual nombre, distintos parmetros


Funciones o procedimientos con igual nombre y distintos parmetros:
int abs(int n);
double abs(double n);
longint abs(longint n);

Se ejecutar la funcin que corresponda al tipo de argumento:


abs(13)

//argumentoint>primerafuncin

abs(2.3) //argumentodouble>segundafuncin

LuisHernndezYez

abs(3L)

//argumentolongint>tercerafuncin

Para indicar que es un literal longint, en lugar de int

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 509

inter.cpp
#include<iostream>
usingnamespace std;
void intercambia(int&x,int&y);
void intercambia(double&x,
double&y);
void intercambia(char&x,char&y);

LuisHernndezYez

void intercambia(int&x,int&y){
int tmp;
tmp=x;
x=y;
y=tmp;
}
void intercambia(double&x,
double&y){
double tmp;
tmp=x;
x=y;
y=tmp;
}

void intercambia(char&x,char&y){
char tmp;
tmp=x;
x=y;
y=tmp;
}
int main(){
int i1=3,i2=7;
double d1=12.5,d2=35.9;
char c1='a',c2='b';
cout<<i1<<" " <<i2<<endl;
cout<<d1<<" " <<d2<<endl;
cout<<c1<<" " <<c2<<endl;
intercambia(i1,i2);
intercambia(d1,d2);
intercambia(c1,c2);
cout<<i1<<" " <<i2<<endl;
cout<<d1<<" " <<d2<<endl;
cout<<c1<<" " <<c2<<endl;
return 0;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 510

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 511

Fundamentosdelaprogramacin

5
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez/Pablo Moreno Ger

LuisHernndezYez/PabloMorenoGer

Facultad de Informtica
Universidad Complutense

Tiposdedatos
Arraysdenuevo
Arraysybuclesfor
Mssobrearrays
Inicializacindearrays
Enumeradoscomondices
Pasodearraysasubprogramas
Implementacindelistas
Cadenasdecaracteres
Cadenasdecaracteresdetipostring
Entrada/salidaconstring
Operacionesconstring
Estructuras
Estructurasdentrodeestructuras
Arraysdeestructuras
Arraysdentrodeestructuras
Listasdelongitudvariable
Unejemplocompleto
Elbucledo..while
Fundamentosdelaprogramacin:Tiposdedatosestructurados

514
517
520
522
523
524
525
528
531
535
539
541
543
549
550
551
552
558
562

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 514

Clasificacin de tipos
Simples

LuisHernndezYez/PabloMorenoGer

Estndar: int, float, double, char, bool


Conjunto de valores predeterminado
Definidos por el usuario: enumerados
Conjunto de valores definido por el programador

Estructurados

Colecciones homogneas: arrays


Todos los elementos del mismo tipo
Colecciones heterogneas: estructuras
Los elementos pueden ser de tipos distintos

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 515

Colecciones o tipos aglomerados


Agrupaciones de datos (elementos):
Todos del mismo tipo: array o tabla
De tipos distintos: estructura, registro o tupla
Elementos organizados por posicin: 0, 1, 2, 3, ...
Acceso por ndice: 0, 1, 2, 3, ...
Una o varias dimensiones

Estructuras (tuplas, registros)


Elementos (campos) sin orden establecido
Acceso por nombre
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 516

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 517

LuisHernndezYez/PabloMorenoGer

LuisHernndezYez/PabloMorenoGer

Arrays (tablas)

Estructura secuencial
Cada elemento se encuentra en una posicin (ndice):
Los ndices son enteros positivos
El ndice del primer elemento siempre es 0
Los ndices se incrementan de uno en uno

LuisHernndezYez/PabloMorenoGer

ventas 125.40
0

76.95
1

328.80 254.62 435.00 164.29


2

0.00

[]
Acceso directo
A cada elemento se accede a travs de su ndice:
ventas[4] accede al 5 elemento (contiene el valor 435.00)
cout<<ventas[4];
ventas[4]=442.75;

Datos de un mismo tipo base:


Se usan como cualquier variable

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 518

Declaracin de tipos de arrays


constint Dimensin =...;
typedef tipo_base tNombre[Dimensin];
Ejemplo:
constint Dias =7;
typedef double tVentas[Dias];
LuisHernndezYez/PabloMorenoGer

Declaracin de variables de tipos array: como cualquier otra


tVentas ventas;

NO se inicializan los elementos automticamente!


Es responsabilidad del programador usar ndices vlidos!
No se pueden copiar arrays directamente (array1=array2)
Hay que copiarlos elemento a elemento
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 519

Procesamiento de arrays
Recorridos
Bsquedas
Ordenacin

etctera...

Recorrido de arrays con bucles for


LuisHernndezYez/PabloMorenoGer

Arrays: tamao fijo Bucles de recorrido fijo (for)


tVentas ventas;
constint Dias =7;
double media,total=0;
typedef double tVentas[Dias];
...
for(int i=0;i<Dias;i++){
total=total+ventas[i];
}
media=total/Dias;

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 520

12.40

10.96

8.43

11.65

13.70

13.41

14.07

tVentas ventas;
double media,total=0;
...
for(int i=0;i<Dias;i++){
total=total+ventas[i];
}

Memoria

LuisHernndezYez/PabloMorenoGer

i=0
true

i<Dias

total+=ventas[i]

false

...

i++

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Dias

ventas[0]

12.40

ventas[1]

10.96

ventas[2]

8.43

ventas[3]

11.65

ventas[4]

13.70

ventas[5]

13.41

ventas[6]

14.07

media

total

84.62
23.36
31.79
12.40
0.00
43.44

3
2
70
4
1

Pgina 521

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 522

Podemos inicializar los elementos de los arrays en la declaracin


Asignamos una serie de valores al array:
const intDIM=10;
typedef inttTabla[DIM];
tTabla i={1,2,3,4,5,6,7,8,9,10};

Se asignan los valores por su orden:


LuisHernndezYez/PabloMorenoGer

i[0]i[1]i[2]i[3]i[4]...i[9]
1

5...10

Si hay menos valores que elementos, los restantes se ponen a 0


tTabla i={0};//Ponetodosloselementosa0

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 523

LuisHernndezYez/PabloMorenoGer

constintColores=3,
typedefenum{rojo,verde, azul}tRGB;
typedefint tColor[Colores];
tColor color;
...
cout<<"Cantidadderojo(0255):";
cin>>color[rojo];
cout<<"Cantidaddeverde(0255):";
cin>>color[verde];
cout<<"Cantidaddeazul(0255):";
cin>>color[azul];
Recuerda que internamente se asignan enteros a partir de 0
a los distintos smbolos del enumerado
rojo 0 verde 1 azul 2
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 524

Simulacin de paso de parmetro por referencia


Sin poner & en la declaracin del parmetro
Los subprogramas reciben la direccin en memoria del array
const intMax=10;
typedef inttTabla[Max];

LuisHernndezYez/PabloMorenoGer

void inicializa(tTabla tabla);//Sinponer&

Las modificaciones del array quedan reflejadas en el argumento


inicializa(array);

Si inicializa() modifica algn elemento de tabla,


automticamente queda modificado ese elemento de array

Son el mismo array!


Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 525

LuisHernndezYez/PabloMorenoGer

const intDim =10;


typedef inttTabla[Dim];
void inicializa(tTabla tabla);//noseusa&
void inicializa(tTabla tabla){
for (int i=0;i<Dim;i++)
tabla[i]=i;
}
intmain(){
tTabla array;
inicializa(array);//arrayquedamodificado
for (int i=0;i<Dim;i++)
cout<<array[i]<<"";
...
0123456789

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 526

Cmo evitar que se modifique el array?


Usando el modificador const en la declaracin del parmetro:
consttTabla tabla

Un array de constantes

void muestra(consttTabla tabla);

LuisHernndezYez/PabloMorenoGer

El argumento se tratar como un array de constantes


Si en el subprograma hay alguna instruccin que intente
modificar un elemento del array: error de compilacin
void muestra(consttTabla tabla){
for (int i=0;i<Dim;i++){
cout<<tabla[i]<<"";
//OK.Seaccede,peronosemodifica
}
}
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 527

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 528

Listas con un nmero fijo de elementos


Array con el n de elementos como dimensin
constint NUM=100;
typedefdoubletLista[NUM];//Exactamente100double
tLista lista;

LuisHernndezYez/PabloMorenoGer

Recorrido de la lista:
for(int i=0;i<NUM;i++){
...

Bsqueda en la lista:
while((i<NUM)&&!encontrado){
...

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 529

Listas con un nmero variable de elementos


Array con un mximo de elementos + Contador de elementos
constint MAX=100;
typedefdoubletLista[MAX];//Hasta100elementos
tLista lista;
int contador=0;//Seincrementaalinsertar
for(int i=0;i<contador;i++){
...

Bsqueda en la lista:
while((i<contador)&&!encontrado){
...
Array y contador por separado? Estructuras
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 530

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 531

LuisHernndezYez/PabloMorenoGer

LuisHernndezYez/PabloMorenoGer

Recorrido de la lista:

Arrays de caracteres
Cadenas: secuencias de caracteres de longitud variable

LuisHernndezYez/PabloMorenoGer

"Hola""Adis""Supercalifragilstico""1234567"

Variables de cadena: contienen secuencias de caracteres


Se guardan en arrays de caracteres: tamao mximo (dimensin)
No todas las posiciones del array son relevantes:
Longitud de la cadena: nmero de caracteres, desde el
primero, que realmente constituyen la cadena:
H

10

11

12

13

14

15

16

17

18

19

20

21

21

Longitud actual: 4
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 532

Longitud de la cadena
A

10

11

12

13

14

15

16

17

18

19

20

LuisHernndezYez/PabloMorenoGer

Longitud: 5
S

10

11

12

13

14

15

16

17

18

19

20

Longitud: 21
Necesidad de saber dnde terminan los caracteres relevantes:
Mantener la longitud de la cadena como dato asociado
Colocar un carcter de terminacin al final (centinela)
A

\0

Fundamentosdelaprogramacin:Tiposdedatosestructurados

10

Pgina 533

21

Cadenas de caracteres en C++

Cadenas al estilo de C
Anexo del tema
Arrays de tipo char con una longitud mxima
Un ltimo carcter especial al final: '\0'
Tipo string
Cadenas ms sofisticadas
Sin longitud mxima (gestin automtica de la memoria)
Multitud de funciones de utilidad (biblioteca string)
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 534

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 535

LuisHernndezYez/PabloMorenoGer

LuisHernndezYez/PabloMorenoGer

Dos alternativas para el manejo de cadenas:


Cadenas al estilo de C (terminadas en nulo)
Tipo string

El tipo string
El tipo asume la responsabilidad de la gestin de memoria
Define operadores sobrecargados (+ para concatenar)
Cadenas ms eficientes y seguras de usar

LuisHernndezYez/PabloMorenoGer

Biblioteca string
Requiere establecer el espacio de nombres a std

Se pueden inicializar en la declaracin


Se pueden copiar con el operador de asignacin
Se pueden concatenar con el operador +
Multitud de funciones de utilidad

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 536

string.cpp

LuisHernndezYez/PabloMorenoGer

#include<iostream>
#include<string>
usingnamespacestd;
int main(){
string cad1("Hola");//inicializacin
string cad2="amigo";//inicializacin
string cad3;
cad3=cad1;//copia
cout<<"cad3=" <<cad3<<endl;
cad3=cad1+"";//concatenacin
cad3+=cad2;//concatenacin
cout<<"cad3=" <<cad3<<endl;
cad1.swap(cad2);//intercambio
cout<<"cad1=" <<cad1<<endl;
cout<<"cad2=" <<cad2<<endl;
return 0;
}
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 537

Longitud de la cadena:
cadena.length() o cadena.size()

Se pueden comparar con los operadores relacionales:

LuisHernndezYez/PabloMorenoGer

if(cad1<=cad2){...

Acceso a los caracteres de una cadena:


Como array de caracteres: cadena[i]
Sin control de acceso a posiciones inexistentes del array
Slo debe usarse si se est seguro de que el ndice es vlido
Funcin at(ndice): cadena.at(i)
Error de ejecucin si se accede a una posicin inexistente

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 538

Se muestran en la pantalla con cout<<


Lectura con cin>>: termina con espacio en blanco (inc. Intro)
El espacio en blanco queda pendiente
Descartar el resto de los caracteres del bfer:
cin.sync();

Lectura incluyendo espacios en blanco:


LuisHernndezYez/PabloMorenoGer

getline(cin,cadena)

Guarda en la cadena los caracteres ledos hasta el fin de lnea


Lectura de archivos de texto:
Igual que de consola; sync() no tiene efecto
archivo>>cadenagetline(archivo,cadena)

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 539

string2.cpp

LuisHernndezYez/PabloMorenoGer

#include<iostream>
#include<string>
usingnamespacestd;
int main(){
string nombre,apellidos;
cout<<"Introduzcaunnombre:";
cin>>nombre;
cout<<"Introduzcalosapellidos:";
cin.sync();
getline(cin,apellidos);
cout<<"Nombrecompleto:" <<nombre<<""
<<apellidos<<endl;
return 0;
}

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 540

cadena.substr(posicin,longitud)
Subcadena de longitud caracteres desde posicin
string cad ="abcdefg";
cout<<cad.substr(2,3);//Muestracde

LuisHernndezYez/PabloMorenoGer

cadena.find(subcadena)
Posicin de la primera ocurrencia de subcadena en cadena
string cad ="Olala";
cout<<cad.find("la");//Muestra1
(Recuerda que los arrays de caracteres comienzan con el ndice 0)

cadena.rfind(subcadena)
Posicin de la ltima ocurrencia de subcadena en cadena
string cad ="Olala";
cout<<cad.rfind("la");//Muestra3
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 541

cadena.erase(ini,num)
Elimina num caracteres a partir de la posicin ini
string cad ="abcdefgh";
cad.erase(3,4);//cad ahoracontiene"abch"

cadena.insert(ini,cadena2)
Inserta cadena2 a partir de la posicin ini

http://www.cplusplus.com/reference/string/string/

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 542

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 543

LuisHernndezYez/PabloMorenoGer

LuisHernndezYez/PabloMorenoGer

string cad ="abcdefgh";


cad.insert(3,"123");//cad ahoracontiene"abc123defgh"

Colecciones heterogneas (tuplas, registros)

LuisHernndezYez/PabloMorenoGer

Elementos de (posiblemente) distintos tipos: campos


Campos identificados por su nombre
Informacin relacionada que se puede manejar como una unidad
Acceso a cada elemento por su nombre de campo (operador.)

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 544

typedefstruct {
...//declaracionesdecampos(comovariables)
}tTipo;//nombredetipo alfinal!

LuisHernndezYez/PabloMorenoGer

typedefstruct {
string nombre;
string apellidos;
int edad;
string nif;
}tPersona;

Campos:
Tipos estndar o previamente declarado

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 545

tPersona persona;

Las variables de tipo tPersona contienen cuatro datos (campos):


nombre

apellidos

edad

nif

Acceso a los campos con el operador punto (.):


persona.nombre //unacadena(string)

LuisHernndezYez/PabloMorenoGer

persona.apellidos //unacadena(string)
persona.edad
//unentero(int)
persona.nif //unacadena(string)

Podemos copiar dos estructuras directamente:


tPersona persona1,persona2;
...
persona2=persona1;

Se copian todos los campos a la vez


Fundamentosdelaprogramacin:Tiposdedatosestructurados

typedefstruct {
string nombre;
string apellidos;
int edad;
string nif;
}tPersona;
tPersona persona;

Pgina 546

Memoria

persona.nombre

Luis
Antonio

persona.apellidos

Hernndez
Yez

LuisHernndezYez/PabloMorenoGer

persona
nombre LuisAntonio
apellidos HernndezYez
edad

22

persona.edad

22

persona.nif

00223344F

nif 00223344F

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 547

LuisHernndezYez/PabloMorenoGer

typedefstruct {
string nombre;
string apellidos;
int edad;
string nif;
}tPersona;
tPersona persona;

Los campos no siguen ningn orden establecido


Acceso directo por nombre de campo (operador .)
Con cada campo se puede hacer lo que permita su tipo
Las estructuras se pasan por valor (sin &)
o por referencia (con &) a los subprogramas

Fundamentosdelaprogramacin:Tiposdedatosestructurados

typedefstruct {
stringdni;
char letra;
} tNif;

typedefstruct {
...
tNif nif;
}tPersona;

tPersona persona;

tPersona

Acceso al NIF completo:

apellidos

persona.nif //Otraestructura
LuisHernndezYez/PabloMorenoGer

Pgina 548

Acceso a la letra del NIF:


persona.nif.letra

nombre

edad

tNif

nif
dni
letra

Acceso al DNI:
persona.nif.dni

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 549

personal

LuisHernndezYez/PabloMorenoGer

tPersona
const intDIM =100;
typedefstruct {
nombre
string nombre;
apellidos
string apellidos;
edad
int edad;
nif
string nif;
}tPersona;
typedeftPersona tArray[DIM];
tArray personal;

nombre

edad
nif
nombre

apellidos
edad
nif
nombre

apellidos
edad
nif

Nombre de la tercera persona:


personal[2].nombre

nombre

Edad de la duodcima persona:

DIM1

apellidos
edad
nif

personal[11].edad

NIF de la primera persona:


personal[0].nif
Fundamentosdelaprogramacin:Tiposdedatosestructurados

LuisHernndezYez/PabloMorenoGer

apellidos

const intMAX=100;
lista
typedefstruct {
string nombre;
string apellidos;
int edad;
string nif;
}tPersona;
typedeftPersona tArray[MAX];
typedefstruct {
tArray elementos;
int contador;
}tLista;
tLista lista;

Pgina 550

elementos
0

nombre
apellidos
edad
nif

nombre
apellidos
edad
nif

nombre
apellidos
edad
nif

MAX1

nombre
apellidos
edad
nif

contador

Nombre de la tercera persona: lista.elementos[2].nombre


Edad de la duodcima persona: lista.elementos[11].edad
NIF de la primera persona: lista.elementos[0].nif
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 551

LuisHernndezYez/PabloMorenoGer
/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 552

Estructura que agrupe el array y el contador:


const intMAX=10;
typedefdoubletArray[MAX];
typedefstruct {
tArray elementos;
int contador;
}tLista;

Elementos sin usar


(datos basura)

LuisHernndezYez/PabloMorenoGer

elementos
12.0

2.2

5.4

0.0

36.2

35.0

contador

6
N de elementos (y primer ndice sin elemento)

Operaciones principales: insercin y eliminacin de elementos


Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 553

Insertar un nuevo elemento en una posicin


Posiciones vlidas: 0 a contador
42.0
nuevo

LuisHernndezYez/PabloMorenoGer

3
pos

12.0 2.2
0

5.4

0.0

36.2 35.0
4

Hay que asegurarse de que haya sitio (contador < mximo)


Operacin en 3 pasos:
1. Abrir hueco para el nuevo elemento (desde la posicin)
2. Colocar el elemento nuevo en la posicin
3. Incrementar el contador
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 554

LuisHernndezYez/PabloMorenoGer

if(lista.contador<N){
//Abrirhueco
for(int i=lista.contador;i>pos;i){
lista.elementos[i]=lista.elementos[i 1];
}
//Insertareincrementarcontador
lista.elementos[pos]=nuevoElemento;
lista.contador++;
}
42.0
nuevo
3
pos

12.0 2.2
0

5.4

42.0

0.0

36.2 35.0
5

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 555

Eliminar el elemento en una posicin


Posiciones vlidas: 0 a contador1
12.0 2.2
3
pos

5.4

0.0

36.2 35.0
4

LuisHernndezYez/PabloMorenoGer

Desplazar a la izquierda desde el siguiente y decrementar el contador:


for(int i=pos;i<lista.contador 1;i++){
lista.elementos[i]=lista.elementos[i+1];
}
lista.contador;

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 556

for(int i=pos;i<lista.contador 1;i++){


lista.elementos[i]=lista.elementos[i+1];
}
lista.contador;

LuisHernndezYez/PabloMorenoGer

12.0 2.2
3

pos

12.0 2.2
3

pos

5.4

0.0

5.4
2

36.2 35.0
4

36.2 35.0 35.0


3

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 557

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 558

LuisHernndezYez/PabloMorenoGer

Descripcin
Programa que mantenga una lista de los estudiantes de una clase
De cada estudiante: nombre, apellidos, edad, NIF y nota
Se desconoce el nmero total de estudiantes (mximo 100)
La informacin 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:
Aadir un nuevo alumno
Eliminar un alumno existente
Calificar a los estudiantes
Listado de notas, identificando la mayor y la media

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 559

bd.cpp

LuisHernndezYez/PabloMorenoGer

#include<iostream>
#include<string>
usingnamespacestd;
#include<fstream>
#include<iomanip>
const int MAX=100;
typedef struct {
string nombre;
string apellidos;
int edad;
string nif;
double nota;
} tEstudiante;
typedef tEstudiantetArray[MAX];
typedef struct{
tArray elementos;
int contador;
} tLista;

Declaraciones de constantes
y tipos globales
Tras las bibliotecas

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 560

//Prototipos
int menu();//Mendelprograma devuelvelaopcinelegida
void cargar(tLista&lista,bool &ok); //Cargadelarchivo
void guardar(consttLista&lista); //Laguardaenelarchivo
void leerEstudiante(tEstudiante&estudiante);//Leelosdatos
void insertarEstudiante(tLista&lista,tEstudianteestudiante,
bool &ok);//Insertaunnuevoestudianteenlalista
void eliminarEstudiante(tLista&lista,intpos,bool &ok);
//Eliminaelestudianteenesaposicin
string nombreCompleto(tEstudiante estudiante);
void calificar(tLista&lista); //Notasdelosestudiantes
doublemediaClase(consttLista &lista); //Notamedia
intmayorNota(consttLista &lista);
//ndicedelestudianteconmayornota
voidmostrarEstudiante(tEstudiante estudiante);
voidlistado(consttLista &lista,doublemedia,intmayor);
//Listadodelaclase
Los prototipos, despus de los tipos globales
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 561

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 562

El bucle do..while
do cuerpo while(condicin);

LuisHernndezYez/PabloMorenoGer

do

cuerpo

while

Condicin al final del bucle


condicin

int i=1;
do {
cout<<i<<endl;
i++;
}while(i<=100);
El cuerpo siempre se ejecuta al menos una vez
El cuerpo es un bloque de cdigo

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 563

int i=1;
do {
cout<<i<<endl;
i++;
}while(i<=100);

Cuerpo
true

Condicin
false

LuisHernndezYez/PabloMorenoGer

i=1;

cout<<i<<endl;
i++;
true

El cuerpo
se ejecuta
al menos
una vez

i<=100
false

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 564

LuisHernndezYez/PabloMorenoGer

Ha de ejecutarse al menos una vez el cuerpo del bucle?


cin>>d;//Lecturadel1
while(d!=0){
suma=suma+d;
cont++;
cin>>d;
}

do {
cin>>d;
if(d!=0){//Final?
suma=suma+d;
cont++;
}
}while (d!=0);

cout<<"Opcin:";
cin>>op; //Lecturadel1
while((op <0)||(op >4)){
cout<<"Opcin:";
cin>>op;
}

do {//Mssimple
cout<<"Opcin:";
cin>>op;
}while ((op <0)||(op >4));

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 565

LuisHernndezYez/PabloMorenoGer

int menu(){
int op;
do {
cout<<"1 Aadirunnuevoestudiante"<<endl;
cout<<"2 Eliminarunestudiante"<<endl;
cout<<"3 Calificaralosestudiantes"<<endl;
cout<<"4 Listadodeestudiantes"<<endl;
cout<<"0 Salir"<<endl;
cout<<"Opcin:";
cin>>op;
}while((op <0)||(op >4));
return op;
}

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 566

LuisHernndezYez/PabloMorenoGer

El archivo clase.txt
Un dato en cada lnea
Por cada estudiante:
Nombre (cadena)
Apellidos (cadena)
Edad (entero)
NIF (cadena)
Nota (real; 1 si no calificado)
Termina con XXX como nombre

El archivo se supone correcto

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 567

Lectura de la informacin de un estudiante


Nombre y apellidos:
Puede haber varias palabras getline()
Edad extractor (>>)
NIF: Una sola palabra extractor (>>)
LuisHernndezYez/PabloMorenoGer

Nota extractor (>>)


Queda pendiente de leer el Intro
Hay que saltar (leer) ese carcter con get()
Si no, en el siguiente nombre se leera una cadena vaca (Intro)
No leas directamente en la lista:
getline(archivo,lista.elementos[lista.contador].nombre);

Lee en una variable auxiliar de tipo tEstudiante

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 568

void cargar(tLista&lista,bool &ok){


tEstudiante estudiante;//Variableauxiliarparaleer
ifstream archivo;
char aux;
lista.contador=0;//Inicializamoslalista
archivo.open("clase.txt");
if (!archivo.is_open()){
ok=false;
}
else {
ok=true;
getline(archivo,estudiante.nombre);//Leemoselprimernombre
while ((estudiante.nombre!="XXX")&&(lista.contador<MAX)){
getline(archivo,estudiante.apellidos);
archivo>>estudiante.edad;
archivo>>estudiante.nif;
archivo>>estudiante.nota;
archivo.get(aux);//SaltamoselIntro
lista.elementos[lista.contador]=estudiante;//Alfinal
lista.contador++;
getline(archivo,estudiante.nombre);//Siguientenombre
}//SihaymsdeMAXestudiantes,ignoramoselresto
archivo.close();
}
}
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 569

LuisHernndezYez/PabloMorenoGer

Simplemente, un dato en cada lnea y en orden:


void guardar(consttLista&lista){
ofstream archivo;
archivo.open("clase.txt");
for (int i=0;i<lista.contador;i++){
archivo<<lista.elementos[i].nombre<<endl;
archivo<<lista.elementos[i].apellidos<<endl;
archivo<<lista.elementos[i].edad<<endl;
archivo<<lista.elementos[i].nif <<endl;
archivo<<lista.elementos[i].nota<<endl;
}
archivo<<"XXX" <<endl; //Centinelafinal
archivo.close();
}
consttLista&lista Referencia constante
Paso por referencia pero como constante Paso por valor
Evita la copia del argumento en el parmetro (estructuras grandes)

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 570

void leerEstudiante(tEstudiante&estudiante){
cin.sync(); //Descartamoscualquierentradapendiente
cout<<"Nombre:";
getline(cin,estudiante.nombre);
cout<<"Apellidos:";
getline(cin,estudiante.apellidos);
cout<<"Edad:";
cin>>estudiante.edad;
cout<<"NIF:";
cin>>estudiante.nif;
estudiante.nota=1;//Sincalificardemomento
cin.sync(); //Descartamoscualquierentradapendiente
}

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 571

LuisHernndezYez/PabloMorenoGer

voidinsertarEstudiante(tLista&lista,tEstudianteestudiante,
bool&ok){
ok=true;
if(lista.contador==MAX){
ok=false;
}
else {
lista.elementos[lista.contador]=estudiante;
//Insertamosalfinal
lista.contador++;
}
}

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 572

LuisHernndezYez/PabloMorenoGer

voideliminarEstudiante(tLista&lista,intpos,bool&ok){
//Esperaelndicedelelementoenpos
if((pos<0)||(pos>lista.contador 1)){
ok=false;//Elementoinexistente
}
else {
ok=true;
for(int i=pos;i<lista.contador 1;i++){
lista.elementos[i]=lista.elementos[i+1];
}
lista.contador;
}
}

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 573

string nombreCompleto(tEstudiante estudiante){


return estudiante.nombre+"" +estudiante.apellidos;
}

LuisHernndezYez/PabloMorenoGer

voidcalificar(tLista&lista){
for(int i=0;i<lista.contador;i++){
cout<<"Notadelestudiante"
<<nombreCompleto(lista.elementos[i])<<":";
cin>>lista.elementos[i].nota;
}
}

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 574

LuisHernndezYez/PabloMorenoGer

double mediaClase(consttLista &lista){


double total=0.0;
for(int i=0;i<lista.contador;i++){
total=total+lista.elementos[i].nota;
}
return total/lista.contador;
}
int mayorNota(consttLista &lista){
double max =0;
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;
}
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 575

LuisHernndezYez/PabloMorenoGer

void mostrarEstudiante(tEstudiante estudiante){


cout<<setw(35)<<left <<nombreCompleto(estudiante);
cout<<estudiante.nif<<"";
cout <<setw(2)<<estudiante.edad<<"aos";
cout<<fixed <<setprecision(1)<<estudiante.nota;
}
void listado(consttLista &lista,double media,int mayor){
for(int i=0;i<lista.contador;i++){
cout<<setw(3)<<i<<":";
mostrarEstudiante(lista.elementos[i]);
if(i==mayor){
cout<<"<<<Mayornota!";
}
cout<<endl;
}
cout<<"Mediadelaclase:"<<fixed <<setprecision(1)
<<media<<endl<<endl;
}
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 576

LuisHernndezYez/PabloMorenoGer

int main(){
tLista lista;
tEstudiante estudiante;
bool exito;
int op,pos;
cargar(lista,exito);
if (!exito){
cout<<"Nosehapodidocargarlalista!" <<endl;
}
else {
do {//Elbucledoevitatenerqueleeranteslaprimeraopcin
op =menu();
switch(op){
case1:
{
leerEstudiante(estudiante);
insertarEstudiante(lista,estudiante,exito);
if(!exito){
cout<<"Listallena:imposibleinsertar" <<endl;
}
}
break;
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 577

LuisHernndezYez/PabloMorenoGer

case2:
{
cout<<"Posicin:";
cin>>pos;
eliminarEstudiante(lista,pos 1,exito);
if(!exito){
cout<<"Elementoinexistente!" <<endl;
}
}
break;
case3:
{
calificar(lista);
}
break;
case4:
{
listado(lista,mediaClase(lista),mayorNota(lista));
}
}
}while(op !=0);
guardar(lista);
}
return 0;
}
Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 578

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:

LuisHernndezYez/PabloMorenoGer

Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.
No comercial (Non commercial):
La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 579

Fundamentosdelaprogramacin

5A
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez/Pablo Moreno Ger

Facultad de Informtica
Universidad Complutense

LuisHernndezYez/PabloMorenoGer

CadenasalestilodeC
E/SconcadenasalestilodeC
Labibliotecacstring
Ejemplo

Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo)

582
583
584
585

Arrays de caracteres terminados en nulo


constMax=15;
typedefchar tCadena[Max];
tCadena cadena="Adis";//Inicializacinaldeclarar

Siempre hay al final un carcter nulo (cdigo ASCII 0 '\0')


Indica que en esa posicin termina la cadena (exclusive)

LuisHernndezYez/PabloMorenoGer

cadena

\0

10

11

12

13

14

En el array caben MAX1 caracteres significativos


Longitud mxima de la variable cadena: 14
No se pueden asignar cadenas literales: cadena="Hola";
Ni copiar cadenas directamente: cad2=cad1;
Ni comparar con op. relacionales: if(cad1<cad2)...
Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo)

Pgina 582

tCadena cadena;
cin>>cadena;//Seaadeunnuloalfinal

Extractor: la lectura termina en el primer espacio en blanco


No se comprueba si se leen ms caracteres de los que caben!
setw(): mximo de caracteres a colocar (incluyendo el nulo)

LuisHernndezYez/PabloMorenoGer

cin>>setw(15)>>cadena;

cin.getline(cadena_estilo_C,mx):
Para leer tambin los espacios en blanco y no ms de mx1
cin.getline(cadena,15);//Hasta14caracteres
cout<<cadena<<endl;//Elnulonosemuestra
cin.getline(cad,mx) Cadenas al estilo de C
getline(cin,cad)
Cadenas de tipo string
Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo)

Pgina 583

strlen(cadena): longitud actual de la cadena


cout<<"Longitud:" <<strlen(cadena);
strcpy(destino,origen): copia origen en destino
strcpy(cad2,cad1); strcpy(cad,"MegustaC++");

LuisHernndezYez/PabloMorenoGer

strcat(destino,origen): aade origen al final de destino


tCadena cad1="Hola",cad2="Adis";
strcat(cad1,cad2);//cad1contiene"HolaAdis"
strcmp(cad1,cad2): compara lexicogrficamente las cadenas
0 si son iguales, 1 si cad1 > cad2 1 si cad1 < cad2
tCadena cad1="Hola",cad2="Adis";
strcmp(cad1,cad2)//Devuelve1("Hola">"Adis")
. . .
http://www.cplusplus.com/reference/clibrary/cstring/

Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo)

Pgina 584

cadenas.cpp

LuisHernndezYez/PabloMorenoGer

#include<iostream>
usingnamespacestd;
#include<cstring>
int main(){
const int MAX=20;
typedef chartCad[MAX];
tCad cadena="MegustaC++";
cout<<cadena<<endl;
cout<<"Cadena:";
cin>>cadena;//Leehastaelprimerespacioenblanco
cout<<cadena<<endl;
cin.sync();//Sincronizarlaentrada
cout<<"Cadena:";
cin.getline(cadena,MAX);
cout<<cadena<<endl;
cout<<"Longitud:" <<strlen(cadena)<<endl;
strcpy(cadena,"Hola");
...
Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo)

Pgina 585

LuisHernndezYez/PabloMorenoGer

tCad cadena2="amigo";
strcat(cadena,cadena2);
cout<<cadena<<endl;
if(strcmp(cadena,cadena2)==0){
cout<<"Iguales";
}
elseif(strcmp(cadena,cadena2)>0){
cout<<cadena<<"esmayorque" <<cadena2;
}
else{
cout<<cadena<<"esmenorque" <<cadena2;
}
cout<<endl;
return 0;
}

Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo)

Pgina 586

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:

LuisHernndezYez/PabloMorenoGer

Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.
No comercial (Non commercial):
La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo)

Pgina 587

Fundamentosdelaprogramacin

6
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez / Pablo Moreno Ger

LuisHernndezYez

Facultad de Informtica
Universidad Complutense

Recorridodearrays
Arrayscompletos
Arraysnocompletosconcentinela
Arraysnocompletosconcontador
Ejemplos
Generacindenmerosaleatorios
Bsquedasenarrays
Arrayscompletos
Arraysnocompletosconcentinela
Arraysnocompletosconcontador
Ejemplo
Recorridosybsquedasencadenas
Msejemplosdemanejodearrays
Arraysmultidimensionales
Inicializacindearraysmultidimensionales
Recorridodeunarraybidimensional
RecorridodeunarrayNdimensional
Bsquedaenunarraymultidimensional

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

590
593
594
595
597
601
604
606
607
608
610
614
617
630
638
641
644
647

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 590

Esquema de recorrido
Inicializacin

Inicializacin

Mientras no al final de la secuencia:


Obtener el siguiente elemento
Procesar el elemento
Finalizacin

Al final?

true

false
Obtener elemento

LuisHernndezYez

Procesar elemento

Finalizacin

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 591

Recorrido de secuencias en arrays

LuisHernndezYez

Todas las posiciones ocupadas:


Tamao del array = longitud de la secuencia
N elementos en un array de N posiciones:
Recorrer el array desde la primera posicin hasta la ltima
Posiciones libres al final del array:
Tamao del array > longitud de la secuencia
Con centinela:
Recorrer el array hasta encontrar el valor centinela
Con contador de elementos:
Recorrer el array hasta el ndice contador 1

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 592

Recorrido de arrays completos


Todas las posiciones del array ocupadas
const intN=10;
typedef doubletVentas[N];
tVentas ventas;
...

LuisHernndezYez

ventas

125.40

76.95

328.80 254.62 435.00 164.29 316.05

219.99

93.45

756.62

double elemento;
for(int i=0;i<N;i++){
elemento=ventas[i];
//Procesarelelemento...
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 593

Recorrido de arrays no completos con centinela


No todas las posiciones del array estn ocupadas
const intN=10;
typedef doubletArray[N];
tArray datos;//Datospositivos:centinela=1
...
datos 125.40

76.95

LuisHernndezYez

328.80 254.62 435.00 164.29 316.05

int i=0;
double elemento=datos[i];
while(elemento!=1){
//Procesarelelemento...
i++;
elemento=datos[i];
}

1.0

int i=0;
double elemento;
do {
elemento=datos[i];
if(elemento!=1){
//Procesarelelemento...
i++;
}
}while(elemento!=1);

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 594

Recorrido de arrays no completos con contador


Array y contador ntimamente relacionados: estructura
const intN=10;
typedefdoubletArray[N];
typedefstruct {
tArray elementos;
int contador;
}tLista;

Listas de elementos de longitud variable

LuisHernndezYez

elementos
125.40

76.95

328.80

254.62

435.00

164.29

316.05

contador

7
N de elementos (primer ndice sin elemento)

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 595

const intN=10;
typedefdoubletArray[N];
typedefstruct {
tArray elementos;
int contador;
}tLista;
tLista lista;
...
double elemento;
for(int i=0;i<lista.contador;i++){
elemento=lista.elementos[i];
//Procesarelelemento...
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 596

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 597

LuisHernndezYez

LuisHernndezYez

Recorrido de arrays no completos con contador

fibonacci.cpp

LuisHernndezYez

Array con los N primeros nmeros de Fibonacci


const intN=50;
typedef longlong inttFibonacci[N];//50nmeros
tFibonacci fib;
fib[0]=1;
fib[1]=1;
for(inti=2;i<N;i++){
fib[i]=fib[i 1]+fib[i 2];
}
for(inti=0;i<N;i++){
cout<<fib[i]<<"";
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 598

Cuenta de valores con k dgitos


Recorrer una lista de N enteros contabilizando cuntos son
de 1 dgito, cuntos de 2 dgitos, etctera (hasta 5 dgitos)
2 arrays: array con los nmeros y array de contadores

LuisHernndezYez

const intNUM=100;
typedef inttNum[NUM];//Exactamente100nmeros
tNum numeros;
const intDIG =5;
typedef inttDig[DIG];//i>nmerosdei+1dgitos
tDig numDig ={0 };
numeros
numDig

123

46237

2345

236

11234

33

999

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

...

61
99

Pgina 599

Cuenta de valores con k dgitos

LuisHernndezYez

Funcin que devuelve el nmero de dgitos de un entero:


int digitos(int dato){
int n_digitos =1;//Almenostieneundgito
//Recorremoslasecuenciadedgitos...
while (dato>=10){
dato=dato/10;
n_digitos++;
}
return n_digitos;
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 600

Generacin de nmeros pseudoaleatorios

LuisHernndezYez

Probemos con una secuencia de enteros generada aleatoriamente


Funcin rand() (cstdlib): entero aleatorio entre 0 y 32766
srand() (cstdlib): inicia la secuencia de nmeros aleatorios
Acepta un entero que usa como semilla para iniciar la secuencia
Qu valor usar? Uno distinto en cada ejecucin
El instante de tiempo actual (diferente cada vez)
Funcin time() (ctime): segundos transcurridos desde 1970
Requiere un argumento, que en nuestro caso ser NULL
srand(time(NULL));//Inicialasecuencia
...
numeros[0]=rand();//Entre0y32766

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 601

digitos.cpp

Cuenta de valores con k dgitos


#include<iostream>
usingnamespacestd;
#include<cstdlib>//srand()yrand()
#include<ctime>//time()

LuisHernndezYez

int digitos(int dato);


int main(){
const intNUM=100;
typedef inttNum[NUM];//Exactamente100nmeros
const intDIG =5;
typedef inttDig[DIG];
tNum numeros;
tDig numDig ={0 };//Inicializatodoelarraya0
srand(time(NULL)); //Inicialasecuenciaaleatoria
...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 602

for (int i=0;i<NUM;i++){//Creamoslasecuencia


numeros[i]=rand();//Entre0y32766
}

LuisHernndezYez

for (int i=0;i<NUM;i++){


//Recorremoslasecuenciadeenteros
numDig[digitos(numeros[i]) 1]++;
}
for (int i=0;i<DIG;i++){
//Recorremoslasecuenciadecontadores
cout<<"De"<<i+1 <<"dg.="<<numDig[i]
<<endl;
}
return 0;
}
int digitos(int dato){
...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 603

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 604

Esquema de bsqueda
Inicializacin
Mientras no se encuentre el elemento
y no se est al final de la secuencia:

Inicializacin / encontrado=false;

Al final o
encontrado?

Obtener el siguiente elemento

false

Comprobar si el elemento
satisface la condicin

Obtener elemento

LuisHernndezYez

Finalizacin
(tratar el elemento encontrado
o indicar que no se ha encontrado)

Encontrado?

Finalizacin

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 605

true

LuisHernndezYez

Todas las posiciones ocupadas

const intN=100;
typedef inttArray[N];
tArray lista;

int buscado;
bool encontrado=false;
cout<<"Valorabuscar:";
cin>>buscado;
int pos=0;
while((pos<N)&&!encontrado){
//Mientrasnoselleguealfinalynoencontrado
if(lista[pos]==buscado){
encontrado=true;
}
else{
pos++;
}
}
if(encontrado)//...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 606

Con centinela

LuisHernndezYez

const intN=10;
typedef inttArray[N];
tArray array;
constint centinela=1;

int buscado;
cout<<"Valorabuscar:";
cin>>buscado;
int pos=0;
bool encontrado=false;
while((array[pos]!=centinela)&&!encontrado){
if(array[pos]==buscado){
encontrado=true;
}
else{
pos++;
}
}
if(encontrado)//...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 607

LuisHernndezYez

Con contador

const intN=10;
typedefdoubletArray[N];
typedefstruct {
tArray elementos;
int contador;
}tLista;
tLista miLista;

int buscado;
cout<<"Valorabuscar:";
cin>>buscado;
int pos=0;
bool encontrado=false;
while((pos<miLista.contador)
&&!encontrado){
//Mientrasnoalfinalynoencontrado
if(miLista.elementos[pos]==buscado){
encontrado=true;
}
else{
pos++;
}
}
if(encontrado)//...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 608

Acceso directo a cualquier posicin


Acceso directo: array[posicin]
Si se puede calcular la posicin del elemento, su acceso es directo

LuisHernndezYez

typedefdouble tVentaMes[DIAS][SUCURSALES];
typedefstruct {
tVentaMes ventas;
int dias;
}tMes;
typedeftMes tVentaAnual[MESES];
tVentaAnual anual;

Ventas del cuarto da del tercer mes en la primera sucursal:


anual[2].ventas[3][0]

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 609

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

#include<iostream>
usingnamespacestd;
#include<fstream>

Pgina 610

umbral.cpp

const intN=100;
typedefdoubletArray[N];
typedefstruct {
tArray elementos;
int contador;
}tLista;

LuisHernndezYez

void cargar(tLista&lista,bool &ok);


int main(){
tLista lista;
bool ok;
cargar(lista,ok);
if (!ok){
cout<<"Error:nohayarchivoodemasiadosdatos"
<<endl;
}
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 611

LuisHernndezYez

else {
double umbral;
cout<<"Valorumbral:";cin>>umbral;
boolencontrado=false;
int pos=0;
while ((pos<lista.contador)&&!encontrado){
if (lista.elementos[pos]>umbral){
encontrado=true;
}
else {
pos++;
}
}
if (encontrado){
cout<<"Valorenpos."<<pos+1 <<"("
<<lista.elementos[pos]<<")" <<endl;
}
else {
cout<<"Noencontrado!"<<endl;
}
}
return0;
}

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 612

void cargar(tLista&lista,bool &ok){


ifstreamarchivo;
doubledato;
boolabierto=true,overflow =false;
lista.contador =0;
archivo.open("datos.txt");
if(!archivo.is_open()){
abierto=false;
}
else {
archivo>>dato;
while((dato>=0)&&!overflow){
if(lista.contador ==N){
overflow =true;//Demasiados!
}
else {
lista.elementos[lista.contador]=dato;
lista.contador++;
archivo>>dato;
}
}
archivo.close();
}
ok=abierto&&!overflow;
}
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 613

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 614

inversa.cpp

Recorridos y bsquedas en cadenas de caracteres

LuisHernndezYez

Longitud de la cadena: size() o length()


Caso similar a los arrays con contador de elementos
Ejemplo: Recorrido de una cadena generando otra invertida
string cadena,inversa="";
int pos;
char car;
//...(lecturadecadena)
pos=0;
while(pos<cadena.size()){
//Mientrasnoselleguealfinaldelacadena
car=cadena.at(pos);
inversa=car+inversa;//Insertacaralprincipio
pos++;
}//...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 615

busca.cpp

string cadena;
char buscado;
int pos;
bool encontrado;
//...(lecturadecadena)
cout<<"Introduceelcarcterabuscar:";
cin>>buscado;
pos=0;
encontrado=false;
while((pos<cadena.size())&&!encontrado){
if(cadena.at(pos)==buscado){
encontrado=true;
}
else {
pos++;
}
}
if(encontrado)//...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 616

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 617

LuisHernndezYez

LuisHernndezYez

Bsqueda de un carcter en una cadena

Tipo tVector para representar secuencias de N enteros:


const int N=10;
typedef inttVector[N];
Subprogramas:
Dado un vector, mueve sus componentes un lugar a la derecha;
el ltimo componente se mover al 1er lugar
Dado un vector, calcula y devuelve la suma de los elementos que se
encuentran en las posiciones pares del vector
Dado un vector, encuentra y devuelve la componente mayor

LuisHernndezYez

Dados dos vectores, devuelve un valor que indique si son iguales


Dado un vector, determina si alguno de los valores almacenados en
el vector es igual a la suma del resto de los valores del mismo;
devuelve el ndice del primero encontrado o 1 si no se encuentra
Dado un vector, determina si alguno de los valores almacenados
en el vector est repetido
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 618

vectores.cpp
void desplazar(tVector v){
int aux=v[N 1];
for (int i=N 1;i>0;i){
v[i]=v[i 1];
}
v[0]=aux;
}

LuisHernndezYez

int sumaPares(const tVector v){


int suma=0;
for (int i=0;i<N;i=i+2){
suma=suma+v[i];
}
return suma;
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 619

LuisHernndezYez

int encuentraMayor(const tVector v){


int max=v[0],posMayor=0;
for (int i=1;i<N;i++){
if (v[i]>max){
posMayor=i;
max=v[i];
}
}
return posMayor;
}
bool sonIguales(const tVector v1,const tVector v2){
//Implementacincomobsquedadelprimerelementodistinto
bool encontrado=false;
int i=0;
while ((i<N)&&!encontrado){
encontrado=(v1[i]!=v2[i]);
i++;
}
return !encontrado;
}

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 620

int compruebaSuma(const tVector v){


//Algunoigualalasumadelresto?
bool encontrado=false;
int i=0;
int suma;
while ((i<N)&&!encontrado){
suma=0;
for (int j=0;j<N;j++){
if (j!=i){
suma=suma+v[j];
}
}
encontrado=(suma==v[i]);
i++;
}
if (!encontrado){
i=0;
}
return i 1;
}
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 621

bool hayRepetidos(const tVector v){


bool encontrado=false;
int i=0,j;
while ((i<N)&&!encontrado){
j=i+1;
while ((j<N)&&!encontrado){
encontrado=(v[i]==v[j]);
j++;
}
i++;
}
return encontrado;

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 622

Dado un vector de N caracteres v1, en el que no hay elementos


repetidos, y otro vector de M caracteres v2, donde N M, se
quiere comprobar si todos los elementos del vector v1 estn
tambin en el vector v2
Por ejemplo, si:
v1= 'a'
'h'
'i'
'm'
v2= 'h'
'a'
'x'
'x'
'm'
'i'

LuisHernndezYez

El resultado sera cierto, ya que todos los elementos de v1 estn


en v2

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 623

incluidos.cpp
#include<iostream>
usingnamespacestd;
const int N=3;
const int M=10;
typedef chartVector1[N];
typedefchartVector2[M];

LuisHernndezYez

bool esta(char dato,const tVector2 v2);


bool vectorIncluido(const tVector1v1,const tVector2 v2);
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:v1estaincluidoenv2" <<endl;
}
else {
cout<<"NO:v1noestaincluidoenv2" <<endl;
}
return 0;
}
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 624

bool esta(chardato,const tVector2 v2){


int i=0;
bool encontrado=(dato==v2[0]);
while (!encontrado&&(i<M 1)){
i++;
encontrado=(dato==v2[i]);
}
return encontrado;
}

LuisHernndezYez

bool vectorIncluido(const tVector1 v1,const tVector2 v2){


int i=0;
bool encontrado=esta(v1[0],v2);
while(encontrado&&(i<N 1)){
i++;
encontrado=esta(v1[i],v2);
}
return encontrado;
}
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 625

LuisHernndezYez

Un programa que lea dos cadenas del teclado y determine si una es


un anagrama de la otra, es decir, si una cadena es una permutacin
de los caracteres de la otra.
Por ejemplo, "acre" es un anagrama de "cera" y de "arce". Ten
en cuenta que puede haber letras repetidas ("carro", "llave").

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 626

anagramas.cpp
#include<iostream>
#include<string>
usingnamespace std;
int buscaCaracter(string cad,char c);//ndiceo1sinoest

LuisHernndezYez

int main(){
string cad1,cad2;
bool sonAnagramas=true;
int numCar,posEnCad2;
cout<<"Introducelaprimeracadena:";
getline(cin,cad1);
cout<<"Introducelasegundacadena:";
getline(cin,cad2);
if (cad1.length()!=cad2.length()){//Nosonanagramas
sonAnagramas=false;
}
else {
numCar=0;//Contadordecaracteresdelaprimeracadena
while (sonAnagramas&&(numCar<cad1.length())){
posEnCad2=buscaCaracter(cad2,cad1.at(numCar));
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 627

if (posEnCad2==1){//Nosehaencontradoelcaracter
sonAnagramas=false;
}
else {
cad2.erase(posEnCad2,1);
}
numCar++;
}
}

LuisHernndezYez

if (sonAnagramas){
cout<<"Laspalabrasintroducidassonanagramas" <<endl;
}
else {
cout<<"LaspalabrasintroducidasNOsonanagramas" <<endl;
}
return 0;
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 628

int buscaCaracter(string cad,char c){


int pos=0,lon=cad.length();
bool encontrado=false;

LuisHernndezYez

while ((pos<lon)&&!encontrado){
if (cad.at(pos)==c){
encontrado=true;
}
else {
pos++;
}
}
if (!encontrado){
pos=1;
}
return pos;
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 629

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 630

Arrays de varias dimensiones


Varios tamaos en la declaracin: cada uno con sus corchetes
typedef tipo_base nombre[tamao1][tamao2]...[tamaoN];

Varias dimensiones, tantas como tamaos se indiquen


typedefdouble tMatriz[50][100];
tMatriz matriz;

Tabla bidimensional de 50 filas por 100 columnas:

LuisHernndezYez

...

...

...

...

...

...

...

...

...

...

48

...

49

...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

98

99

...

...

Pgina 631

Arrays de varias dimensiones


typedefdouble tMatriz[50][100];
tMatriz matriz;

Cada elemento se localiza con dos ndices, uno por dimensin


cout<<matriz[2][98];

...

...

...

...

...
LuisHernndezYez

...

...

...

...

...

48

...

49

...

98

99

...

...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 632

Arrays de varias dimensiones


Podemos definir tantas dimensiones como necesitemos
typedefdouble tMatriz[5][10][20][10];
tMatriz matriz;

Necesitaremos tantos ndices como dimensiones:

LuisHernndezYez

cout<<matriz[2][9][15][6];

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 633

Ejemplo de array bidimensional


Temperaturas mnimas y mximas
Matriz bidimensional de das y mnima/mxima:
const int MaxDias =31;
const int MED =2;//Ndemedidas
typedefdouble tTemp[MaxDias][MED];//Daxmn./mx.
tTemp temp;

LuisHernndezYez

Ahora:
temp[i][0] es la temperatura mnima del da i+1
temp[i][1] es la temperatura mxima del da i+1

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 634

temp.cpp

LuisHernndezYez

int main(){
constint MaxDias =31;
const int MED =2;//Ndemedidas
typedef doubletTemp[MaxDias][MED];//Daxmn./mx.
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<<"Nosehapodidoabrirelarchivo!"<<endl;
}
else {
archivo>>min>>max;
//Elarchivoterminacon9999
...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 635

LuisHernndezYez

while(!((min==99)&&(max ==99))
&&(dia <MaxDias)){
temp[dia][0]=min;
temp[dia][1]=max;
dia++;
archivo>>min>>max;
}
archivo.close();
for(int i=0;i<dia;i++){
tMinMedia =tMinMedia +temp[i][0];
if(temp[i][0]<tMinAbs){
tMinAbs =temp[i][0];
}
tMaxMedia =tMaxMedia +temp[i][1];
if(temp[i][1]>tMaxAbs){
tMaxAbs =temp[i][1];
}
}
...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 636

tMinMedia =tMinMedia /dia;


tMaxMedia =tMaxMedia /dia;
cout<<"Temperaturasmnimas." <<endl;
cout<<"Media=" <<fixed<<setprecision(1)
<<tMinMedia <<"CMnimaabsoluta="
<<setprecision(1)<<tMinAbs <<"C" <<endl;
cout<<"Temperaturasmximas." <<endl;
cout<<"Media=" <<fixed<<setprecision(1)
<<tMaxMedia <<"CMximaabsoluta="
<<setprecision(1)<<tMaxAbs <<"C" <<endl;
}
return 0;
LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 637

Podemos dar valores a los elementos de un array al declararlo


Arrays bidimensionales:
typedefinttArray[5][2];
tArray cuads ={1,1,2,4,3,9,4,16,5,25};

Se asignan en el orden en el que los elementos estn en memoria


La memoria es de una dimensin: secuencia de celdas
En memoria varan ms rpidamente los ndices de la derecha:
cuads[0][0]cuads[0][1]cuads[1][0]cuads[1][1]cuads[2][0]...

LuisHernndezYez

Para cada valor del primer ndice: todos los valores del segundo

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 638

Inicializacin de un array bidimensional


typedefinttArray[5][2];
tArray cuads ={1,1,2,4,3,9,4,16,5,25};

LuisHernndezYez

Memoria

cuads[0][0]

cuads[0][1]

cuads[1][0]

cuads[1][1]

16

cuads[2][0]

25

cuads[2][1]

cuads[3][0]

Si hay menos valores que elementos,


el resto se inicializan a cero

cuads[3][1]

16

Inicializacin a cero de todo el array:

cuads[4][0]

cuads[4][1]

25

int cuads[5][2]={0 };

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 639

typedefdouble tMatriz[3][4][2][3];
tMatriz matriz=
{1,2,3,4,5,6,

LuisHernndezYez

7,8,9,10,11,12};

Memoria
matriz[0][0][0][0]

matriz[0][0][0][1]

matriz[0][0][0][2]

matriz[0][0][1][0]

matriz[0][0][1][1]

matriz[0][0][1][2]

matriz[0][1][0][0]

matriz[0][1][0][1]

matriz[0][1][0][2]

matriz[0][1][1][0]

10

matriz[0][1][1][1]

11

matriz[0][1][1][2]

12

matriz[0][2][0][0]

...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 640

const intFILAS=10;
const intCOLUMNAS=5;
typedefdouble tMatriz[FILAS][COLUMNAS];
tMatriz matriz;

LuisHernndezYez

Para cada fila (de 0 a FILAS 1):


Para cada columna (de 0 a COLUMNAS 1):
Procesar el elemento en [fila][columna]
for (int fila=0;fila<FILAS;fila++){
for (int columna=0;columna<COLUMNAS;columna++){
//Procesarmatriz[fila][columna]
}
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 641

Ventas de todos los meses de un ao

LuisHernndezYez

constint Meses=12;
constint MaxDias =31;
typedef doubletVentas[Meses][MaxDias];
tVentas ventas;//Ventasdetodoelao
typedef shortinttDiasMes[Meses];
tDiasMes diasMes;
inicializa(diasMes);//Ndedasdecadames
//Pedimoslasventasdecadadadelao...
for(int mes=0;mes<Meses;mes++){
for(int dia =0;dia <diasMes[mes];dia++){
cout<<"Ventasdelda"<<dia +1
<<"delmes"<<mes+1 <<":";
cin>>ventas[mes][dia];
}
}
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 642

Ventas de todos los meses de un ao


Das

LuisHernndezYez

Meses

...

28

29

30

201

125

234

112

156

...

234

543

667

323

231

675

325

111

...

523

417

327

333

324

...

444

367

437

145

845

654

212

562

...

354

548

327

652

555

222

777

...

428

999

854

438

824

547

175

...

321

356

654

543

353

777

437

...

765

678

555

327

541

164

563

327

...

538

159

235

333

327

432

249

777

...

528

529

524

583

333

100

334

...

743

468

10

217

427

585

218

843

...

777

555

11

222

666

512

400

259

...

438

637

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

666

Celdas no
utilizadas

531
879
Pgina 643

const
const
const
const

intDIM1=10;
intDIM2=5;
intDIM3=25;
intDIM4=50;

typedefdouble tMatriz[DIM1][DIM2][DIM3][DIM4];
tMatriz matriz;

LuisHernndezYez

Bucles anidados, desde la primera dimensin hasta la ltima:


for (int n1=0;n1<DIM1;n1++){
for (int n2=0;n2<DIM2;n2++){
for (int n3=0;n3<DIM3;n3++){
for (int n4=0;n4<DIM4;n4++){
//Procesarmatriz[n1][n2][n3][n4]
}
}
}
}
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 644

Ventas diarias de cuatro sucursales


Cada mes del ao: ingresos de cada sucursal cada da del mes
Meses con distinto n de das junto con la matriz de ventas
mensual guardamos el n de das del mes concreto estructura

LuisHernndezYez

const intDIAS=31;
const intSUCURSALES=4;
typedefdouble tVentaMes[DIAS][SUCURSALES];
typedefstruct {
anual tVentaAnual
tVentaMes ventas;
anual[i] tMes
int dias;
anual[i].dias int
}tMes;

anual[i].ventas tVentaMes
anual[i].ventas[j][k] double

const intMESES=12;
typedeftMes tVentaAnual[MESES];
tVentaAnual anual;
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 645

LuisHernndezYez

Clculo de las ventas


de todo el ao:
Para cada mes...
Para cada da del mes...
Para cada sucursal...
Acumular las ventas

const intMESES=12;
typedeftMes tVentaAnual[MESES];
tVentaAnual anual;

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++){
total=total+anual[mes].ventas[dia][suc];
}
}
}
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

LuisHernndezYez

const intDIAS =31;


const intSUCURSALES=4;
typedefdouble
tVentaMes[DIAS][SUCURSALES];
typedefstruct {
tVentaMes ventas;
int dias;
}tMes;

Pgina 646

Primer valor > umbral


boolencontrado=false;
int mes=0,dia,suc;
while ((mes<MESES)&&!encontrado){
dia =0;
while ((dia <anual[mes].dias)&&!encontrado){
suc =0;
while ((suc <SUCURSALES)&&!encontrado){
if (anual[mes].ventas[dia][suc]>umbral){
encontrado=true;
}
else {
suc++;
}
}
if (!encontrado){
dia++;
}
}
if (!encontrado){
mes++;
}
}
if (encontrado){...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 647

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 648

Fundamentosdelaprogramacin

7
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

LuisHernndezYez

Algoritmosdeordenacin
Algoritmodeordenacinporinsercin
Ordenacindearraysporinsercin
Algoritmodeordenacinporinsercin
conintercambios
Clavesdeordenacin
Estabilidaddelaordenacin
Complejidadyeficiencia
Ordenacionesnaturales
Ordenacinporseleccindirecta
Mtododelaburbuja
Listasordenadas
Bsquedasenlistasordenadas
Bsquedabinaria

Fundamentosdelaprogramacin:Algoritmosdeordenacin

651
654
665
672
680
688
692
694
701
716
722
729
731

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 651

Ordenacin de listas
array
125.40

76.95

328.80

254.62

435.00

164.29

316.05

219.99

93.45

756.62

Algoritmo de ordenacin
(de menor a mayor)
array
76.95
0

93.45 125.40 164.29 219.99 254.62 316.05 328.80 435.00 756.62


1

LuisHernndezYez

array[i]<=array[i+1]

Mostrar los datos en orden, facilitar las bsquedas, ...


Variadas formas de hacerlo (algoritmos)
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 652

Los datos de la lista deben poderse comparar entre s


Sentido de la ordenacin:
Ascendente (de menor a mayor)
Descendente (de mayor a menor)
Algoritmos de ordenacin bsicos:
Ordenacin por insercin
Ordenacin por seleccin directa
Ordenacin por el mtodo de la burbuja
Los algoritmos se basan en comparaciones e intercambios
Hay otros algoritmos de ordenacin mejores

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 653

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 654

LuisHernndezYez

LuisHernndezYez

Ordenacin de listas

Algoritmo de ordenacin por insercin


Partimos de una lista vaca
Vamos insertando cada elemento en el lugar que le corresponda

LuisHernndezYez

6
1
3
8
2
9
4
7
5

Baraja de nueve cartas numeradas del 1 al 9


Las cartas estn desordenadas
Ordenaremos de menor a mayor (ascendente)

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 655

Algoritmo de ordenacin por insercin

LuisHernndezYez

6
1
3
8
2
9
4
7
5

Colocamos el primer elemento en la lista vaca

Lista ordenada:

5
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 656

Algoritmo de ordenacin por insercin

6
1
3
8
2
9
4
7

El 7 es mayor que todos los elementos de la lista


Lo insertamos al final

Lista ordenada:

LuisHernndezYez

5 7
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 657

Algoritmo de ordenacin por insercin

6
1
3
8
2
9
4

Primer elemento (5) mayor que el nuevo (4):


Desplazamos todos una posicin a la derecha
Insertamos el nuevo en la primera posicin
Hemos insertado el elemento en su lugar

LuisHernndezYez

Lista ordenada:

5 5
4
7 7
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 658

Algoritmo de ordenacin por insercin

6
1
3
8
2
9

9 es mayor que todos los elementos de la lista


Lo insertamos al final

Lista ordenada:
LuisHernndezYez

4 5 7 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 659

Algoritmo de ordenacin por insercin

6
1
3
8
2

Primer elemento (4) mayor que el nuevo (2):


Desplazamos todos una posicin a la derecha
Insertamos el nuevo en la primera posicin

LuisHernndezYez

Lista ordenada:

4 4
2
5 5
7 7
9 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 660

Algoritmo de ordenacin por insercin

6
1
3
8

El 9 es el primer elemento mayor que el nuevo (8):


Desplazamos desde ese hacia la derecha
Insertamos donde estaba el 9

Lista ordenada:
LuisHernndezYez

2 4 5 7 8
4
9 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 661

Algoritmo de ordenacin por insercin

6
1
3

Segundo elemento (4) mayor que el nuevo (3):


Desplazamos desde ese hacia la derecha
Insertamos donde estaba el 4

LuisHernndezYez

Lista ordenada:

2 3
4
4 4
5 5
7 7
8 8
9 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 662

Algoritmo de ordenacin por insercin

6
1

Primer elemento (2) mayor que el nuevo (1):


Desplazamos todos una posicin a la derecha
Insertamos el nuevo en la primera posicin

Lista ordenada:
LuisHernndezYez

2 2
1
3 3
4 4
5 5
7 7
8 8
9 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 663

Algoritmo de ordenacin por insercin

El 7 es el primer elemento mayor que el nuevo (6):


Desplazamos desde ese hacia la derecha
Insertamos donde estaba el 7

LISTA ORDENADA !!!

LuisHernndezYez

Lista ordenada:

1 2 3 4 5 6
7 7
8 8
9 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 664

Ordenacin de arrays por insercin


El array contiene inicialmente la lista desordenada:
20

14

32

14

27

12

13

15

LuisHernndezYez

A medida que insertamos: dos zonas en el array


Parte ya ordenada y elementos por procesar
7

14

20

32

14

27

12

13

15

Parte ya ordenada

Elementos por insertar

Siguiente elemento a insertar en la parte ya ordenada

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 665

Ordenacin de arrays por insercin


Situacin inicial: Lista ordenada con un solo elemento (primero)
20

14

32

14

27

12

13

15

LuisHernndezYez

Desde el segundo elemento del array hasta el ltimo:


Localizar el primer elemento mayor en lo ya ordenado

20

14

32

14

27

12

13

15

nuevo 7

Primer elemento mayor o igual: ndice 0


Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 666

Ordenacin de arrays por insercin


. . .
Desplazar a la derecha los ordenados desde ese lugar
Insertar el nuevo en la posicin que queda libre
20

14

32

14

27

12

13

15

LuisHernndezYez

nuevo 7
7

20

14

32

14

27

12

13

15

nuevo 7
Fundamentosdelaprogramacin:Algoritmosdeordenacin

LuisHernndezYez

Implementacin

Pgina 667

constintN=15;
typedefinttLista[N];
tLista lista;

...
int nuevo,pos;
//Desdeelsegundoelementohastaelltimo...
for(int i=1;i<N;i++){
nuevo=lista[i];
pos=0;
while((pos<i)&&!(lista[pos]>nuevo)){
pos++;
}
//pos:ndicedelprimermayor;isinolohay
for(int j=i;j>pos;j){
lista[j]=lista[j 1];
}
lista[pos]=nuevo;
}
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 668

20

14

32

14

27

12

13

15

LuisHernndezYez

i 1

pos 0

nuevo 7

20

14

32

14

27

12

13

15

20

20

14

32

14

27

12

13

15

20

14

32

14

27

12

13

15

7
0

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 669

14

20

32

14

27

12

13

15

LuisHernndezYez

i 4

pos 0

nuevo 5

14

20

32

14

27

12

13

15

14

20

32

14

27

12

13

15

14

20

32

14

27

12

13

15

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 670

14

20

32

14

27

12

13

15

i 5

pos 3

nuevo 14

14

20

32

14

27

12

13

15

14

20

20

32

27

12

13

15

14

32

27

12

13

15

14 20
3

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 671

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 672

LuisHernndezYez

LuisHernndezYez

La insercin de cada elemento se puede realizar


con comparaciones e intercambios

LuisHernndezYez

Desde el segundo elemento hasta el ltimo:


Desde la posicin del nuevo elemento a insertar:
Mientras el anterior sea mayor, intercambiar
5

14

20

32

14

27

12

13

15

14

20

14

32

27

12

13

15

14

32

27

12

13

15

14 20
3

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 673

14

20

32

14

27

12

13

15

14

20

32

14

27

12

13

15

14

20

32

14

27

12

13

15

14

20

32

14

27

12

13

15

14

20

32

14

27

12

13

15

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 674

LuisHernndezYez

constintN=15;
typedefinttLista[N];
tLista lista;

...
int tmp,pos;
//Desdeelsegundoelementohastaelltimo...
for(int i=1;i<N;i++){
pos=i;
//Mientrasnoalprincipioyanteriormayor...
while((pos>0)&&(lista[pos 1]>lista[pos])){
//Intercambiar...
tmp=lista[pos];
lista[pos]=lista[pos 1];
lista[pos 1]=tmp;
pos;//Posicinanterior
}
}

Fundamentosdelaprogramacin:Algoritmosdeordenacin

#include<iostream>
usingnamespacestd;
#include<fstream>

Pgina 675

insercion.cpp

LuisHernndezYez

const int N=100;


typedef inttArray[N];
typedefstruct{ //Listadelongitudvariable
tArray elementos;
int contador;
}tLista;
int main(){
tLista lista;
ifstream archivo;
int dato,pos,tmp;
lista.contador =0;
...
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 676

LuisHernndezYez

archivo.open("insercion.txt");
if (!archivo.is_open()){
cout<<"Errordeaperturadearchivo!" <<endl;
}
else {
archivo>>dato;
while ((lista.contador <N)&&(dato!=1)){
//Centinela1alfinal
lista.elementos[lista.contador]=dato;
lista.contador++;
archivo>>dato;
}
archivo.close();
//SihaymsdeNignoramoselresto
cout<<"Antesdeordenar:"<<endl;
for (int i=0;i<lista.contador;i++){
cout<<lista.elementos[i]<<"";
}
cout<<endl;...

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 677

for (int i=1;i<lista.contador;i++){


pos=i;
while ((pos>0)
&&(lista.elementos[pos1]>lista.elementos[pos]))
{
tmp=lista.elementos[pos];
lista.elementos[pos]=lista.elementos[pos 1];
lista.elementos[pos 1]=tmp;
pos;
}
}
cout<<"Despusdeordenar:"<<endl;
for (int i=0;i<lista.contador;i++){
cout<<lista.elementos[i]<<"";
}
cout<<endl;
}
return 0;
}
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 678

Consideracin de implementacin

14

20

32

14

27

12

13

15

14

20

14

32

27

12

13

15

14

14

20

32

27

12

13

15

Intercambio intil!
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 679

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 680

LuisHernndezYez

LuisHernndezYez

Operador relacional adecuado?


lista[pos 1] > o >= ?
lista[pos]
Con >= se realizan intercambios intiles:

Claves de ordenacin
Elementos que son estructuras con varios campos:

LuisHernndezYez

constintN=15;
typedefstruct {
intcodigo;
stringnombre;
doublesueldo;
} tDato;
typedeftDatotLista[N];
tListalista;

Clave de ordenacin:
Campo en el que se basan las comparaciones

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 681

Claves de ordenacin
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;
}

LuisHernndezYez

Comparacin: campo concreto


Intercambio: elementos completos

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 682

Claves de ordenacin
Funcin para la comparacin:

LuisHernndezYez

bool operator>(tDato opIzq,tDato opDer){


return (opIzq.nombre >opDer.nombre);
}
tDato tmp;
while ((pos>0)&&(lista[pos 1]>lista[pos])){
tmp=lista[pos];
lista[pos]=lista[pos 1];
lista[pos 1]=tmp;
pos;
}

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 683

claves.cpp

LuisHernndezYez

Claves de ordenacin
#include<iostream>
#include<string>
usingnamespacestd;
#include<fstream>
#include<iomanip>
constint N=15;
typedef struct {
int codigo;
string nombre;
double sueldo;
}tDato;
typedef tDatotArray[N];
typedef struct {
tArray datos;
int cont;
}tLista;
...
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 684

LuisHernndezYez

void mostrar(tListalista);
bool operator>(tDato opIzq,tDato opDer);
int main(){
tListalista;
ifstreamarchivo;
lista.cont =0;
archivo.open("datos.txt");
if(!archivo.is_open()){
cout<<"Errordeaperturadelarchivo!" <<endl;
}
else {
tDato dato;
archivo>>dato.codigo;
while ((lista.cont <N)&&(dato.codigo !=1)){
archivo>>dato.nombre >>dato.sueldo;
lista.datos[lista.cont]=dato;
lista.cont++;
archivo>>dato.codigo;
}
archivo.close();...

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 685

cout<<"Antesdeordenar:"<<endl;
mostrar(lista);
for (int i=1;i<lista.cont;i++){
//Desdeelsegundoelementohastaelltimo
int pos=i;
while ((pos>0)
&&(lista.datos[pos1]>lista.datos[pos])){
tDatotmp;
tmp=lista.datos[pos];
lista.datos[pos]=lista.datos[pos 1];
lista.datos[pos 1]=tmp;
pos;
}
}
cout<<"Despusdeordenar:"<<endl;
mostrar(lista);
}
return 0;
}

...
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 686

bool operator>(tDato opIzq,tDato opDer){


return (opIzq.nombre >opDer.nombre);
}

Cambia a codigo o sueldo para ordenar por otros campos


Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 687

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 688

LuisHernndezYez

LuisHernndezYez

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

Algoritmos de ordenacin estables


Al ordenar por otra clave una lista ya ordenada,
la segunda ordenacin preserva el orden de la primera
tDato: tres posibles claves de ordenacin (campos)
Codigo
12345lvarez120000
Nombre
11111Bentez100000
21112Domnguez90000
Sueldo

LuisHernndezYez

Lista ordenada por Nombre

11111Durn120000
22222Fernndez120000
12345Gmez100000
10000Hernndez150000
21112Jimnez100000
11111Prez90000
12345Snchez90000
10000Sergei100000
33333Tarazona120000
12345Turgano100000
11111Urpiano90000

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 689

Ordenamos ahora por el campo Codigo:

LuisHernndezYez

10000Sergei100000
10000Hernndez150000
11111Urpiano
90000
11111Bentez
100000
11111Prez
90000
11111Durn
120000
12345Snchez90000
12345lvarez120000
12345Turgano100000
12345Gmez100000
21112Domnguez90000
21112Jimnez100000
22222Fernndez120000
33333Tarazona120000

No estable:
Los nombres no mantienen
sus posiciones relativas

Fundamentosdelaprogramacin:Algoritmosdeordenacin

10000Hernndez150000
10000Sergei100000
11111Bentez
100000
11111Durn
120000
11111Prez
90000
11111Urpiano
90000
12345lvarez120000
12345Gmez100000
12345Snchez90000
12345Turgano100000
21112Domnguez90000
21112Jimnez100000
22222Fernndez120000
33333Tarazona120000

Estable:
Los nombres mantienen
sus posiciones relativas

Pgina 690

Ordenacin por insercin

10000Hernndez150000
10000Sergei100000
11111Bentez100000
11111Durn120000
11111Prez90000
11111Urpiano90000
12345lvarez120000
12345Gmez100000
12345Snchez90000
12345Turgano100000
21112Domnguez90000
21112Jimnez100000
22222Fernndez120000
33333Tarazona120000

11111Prez90000
11111Urpiano90000
12345Snchez90000
21112Domnguez90000
10000
Sergei100000
11111
Bentez100000
12345
Gmez
100000
12345
Turgano
100000
21112
Jimnez100000
11111Durn120000
12345lvarez120000
22222Fernndez120000
33333Tarazona120000
10000Hernndez150000

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 691

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 692

LuisHernndezYez

LuisHernndezYez

Estable siempre que utilicemos < o > Con <= o >= no es estable
Ordenamos por sueldo:
A igual sueldo, ordenado por cdigos y a igual cdigo, por nombres

Casos de estudio para los algoritmos de ordenacin


Lista inicialmente ordenada
5

12

13

14

14

15

20

27

32

Lista inicialmente ordenada al revs


32

27

20

15

14

14

13

12

LuisHernndezYez

Lista con disposicin inicial aleatoria


13

20

14

12

32

27

14

15

Trabaja menos, ms o igual la ordenacin en cada caso?

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 693

Ordenaciones naturales
Si el algoritmo trabaja menos cuanto ms ordenada est
inicialmente la lista, se dice que la ordenacin es natural
Ordenacin por insercin con la lista inicialmente ordenada:
Versin que busca el lugar primero y luego desplaza:
No hay desplazamientos; mismo nmero de comparaciones
Comportamiento no natural

LuisHernndezYez

Versin con intercambios:


Trabaja mucho menos; basta una comparacin cada vez
Comportamiento natural

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 694

Eleccin de un algoritmo de ordenacin

LuisHernndezYez

Cmo de bueno es cada algoritmo?


Cunto tarda en comparacin con otros algoritmos?
Algoritmos ms eficientes: los de menor complejidad
Tardan menos en realizar la misma tarea
Comparamos en orden de complejidad: O()
En funcin de la dimensin de la lista a ordenar: N
O()=f(N)
Operaciones que realiza el algoritmo de ordenacin:
Comparaciones
Intercambios
Asumimos que tardan un tiempo similar
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 695

Clculo de la complejidad

LuisHernndezYez

Ordenacin por insercin (con intercambios):


...
for(int i=1;i<N;i++){
int pos=i;
while((pos>0)&&(lista[pos 1]>lista[pos])){
int tmp;
Comparacin
tmp=lista[pos];
lista[pos]=lista[pos 1];
lista[pos 1]=tmp;
pos;
Intercambio
}
}

Intercambios y comparaciones:
Tantos como ciclos realicen los correspondientes bucles
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 696

LuisHernndezYez

Clculo de la complejidad
N 1 ciclos
...
for(int i=1;i<N;i++){
N variable de ciclos
int pos=i;
while((pos>0)&&(lista[pos 1]>lista[pos])){
int tmp;
tmp=lista[pos];
lista[pos]=lista[pos 1];
lista[pos 1]=tmp;
pos;
}
}

Caso en el que el while se ejecuta ms: caso peor


Caso en el que se ejecuta menos: caso mejor
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 697

LuisHernndezYez

Clculo de la complejidad
Caso mejor: lista inicialmente ordenada
La primera comparacin falla: ningn intercambio
(N 1) * (1 comparacin + 0 intercambios) = N 1 O(N)
Caso peor: lista inicialmente ordenada al revs
Para cada pos, entre i y 1: 1 comparacin 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)
Notacin O grande: orden de complejidad en base a N
El trmino en N que ms rpidamente crece al crecer N
En el caso peor, N2 crece ms rpido que N O(N2)
(Ignoramos las constantes, como 2)
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 698

Ordenacin por insercin (con intercambios)


Caso mejor: O(N)
Caso peor: O(N2)
Caso medio (distribucin aleatoria de los elementos): O(N2)

LuisHernndezYez

Hay algoritmos de ordenacin mejores

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 699

rdenes de complejidad

LuisHernndezYez

O(log N) < O(N) < O(N log N) < O(N2) < O(N3) ...
Nlog2 NN2

101
214
4216
8364
164256
3251024
6464096
128716384
256865536
...
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 700

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 701

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

LuisHernndezYez

Lista desordenada:

5 7 4 9 2 8 3 1 6

Lista ordenada:

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 702

Algoritmo de ordenacin por seleccin directa

LuisHernndezYez

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

5 7 4 9 2 8 3

Lista ordenada:

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 703

Algoritmo de ordenacin por seleccin directa

LuisHernndezYez

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

5 7 4 9

Lista ordenada:

1 2

Fundamentosdelaprogramacin:Algoritmosdeordenacin

8 3

Pgina 704

Algoritmo de ordenacin por seleccin directa

LuisHernndezYez

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

5 7 4 9

Lista ordenada:

1 2 3

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 705

Algoritmo de ordenacin por seleccin directa

LuisHernndezYez

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

5 7

Lista ordenada:

1 2 3 4

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 706

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

LuisHernndezYez

Lista desordenada:

Lista ordenada:

1 2 3 4 5

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 707

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

LuisHernndezYez

Lista desordenada:

Lista ordenada:

1 2 3 4 5 6

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 708

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

LuisHernndezYez

Lista desordenada:

Lista ordenada:

1 2 3 4 5 6 7

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 709

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

LuisHernndezYez

Lista desordenada:

Lista ordenada:

9
1 2 3 4 5 6 7 8

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 710

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

LuisHernndezYez

LISTA ORDENADA !!!

1 2 3 4 5 6 7 8 9

Lista ordenada:

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 711

Ordenacin de un array por seleccin directa


Desde el primer elemento (i = 0) hasta el penltimo (N2):
Menor elemento (en m) entre i + 1 y el ltimo (N1)
Intercambiar los elementos en i y m si no son el mismo
i

20

14

32

14

27

12

13

15

LuisHernndezYez

im

Slo intercambiamos si no es la misma posicin

14

32

20

14

27

12

13

15

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 712

Ordenacin de un array por seleccin directa


i

14

32

20

14

27

12

13

15

LuisHernndezYez

12

32

20

14

27

14

13

15

12

13

20

14

27

14

32

15

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 713

seleccion.cpp

LuisHernndezYez

Implementacin

constintN=15;
typedefinttLista[N];
tLista lista;

//Desdeelprimerelementohastaelpenltimo...
for(int i=0;i<N 1;i++){
int menor=i;
//Desdei+1hastaelfinal...
for(int j=i+1;j<N;j++){
if (lista[j]<lista[menor]){
menor=j;
}
}
if (menor>i){
int tmp;
tmp=lista[i];
lista[i]=lista[menor];
lista[menor]=tmp;
}
}
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 714

Complejidad de la ordenacin por seleccin directa


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

No es estable: intercambios a larga distancia


No se garantiza que se mantenga el mismo orden relativo original
Comportamiento no natural (trabaja siempre lo mismo)
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 715

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 716

LuisHernndezYez

LuisHernndezYez

Mismo nmero de comparaciones en todos los casos


Igual que el mtodo de insercin
Complejidad: O(N2)
Algo mejor (menos intercambios; uno en cada paso)

Algoritmo de ordenacin por el mtodo de la burbuja

LuisHernndezYez

Variacin del mtodo de seleccin directa


El elemento menor va ascendiendo hasta alcanzar su posicin

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 717

12

32

14

14

12

32

14

14

12

32

14

14

12

32

14

14

12

32

14

14

12

32

14

14

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 718

burbuja.cpp

Ordenacin de un array por el mtodo de la burbuja

LuisHernndezYez

Desde el primero (i = 0), hasta el penltimo (N 2):


Desde el ltimo (j = N 1), hasta i + 1:
Si elemento en j < elemento en j 1, intercambiarlos
constintN=10;
...
int tmp;
typedefinttLista[N];
//Delprimeroalpenltimo...
tLista lista;
for(int i=0;i<N 1;i++){
//Desdeelltimohastaelsiguienteai...
for(int j=N 1;j>i;j){
if (lista[j]<lista[j 1]){
tmp=lista[j];
lista[j]=lista[j 1];
lista[j 1]=tmp;
}
}
}
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 719

Algoritmo de ordenacin por el mtodo de la burbuja

LuisHernndezYez

Complejidad: O(N2)
Comportamiento no natural
Estable (mantiene el orden relativo)
Mejora:
Si en un paso del bucle exterior no ha habido intercambios:
La lista ya est ordenada (no es necesario seguir)
14141412
16161214
35121616
12353535
50505050
Fundamentosdelaprogramacin:Algoritmosdeordenacin

La lista ya est ordenada


No hace falta seguir

Pgina 720

bool inter=true;
int i=0;
//Desdeel1hastaelpenltimosihayintercambios...
while((i<N 1)&&inter){
inter=false;
//Desdeelltimohastaelsiguienteai...
for(int j=N 1;j>i;j){
if (lista[j]<lista[j 1]){
int tmp;
tmp=lista[j];
lista[j]=lista[j 1];
lista[j 1]=tmp;
inter=true;
}
}
if (inter){
i++;
}
}
Esta variacin s tiene un comportamiento natural
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 721

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 722

LuisHernndezYez

LuisHernndezYez

burbuja2.cpp

Gestin de listas ordenadas

LuisHernndezYez

Casi todas las tareas se realizan igual que en listas sin orden
Operaciones que tengan en cuenta el orden:
Insercin de un nuevo elemento: debe seguir en orden
Bsquedas ms eficientes
Y la carga desde archivo?
Si los elementos se guardaron en orden: se lee igual
Si los elementos no estn ordenados en el archivo: insertar

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 723

lista.cpp

Declaraciones: Iguales que para listas sin orden


constint N=20;
typedef struct {
int codigo;
string nombre;
double sueldo;
}tRegistro;

LuisHernndezYez

typedef tRegistro tArray[N];


typedef struct {
tArray registros;
int cont;
}tLista;

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 724

Subprogramas: Misma declaracin que para listas sin orden


void mostrarDato(int pos,tRegistro registro);
voidmostrar(tLista lista);
booloperator>(tRegistro opIzq,tRegistro opDer);
booloperator<(tRegistro opIzq,tRegistro opDer);
tRegistro nuevo();
void insertar(tLista &lista,tRegistro registro,bool&ok);
voideliminar(tLista &lista,intpos,bool&ok);//pos=1..N
intbuscar(tLista lista,stringnombre);
void cargar(tLista &lista,bool&ok);

LuisHernndezYez

voidguardar(tLista lista);

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 725

Nuevas implementaciones:
Operadores relacionales
Insercin (mantener el orden)
Bsqueda (ms eficiente)
Se guarda la lista en orden, por lo que cargar() no cambia
booloperator>(tRegistro opIzq,tRegistro opDer){
return opIzq.nombre >opDer.nombre;
}

LuisHernndezYez

booloperator<(tRegistro opIzq,tRegistro opDer){


return opIzq.nombre <opDer.nombre;
}

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 726

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 727

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 728

LuisHernndezYez

LuisHernndezYez

void insertar(tLista &lista,tRegistro registro,bool &ok){


ok=true;
if (lista.cont ==N){
ok=false;//listallena
}
else {
int i=0;
while ((i<lista.cont)&&(lista.registros[i]<registro)){
i++;
}
//Insertamosenlaposicini(primermayoroigual)
for (int j=lista.cont;j>i;j){
//Desplazamosunaposicinaladerecha
lista.registros[j]=lista.registros[j 1];
}
lista.registros[i]=registro;
lista.cont++;
}
}

Bsqueda de un elemento en una secuencia

LuisHernndezYez

No ordenada: recorremos hasta encontrarlo o al final


Ordenada: recorremos hasta encontrarlo o mayor / al final
5

12

13

14

14

15

20

27

32

Buscamos el 36: al llegar al final sabemos que no est


Buscamos el 17: al llegar al 20 ya sabemos que no est
Condiciones de terminacin:
Se llega al final
Se encuentra el elemento buscado
Se encuentra uno mayor
Mientras no al final y el valor sea menor que el buscado

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 729

int buscado;
constintN=10;
cout<<"Valorabuscar:";
typedefinttLista[N];
cin>>buscado;
tLista lista;
int i=0;
while((i<N)&&(lista[i]<buscado)){
i++;
}
//Ahora,oestamosalfinalolista[i]>=buscado
if(i==N){//Alfinal:nosehaencontrado
cout<<"Noencontrado!" <<endl;
}
elseif (lista[i]==buscado){//Encontrado!
cout<<"Encontradoenposicin" <<i+1 <<endl;
}
else { //Hemosencontradounomayor
cout<<"Noencontrado!" <<endl;
}
Complejidad: O(N)
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 730

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 731

Bsqueda mucho ms rpida que aprovecha la ordenacin


Comparar con el valor que est en el medio de la lista:
Si es el que se busca, terminar
Si no, si es mayor, buscar en la primera mitad de la lista
Si no, si es menor, buscar en la segunda mitad de la lista
Repetir hasta encontrarlo o no quede sublista donde buscar
Elemento mitad

LuisHernndezYez

Buscamos el 12
5

12

14

14

15

18

20

27

32

12

14

14

15

18

20

27

32

12

14

14

15

18

20

27

32

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 732

Vamos buscando en sublistas cada vez ms pequeas (mitades)


Delimitamos el segmento de la lista donde buscar
Inicialmente tenemos toda la lista:
ini

mitad

fin

12

14

14

15

18

20

27

32

LuisHernndezYez

ndice del elemento en la mitad: mitad=(ini+fin)/2


Si no se encuentra, dnde seguir buscando?
Buscado < elemento en la mitad: fin=mitad 1
Buscado > elemento en la mitad: ini=mitad+1
Si ini > fin, no queda dnde buscar

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 733

Buscamos el 12
ini

mitad

fin

12

14

14

15

18

20

27

32

12 <lista[mitad] fin=mitad 1
ini mitad

fin

12

14

14

15

18

20

27

32

LuisHernndezYez

12 >lista[mitad] ini=mitad+1
ini

fin

12

14

14

15

18

20

27

32

mitad

Encontrado!

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 734

Si el elemento no est, nos quedamos sin sublista: ini>fin


Para el 13:

mitad
ini fin

12

14

14

15

18

20

27

32

13 >lista[mitad] ini=mitad+1

LuisHernndezYez

mitad
ini
fin
5

12

14

14

15

18

20

27

32

13 <lista[mitad] fin=mitad 1 2
ini>fin !!! No hay dnde seguir buscando No est
Fundamentosdelaprogramacin:Algoritmosdeordenacin

LuisHernndezYez

Implementacin

Pgina 735

constintN=10;
typedefinttLista[N];
tLista lista;

int buscado;
cout<<"Valorabuscar:";
cin>>buscado;
int ini=0,fin=N 1,mitad;
bool encontrado=false;
while((ini<=fin)&&!encontrado){
mitad=(ini+fin)/2;//Divisinentera
if(buscado==lista[mitad]){
encontrado=true;
}
elseif(buscado<lista[mitad]){
fin=mitad 1;
}
else{
ini=mitad+1;
}
}//Sisehaencontrado,esten[mitad]
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 736

#include<iostream>
usingnamespacestd;
#include<fstream>

binaria.cpp

constint N=100;
typedef int tArray[N];
typedef struct {
tArray elementos;
int cont;
}tLista;

LuisHernndezYez

int buscar(tLista lista,int buscado);


int main(){
tLista lista;
ifstream archivo;
int dato;
lista.cont =0;
archivo.open("ordenados.txt");//Existeyescorrecto
archivo>>dato;
...

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 737

while ((lista.cont <N)&&(dato!=1)){


lista.elementos[lista.cont]=dato;
lista.cont++;
archivo>>dato;
}
archivo.close();
for (int i=0;i<lista.cont;i++){
cout<<lista.elementos[i]<<"";
}
cout<<endl;
int buscado,pos;
cout<<"Valorabuscar:";
cin>>buscado;
pos=buscar(lista,buscado);
if (pos!=1){
cout<<"Encontradoenlaposicin"<<pos+1 <<endl;
}
else {
cout<<"Noencontrado!"<<endl;
}
return 0;
}...
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 738

LuisHernndezYez

int buscar(tListalista,int buscado){


int pos=1,ini=0,fin=lista.cont 1,mitad;
bool encontrado=false;
while ((ini<=fin)&&!encontrado){
mitad=(ini+fin)/2;//Divisinentera
if (buscado==lista.elementos[mitad]){
encontrado=true;
}
elseif(buscado<lista.elementos[mitad]){
fin=mitad 1;
}
else {
ini=mitad+1;
}
}
if (encontrado){
pos=mitad;
}
return pos;
}
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 739

LuisHernndezYez

Complejidad
Qu orden de complejidad tiene la bsqueda binaria?
Caso peor:
No est 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:
20, 21, 22, 23, ..., 2k4, 2k3, 2k2, 2k1
N de elementos de esa serie: k
N de comparaciones = k N = 2k k = log2 N
Complejidad: O(log2 N)
Mucho ms rpida que O(N)
Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 740

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 741

Fundamentosdelaprogramacin

7A
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

LuisHernndezYez

Ordenacinporintercambio
Mezcladedoslistasordenadas

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

744
747

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

Pgina 744

Algoritmo de ordenacin por intercambio

LuisHernndezYez

Variacin del mtodo de seleccin directa


Se intercambia el elemento de la posicin que se trata en cada
momento siempre que se encuentra uno que es menor:
14

12

32

20

14

27

13

15

14

12

32

20

14

27

13

15

14

12

32

20

14

27

13

15

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

Pgina 745

intercambio.cpp

Igual nmero de comparaciones, muchos ms intercambios


No es estable
Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

Pgina 746

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

Pgina 747

LuisHernndezYez

LuisHernndezYez

constintN=10;
typedefinttLista[N];
tLista lista;
...
for(int i=0;i<N 1;i++){
//Desdeelprimerelementohastaelpenltimo
for(int j=i+1;j<N;j++){
//Desdei+1hastaelfinal
if (lista[j]<lista[i]){
int tmp;
tmp=lista[i];
lista[i]=lista[j];
lista[j]=tmp;
}
}

Mezcla de dos listas ordenadas en arrays


const int N=100;
typedef struct {
int elementos[N];
int cont;
}tLista;
Un ndice para cada lista, inicializados a 0 (principio de las listas)
Mientras que no lleguemos al final de alguna de las dos listas:
Elegimos el elemento menor de los que tienen los ndices
LuisHernndezYez

Lo copiamos en la lista resultado y avanzamos su ndice una posicin


Copiamos en la lista resultado los que queden en la lista no acabada

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

Pgina 748

LuisHernndezYez

void mezcla(tLista lista1,tLista lista2,tLista&listaM){


int pos1=0,pos2=0;
listaM.cont =0;
while ((pos1<lista1.cont)&&(pos2<lista2.cont)
&&(listaM.cont <N)){
if (lista1.elementos[pos1]<lista2.elementos[pos2]){
listaM.elementos[listaM.cont]=lista1.elementos[pos1];
pos1++;
}
else {
listaM.elementos[listaM.cont]=lista2.elementos[pos2];
pos2++;
}
listaM.cont++;
}
...

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

Pgina 749

mezcla1.cpp

LuisHernndezYez

//Puedenquedardatosenalgunadelaslistas
if (pos1<lista1.cont){
while ((pos1<lista1.cont)&&(listaM.cont <N)){
listaM.elementos[listaM.cont]=lista1.elementos[pos1];
pos1++;
listaM.cont++;
}
}
else {//pos2<lista2.cont
while ((pos2<lista2.cont)&&(listaM.cont <N)){
listaM.elementos[listaM.cont]=lista2.elementos[pos2];
pos2++;
listaM.cont++;
}
}
}

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

Pgina 750

Mezcla de dos listas ordenadas en archivos

LuisHernndezYez

voidmezcla(string nombre1,string nombre2,string nombreM){


//Mezclalassecuenciasenlosarchivosnombnre1ynombre2
//generandolasecuenciamezcladaenelarchivonombreM
ifstream archivo1,archivo2;
ofstream mezcla;
int dato1,dato2;
//Losarchivosexistenysoncorrectos
archivo1.open(nombre1.c_str());
archivo2.open(nombre2.c_str());
mezcla.open(nombreM.c_str());
archivo1>>dato1;
archivo2>>dato2;
while ((dato1!=1)&&(dato2!=1)){
//Mientrasquedealgoenambosarchivos
...

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

Pgina 751

LuisHernndezYez

if (dato1<dato2){
mezcla<<dato1<<endl;
archivo1>>dato1;
}else{
mezcla<<dato2<<endl;
archivo2>>dato2;
}
}//Unodelosdosarchivossehaacabado
if (dato1!=1){//Quedanenelprimerarchivo
while (dato1!=1){
mezcla<<dato1<<endl;
archivo1>>dato1;
}
}
else {//Quedanenelsegundoarchivo
while (dato2!=1){
mezcla<<dato2<<endl;
archivo2>>dato2;
}
}
...
Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

Pgina 752

mezcla2.cpp
archivo2.close();
archivo1.close();
mezcla<<1 <<endl;
mezcla.close();

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

Pgina 753

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)

Pgina 754

Fundamentosdelaprogramacin

8
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

LuisHernndezYez

Facultad de Informtica
Universidad Complutense

Programasmultiarchivoycompilacinseparada
Interfazfrenteaimplementacin
Usodemdulosdebiblioteca
Ejemplo:GestindeunalistaordenadaI
Compilacindeprogramasmultiarchivo
Elpreprocesador
Cadacosaensumdulo
Ejemplo:GestindeunalistaordenadaII
Elproblemadelasinclusionesmltiples
Compilacincondicional
Proteccinfrenteainclusionesmltiples
Ejemplo:GestindeunalistaordenadaIII
Implementacionesalternativas
Espaciosdenombres
Implementacionesalternativas
Calidadyreutilizacindelsoftware

Fundamentosdelaprogramacin:Programacinmodular

757
762
768
770
778
780
782
784
789
794
795
796
804
808
817
827

LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular

Pgina 757

Programas multiarchivo
Cdigo fuente repartido entre varios archivos (mdulos)
Cada mdulo con sus declaraciones y sus subprogramas
Mdulo: Unidad funcional (estructura de datos, utilidades, ...)
Principal

Lista
constintN=10;
typedefdoubletArray[N];
typedefstruct{
tArray elem;
intcont;
}tArray;
voidinit(tArray &lista);
voidinsert(tArray &lista,
doubleelem,bool&ok);
voidremove(tArray &lista,
intpos,bool&ok);
...

Clculos

intmain(){
tArray lista;
boolok;
init(lista);
cargar(lista,"bd.txt");
sort(lista);
doubledato;
cout<<"Dato:";
cin>>dato;
insert(lista,dato,ok);
cout<<min(lista)<<endl;
cout<<max(lista)<<endl;
cout<<sum(lista)<<endl;
guardar(lista,"bd.txt");

doublemean(tArray lista);

Archivos
boolcargar(tArray &lista,
stringnombre);

doublemin(tArray lists);
doublemax(tArray lista);
doubledesv(tArray lista);

boolguardar(tArray lista,
stringnombre);
boolmezclar(stringarch1,
stringarch2);

intminIndex(tArray lista);
intsize(stringnombre);
intmaxIndex(tArray lista);
boolexportar(stringnombre);
doublesum(tArray lista);

return0;

LuisHernndezYez

Ejecutable
Fundamentosdelaprogramacin:Programacinmodular

Pgina 758

Compilacin separada
Cada mdulo se compila a cdigo objeto de forma independiente
Lista

lista.obj

constintN=10;
typedefdoubletArray[N];
typedefstruct{
tArray elem;
intcont;
}tArray;
voidinit(tArray &lista);
voidinsert(tArray &lista,
doubleelem,bool&ok);
voidremove(tArray &lista,
intpos,bool&ok);
...

Clculos

00101110101011001010010010101
00101010010101011111010101000
10100101010101010010101010101
01100101010101010101010101001
01010101010100000101010101101
01001010101010101000010101011
11001010101010111100110010101
01101010101010010010101001111
00101010101001010100101010010
10100101010100101000010011110
10010101011001010101001010100
10101010101010010101001010101
01000010101011100101010010100
01110101011101001101010100101
01011111110101011001101010111
00001001010100101010101010110

calculos.obj

Archivos

archivos.obj

boolcargar(tArray &lista,
stringnombre);
boolguardar(tArray lista,
stringnombre);
boolmezclar(stringarch1,
stringarch2);
intsize(stringnombre);
boolexportar(stringnombre);

doublemean(tArray lista);
doublemin(tArray lists);

LuisHernndezYez

doublemax(tArray lista);
doubledesv(tArray lista);
intminIndex(tArray lista);
intmaxIndex(tArray lista);
doublesum(tArray lista);

01011001010010010101001010100
10101011111010101000101001010
10101010010101010101011001010
10101010101010101001010101010
10100000101010101101010010101
01010101000010101011110010101
01010111100110010101011010101
01010010010101001111001010101
01001010100101010010101001010
10100101000010011110100101010
11001010101001010100101010101
01010010101001010101010000101
01011100101010010100011101010
11101001101010100101010111111
10101011001101010111000010010
10100101010101010110001111010

Fundamentosdelaprogramacin:Programacinmodular

11101010110010100100101010010
10100101010111110101010001010
01010101010100101010101010110
01010101010101010101010010101
01010101000001010101011010100
10101010101010000101010111100
10101010101111001100101010110
10101010100100101010011110010
10101010010101001010100101010
01010101001010000100111101001
01010110010101010010101001010
10101010100101010010101010100
00101010111001010100101000111
01010111010011010101001010101
11111101010110011010101110000
10010101001010101010101101111

Pgina 759

Compilacin separada
Al compilar el programa principal, se adjuntan los mdulos compilados
Principal
Mdulos del programa

intmain(){
tArray lista;
boolok;
init(lista);
cargar(lista,"bd.txt");
sort(lista);
doubledato;
cout<<"Dato:";
cin>>dato;
insert(lista,dato,ok);
cout<<min(lista)<<endl;
cout<<max(lista)<<endl;
cout<<sum(lista)<<endl;
guardar(lista,"bd.txt");

lista.obj
calculos.obj

LuisHernndezYez

archivos.obj

...

return0;
}

Bibliotecas del sistema


iostream.obj
fstream.obj
math.obj

Ejecutable

Fundamentosdelaprogramacin:Programacinmodular

Pgina 760

...

Compilacin separada
Slo los archivos fuente modificados necesitan ser recompilados!
Principal
lista.cpp

main.cpp

COMPILACIN
lista.obj

archivos.obj
...

iostream.obj
fstream.obj

main.obj

math.obj

...
ENLACE

Ejecutable
Fundamentosdelaprogramacin:Programacinmodular

Pgina 761

Fundamentosdelaprogramacin:Programacinmodular

Pgina 762

LuisHernndezYez

LuisHernndezYez

calculos.obj

LuisHernndezYez

Creacin de mdulos de biblioteca


Cdigo de un programa de un nico archivo:
Definiciones de constantes
Declaraciones de tipos de datos
Prototipos de los subprogramas
Implementacin de los subprogramas
Implementacin de la funcin main()
Constantes, tipos y prototipos indican cmo se usa: Interfaz
Estructura de datos con los subprogramas que la gestionan
Conjunto de utilidades (subprogramas) de uso general
Etctera
+ Implementacin de los subprogramas (cmo se hace)
Fundamentosdelaprogramacin:Programacinmodular

Pgina 763

LuisHernndezYez

Creacin de mdulos de biblioteca


Interfaz: Definiciones/declaraciones de datos y prototipos
Todo lo que el usuario de la unidad funcional necesita saber!
Implementacin: Cdigo de los subprogramas que hacen el trabajo
No hay que conocerlo para usarlo: Seguro que es correcto!
Interfaz e implementacin en dos archivos separados:
Cabecera: Definiciones/declaraciones de datos y prototipos
Implementacin: Implementacin de los subprogramas.
Archivo de cabecera: extensin .h
Mismo nombre
Archivo de implementacin: extensin .cpp
Repartimos el cdigo entre ambos archivos (lista.h/lista.cpp)

Fundamentosdelaprogramacin:Programacinmodular

Pgina 764

Creacin de mdulos de biblioteca


Interfaz frente a implementacin
lista.h
constintN=10;
typedefdoubletArray[N];
typedefstruct{
tArray elem;
intcont;
}tArray;
voidinit(tArray &lista);
voidinsert(tArray &lista,
doubleelem,bool&ok);

LuisHernndezYez

voidremove(tArray &lista,
intpos,bool&ok);
...

lista.cpp

Mdulo
Unidad
Biblioteca

#include"lista.h"
voidinit(tArray &lista){
lista.cont =0;
}
voidinsert(tArray &lista,
doubleelem,bool&ok){
if(lista.cont ==N){
okfalse;
}
else{
...

Si otro mdulo quiere usar algo de esa biblioteca:


Debe incluir el archivo de cabecera
main.cpp
#include"lista.h"
...

Los nombres de archivos de cabecera


propios (no del sistema) se encierran
entre dobles comillas, no entre ngulos

Fundamentosdelaprogramacin:Programacinmodular

Pgina 765

Creacin de mdulos de biblioteca

lista.h
constintN=10;
typedefdoubletArray[N];
typedefstruct{
tArray elem;
intcont;
}tArray;

Interfaz
Archivo de cabecera (.h): todo lo que necesita
conocer otro mdulo (o programa principal)
que quiera utilizar sus servicios (subprogramas)
La directiva #include aade las declaraciones del archivo
de cabecera en el cdigo del mdulo (preprocesamiento):

voidinit(tArray &lista);
voidinsert(tArray &lista,
doubleelem,bool&ok);
voidremove(tArray &lista,
intpos,bool&ok);
...

main.cpp

LuisHernndezYez

#include"lista.h"
...

Preprocesador

Todo lo que se necesita saber para


comprobar si el cdigo de main.cpp
hace un uso correcto de la lista
(declaraciones y llamadas)
Fundamentosdelaprogramacin:Programacinmodular

main.cpp
constintN=10;
typedefdoubletArray[N];
typedefstruct{
tArray elem;
intcont;
}tArray;
voidinit(tArray &lista);
voidinsert(tArray &lista,doubleelem,
bool&ok);
voidremove(tArray &lista,intpos,
bool&ok);
...

Pgina 766

Creacin de mdulos de biblioteca

lista.cpp

Implementacin
Compilar el mdulo significa compilar
su archivo de implementacin (.cpp)
Tambin necesita conocer sus propias declaraciones:

#include"lista.h"
voidinit(tArray &lista){
lista.cont =0;
}
voidinsert(tArray &lista,
doubleelem,bool&ok){
if(lista.cont ==N){
okfalse;
}
else{
...

lista.cpp
lista.obj
00101110101011001010010010101
00101010010101011111010101000
10100101010101010010101010101
01100101010101010101010101001
01010101010100000101010101101
01001010101010101000010101011
11001010101010111100110010101
01101010101010010010101001111
00101010101001010100101010010
10100101010100101000010011110
10010101011001010101001010100
10101010101010010101001010101
01000010101011100101010010100
01110101011101001101010100101
01011111110101011001101010111
00001001010100101010101010110

Al compilar el mdulo se genera el cdigo objeto


Si no se modifica no hay necesidad de recompilar
Cdigo que usa el mdulo:
Necesita slo el archivo de cabecera para compilar
Se adjunta el cdigo objeto del mdulo durante el enlace
Fundamentosdelaprogramacin:Programacinmodular

Pgina 767

Fundamentosdelaprogramacin:Programacinmodular

Pgina 768

LuisHernndezYez

LuisHernndezYez

#include"lista.h"
...

LuisHernndezYez

Uso de mdulos de biblioteca


Ejemplo: Gestin de una lista ordenada (Tema 7)
Todo lo que tenga que ver con la lista estar en su propio mdulo
Ahora el cdigo estar repartido en tres archivos:
lista.h: archivo de cabecera del mdulo de lista
lista.cpp: implementacin del mdulo de lista
bd.cpp: programa principal que usa la lista
Tanto lista.cpp como bd.cpp deben incluir al principio lista.h
Mdulo propio: dobles comillas en la directiva #include
#include "lista.h"
Archivos de cabecera de bibliotecas del sistema: entre ngulos
Y no tienen necesariamente que llevar extensin .h
Fundamentosdelaprogramacin:Programacinmodular

Pgina 769

Archivodecabecera

lista.h

Mdulo: Gestin de una lista ordenada I

LuisHernndezYez

#include<string>
usingnamespacestd;
const int N=100;
typedef struct {
int codigo;
string nombre;
double sueldo;
}tRegistro;
typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;
const string BD="bd.txt";
...
Documenta bien el cdigo!
Fundamentosdelaprogramacin:Programacinmodular

Pgina 770

void mostrar(int pos,tRegistro registro);


voidmostrar(const tLista&lista);
booloperator>(tRegistro opIzq,tRegistro opDer);
booloperator<(tRegistro opIzq,tRegistro opDer);
tRegistro nuevo();
void insertar(tLista&lista,tRegistro registro,bool &ok);
voideliminar(tLista&lista,intpos,bool &ok);//pos=1..N
intbuscar(tLista lista,stringnombre);
voidcargar(tLista&lista,bool &ok);

LuisHernndezYez

voidguardar(tLista lista);

Cada prototipo, con un comentario que explique su utilidad/uso


(Aqu se omiten por cuestin de espacio)

Fundamentosdelaprogramacin:Programacinmodular

Pgina 771

Implementacin

lista.cpp

Mdulo: Gestin de una lista ordenada I

LuisHernndezYez

#include <iostream>
#include <string>
usingnamespacestd;
#include <fstream>
#include <iomanip>
#include "lista.h"
tRegistro nuevo(){
tRegistro registro;
cout<<"Introduceelcdigo:";
cin>>registro.codigo;
cout<<"Introduceelnombre:";
cin>>registro.nombre;
cout<<"Introduceelsueldo:";
cin>>registro.sueldo;
return registro;
}...
Fundamentosdelaprogramacin:Programacinmodular

Pgina772

LuisHernndezYez

void insertar(tLista&lista,tRegistro registro,bool &ok){


ok=true;
if (lista.cont ==N){
ok=false;//Listallena
}
else {
int i=0;
while((i<lista.cont)&&(lista.registros[i]<registro)){
i++;
}
//Insertamosenlaposicini
for (intj=lista.cont;j>i;j){
//Desplazamosaladerecha
lista.registros[j]=lista.registros[j 1];
}
lista.registros[i]=registro;
lista.cont++;
}
}...
Fundamentosdelaprogramacin:Programacinmodular

Pgina773

LuisHernndezYez

voideliminar(tLista&lista,intpos,bool &ok){//pos=1..
ok=true;
if ((pos<1)||(pos>lista.cont)){
ok=false;//Posicininexistente
}
else {
pos;//Pasamosandicedelarray
for (inti=pos+1;i<lista.cont;i++){
//Desplazamosalaizquierda
lista.registros[i 1]=lista.registros[i];
}
lista.cont;
}
}
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina774

Programaprincipal

bd.cpp

Mdulo: Gestin de una lista ordenada I


#include<iostream>
usingnamespacestd;
#include"lista.h"

LuisHernndezYez

intmenu();
int main(){
tLista lista;
bool ok;
int op,pos;
cargar(lista,ok);
if (!ok){
cout<<"Nosehapodidoabrirelarchivo!"<<endl;
}
else {
do {
mostrar(lista);
op =menu();...

LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular

Pgina775

if (op ==1){
tRegistro registro=nuevo();
insertar(lista,registro,ok);
if (!ok){
cout<<"Error:Listallena!"<<endl;
}
}
elseif(op ==2){
cout<<"Posicin:";
cin>>pos;
eliminar(lista,pos,ok);
if (!ok){
cout<<"Error:Posicion inexistente!"<<endl;
}
}
elseif(op ==3){
stringnombre;
cin.sync();
cout<<"Nombre:";
cin>>nombre;
intpos=buscar(lista,nombre);
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina776

if (pos==1){
cout<<"Nosehaencontrado!" <<endl;
}
else {
cout<<"Encontradoenlaposicin" <<pos<<endl;
}
}
}while (op !=0);
guardar(lista);
}
return 0;
int menu(){
cout<<endl;
cout<<"1 Insertar"<<endl;
cout<<"2 Eliminar" <<endl;
cout<<"3 Buscar" <<endl;
cout<<"0 Salir" <<endl;
int op;
do {
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina777

Fundamentosdelaprogramacin:Programacinmodular

Pgina 778

LuisHernndezYez

LuisHernndezYez

G++
Archivos de cabecera e implementacin en la misma carpeta
Listamos todos los .cpp en la orden g++:
D:\FP\Tema08>g++obd.exelista.cppbd.cpp
Recuerda que slo se compilan los .cpp

Visual C++/Studio

A los archivos de cabecera


los llama de encabezado
Con Depurar>Generarsolucin
se compilan todos los .cpp
Fundamentosdelaprogramacin:Programacinmodular

Pgina 779

Fundamentosdelaprogramacin:Programacinmodular

Pgina 780

LuisHernndezYez

LuisHernndezYez

Archivos de cabecera e implementacin en grupos distintos:

Directivas: #...
Antes de compilar se pone en marcha el preprocesador
Interpreta las directivas y genera un nico archivo temporal con
todo el cdigo del mdulo o programa
Como en la inclusin (directiva #include):
#include<string>
usingnamespacestd;

intmenu();

#include<string>
usingnamespacestd;

...

constintN=100;

typedefstruct{
intcodigo;
stringnombre;
doublesueldo;
}tRegistro;

typedefstruct{
intcodigo;
stringnombre;
doublesueldo;
}tRegistro;

typedeftRegistro
tArray[N];

typedeftRegistro
tArray[N];

typedefstruct{
tArray registros;
intcont;
}tLista;
...

typedefstruct{
tArray registros;
intcont;
}tLista;
...
intmenu();
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 781

Fundamentosdelaprogramacin:Programacinmodular

Pgina 782

LuisHernndezYez

LuisHernndezYez

constintN=100;

#include"lista.h"

Distribuir la funcionalidad del programa en mdulos

LuisHernndezYez

Encapsulacin de un conjunto de subprogramas relacionados:


Por la estructura de datos sobre la que trabajan
Subprogramas de utilidad
A menudo las estructuras de datos contienen otras estructuras:
const int N=100;
typedef struct {
int codigo;
string nombre;
double sueldo;
}tRegistro;
typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;

Lista de registros:
Estructura tRegistro
Estructura tLista
(contiene tRegistro)
Cada estructura, en su mdulo

Fundamentosdelaprogramacin:Programacinmodular

Pgina 783

Cabecera

registro.h

Gestin de una lista ordenada II


#include<string>
usingnamespacestd;

LuisHernndezYez

typedef struct {
int codigo;
string nombre;
double sueldo;
}tRegistro;
tRegistro nuevo();
booloperator>(tRegistro opIzq,tRegistro opDer);
booloperator<(tRegistro opIzq,tRegistro opDer);
void mostrar(int pos,tRegistro registro);

Fundamentosdelaprogramacin:Programacinmodular

Pgina 784

Implementacin

registro.cpp

Gestin de una lista ordenada II

LuisHernndezYez

#include <iostream>
#include <string>
usingnamespacestd;
#include <iomanip>
#include "registro.h"
tRegistro nuevo(){
tRegistro registro;
cout<<"Introduceelcdigo:";
cin>>registro.codigo;
cout<<"Introduceelnombre:";
cin>>registro.nombre;
cout<<"Introduceelsueldo:";
cin>>registro.sueldo;
return registro;
}
booloperator>(tRegistro opIzq,tRegistro opDer){
returnopIzq.nombre >opDer.nombre;
}...
Fundamentosdelaprogramacin:Programacinmodular

Pgina 785

Cabecera

lista2.h

Gestin de una lista ordenada II


#include<string>
usingnamespacestd;
#include "registro.h"

LuisHernndezYez

const int N=100;


typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;
const string BD="bd.txt";
void insertar(tLista&lista,tRegistro registro,bool&ok);
voideliminar(tLista&lista,intpos,bool &ok);//pos=1..N
intbuscar(tLista lista,stringnombre);
voidmostrar(const tLista&lista);
voidcargar(tLista&lista,bool &ok);
voidguardar(tLista lista);

Fundamentosdelaprogramacin:Programacinmodular

Pgina 786

Implementacin

lista2.cpp

Gestin de una lista ordenada II

LuisHernndezYez

#include <iostream>
usingnamespacestd;
#include <fstream>
#include "lista2.h"
void insertar(tLista&lista,tRegistro registro,bool&ok){
ok=true;
if (lista.cont ==N){
ok=false;//Lista llena
}
else {
int i =0;
while((i<lista.cont)&&(lista.registros[i]<registro)){
i++;
}
//Insertamos enlaposicin i
for (intj=lista.cont;j>i;j){//Desplazar aladerecha
lista.registros[j]=lista.registros[j 1];
}
...
Fundamentosdelaprogramacin:Programacinmodular

Pgina 787

bd2.cpp

Gestin de una lista ordenada II


#include<iostream>
usingnamespacestd;
#include"registro.h"
#include"lista2.h"
intmenu();

LuisHernndezYez

int main(){
tLista lista;
bool ok;
int op,pos;

No intentes compilar este ejemplo!


Tiene errores

cargar(lista,ok);
if (!ok){
cout<<"Nosepudoabrirelarchivo!"<<endl;
}
else {
do {
mostrar(lista);
op =menu();
...
Fundamentosdelaprogramacin:Programacinmodular

Pgina788

LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular

Pgina 789

Gestin de una lista ordenada II


2 mdulos y el programa principal:

bd2.cpp
...
#include"registro.h"
#include"lista2.h"
...

registro.h
#include<string>
...

registro.cpp
...
#include"registro.h"
...

lista2.h

LuisHernndezYez

...
#include"registro.h"
...

lista2.cpp

Incluye...

...
#include"lista2.h"
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 790

Gestin de una lista ordenada II


Preprocesamiento de #include:
#include<iostream>
usingnamespacestd;

#include<string>
usingnamespacestd;
typedef struct {
...
}tRegistro;
...

#include"registro.h"
#include"lista2.h"
intmenu();
#include<string>
usingnamespacestd;
#include "registro.h"

...

LuisHernndezYez

const int N=100;


typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;
...

#include<string>
usingnamespacestd;
typedef struct {
...
}tRegistro;
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 791

Gestin de una lista ordenada II


Preprocesamiento de #include:
#include<iostream>
usingnamespacestd;
#include<string>
usingnamespacestd;
typedef struct {
...
}tRegistro;
...

Sustituido

#include<string>
usingnamespacestd;
#include<string>
usingnamespacestd;
typedef struct {
...
}tRegistro;
...

#include"lista2.h"

LuisHernndezYez

intmenu();
...

const int N=100;


typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 792

Gestin de una lista ordenada II


#include<iostream>
usingnamespacestd;

const int N=100;


typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;
...

#include<string>
usingnamespacestd;
typedef struct {
...
}tRegistro;
...

intmenu();
...

LuisHernndezYez

#include<string>
usingnamespacestd;
#include<string>
usingnamespacestd;

Identificador duplicado!

typedef struct {
...
}tRegistro;
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 793

Compilacin condicional
Directivas #ifdef, #ifndef, #else y #endif
Se usan en conjuncin con la directiva #define

LuisHernndezYez

#define X
#ifdef X
...//Cdigoif
[#else
...//Cdigoelse
]
#endif

#define X
#ifndef X
...//Cdigoif
[#else
...//Cdigoelse
]
#endif

La directiva #define define un smbolo (identificador)


Izquierda: se compilar el Cdigo if y no el Cdigo else
Derecha: al revs, o nada si no hay else
Las clusulas else son opcionales
Fundamentosdelaprogramacin:Programacinmodular

Pgina 794

Proteccin frente a inclusiones mltiples


lista2.cpp y bd2.cpp incluyen registro.h

Identificadores duplicados!
Cada mdulo debe incluirse una y slo una vez
Proteccin frente a inclusiones mltiples:

LuisHernndezYez

#ifndef X
#define X
...//Mdulo
#endif

El smbolo X debe ser nico


para cada mdulo de la aplicacin

La primera vez no est definido el smbolo X: se incluye y define


Las siguientes veces el smbolo X ya est definido: no se incluye
Smbolo X: nombre del archivo con _ en lugar de .
registro_h, lista2_h, ...
Fundamentosdelaprogramacin:Programacinmodular

Pgina 795

Cabecera

registrofin.h

Gestin de una lista ordenada III


#ifndef registrofin_h
#define registrofin_h
#include<string>
usingnamespacestd;

LuisHernndezYez

typedef struct {
int codigo;
string nombre;
double sueldo;
}tRegistro;
tRegistro nuevo();
booloperator>(tRegistro opIzq,tRegistro opDer);
booloperator<(tRegistro opIzq,tRegistro opDer);
void mostrar(int pos,tRegistro registro);
#endif
Fundamentosdelaprogramacin:Programacinmodular

Pgina 796

Implementacin

registrofin.cpp

Gestin de una lista ordenada III

LuisHernndezYez

#include <iostream>
#include <string>
usingnamespacestd;
#include <iomanip>
#include "registrofin.h"
tRegistro nuevo(){
tRegistro registro;
cout<<"Introduceelcdigo:";
cin>>registro.codigo;
cout<<"Introduceelnombre:";
cin>>registro.nombre;
cout<<"Introduceelsueldo:";
cin>>registro.sueldo;
return registro;
}
booloperator>(tRegistro opIzq,tRegistro opDer){
returnopIzq.nombre >opDer.nombre;
}...
Fundamentosdelaprogramacin:Programacinmodular

Pgina 797

Cabecera

listafin.h

Gestin de una lista ordenada III

LuisHernndezYez

#ifndef listafin_h
#define listafin_h
#include<string>
usingnamespacestd;
#include "registrofin.h"
const int N=100;
typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;
const string BD="bd.txt";
voidmostrar(const tLista&lista);
void insertar(tLista&lista,tRegistro registro,bool&ok);
voideliminar(tLista&lista,intpos,bool&ok);//pos=1..N
intbuscar(tLista lista,stringnombre);
voidcargar(tLista&lista,bool&ok);
voidguardar(tLista lista);
#endif
Fundamentosdelaprogramacin:Programacinmodular

Pgina 798

Implementacin

listafin.cpp

Gestin de una lista ordenada III

LuisHernndezYez

#include <iostream>
usingnamespacestd;
#include <fstream>
#include "listafin.h"
void insertar(tLista&lista,tRegistro registro,bool &ok){
ok=true;
if (lista.cont ==N){
ok=false;//listallena
}
else {
int i=0;
while((i<lista.cont)&&(lista.registros[i]<registro)){
i++;
}
//Insertamosenlaposicini
for (intj=lista.cont;j>i;j){
//Desplazamosaladerecha
lista.registros[j]=lista.registros[j 1];
}
...
Fundamentosdelaprogramacin:Programacinmodular

Pgina799

bdfin.cpp

Gestin de una lista ordenada III


#include<iostream>
usingnamespacestd;
#include"registrofin.h"
#include"listafin.h"
intmenu();

LuisHernndezYez

int main(){
tLista lista;
bool ok;
int op,pos;

Ahora ya puedes compilarlo!

cargar(lista,ok);
if (!ok){
cout<<"Nosepudo abrir elarchivo!" <<endl;
}
else {
do {
mostrar(lista);
op=menu();
...
Fundamentosdelaprogramacin:Programacinmodular

Pgina 800

Gestin de una lista ordenada III


Preprocesamiento de #include en bdfin.cpp:
#include<iostream>
usingnamespacestd;

#ifndef registrofin_h
#define registrofin_h
#include<string>
usingnamespacestd;

#include"registrofin.h"
#include"listafin.h"

typedef struct {
...
}tRegistro;
...

intmenu();
...

LuisHernndezYez

registrofin_h no se ha definido todava

Fundamentosdelaprogramacin:Programacinmodular

Pgina 801

Gestin de una lista ordenada III


Preprocesamiento de #include en bdfin.cpp:
#include<iostream>
usingnamespacestd;
#define registrofin_h
#include<string>
usingnamespacestd;

LuisHernndezYez

typedef struct {
...
}tRegistro;
...
#include"listafin.h"

#ifndef listafin_h
#define listafin_h
#include<string>
usingnamespacestd;
#include "registrofin.h"
const int N=100;
typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;
...

intmenu();
...

listafin_h no se ha definido todava

Fundamentosdelaprogramacin:Programacinmodular

Pgina 802

Gestin de una lista ordenada III


Preprocesamiento de #include en bdfin.cpp:

typedef struct {
...
}tRegistro;
...

#ifndef registrofin_h
#define registrofin_h
#include<string>
usingnamespacestd;

#define listafin_h
#include<string>
usingnamespacestd;
#include "registrofin.h"

typedef struct {
...
}tRegistro;
...

...
intmenu();

registrofin_h ya est definido!

...
Fundamentosdelaprogramacin:Programacinmodular

Pgina 803

Fundamentosdelaprogramacin:Programacinmodular

Pgina 804

LuisHernndezYez

LuisHernndezYez

#include<iostream>
usingnamespacestd;
#define registrofin_h
#include<string>
usingnamespacestd;

Misma interfaz, implementacin alternativa


lista.h

#include<string>
usingnamespacestd;
#include "registrofin.h"

Lista
ordenada

const int N=100;


typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;

Lista
no ordenada

LuisHernndezYez

void insertar(tLista&lista,tRegistro registro,bool &ok);


void insertar(tLista&lista,tRegistro registro,bool &ok){
ok=true;
void insertar(tLista&lista,tRegistro registro,bool &ok){
if (lista.cont ==N){
ok=true;
ok=false;//Lista llena
if (lista.cont ==N){
}
ok=false;//Listallena
else {
}
int i =0;
else {
while((i<lista.cont)&&(lista.registros[i]<registro)){
i++;
lista.registros[lista.cont]=registro;
}
lista.cont++;
//Insertamos enlaposicin i
}
for (intj=lista.cont;j>i;j){ }
//Desplazamos aladerecha
lista.registros[j]=lista.registros[j 1];
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 805

Misma interfaz, implementacin alternativa


listaDES.cpp: Lista no ordenada
...
#include "lista.h"

void insertar(tLista&lista,tRegistro registro,bool &ok){


ok=true;
if (lista.cont ==N){
ok=false;//Listallena
...
}
#include "lista.h"
else {
lista.registros[lista.cont]=registro;
void insertar(tLista&lista,tRegistro registro,bool &ok){
lista.cont++;
ok=true;
}
if (lista.cont ==N){
}
ok=false;//Lista llena
...
}
else {
int i=0;
while((i<lista.cont)&&(lista.registros[i]<registro)){
i++;
}
//Insertamos enlaposicin i
for (intj=lista.cont;j>i;j){
//Desplazamos aladerecha
lista.registros[j]=lista.registros[j 1];
}
lista.registros[i]=registro;
...

LuisHernndezYez

listaORD.cpp: Lista ordenada

Fundamentosdelaprogramacin:Programacinmodular

Pgina 806

Misma interfaz, implementacin alternativa


Al compilar, incluimos un archivo de implementacin u otro:
Programa con lista ordenada o con lista desordenada?
g++oprograma.exeregistrofin.cpplistaORD.cpp...

Incluye la implementacin de la lista con ordenacin


g++oprograma.exeregistrofin.cpplistaDES.cpp...

LuisHernndezYez

Incluye la implementacin de la lista sin ordenacin

Pgina 807

Fundamentosdelaprogramacin:Programacinmodular

Pgina 808

LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular

Agrupaciones lgicas de declaraciones


Espacio de nombres: agrupacin de declaraciones
(tipos, datos, subprogramas) bajo un nombre distintivo
Forma de un espacio de nombres:
namespace nombre {
//Declaraciones
}

LuisHernndezYez

Por ejemplo:
namespace miEspacio {
int i;
double d;
}

Variables i y d declaradas en el espacio de nombres miEspacio

Fundamentosdelaprogramacin:Programacinmodular

Pgina 809

Acceso a miembros de un espacio de nombres


Operador de resolucin de mbito (::)
Acceso a las variables del espacio de nombres miEspacio:
Nombre del espacio y operador de resolucin de mbito
miEspacio::i
miEspacio::d

LuisHernndezYez

Puede haber entidades con el mismo identificador en distintos


mdulos o en mbitos distintos de un mismo mdulo
Cada declaracin en un espacio de nombres distinto:
namespace primero {
int x=5;
}

namespace segundo {
double x=3.1416;
}

Ahora se distingue entre primero::x y segundo::x


Fundamentosdelaprogramacin:Programacinmodular

Pgina 810

using

LuisHernndezYez

Introduce un nombre de un espacio de nombres en el mbito actual:


#include <iostream>
usingnamespacestd;
namespace primero{
int x=5;
int y=10;
5
}
namespace segundo{
2.7183
double x=3.1416;
10
double y=2.7183;
}
3.1416
int main(){
using primero::x;
using segundo::y;
cout<<x<<endl;//xesprimero::x
cout<<y<<endl;//yessegundo::y
cout<<primero::y<<endl;//espacioexplcito
cout<<segundo::x<<endl;//espacioexplcito
return 0;
}
Fundamentosdelaprogramacin:Programacinmodular

Pgina 811

usingnamespace

LuisHernndezYez

Introduce todos los nombres de un espacio en el mbito actual:


#include <iostream>
usingnamespacestd;
namespace primero{
int x=5;
5
int y=10;
using [namespace]
10
}
slo tiene efecto
namespace segundo{
3.1416
double x=3.1416;
en el bloque
2.7183
double y=2.7183;
en que se encuentra
}
int main(){
usingnamespace primero;
cout<<x<<endl;//xesprimero::x
cout<<y<<endl;//yesprimero::y
cout<<segundo::x<<endl;//espacioexplcito
cout<<segundo::y<<endl;//espacioexplcito
return 0;
}
Fundamentosdelaprogramacin:Programacinmodular

Pgina 812

LuisHernndezYez

#ifndef listaEN_h
#definelistaEN_h
#include"registrofin.h"
namespace ord {//Listaordenada
const int N=100;
typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;
const stringBD="bd.txt";
voidmostrar(const tLista&lista);
voidinsertar(tLista&lista,tRegistro registro,bool &ok);
voideliminar(tLista&lista,intpos,bool &ok);//1..N
intbuscar(tLista lista,stringnombre);
voidcargar(tLista&lista,bool &ok);
voidguardar(tLista lista);
}//namespace
#endif
Fundamentosdelaprogramacin:Programacinmodular

Pgina 813

Implementacin
#include<iostream>
#include<fstream>
usingnamespacestd;
#include"listaEN.h"
void ord::insertar(tLista&lista,tRegistro registro,bool &ok){
//...
}

LuisHernndezYez

voidord::eliminar(tLista&lista,intpos,bool &ok){
//...
}
intord::buscar(tLista lista,stringnombre){
//...
}
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 814

Uso del espacio de nombres


Quien utilice listaEN.h debe poner el nombre del espacio:
#include<iostream>
usingnamespacestd;
#include"registrofin.h"
#include"listaEN.h"

LuisHernndezYez

int menu();
int main(){
ord::tLista lista;
boolok;
ord::cargar(lista,ok);
if (!ok){
cout<<"Nosepudoabrirelarchivo!"<<endl;
}
else {
ord::mostrar(lista);
...

O usar una instruccin usingnamespace ord;


Fundamentosdelaprogramacin:Programacinmodular

Pgina 815

Uso del espacio de nombres


#include<iostream>
usingnamespacestd;
#include"registrofin.h"
#include"listaEN.h"
usingnamespaceord;

LuisHernndezYez

int menu();
int main(){
tLista lista;
bool ok;
cargar(lista,ok);
if (!ok){
cout<<"Nosepudoabrirelarchivo!"<<endl;
}
else {
mostrar(lista);
...
Fundamentosdelaprogramacin:Programacinmodular

Pgina 816

Implementaciones alternativas
Distintos espacios de nombres para distintas implementaciones
Lista ordenada o lista desordenada?

LuisHernndezYez

namespace ord {//Lista ordenada


const int N=100;
typedef tRegistro tArray[N];
...
void mostrar(const tLista&lista);
void insertar(tLista&lista,tRegistro registro,bool &ok);
...
}//namespace
namespace des{//Lista desordenada
const int N=100;
typedef tRegistro tArray[N];
...
void mostrar(const tLista&lista);
void insertar(tLista&lista,tRegistro registro,bool &ok);
...
}//namespace
Fundamentosdelaprogramacin:Programacinmodular

Pgina 817

Cabecera

listaEN.h

Implementaciones alternativas
Todo lo comn puede estar fuera de la estructura namespace:
#ifndef listaEN_H
#definelistaEN_H
#include"registrofin.h"
const int N=100;

LuisHernndezYez

typedef tRegistro tArray[N];


typedef struct {
tArray registros;
int cont;
}tLista;
void mostrar(consttLista&lista);
void eliminar(tLista&lista,int pos,bool &ok);//pos =1..N
...
Fundamentosdelaprogramacin:Programacinmodular

Pgina 818

LuisHernndezYez

namespace ord {//Lista ordenada


const string BD="bd.txt";
void insertar(tLista&lista,tRegistro registro,bool &ok);
int buscar(tLista lista,string nombre);
void cargar(tLista&lista,bool &ok);
void guardar(tLista lista);
}//namespace
namespace des{//Lista desordenada
const string BD="bddes.txt";
void insertar(tLista&lista,tRegistro registro,bool &ok);
int buscar(tLista lista,string nombre);
void cargar(tLista&lista,bool &ok);
void guardar(tLista lista);
}//namespace
#endif

cargar() y guardar() se distinguen porque usan


su propia BD, pero se implementan exactamente igual

Fundamentosdelaprogramacin:Programacinmodular

Pgina 819

listaEN.cpp
#include<iostream>
usingnamespacestd;
#include <fstream>
#include "listaEN.h"
//IMPLEMENTACINDELOSSUBPROGRAMASCOMUNES
void eliminar(tLista&lista,int pos,bool &ok){//...
}

LuisHernndezYez

void mostrar(const tLista&lista){//...


}
//IMPLEMENTACINDELOSSUBPROGRAMASDELESPACIODENOMBRESord
void ord::insertar(tLista&lista,tRegistro registro,bool &ok){
ok=true;
if (lista.cont ==N){
ok=false;//Listallena
}
else {
int i=0;
while ((i<lista.cont)&&(lista.registros[i]<registro)){
i++;
}...
Fundamentosdelaprogramacin:Programacinmodular

Pgina 820

for (int j=lista.cont;j>i;j){


lista.registros[j]=lista.registros[j 1];
}
lista.registros[i]=registro;
lista.cont++;
}

LuisHernndezYez

}
int ord::buscar(tLista lista,string nombre){
int ini=0,fin=lista.cont 1,mitad;
bool encontrado=false;
while ((ini<=fin)&&!encontrado){
mitad=(ini+fin)/2;
if (nombre==lista.registros[mitad].nombre){
encontrado=true;
}
elseif(nombre<lista.registros[mitad].nombre){
fin=mitad 1;
}
else {
ini=mitad+1;
}
}...
Fundamentosdelaprogramacin:Programacinmodular

Pgina 821

if (encontrado){
mitad++;
}
else {
mitad=1;
}
return mitad;
}
void ord::cargar(tLista&lista,bool &ok){//...
}

LuisHernndezYez

void ord::guardar(tLista lista){//...


}
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 822

//IMPLEMENTACINDELOSSUBPROGRAMASDELESPACIODENOMBRESdes

LuisHernndezYez

void des::insertar(tLista&lista,tRegistro registro,bool &ok){


ok=true;
if (lista.cont ==N){
ok=false;//Listallena
}
else {
lista.registros[lista.cont]=registro;
lista.cont++;
}
}
int des::buscar(tLista lista,string nombre){
int pos=0;
bool encontrado=false;
while ((pos<lista.cont)&&!encontrado){
if (nombre==lista.registros[pos].nombre){
encontrado=true;
}
else {
pos++;
}
}...
Fundamentosdelaprogramacin:Programacinmodular

Pgina 823

if (encontrado){
pos++;
}
else {
pos=1;
}
return pos;
}
void des::cargar(tLista&lista,bool &ok){//...
}

LuisHernndezYez

void des::guardar(tLista lista){//...


}

Fundamentosdelaprogramacin:Programacinmodular

Pgina 824

bdEN.cpp

Programa principal
#include<iostream>
usingnamespacestd;
#include"registrofin.h"
#include"listaEN.h"
usingnamespaceord;

LuisHernndezYez

int menu();
int main(){
tLista lista;
bool ok;
...
tRegistro registro=nuevo();
insertar(lista,registro,ok);
if (!ok){
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 825

bdEN.cpp

Programa principal
#include<iostream>
usingnamespacestd;
#include"registrofin.h"
#include"listaEN.h"
usingnamespacedes;

LuisHernndezYez

int menu();
int main(){
tLista lista;
bool ok;
...
tRegistro registro=nuevo();
insertar(lista,registro,ok);
if (!ok){
...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 826

LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular

Pgina 827

Software de calidad

LuisHernndezYez

El software debe ser desarrollado con buenas prcticas de


ingeniera del software que aseguren un buen nivel de calidad
Los distintos mdulos de la aplicacin deben ser probados
exhaustivamente, tanto de forma independiente como en su
relacin con los dems mdulos
La prueba y depuracin es muy importante y todos los equipos
debern seguir buenas pautas para asegurar la calidad
Los mdulos deben ser igualmente bien documentados, de
forma que otros desarrolladores puedan aprovecharlos

Fundamentosdelaprogramacin:Programacinmodular

Pgina 828

LuisHernndezYez

Prueba exhaustiva
El software debe ser probado exhaustivamente
Debemos intentar descubrir todos los errores posible
Los errores deben ser depurados, corrigiendo el cdigo
Pruebas sobre listas:
Lista inicialmente vaca
Lista inicialmente llena
Lista con un nmero intermedio de elementos
Archivo no existente
Etctera...
Se han de probar todas las opciones/situaciones del programa
En las clases prcticas veremos cmo se depura el software
Fundamentosdelaprogramacin:Programacinmodular

Pgina 829

No reinventemos la rueda
Desarrollar el software pensando en su posible reutilizacin
Un software de calidad debe poder ser fcilmente reutilizado
Nuestros mdulos deben ser fcilmente usados y modificados

LuisHernndezYez

Por ejemplo: Nueva aplicacin que gestione una lista de longitud


variable de registros con NIF, nombre, apellidos y edad
Partiremos de los mdulos registro y lista existentes
Las modificaciones bsicamente afectarn al mdulo registro

Fundamentosdelaprogramacin:Programacinmodular

Pgina 830

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Programacinmodular

Pgina 831

Fundamentosdelaprogramacin

8A
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

ventas.cpp
#include<iostream>
#include<string>
usingnamespacestd;
const int NCLI=100;
const int NPROD=200;
const int NVENTAS=3000;
typedef struct {
intid_cli;
string nif;
string nombre;
string telefono;
}tCliente;

LuisHernndezYez

typedef struct {
tCliente clientes[NCLI];
int cont;
}tListaClientes;
typedef struct{
int id_prod;
string codigo;

string nombre;
double precio;
int unidades;
}tProducto;
typedef struct {
tProducto productos[NPROD];
int cont;
}tListaProductos;
typedef struct {
int id;
int id_prod;
int id_cli;
int unidades;
}tVenta;
typedef struct {
tVenta ventas[NVENTAS];
int cont;
}tListaVentas;
...

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 833

LuisHernndezYez

tCliente nuevoCliente();
bool valida(tCliente cliente);//Funcininterna
bool operator<(tCliente opIzq,tCliente opDer);//PorNIF
voidmostrar(tCliente cliente);
voidinicializar(tListaClientes &lista);
voidcargar(tListaClientes &lista);
voidinsertar(tListaClientes &lista,tCliente cliente,bool &ok);
voidbuscar(const tListaClientes &lista,stringnif,tCliente &cliente,bool &ok);
voideliminar(tListaClientes &lista,stringnif,bool &ok);
voidmostrar(const tListaClientes &lista);
tProducto nuevoProducto();
boolvalida(tProducto producto);//Funcininterna
booloperator<(tProducto opIzq,tProducto opDer);//Porcdigo
voidmostrar(tProducto producto);
voidinicializar(tListaProductos &lista);
voidcargar(tListaProductos &lista);
voidinsertar(tListaProductos &lista,tProducto producto,bool &ok);
voidbuscar(const tListaProductos &lista,stringcodigo,tProducto &producto,
bool &ok);
voideliminar(tListaProductos &lista,stringcodigo,bool &ok);
...

LuisHernndezYez

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 834

void mostrar(const tListaProductos &lista);


tVenta nuevaVenta(int id_prod,int id_cli,intunidades);
bool valida(tVenta venta);//Funcininterna
voidmostrar(tVenta venta,consttListaClientes &clientes,
const tListaProductos &productos);
voidinicializar(tListaVentas &lista);
voidcargar(tListaVentas &lista);
void insertar(tListaVentas &lista,tVenta venta,bool &ok);
voidbuscar(const tListaVentas &lista,intid,tVenta &venta,bool &ok);
void eliminar(tListaVentas &lista,intid,bool &ok);
voidventasPorClientes(const tListaVentas &lista);
voidventasPorProductos(const tListaVentas &lista);
doubletotalVentas(const tListaVentas &ventas,stringnif,
consttListaClientes &clientes,
consttListaProductos &productos);
voidstock(const tListaVentas &ventas,consttListaClientes &clientes,
consttListaProductos &productos);
intmenu();
intmain(){
...

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 835

string nombre;
double precio;
int unidades;
}tProducto;

#include<iostream>
#include<string>
usingnamespacestd;
const int NCLI=100;
const int NPROD=200;
const int NVENTAS=3000;

LuisHernndezYez

typedef struct {
intid_cli;
string nif;
string nombre;
string telefono;
}tCliente;

Cliente

Lista de clientes

typedef struct {
tCliente clientes[NCLI];
int cont;
}tListaClientes;
typedef struct{
int id_prod;
string codigo;

Producto

Lista de productos

typedef struct {
tProducto productos[NPROD];
int cont;
}tListaProductos;
typedef struct {
int id;
int id_prod;
int id_cli;
int unidades;
}tVenta;

Venta

Lista de ventas

typedef struct {
tVenta ventas[NVENTAS];
int cont;
}tListaVentas;
...

Fundamentosdelaprogramacin:Ejemplodemodularizacin

tCliente nuevoCliente();

Pgina 836

Cliente

bool valida(tCliente cliente);//Funcininterna


bool operator<(tCliente opIzq,tCliente opDer);//PorNIF

Lista de clientes

voidmostrar(tCliente cliente);
voidinicializar(tListaClientes &lista);
voidcargar(tListaClientes &lista);
voidinsertar(tListaClientes &lista,tCliente cliente,bool &ok);

voidbuscar(const tListaClientes &lista,stringnif,tCliente &cliente,


bool &ok);
voideliminar(tListaClientes &lista,stringnif,bool &ok);
voidmostrar(const tListaClientes &lista);
tProducto nuevoProducto();
boolvalida(tProducto producto);//Funcininterna

Producto

LuisHernndezYez

booloperator<(tProducto opIzq,tProducto opDer);//Porcdigo


voidmostrar(tProducto producto);
...

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 837

Lista de productos
voidinicializar(tListaProductos &lista);
voidcargar(tListaProductos &lista);
voidinsertar(tListaProductos &lista,tProducto producto,bool &ok);
voidbuscar(const tListaProductos &lista,stringcodigo,tProducto &producto,
bool &ok);
voideliminar(tListaProductos &lista,stringcodigo,bool &ok);
void mostrar(const tListaProductos &lista);
tVenta nuevaVenta(int id_prod,int id_cli,intunidades);
bool valida(tVenta venta);//Funcininterna
voidmostrar(tVenta venta,consttListaClientes &clientes,
const tListaProductos &productos);

Venta

LuisHernndezYez

...

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 838

Lista de ventas
voidinicializar(tListaVentas &lista);
voidcargar(tListaVentas &lista);
void insertar(tListaVentas &lista,tVenta venta,bool &ok);
voidbuscar(const tListaVentas &lista,intid,tVenta &venta,bool &ok);
void eliminar(tListaVentas &lista,intid,bool &ok);
voidventasPorClientes(const tListaVentas &lista);
voidventasPorProductos(const tListaVentas &lista);
doubletotalVentas(const tListaVentas &ventas,stringnif,
consttListaClientes &clientes,
consttListaProductos &productos);

LuisHernndezYez

voidstock(const tListaVentas &ventas,consttListaClientes &clientes,


consttListaProductos &productos);
intmenu();
intmain(){
...

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 839

LuisHernndezYez

Cliente: cliente.h y cliente.cpp


Lista de clientes: listaclientes.h y listaclientes.cpp
Producto: producto.h y producto.cpp
Lista de productos: listaproductos.h y listaproductos.cpp
Venta: venta.h y venta.cpp
Lista de ventas: listaventas.h y listaventas.cpp
Programa principal: main.cpp
Distribucin del cdigo en los mdulos:
Declaraciones de tipos y datos en el archivo de cabecera (.h)
Prototipos en el archivo de cabecera (.h) (excepto los de los
subprogramas privados internos, que irn en el .cpp)
Implementacin de los subprogramas en el .cpp

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 840

Ventas

LuisHernndezYez

main.cpp

Cliente

Lista de clientes

Venta

Lista de ventas

cliente.h
cliente.cpp

listaclientes.h
listaclientes.cpp

venta.h
venta.cpp

listaventas.h
listaventas.cpp

Producto

Lista de productos

producto.h
producto.cpp

listaproductos.h
listaproductos.cpp

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 841

Inclusiones (adems de otras bibliotecas del sistema)


typedef struct {
intid_cli;
string nif;
string nombre;
string telefono;
}tCliente;

cliente.h

string

const int NCLI=100;

LuisHernndezYez

typedef struct {
tCliente clientes[NCLI];
int cont;
}tListaClientes;

listaclientes.h

cliente.h
string

voidbuscar(const tListaClientes &lista,stringnif,tCliente


&cliente,bool &ok);

Fundamentosdelaprogramacin:Ejemplodemodularizacin

typedef struct{
int id_prod;
string codigo;
string nombre;
double precio;
int unidades;
}tProducto;

producto.h

Pgina 842

string

LuisHernndezYez

const int NPROD=200;


typedef struct {
tProducto productos[NPROD];
int cont;
}tListaProductos;

listaproductos.h

producto.h
string

voidbuscar(const tListaProductos &lista,stringcodigo,tProducto


&producto,bool &ok);

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 843

typedef struct {
int id;
int id_prod;
int id_cli;
int unidades;
}tVenta;

venta.h

listaclientes.h
listaproductos.h

voidmostrar(tVenta venta,consttListaClientes &clientes,


const tListaProductos &productos);
const int NVENTAS =3000;

LuisHernndezYez

listaventas.h
typedef struct {
tVenta ventas[NVENTAS];
int cont;
}tListaVentas;

venta.h
listaclientes.h
listaproductos.h

doubletotalVentas(const tListaVentas &ventas,stringnif,


consttListaClientes &clientes,
consttListaProductos &productos);
Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 844

#ifndef cliente_h
#definecliente_h
#include<string>
usingnamespacestd;

LuisHernndezYez

typedefstruct {
int id_cli;
string nif;
string nombre;
string telefono;
}tCliente;
tCliente nuevoCliente();
bool operator<(tCliente opIzq,tCliente opDer);//PorNIF
void mostrar(tCliente cliente);
#endif

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 845

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 846

Fundamentosdelaprogramacin

9
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

LuisHernndezYez

Facultad de Informtica
Universidad Complutense

Direccionesdememoriaypunteros
Operadoresdepunteros
Punterosydireccionesvlidas
Punterosnoinicializados
Unvalorseguro:NULL
Copiaycomparacindepunteros
Tipospuntero
Punterosaestructuras
Punterosaconstantesypunterosconstantes
Punterosypasodeparmetros
Punterosyarrays
Memoriaydatosdelprograma
Memoriadinmica
Punterosydatosdinmicos
Gestindelamemoria
Errorescomunes
Arraysdedatosdinmicos
Arraysdinmicos

Fundamentosdelaprogramacin:Punterosymemoriadinmica

849
854
864
866
867
868
873
875
877
879
883
886
891
895
907
911
916
928

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 849

Los datos en la memoria


Todo dato se almacena en memoria:
Varios bytes a partir de una direccin
i

int i=5;

LuisHernndezYez

Direccin base

0F03:1A37

...

0F03:1A38

00000000

0F03:1A39

00000000

0F03:1A3A

00000000

0F03:1A3B

00000101

0F03:1A3C

...

El dato (i) se accede a partir de su direccin base (0F03:1A38)


Direccin de la primera celda de memoria utilizada por el dato
El tipo del dato (int) indica cuntos bytes (4) requiere el dato:
00000000000000000000000000000101 5
(La codificacin de los datos puede ser diferente; y la de las direcciones tambin)
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 850

Los punteros contienen direcciones de memoria


Un puntero sirve para acceder a travs de l a otro dato
El valor del puntero es la direccin de memoria base de otro dato
...
i

0F03:1A38

00

0F03:1A39

00

0F03:1A3A

00

0F03:1A3B

05

Indireccin:
Acceso indirecto a un dato

...

LuisHernndezYez

punt

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38
...

punt apunta a i

punt

De qu tipo es el dato apuntado?


Cuntas celdas ocupa?
Cmo se interpretan los 0/1?

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 851

Los punteros contienen direcciones de memoria


De qu tipo es el dato apuntado?
La variable a la que apunta un puntero ser de un tipo concreto
Cunto ocupa? Cmo se interpreta?
El tipo de variable apuntado se establece al declarar el puntero:
tipo*nombre;

El puntero nombre apuntar a una variable del tipo indicado


El asterisco (*) indica que es un puntero a datos de ese tipo

LuisHernndezYez

int*punt;//punt inicialmentecontieneunadireccin
//quenoesvlida(noapuntaanada)

El puntero punt apuntar a una variable entera (int)


int i;//Datoenterovs. int*punt;//Punteroaentero

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 852

Los punteros contienen direcciones de memoria


Las variables puntero tampoco se inicializan automticamente
Al declararlas sin inicializador contienen direcciones no vlidas
int*punt;//puntinicialmentecontieneunadireccin
//quenoesvlida(noapuntaanada)

Para qu sirven los punteros?


Para implementar el paso de parmetros por referencia
Para manejar datos dinmicos
(Datos que se crean y destruyen durante la ejecucin)
Para implementar los arrays
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 853

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 854

LuisHernndezYez

LuisHernndezYez

Un puntero puede apuntar a cualquier dato de su tipo base


Un puntero no tiene por qu apuntar necesariamente a un dato
(puede no apuntar a nada: valor NULL)

&
Obtener la direccin de memoria de ...
Operador monario y prefijo
& devuelve la direccin de memoria base del dato al que precede
int i;
cout<<&i;//Muestraladireccindememoriadei

Un puntero puede recibir la direccin de datos de su tipo base


punt

int i;
int*punt;

LuisHernndezYez

punt=&i;//puntcontieneladireccindei

Ahora punt ya contiene una direccin de memoria vlida


punt apunta a (contiene la direccin de) la variable i (int)

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 855

&
Obtener la direccin de memoria de ...
...

int i,j;

0F03:1A38
0F03:1A39

...

0F03:1A3A

int*punt;

0F03:1A3B

0F03:1A3C
0F03:1A3D
0F03:1A3E
0F03:1A3F
...

LuisHernndezYez

punt

0F07:0417
0F07:0418
0F07:0419
0F07:041A
...

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 856

&
Obtener la direccin de memoria de ...
...

int i,j;

0F03:1A38

00

0F03:1A39

00

...

0F03:1A3A

00

int*punt;

0F03:1A3B

05

...

0F03:1A3C
0F03:1A3D

i=5;

0F03:1A3E
0F03:1A3F
...

LuisHernndezYez

punt

0F07:0417
0F07:0418

0F07:0419

0F07:041A
...
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 857

&
Obtener la direccin de memoria de ...
...

0F03:1A38

00

0F03:1A39

00

...

0F03:1A3A

00

int*punt;

0F03:1A3B

05

int i,j;

...

0F03:1A3C
0F03:1A3D

i=5;

0F03:1A3E

punt=&i;

0F03:1A3F
...

punt

LuisHernndezYez

punt
i

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

...
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 858

*
Obtener lo que hay en la direccin ...
Operador monario y prefijo
* accede a lo que hay en la direccin de memoria a la que precede
Permite acceder a un dato a travs un puntero que lo apunte:
punt=&i;
cout<<*punt;//Muestraloquehayenladireccinpunt
*punt: lo que hay en la direccin que contiene el puntero punt
punt contiene la direccin de memoria de la variable i
LuisHernndezYez

*punt accede al contenido de esa variable i

Acceso indirecto al valor de i

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 859

*
Obtener lo que hay en la direccin ...
...

0F03:1A38

00

0F03:1A39

00

...

0F03:1A3A

00

int *punt;

0F03:1A3B

05

int i,j;

...

0F03:1A3D

i=5;

0F03:1A3E

punt=&i;

0F03:1A3F

j=*punt;

...

punt
LuisHernndezYez

0F03:1A3C

punt:

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

...
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 860

*
Obtener lo que hay en la direccin ...
...

int i,j;
...
int *punt;
...
i=5;
punt=&i;

Direccionamiento
indirecto
(indireccin)
Seaccedealdatoi
deformaindirecta

00

0F03:1A39

00

0F03:1A3A

00

0F03:1A3B

05

0F03:1A3C
0F03:1A3D
0F03:1A3E
0F03:1A3F

j=*punt;

...

punt
LuisHernndezYez

0F03:1A38

*punt:

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

...
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 861

*
Obtener lo que hay en la direccin ...
...

0F03:1A38

00

0F03:1A39

00

...

0F03:1A3A

00

int *punt;

0F03:1A3B

05

0F03:1A3C

00

0F03:1A3D

00

0F03:1A3E

00

0F03:1A3F

05

int i,j;

...

i=5;
punt=&i;
j=*punt;

...

LuisHernndezYez

punt

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

...
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 862

punteros.cpp

Ejemplo de uso de punteros

int main(){
int i =5;
int j=13;
int *punt;
punt=&i;
cout<<*punt<<endl;//Muestra elvalordei
punt=&j;
cout<<*punt<<endl;//Ahora muestra elvalordej
int *otro =&i;
cout<<*otro +*punt<<endl;//i +j
int k=*punt;
cout<<k<<endl;//Mismo valorque j
return 0;
}
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 863

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 864

LuisHernndezYez

LuisHernndezYez

#include <iostream>
usingnamespacestd;

Todo puntero ha de tener una direccin vlida

LuisHernndezYez

Un puntero slo debe ser utilizado si tiene una direccin vlida


Un puntero NO contiene una direccin vlida tras ser definido
Un puntero obtiene una direccin vlida:
Asignando la direccin de otro dato (operador &)
Asignando otro puntero (mismo tipo base) que ya sea vlido
Asignando el valor NULL (puntero nulo, no apunta a nada)
int i;
int *q;//qnotieneanunadireccinvlida
int *p=&i;//ptomaunadireccinvlida
q=p;//ahoraqyatieneunadireccinvlida
q=NULL;//otradireccinvlidaparaq
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 865

Punteros que apuntan a saber qu...


Un puntero no inicializado contiene una direccin desconocida
int *punt;//Noinicializado
*punt=12;//Aqudatoseestasignandoelvalor?

Direccin de la zona de datos del programa?


Podemos modificar inadvertidamente un dato del programa!

LuisHernndezYez

Direccin de la zona de cdigo del programa?


Podemos modificar el cdigo del propio programa!
Direccin de la zona de cdigo del sistema operativo?
Podemos modificar el cdigo del propio S.O.!
Consecuencias imprevisibles (cuelgue)
(Los S.O. modernos protegen bien la memoria)
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 866

Punteros que no apuntan a nada


Inicializando los punteros a NULL podemos detectar errores:
int *punt =NULL;
...
*punt=13;

punt

punt ha sido inicializado a NULL: No apunta a nada!


Si no apunta a nada, qu significa *punt??? No tiene sentido

Error de ejecucin, lo que ciertamente no es bueno


Pero sabemos cul ha sido el problema, lo que es mucho
Sabemos dnde y qu buscar para depurar

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 867

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 868

LuisHernndezYez

LuisHernndezYez

ERROR: Acceso a un dato a travs de un puntero nulo!

Apuntando al mismo dato


Al copiar un puntero en otro, ambos apuntarn al mismo dato:
int x=5;
int *punt1=NULL;//punt1noapuntaanada
int *punt2=&x;//punt2apuntaalavariablex

LuisHernndezYez

punt1

punt2

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 869

Apuntando al mismo dato


Al copiar un puntero en otro, ambos apuntarn al mismo dato:
int x=5;
int *punt1=NULL;//punt1noapuntaanada
int *punt2=&x;//punt2apuntaalavariablex
punt1=punt2;//ambosapuntanalavariablex

LuisHernndezYez

punt1

punt2

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 870

Apuntando al mismo dato


Al copiar un puntero en otro, ambos apuntarn al mismo dato:
int x=5;
int *punt1=NULL;//punt1noapuntaanada
int *punt2=&x;//punt2apuntaalavariablex
punt1=punt2;//ambosapuntanalavariablex
*punt1=8;

LuisHernndezYez

punt1

Al dato x ahora se puede


acceder de tres formas:
x*punt1*punt2

punt2

8
5

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 871

Apuntan al mismo dato?


Operadores relacionales == y !=:

LuisHernndezYez

int x=5;
int *punt1=NULL;
int *punt2=&x;
...
if (punt1==punt2){
cout<<"Apuntanalmismodato" <<endl;
}
else{
cout<<"Noapuntanalmismodato" <<endl;
}
Slo se pueden comparar punteros con el mismo tipo base

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 872

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 873

tipos.cpp

Declaracin de tipos puntero


Declaramos tipos para los punteros con distintos tipos base:

LuisHernndezYez

typedefint*tIntPtr;
typedefchar*tCharPtr;
typedefdouble*tDoublePtr;
int entero=5;
tIntPtr puntI =&entero;
char caracter ='C';
tCharPtr puntC =&caracter;
double real=5.23;
tDoublePtr puntD =&real;
cout<<*puntI <<""<<*puntC <<""<<*puntD <<endl;

Con *puntero podemos hacer lo que con otros datos del tipo base

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 874

Acceso a estructuras a travs de punteros


Los punteros pueden apuntar tambin a estructuras:
typedefstruct {
int codigo;
string nombre;
double sueldo;
}tRegistro;
tRegistro registro;
typedeftRegistro *tRegistroPtr;
tRegistroPtr puntero=&registro;

LuisHernndezYez

Operador flecha (>):


Acceso a los campos a travs de un puntero sin usar el operador *
puntero>codigo

puntero>nombrepuntero>sueldo

puntero>... (*puntero)....

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 875

structPtr.cpp

LuisHernndezYez

Acceso a estructuras a travs de punteros


typedefstruct {
int codigo;
string nombre;
double sueldo;
}tRegistro;
tRegistro registro;
typedeftRegistro *tRegistroPtr;
tRegistroPtr puntero=&registro;
registro.codigo =12345;
registro.nombre ="Javier";
registro.sueldo =95000;
cout<<puntero>codigo <<""<<puntero>nombre
<<""<<puntero>sueldo<<endl;
puntero>codigo

(*puntero).codigo *puntero.codigo

puntero sera una estructura con campo codigo de tipo puntero


Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 876

Punteros a constantes y punteros constantes


El efecto del modificador de acceso const depende de su sitio:
const tipo *puntero;
Puntero a una constante
tipo*const puntero;
Puntero constante
Punteros a constantes:
typedefconstint*tIntCtePtr;//Punteroaconstante
int entero1=5,entero2=13;

LuisHernndezYez

tIntCtePtr punt_a_cte =&entero1;


(*punt_a_cte)++;//ERROR: Datonomodificable!
punt_a_cte =&entero2;//OK:Elpunteronoescte.

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 877

constPtr.cpp

Punteros a constantes y punteros constantes


El efecto del modificador de acceso const depende de su sitio:
const tipo *puntero;
Puntero a una constante
tipo*const puntero;
Puntero constante
Punteros constantes:
typedefint*consttIntPtrCte;//Punteroconstante
int entero1=5,entero2=13;

LuisHernndezYez

tIntPtrCte punt_cte =&entero1;


(*punt_cte)++;//OK:Elpunteronoapuntaacte.
punt_cte =&entero2;//ERROR: Punteroconstante!

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 878

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 879

param.cpp

Paso de parmetros por referencia o variable


En el lenguaje C no hay mecanismo de paso por referencia (&)
Slo se pueden pasar parmetros por valor
Cmo se simula el paso por referencia? Por medio de punteros:

LuisHernndezYez

void incrementa(int *punt);


void incrementa(int *punt){
(*punt)++;
}
...
int entero=5;
incrementa(&entero);
cout<<entero<<endl;

Paso por valor:


El argumento (el puntero) no cambia
Aquello a lo que apunta (el entero)
S puede cambiar

Mostrar 6 en la consola
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 880

Paso de parmetros por referencia o variable


int entero=5;
incrementa(&entero);

entero

punt recibe la direccin de entero

LuisHernndezYez

void incrementa(int *punt){


(*punt)++;
}

punt

cout<<entero<<endl;

entero

entero

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 881

Paso de parmetros por referencia o variable


Cul es el equivalente en C a este prototipo de C++?
void foo(int&param1,double&param2,char&param3);

Prototipo equivalente:
void foo(int *param1,double *param2,char *param3);

LuisHernndezYez

void foo(int *param1,double *param2,char *param3){


//Alprimerargumentoseaccedecon*param1
//Alsegundoargumentoseaccedecon*param2
//Altercerargumentoseaccedecon*param3
}

Cmo se llamara?
int entero;double real;char caracter;
//...
foo(&entero,&real,&caracter);
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 882

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 883

Una ntima relacin


Variable array Puntero al primer elemento del array
As, si tenemos:
int dias[12]=
{31,28,31,30,31,30,31,31,30,31,30,31};

Entonces:
cout<<*dias <<endl;

Muestra 31 en la consola, el primer elemento del array

LuisHernndezYez

Un nombre de array es un puntero constante!


Siempre apunta al primer elemento (no se puede modificar)
Acceso a los elementos del array:
Por ndice o con aritmtica de punteros (Anexo)
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 884

Paso de arrays a subprogramas


Esto explica por qu no usamos & con los parmetros array!
El nombre del array es un puntero: ya es un paso por referencia
Prototipos equivalentes para parmetros array:

Arrays no delimitados y punteros: se necesita la dimensin


Elementos: se acceden con ndice (arr[i]) o con puntero (*arr)
Una funcin slo puede devolver un array en forma de puntero:
intPtr inicializar();

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 885

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 886

LuisHernndezYez

LuisHernndezYez

constint N=...;
void cuadrado(int arr[N]);
void cuadrado(int arr[],int size);//Arraynodelimitado
void cuadrado(int *arr,int size);//Puntero

Regiones de la memoria
El sistema operativo distingue varias regiones en la memoria:
Pila(Stack)

Montn(Heap)

Datos locales

Datos dinmicos

Datos globales

LuisHernndezYez

Cdigodel
programa

Memoria principal

S.O.

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Memoria principal

LuisHernndezYez

Datos globales del programa:


Declarados fuera
de los subprogramas
typedef struct {
...
}tRegistro;
const intN=1000;
typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;

Pgina 887

Datos locales

Pila

Datos dinmicos

Montn
Datos globales
Cdigodelprograma

Memoria principal

S.O.

intmain(){
...

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 888

La pila (stack)
Datos locales de subprogramas:
Parmetros por valor
y variables locales

LuisHernndezYez

voidfunc(tLista lista,double &total)


{
tLista aux;
int i;
...

Y los punteros temporales


que apuntan a los argumentos
de los parmetros por referencia

Datos locales

Pila

Datos dinmicos

Montn
Datos globales
Cdigodelprograma
S.O.

&resultado

func(lista,resultado)

Fundamentosdelaprogramacin:Punterosymemoriadinmica

El montn (heap)

LuisHernndezYez

Datos dinmicos
Datos que se crean y se destruyen
durante la ejecucin del programa,
a medida que se necesita

Memoria principal

Pgina 889

Datos locales

Pila

Datos dinmicos

Montn
Datos globales
Cdigodelprograma

Memoria principal

S.O.

Sistema de gestin de memoria dinmica (SGMD)


Cuando se necesita memoria para una variable se solicita
El SGMD reserva espacio y devuelve la direccin base
Cuando ya no se necesita ms la variable, se destruye
Se libera la memoria y el SGMD cuenta de nuevo con ella

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 890

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 891

Datos dinmicos
Se crean y se destruyen durante la ejecucin del programa
Se les asigna memoria del montn
Creacin

LuisHernndezYez

Datodinmico

Montn

Destruccin

Por qu utilizar memoria dinmica?


Almacn de memoria muy grande: datos o listas de datos que
no caben en memoria principal pueden caber en el montn
El programa ajusta el uso de la memoria a las necesidades
de cada momento: ni le falta ni la desperdicia
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 892

Cundo se asigna memoria a los datos?


Datos globales
En memoria principal al comenzar la ejecucin del programa
Existen durante toda la ejecucin del programa

LuisHernndezYez

Datos locales de un subprograma


En la pila al ejecutarse el subprograma
Existen slo durante la ejecucin de su subprograma
Datos dinmicos
En el montn cuando el programa lo solicita
Existen a voluntad del programa

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 893

Datos estticos
Datos declarados como de un tipo concreto:
int i;
Se acceden directamente a travs del identificador:
cout<<i;

LuisHernndezYez

Datos dinmicos
Datos accedidos a travs de su direccin de memoria
Esa direccin de memoria debe estar el algn puntero
Los punteros son la base del SGMD
Los datos estticos tambin se pueden acceder a travs de punteros
int *p=&i;
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 894

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

El operador new
new tipo

Pgina 895

Devuelve NULL si no queda memoria suficiente

Reserva memoria del montn para una variable del


tipo y devuelve la primera direccin de memoria
utilizada, que debe ser asignada a un puntero

int *p;//Todavasinunadireccinvlida
p=new int;//Yatieneunadireccinvlida
*p=12;

LuisHernndezYez

La variable dinmica se accede exclusivamente por punteros


No tiene identificador asociado
int i;//iesunavariableesttica
int *p1,*p2;
p1=&i;//Punteroquedaaccesoalavariable
//estticai(accesibleconiocon*p1)
p2=new int;//Punteroquedaaccesoaunavariable
//dinmica(accesiblesloatravsdep2)
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 896

registros.cpp

Inicializacin con el operador new


El operador new admite un valor inicial para el dato creado:
int *p;
p=new int(12);

Se crea la variable, de tipo int, y se inicializa con el valor 12

LuisHernndezYez

#include<iostream>
usingnamespacestd;
#include"registro.h"
int main(){
tRegistroreg;
reg =nuevo();
tRegistro *punt =new tRegistro(reg);
mostrar(*punt);
...
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 897

El operador delete
delete puntero;

Devuelve al montn la memoria usada por


la variable dinmica apuntada por puntero

int *p;
p=new int;
*p=12;
...
delete p;//Yanosenecesitaelenteroapuntadoporp

LuisHernndezYez

El puntero deja de contener una direccin vlida!

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 898

dinamicas.cpp

LuisHernndezYez

#include<iostream>
usingnamespacestd;
int main(){
double a=1.5;
p1
double *p1,*p2,*p3;
p1=&a;
p2=new double;
a
*p2=*p1;
p3=new double;
*p3=123.45;
cout<<*p1<<endl; p2
cout<<*p2<<endl;
cout<<*p3<<endl;
delete p2;
delete p3;
p3
return 0;

Identificadores:

4
(a, p1, p2, p3)

1.5

Variables:

1.5

6
(+ *p2 y *p3)

123.45
Montn (heap)

}
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 899

#include<iostream>
usingnamespacestd;

LuisHernndezYez

int main(){
double a=1.5;
double *p1,*p2,*p3;

PILA
a

1.5

p1

p2

p3

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 900

#include<iostream>
usingnamespacestd;

PILA
a

1.5

p1
p2

p3

LuisHernndezYez

int main(){
double a=1.5;
double *p1,*p2,*p3;
p1=&a;

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 901

#include<iostream>
usingnamespacestd;

PILA
a

LuisHernndezYez

int main(){
double a=1.5;
double *p1,*p2,*p3;
p1=&a;
p2=new double;

1.5

p1
p2
p3

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 902

#include<iostream>
usingnamespacestd;

PILA
a

1.5

p1
p2
p3

LuisHernndezYez

int main(){
double a=1.5;
double *p1,*p2,*p3;
p1=&a;
p2=new double;
*p2=*p1;

1.5
MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 903

#include<iostream>
usingnamespacestd;

PILA
a

LuisHernndezYez

int main(){
double a=1.5;
double *p1,*p2,*p3;
p1=&a;
p2=new double;
*p2=*p1;
p3=new double;

1.5

p1
p2
p3

1.5
MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 904

#include<iostream>
usingnamespacestd;

PILA
a

int main(){
double a=1.5;
double *p1,*p2,*p3;
p1=&a;
p2=new double;
*p2=*p1;
p3=new double;
*p3=123.45;

1.5

p1
p2
p3

LuisHernndezYez

123.45
1.5
MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 905

#include<iostream>
usingnamespacestd;

PILA

LuisHernndezYez

int main(){
double a=1.5;
double *p1,*p2,*p3;
p1=&a;
p2=new double;
*p2=*p1;
p3=new double;
*p3=123.45;
cout<<*p1<<endl;
cout<<*p2<<endl;
cout<<*p3<<endl;
delete p2;

1.5

p1
p2

p3

123.45
MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 906

#include<iostream>
usingnamespacestd;

PILA
1.5

p1
p2

p3

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 907

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 908

LuisHernndezYez

LuisHernndezYez

int main(){
double a=1.5;
double *p1,*p2,*p3;
p1=&a;
p2=new double;
*p2=*p1;
p3=new double;
*p3=123.45;
cout<<*p1<<endl;
cout<<*p2<<endl;
cout<<*p3<<endl;
delete p2;
delete p3;

La memoria se reparte entre la pila y el montn


Crecen en direcciones opuestas
Al llamar a subprogramas la pila crece
Al crear datos dinmicos el montn crece

Pila

Montn

LuisHernndezYez

Colisin pilamontn
Los lmites de ambas regiones se encuentran
Se agota la memoria
Desbordamiento de la pila
La pila suele tener un tamao mximo establecido
Si se sobrepasa se agota la pila
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 909

Gestin del montn

LuisHernndezYez

Sistema de Gestin de Memoria Dinmica (SGMD)


Gestiona la asignacin de memoria a los datos dinmicos
Localiza secciones adecuadas y sigue la pista de lo disponible
No dispone de un recolector de basura, como el lenguaje Java
Hay que devolver toda la memoria solicitada!
Deben ejecutarse tantos delete como new se hayan ejecutado
La memoria disponible en el montn debe ser exactamente la
misma antes y despus de la ejecucin del programa
Y todo dato dinmico debe tener algn acceso (puntero)
Es un grave error perder un dato en el montn

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 910

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 911

Olvido de destruccin de un dato dinmico


...
intmain(){
tRegistro *p;
p=new tRegistro;
*p=nuevo();
mostrar(*p);
Falta delete p;
return 0;

LuisHernndezYez

G++ no indicar ningn error y el programa parecer terminar


correctamente, pero dejar memoria desperdiciada
Visual C++ s comprueba el uso de la memoria dinmica
y nos avisa si dejamos memoria sin liberar
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 912

Intento de destruccin de un dato inexistente

LuisHernndezYez

...
intmain(){
tRegistro *p1=new tRegistro;
*p1=nuevo();
mostrar(*p1);
tRegistro *p2;
p2=p1;
mostrar(*p2);
delete p1;
delete p2;
return 0;
}

p1

tRegistro

p2

Slo se ha creado
una variable

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 913

Prdida de un dato dinmico


...
intmain(){
tRegistro *p1,*p2;
p1=new tRegistro(nuevo());
p2=new tRegistro(nuevo());

LuisHernndezYez

mostrar(*p1);
p1=p2;

mostrar(*p1);

tRegistro

p1

tRegistro
Perdido!

delete p1;
delete p2;
return 0;

p2

Se pierde un dato en el montn


Se intenta eliminar un dato ya eliminado

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 914

Intento de acceso a un dato tras su eliminacin


...
intmain(){
tRegistro *p;
p=new tRegistro(nuevo());
mostrar(*p);
delete p;
...
mostrar(*p);

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 915

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 916

LuisHernndezYez

LuisHernndezYez

return 0;

p ha dejado de apuntar
al dato dinmico destruido
Acceso a memoria inexistente

Arrays de punteros a datos dinmicos

LuisHernndezYez

typedef struct {
intcodigo;
string nombre;
double valor;
}tRegistro;
typedef tRegistro *tRegPtr;

Los punteros ocupan


muy poco en memoria
Los datos a los que apunten
estarn en el montn

const int N=1000;


//Arraydepunterosaregistros:
typedef tRegPtr tArray[N];
typedef struct {
tArray registros;
int cont;
Se crean a medida que se insertan
}tLista;
Se destruyen a medida que se eliminan
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 917

tLista lista;
lista.cont =0;

lista.cont

0
0

998

999

LuisHernndezYez

lista.registros

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 918

tLista lista;
lista.cont =0;
lista.registros[lista.cont]=new tRegistro(nuevo());
lista.cont++;

lista.cont

1
0

998

999

LuisHernndezYez

lista.registros

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 919

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

998

999

LuisHernndezYez

lista.registros

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 920

tLista lista;
lista.cont =0;
lista.registros[lista.cont]=new tRegistro(nuevo());
lista.cont++;
lista.registros[lista.cont]=new tRegistro(nuevo());
lista.cont++;
lista.registros[lista.cont]=new tRegistro(nuevo());
lista.cont++;
lista.cont

3
0

998

999

LuisHernndezYez

lista.registros

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 921

Los registros se acceden a travs de los punteros (operador >):


cout<<lista.registros[0]>nombre;

lista.cont

3
0

998

999

LuisHernndezYez

lista.registros

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 922

No hay que olvidarse de devolver la memoria al montn:


for(int i=0;i<lista.cont;i++){
delete lista.registros[i];
}

lista.cont

3
0

998

999

LuisHernndezYez

lista.registros

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 923

lista.h
#ifndef lista_h
#definelista_h
#include"registro.h"

LuisHernndezYez

const int N=1000;


const string BD="bd.dat";
typedef tRegPtr tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;

registro.h con el tipo puntero:


typedef tRegistro *tRegPtr;

void mostrar(const tLista&lista);


voidinsertar(tLista&lista,tRegistro registro,bool &ok);
voideliminar(tLista&lista,intcode,bool &ok);
intbuscar(const tLista &lista,int code);
void cargar(tLista&lista,bool &ok);
void guardar(const tLista &lista);
void destruir(tLista &lista);
#endif
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 924

lista.cpp

LuisHernndezYez

void insertar(tLista&lista,tRegistro registro,bool &ok){


ok=true;
if (lista.cont ==N){
ok=false;
}
else {
lista.registros[lista.cont]=new tRegistro(registro);
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];
}
lista.cont;
}
}
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 925

LuisHernndezYez

int buscar(const tLista &lista,intcode){


//Devuelveelndiceo1sinosehaencontrado
int ind =0;
bool encontrado=false;
while ((ind <lista.cont)&&!encontrado){
if (lista.registros[ind]>codigo ==code){
encontrado=true;
}
else {
ind++;
}
if (!encontrado){
ind =1;
}
return ind;
}
void destruir(tLista &lista){
for (inti=0;i<lista.cont;i++){
delete lista.registros[i];
}
lista.cont =0;
}
...
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 926

listadinamica.cpp
#include<iostream>
usingnamespacestd;
#include"registro.h"
#include"lista.h"

return 0;
}

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 927

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 928

LuisHernndezYez

LuisHernndezYez

int main(){
tLista lista;
bool ok;
cargar(lista,ok);
if(ok){
mostrar(lista);
destruir(lista);
}

Creacin y destruccin de arrays dinmicos


Array dinmico: array que se ubica en la memoria dinmica
Creacin de un array dinmico:
tipo *puntero =new tipo[dimensin];
int *p=new int[10];

Crea un array de 10 int en memoria dinmica


Los elementos se acceden a travs del puntero: p[i]
Destruccin del array:
LuisHernndezYez

delete []p;

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 929

#include<iostream>
usingnamespacestd;
const int N=10;

LuisHernndezYez

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;
return 0;

No olvides destruir el array dinmico!

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 930

listaAD.h

...
#include"registro.h"
const int N=1000;
//Lista:arraydinmico(puntero)ycontador
typedef struct {
tRegPtr registros;
int cont;
}tLista;

LuisHernndezYez

...

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 931

listaAD.cpp

LuisHernndezYez

void insertar(tLista&lista,tRegistro registro, bool &ok){


ok=true;
if (lista.cont ==N){
ok=false;
No usamos new
}
else {
Se han creado todo
lista.registros[lista.cont]=registro;
el array al cargar
lista.cont++;
}
}
void eliminar(tLista&lista,int code, bool &ok){
ok=true;
int ind =buscar(lista,code);
No usamos delete
if (ind ==1){
Se destruye todo
ok=false;
}
el array al final
else {
for (int i=ind +1;i<lista.cont;i++){
lista.registros[i 1]=lista.registros[i];
}
lista.cont;
}
}...
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 932

LuisHernndezYez

int buscar(tLista lista,int code){


int ind =0;
bool encontrado=false;
while ((ind <lista.cont)&&!encontrado){
if (lista.registros[ind].codigo ==code){
encontrado=true;
}
else {
ind++;
}
}
if (!encontrado){
ind =1;
}
return ind;
}
void destruir(tLista &lista){
delete []lista.registros;
lista.cont =0;
}
...

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 933

void cargar(tLista&lista,bool &ok){


ifstream archivo;
char aux;
ok=true;
archivo.open(BD.c_str());
if (!archivo.is_open()){
ok=false;
}
else {
Se crean todos a la vez
tRegistro registro;
lista.cont =0;
lista.registros =new tRegistro[N];
archivo>>registro.codigo;
while((registro.codigo !=1)&&(lista.cont <N)){
archivo>>registro.valor;
archivo.get(aux);//Saltamoselespacio
getline(archivo,registro.nombre);
lista.registros[lista.cont]=registro;
lista.cont++;
archivo>>registro.codigo;
}
archivo.close();
}
}
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 934

ejemploAD.cpp

LuisHernndezYez

Mismo programa principal que el del array de datos dinmicos


Pero incluyendo listaAD.h, en lugar de lista.h

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 935

Array de datos dinmicos: Array de punteros a datos dinmicos


Array dinmico: Puntero a array en memoria dinmica
Array de datos dinmicos:
Array de punteros
0

Array dinmico:
Puntero a array
7

LuisHernndezYez

Montn

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 936

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 937

Fundamentosdelaprogramacin

9A
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

LuisHernndezYez

Aritmticadepunteros
Recorridodearraysconpunteros
Referencias
Listasenlazadas

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

940
953
962
964

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 940

Operaciones aritmticas con punteros


La aritmtica de punteros es una aritmtica un tanto especial...
Trabaja tomando como unidad de clculo el tamao del tipo base
int dias[12]={31,28,31,30,31,30,31,31,30,31,30,31};
typedef int*tIntPtr;
tIntPtr punt=dias;

punt empieza apuntando al primer elemento del array:


cout<<*punt<<endl;//Muestra 31(primerelemento)
punt++;

LuisHernndezYez

punt++ hace que punt pase a apuntar al siguiente elemento


cout<<*punt<<endl;//Muestra 28(segundo elemento)

A la direccin de memoria actual se le suman tantas unidades


como bytes (4) ocupe en memoria un dato de ese tipo (int)
Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 941

int dias[12]={31,28,31,30,31,30,
31,31,30,31,30,31};

...

dias[0]

0F03:1A39

typedef int*tIntPtr;
tIntPtr punt=dias;

0F03:1A38
0F03:1A3A

31

0F03:1A3B

dias[1]

0F03:1A3C
0F03:1A3D
0F03:1A3E

28

0F03:1A3F

dias[2]

0F03:1A40
0F03:1A41
0F03:1A42

31

0F03:1A43
...

LuisHernndezYez

dias

punt

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

0F07:041B

0F

0F07:041C

03

0F07:041D

1A

0F07:041E

38

...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 942

int dias[12]={31,28,31,30,31,30,
31,31,30,31,30,31};

...

dias[0]

0F03:1A39

typedef int*tIntPtr;
tIntPtr punt=dias;
punt++;

0F03:1A38
0F03:1A3A

31

0F03:1A3B

dias[1]

0F03:1A3C
0F03:1A3D
0F03:1A3E

28

0F03:1A3F

dias[2]

0F03:1A40
0F03:1A41
0F03:1A42

31

0F03:1A43
...

LuisHernndezYez

dias

punt

punt hace que apunte al elemento anterior

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

0F07:041B

0F

0F07:041C

03

0F07:041D

1A

0F07:041E

3C

...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 943

int dias[12]={31,28,31,30,31,30,
31,31,30,31,30,31};

...

dias[0]

0F03:1A39

typedef int*tIntPtr;
tIntPtr punt=dias;
punt =punt+2;

0F03:1A38
0F03:1A3A

31

0F03:1A3B

dias[1]

0F03:1A3C
0F03:1A3D
0F03:1A3E

28

0F03:1A3F

dias[2]

0F03:1A40
0F03:1A41
0F03:1A42

31

0F03:1A43
...

LuisHernndezYez

dias

punt

Restando pasamos a elementos anteriores

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

0F07:041B

0F

0F07:041C

03

0F07:041D

1A

0F07:041E

40

...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 944

int dias[12]={31,28,31,30,31,30,
31,31,30,31,30,31};

...

dias[0]

0F03:1A39

typedef int*tIntPtr;
tIntPtr punt=dias;
punt=punt+2;

0F03:1A38
0F03:1A3A

31

0F03:1A3B

dias[1]

0F03:1A3C
0F03:1A3D
0F03:1A3E

28

0F03:1A3F

int num=punt dias;

dias[2]

0F03:1A40
0F03:1A41

N de elementos entre los punteros

0F03:1A42

31

0F03:1A43
...

LuisHernndezYez

dias

punt

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

0F07:041B

0F

0F07:041C

03

0F07:041D

1A

0F07:041E

3C

...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 945

Otro tipo base

...

shortint (2 bytes)

dias[0]

shortint dias[12]={31,28,31,30,

dias[1]

31,30,31,31,30,31,30,31};
typedef shortint*tSIPtr;

0F03:1A38
0F03:1A39
0F03:1A3A
0F03:1A3B

dias[2]

0F03:1A3C
0F03:1A3D

dias[3]

tSIPtr punt=dias;

0F03:1A3E
0F03:1A3F

dias[4]

0F03:1A40
0F03:1A41

31
28
31
30
31

...
dias

LuisHernndezYez

punt

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

0F07:041B

0F

0F07:041C

03

0F07:041D

1A

0F07:041E

38

...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 946

shortint dias[12]={31,28,31,30,
31,30,31,31,30,31,30,31};

...
dias[0]

typedef shortint*tSIPtr;

0F03:1A38
0F03:1A39

tSIPtr punt=dias;

dias[1]

punt++;

dias[2]

0F03:1A3A
0F03:1A3B
0F03:1A3C
0F03:1A3D

dias[3]

0F03:1A3E
0F03:1A3F

dias[4]

0F03:1A40
0F03:1A41

31
28
31
30
31

...
dias

LuisHernndezYez

punt

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

0F07:041B

0F

0F07:041C

03

0F07:041D

1A

0F07:041E

3A

...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 947

shortint dias[12]={31,28,31,30,
31,30,31,31,30,31,30,31};

...
dias[0]

typedef shortint*tSIPtr;

0F03:1A39

tSIPtr punt=dias;

dias[1]

punt++;

dias[2]

punt=punt+3;

0F03:1A38
0F03:1A3A
0F03:1A3B
0F03:1A3C
0F03:1A3D

dias[3]

0F03:1A3E
0F03:1A3F

dias[4]

0F03:1A40
0F03:1A41

31
28
31
30
31

...
dias

LuisHernndezYez

punt

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

0F07:041B

0F

0F07:041C

03

0F07:041D

1A

0F07:041E

40

...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 948

shortint dias[12]={31,28,31,30,
31,30,31,31,30,31,30,31};

...
dias[0]

typedef shortint*tSIPtr;

0F03:1A39

tSIPtr punt=dias;

dias[1]

punt++;

dias[2]

punt=punt+3;
punt;

0F03:1A38
0F03:1A3A
0F03:1A3B
0F03:1A3C
0F03:1A3D

dias[3]

0F03:1A3E
0F03:1A3F

dias[4]

0F03:1A40
0F03:1A41

31
28
31
30
31

...
dias

LuisHernndezYez

punt

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

0F07:041B

0F

0F07:041C

03

0F07:041D

1A

0F07:041E

3E

...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 949

shortint dias[12]={31,28,31,30,
31,30,31,31,30,31,30,31};

...
dias[0]

typedef shortint*tSIPtr;

0F03:1A39

tSIPtr punt=dias;

dias[1]

punt++;

dias[2]

punt=punt+3;
punt;

0F03:1A38
0F03:1A3A
0F03:1A3B
0F03:1A3C
0F03:1A3D

dias[3]

0F03:1A3E
0F03:1A3F

dias[4]

tSIPtr punt2;

0F03:1A40
0F03:1A41

31
28
31
30
31

...
dias

LuisHernndezYez

punt

punt2

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

0F07:041B

0F

0F07:041C

03

0F07:041D

1A

0F07:041E

3E

0F07:041F

Pgina 950

shortint dias[12]={31,28,31,30,
31,30,31,31,30,31,30,31};

...
dias[0]

typedef shortint*tSIPtr;

0F03:1A39

siPtr punt=dias;

dias[1]

punt++;

dias[2]

punt=punt+3;
punt;

LuisHernndezYez

0F03:1A3C
0F03:1A3D

dias[3]

0F03:1A3E
0F03:1A3F

dias[4]

0F03:1A40
0F03:1A41

31
28
31
30
31

...
dias

punt

punt2

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

0F03:1A3A
0F03:1A3B

tSIPtr punt2;
punt2=dias;

0F03:1A38

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

0F07:041B

0F

0F07:041C

03

0F07:041D

1A

0F07:041E

3E

0F07:041F

0F

Pgina 951

shortint dias[12]={31,28,31,30,
...

31,30,31,31,30,31,30,31};

dias[0]

typedef shortint*tSIPtr;
siPtr punt=dias;
punt++;

0F03:1A38
0F03:1A39

dias[1]

punt=punt+3;
punt;

dias[2]
dias[3]

0F03:1A3E
0F03:1A3F

dias[4]

0F03:1A40
0F03:1A41
...

dias

cout<<punt punt2;//3
punt

LuisHernndezYez

0F03:1A3C
0F03:1A3D

tSIPtr punt2;
punt2=dias;

0F03:1A3A
0F03:1A3B

31
28
31
30
31

punt2

0F07:0417

0F

0F07:0418

03

0F07:0419

1A

0F07:041A

38

0F07:041B

0F

0F07:041C

03

0F07:041D

1A

0F07:041E

3E

0F07:041F

0F

Pgina 952

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 953

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

arraypunt.cpp

Punteros como iteradores para arrays


constint MAX=100;
typedefint tArray[MAX];
typedef struct{
tArray elementos;
int cont;
}tLista;
typedefint*tIntPtr;
tLista lista;

LuisHernndezYez

Usamos un puntero como iterador para recorrer el array:


tIntPtr punt=lista.elementos;
for(int i=0;i<lista.cont;i++){
cout<<*punt <<endl;
punt++;
}

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 954

...
intPtr punt=lista.elementos;

punt

lista.elementos

13

47

53

19

48

...

98

99

LuisHernndezYez

lista.cont

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 955

...
for(int i=0;i<lista.cont;i++){
cout<<*punt <<endl;
punt++;
}
i

punt

lista.elementos

13

47

53

19

48

lista.cont

...

98

99

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 956

...
for(int i=0;i<lista.cont;i++){
cout<<*punt <<endl;
punt++;
}
i

punt

lista.elementos

13

47

53

19

48

...

98

99

LuisHernndezYez

lista.cont

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 957

...
for(int i=0;i<lista.cont;i++){
cout<<*punt <<endl;
punt++;
}
i

punt

lista.elementos

4
13

13

47

53

19

48

lista.cont

...

98

99

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 958

...
for(int i=0;i<lista.cont;i++){
cout<<*punt <<endl;
punt++;
}
i

lista.cont
LuisHernndezYez

punt

lista.elementos

4
13
3

13

47

53

19

48

...

98

99

. . .
Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 959

...
for(int i=0;i<lista.cont;i++){
cout<<*punt <<endl;
punt++;
}
i

punt

lista.elementos

4
13
3
47
53
19
7

13

47

53

19

48

lista.cont

...

98

99

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 960

...
for(int i=0;i<lista.cont;i++){
cout<<*punt <<endl;
punt++;
}
i

punt

lista.elementos

13

47

53

19

48

...

98

99

LuisHernndezYez

lista.cont

4
13
3
47
53
19
7
48

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 961

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 962

Nombres alternativos para los datos


Una referencia es una nueva forma de llamar a una variable
Nos permiten referirnos a una variable con otro identificador:
int x=10;
int&z=x;
x y z son ahora la misma variable (comparten memoria)

Cualquier cambio en x afecta a z y cualquier cambio en z afecta a x


z=30;
cout<<x;
LuisHernndezYez

Las referencias se usan en el paso de parmetros por referencia

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 963

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 964

Una implementacin dinmica de listas enlazadas


Cada elemento de la lista apunta al siguiente elemento:
structtNodo;//Declaracinanticipada
typedef tNodo *tLista;
reg
structtNodo {
tRegistro reg;
tRegistro
tLista sig;
};

sig

tLista

LuisHernndezYez

Una lista (tLista) es un puntero a un nodo


Si el puntero vale NULL, no apunta a ningn nodo: lista vaca
Un nodo (tNodo) es un elemento seguido de una lista
Lista

Vaca
Elemento seguido de una lista

Definicin recursiva!

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 965

Cada elemento de la lista en su nodo


Apuntar al siguiente elemento o a ninguno (NULL)
structtNodo;//Declaracinanticipada
typedef tNodo *tLista;
structtNodo {
tRegistro reg;
tLista sig;
};

Adems, un puntero al primer elemento (nodo) de la lista

LuisHernndezYez

tLista lista=NULL;//Listavaca

lista

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 966

structtNodo;
typedef tNodo *tLista;
structtNodo {
tRegistro reg;
tLista sig;
};

LuisHernndezYez

tLista lista=NULL;//Listavaca
lista=new tNodo;
lista>reg =nuevo();
lista>sig=NULL;

lista

tem1

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 967

tLista lista=NULL;//Listavaca
lista=new tNodo;
lista>reg =nuevo();
lista>sig=NULL;
tLista p;
p=lista;

LuisHernndezYez

lista

tem1

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 968

tLista lista=NULL;//Listavaca
lista=new tNodo;
lista>reg =nuevo();
lista>sig=NULL;
tLista p;
p=lista;
p>sig=new tNodo;
p>sig>reg =nuevo();
p>sig>sig =NULL;

LuisHernndezYez

lista

tem1

tem2

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 969

LuisHernndezYez

tLista lista=NULL;//Listavaca
lista=new tNodo;
lista>reg =nuevo();
lista>sig=NULL;
tLista p;
p=lista;
p>sig=new tNodo;
p>sig>reg =nuevo();
p>sig>sig =NULL;
p=p>sig;
p>sig=new tNodo;
p>sig>reg =nuevo();
p>sig>sig =NULL;
p
...
lista

tRegistro

tRegistro

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

tRegistro

Pgina 970

Usamos la memoria que necesitamos, ni ms ni menos


lista

tRegistro

tRegistro

tRegistro

LuisHernndezYez

Tantos elementos, tantos nodos hay en la lista


Pero perdemos el acceso directo!
Algunas operaciones de la lista se complican y otras no
A continuacin tienes el mdulo de lista implementado
como lista enlazada...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 971

listaenlazada.h
structtNodo;
typedef tNodo *tLista;
struct tNodo {
tRegistro reg;
tLista sig;
};

LuisHernndezYez

const string BD="bd.txt";


void mostrar(tLista lista);
void insertar(tLista&lista,tRegistro registro, bool &ok);
void eliminar(tLista&lista,int code, bool &ok);
tLista buscar(tLista lista,int code);//Devuelvepuntero
void cargar(tLista&lista, bool &ok);
void guardar(tLista lista);
void destruir(tLista &lista);//Liberarlamemoriadinmica

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 972

LuisHernndezYez

listaenlazada.cpp
void insertar(tLista&lista,tRegistro registro, bool &ok){
ok=true;
tLista nuevo=new tNodo;
if (nuevo==NULL){
ok=false;//Nohaymsmemoriadinmica
}
else {
nuevo>reg =registro;
nuevo>sig=NULL;
if (lista==NULL){//Listavaca
lista
lista=nuevo;

}
nuevo
else {
tLista p=lista;
//Localizamoselltimonodo...
while (p>sig!=NULL){
nuevo

p=p>sig;
}
p
p>sig=nuevo;

}
lista
}
}...
Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 973

LuisHernndezYez

void eliminar(tLista&lista,int code,bool &ok){


ok=true;
tLista p=lista;
if (p==NULL){
ok=false;//Listavaca
}
else if (p>reg.codigo ==code){//Elprimero
lista=p>sig;
delete p;
p
}

else {
lista
tLista ant=p;
p=p>sig;
bool encontrado=false;
while ((p!=NULL)&&!encontrado){
if (p>reg.codigo ==code){
ant
encontrado=true;
}
else {
lista

ant=p;
p=p>sig;
}
}...
Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 974

if (!encontrado){
ok=false;//Noexisteesecdigo
}
else {
ant>sig=p>sig;
delete p;
}
}
}
...
ant

LuisHernndezYez

lista

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 975

LuisHernndezYez

tLista buscar(tLista lista,int code){


//Devuelveunpunteroalnodo,oNULLsinoseencuentra
tLista p=lista;
bool encontrado=false;
while ((p!=NULL)&&!encontrado){
if (p>reg.codigo ==code){
encontrado=true;
}
else {
p=p>sig;
}
}
return p;
}
void mostrar(tLista lista){
cout<<endl<<"Elementosdelalista:"<<endl
<<"" <<endl;
tLista p=lista;
while (p!=NULL){
mostrar(p>reg);
p=p>sig;
}
}...

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 976

void cargar(tLista&lista,bool &ok){


ifstream archivo;
char aux;
ok=true;
lista=NULL;
archivo.open(BD.c_str());
if (!archivo.is_open()){
ok=false;
}
else {
tRegistro registro;
tListault =NULL;
archivo>>registro.codigo;
while (registro.codigo !=1){
archivo>>registro.valor;
archivo.get(aux);//Saltamoselespacio
getline(archivo,registro.nombre);
...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 977

if (lista==NULL){
lista=new tNodo;
ult =lista;
}
else {
ult>sig=new tNodo;
ult =ult>sig;
}
ult>reg =registro;
ult>sig=NULL;
archivo>>registro.codigo;
}
archivo.close();

LuisHernndezYez

}
return ok;
}...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 978

LuisHernndezYez

void guardar(tLista lista){


ofstream archivo;
archivo.open(BD);
tLista p=lista;
while (p!=NULL){
archivo<<p>registro.codigo <<"";
archivo<<p>registro.valor <<"";
archivo<<p>registro.nombre <<endl;
p=p>sig;
}
archivo.close();
}
void destruir(tLista &lista){
tLista p;
while (lista!=NULL){
p=lista;
lista=lista>sig;
delete p;
}
}
Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 979

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 980

Fundamentosdelaprogramacin

10
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

LuisHernndezYez

Facultad de Informtica
Universidad Complutense

Conceptoderecursin
Algoritmosrecursivos
Funcionesrecursivas
Diseodefuncionesrecursivas
Modelodeejecucin
Lapiladelsistema
Lapilaylasllamadasafuncin
Ejecucindelafuncinfactorial()
Tiposderecursin
Recursinsimple
Recursinmltiple
Recursinanidada
Recursincruzada
Cdigodelsubprogramarecursivo
Parmetrosyrecursin
Ejemplosdealgoritmosrecursivos
Bsquedabinaria
TorresdeHanoi
Recursinfrenteaiteracin
Estructurasdedatosrecursivas
Fundamentosdelaprogramacin:Introduccinalarecursin

983
986
987
989
990
992
994
1005
1018
1019
1020
1022
1026
1027
1032
1034
1035
1038
1043
1045

LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 983

Recursin (recursividad, recurrencia)


Definicin recursiva: En la definicin aparece lo que se define
Factorial(N) = N x Factorial(N1)

(N >= 0)
Cada tringulo est
formado por otros
tringulos ms pequeos

La cmara graba lo que graba

LuisHernndezYez

(http://farm1.static.flickr.com/83
/229219543_edf740535b.jpg)

La imagen del paquete


aparece dentro del propio
paquete,... hasta el infinito!
(wikipedia.org)
Fundamentosdelaprogramacin:Introduccinalarecursin

(wikipedia.org)

Las matrioskas rusas


Pgina 984

Factorial(N) = N x Factorial(N1)
El factorial se define en funcin de s mismo
Los programas no pueden manejar la recursin infinita
La definicin recursiva debe adjuntar uno o ms casos base
Caso base: aquel en el que no se utiliza la definicin recursiva
Proporcionan puntos finales de clculo:
Caso recursivo (induccin)

Caso base (o de parada)

si N = 0

El valor de N se va aproximando al valor del caso base (0)

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 985

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 986

LuisHernndezYez

LuisHernndezYez

Factorial(N)

N x Factorial(N1) si N > 0

Funciones recursivas
Una funcin puede implementar un algoritmo recursivo
La funcin se llamar a s misma si no se ha llegado al caso base

LuisHernndezYez

Factorial(N)

si N = 0

N x Factorial(N1)

si N > 0

longlong int factorial(int n){


longlong intresultado;
if (n==0){//Caso base
resultado =1;
}
else {
resultado =n*factorial(n 1);
}
return resultado;
}
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 987

factorial.cpp

Funciones recursivas
longlong int factorial(int n){
longlong intresultado;
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)


LuisHernndezYez

5 x 4 x 3 x factorial(2) 5 x 4 x 3 x 2 x factorial(1)
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

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 988

Diseo de funciones recursivas


Una funcin recursiva debe satisfacer tres condiciones:
Caso(s) base: Debe haber al menos un caso base de parada
Induccin: Paso recursivo que provoca una llamada recursiva
Debe ser correcto para distintos parmetros de entrada
Convergencia: Cada paso recursivo debe acercar a un caso base
Se describe el problema en trminos de problemas ms sencillos
1

si N = 0

N x Factorial(N1)

si N > 0

Funcin factorial(): tiene caso base (N = 0), siendo correcta


para N es correcta para N+1 (induccin) y se acerca cada vez
ms al caso base (N1 est ms cerca de 0 que N)
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 989

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 990

LuisHernndezYez

LuisHernndezYez

Factorial(N)

LuisHernndezYez

longlong int factorial(int n){


longlong intresultado;
if (n==0){//Caso base
resultado =1;
}
else {
resultado =n*factorial(n 1);
}
return resultado;
}

Cada llamada recursiva fuerza una nueva ejecucin de la funcin


Cada llamada utiliza sus propios parmetros por valor
y variables locales (n y resultado en este caso)
En las llamadas a la funcin se utiliza la pila del sistema para
mantener los datos locales y la direccin de vuelta

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 991

Regiones de memoria que distingue el sistema operativo:


Pila(Stack)

Montn(Heap)

Llamadas a subprogramas

Memoria dinmica (Tema 9)

Datos delprograma

LuisHernndezYez

Cdigodelprograma

Memoria principal

S.O.

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 992

Mantiene los datos locales de la funcin y la direccin de vuelta


Estructura de tipo pila: lista LIFO (lastin firstout)
El ltimo que entra es el primero que sale:

Entra
4

Entra
7

Entra
2

Sale
2

LuisHernndezYez

2
4

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 993

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}

LuisHernndezYez

int funcA(int a){


intb;
...
<DIR2>
b=funcB(a);
...
return b;
}
int main(){
...
cout<<funcA(4);
<DIR1>
...

Llamada a funcin:
Entra la direccin de vuelta

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 994

Pila

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}

LuisHernndezYez

int funcA(int a){


intb;
...
<DIR2>
b=funcB(a);
...
return b;
}

Entrada en la funcin:
Se alojan los datos locales

int main(){
...
cout<<funcA(4);
<DIR1>
...

<DIR1>
Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 995

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}

LuisHernndezYez

int funcA(int a){


intb;
...
<DIR2>
b=funcB(a);
...
return b;
}

Llamada a funcin:
Entra la direccin de vuelta

int main(){
...
cout<<funcA(4);
<DIR1>
...

Fundamentosdelaprogramacin:Introduccinalarecursin

b
a
<DIR1>
Pila

Pgina 996

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}

Entrada en la funcin:
Se alojan los datos locales

LuisHernndezYez

int funcA(int a){


intb;
...
<DIR2>
b=funcB(a);
...
return b;
}

<DIR2>
b
a

int main(){
...
cout<<funcA(4);
<DIR1>
...

<DIR1>
Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 997

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}

Vuelta de la funcin:
Se eliminan los datos locales

LuisHernndezYez

int funcA(int a){


intb;
...
<DIR2>
b=funcB(a);
...
return b;
}
int main(){
...
cout<<funcA(4);
<DIR1>
...

Fundamentosdelaprogramacin:Introduccinalarecursin

x
<DIR2>
b
a
<DIR1>
Pila

Pgina 998

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}

Vuelta de la funcin:
Sale la direccin de vuelta

LuisHernndezYez

int funcA(int a){


intb;
...
<DIR2>
b=funcB(a);
...
return b;
}

<DIR2>
b
a

int main(){
...
cout<<funcA(4);
<DIR1>
...

<DIR1>
Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 999

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}

LuisHernndezYez

int funcA(int a){


intb;
...
<DIR2>
b=funcB(a);
...
return b;
}

La ejecucin contina
en esa direccin

int main(){
...
cout<<funcA(4);
<DIR1>
...

Fundamentosdelaprogramacin:Introduccinalarecursin

b
a
<DIR1>
Pila

Pgina 1000

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}

LuisHernndezYez

int funcA(int a){


intb;
...
<DIR2>
b=funcB(a);
...
return b;
}

Vuelta de la funcin:
Se eliminan los datos locales

int main(){
...
cout<<funcA(4);
<DIR1>
...

b
a
<DIR1>
Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1001

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}

LuisHernndezYez

int funcA(int a){


intb;
...
<DIR2>
b=funcB(a);
...
return b;
}

Vuelta de la funcin:
Sale la direccin de vuelta

int main(){
...
cout<<funcA(4);
<DIR1>
...

Fundamentosdelaprogramacin:Introduccinalarecursin

<DIR1>
Pila

Pgina 1002

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}

LuisHernndezYez

int funcA(int a){


intb;
...
<DIR2>
b=funcB(a);
...
return b;
}
int main(){
...
cout<<funcA(4);
<DIR1>
...

Pila

La ejecucin contina
en esa direccin

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1003

Mecanismo de pila adecuado para llamadas a funciones anidadas:


Las llamadas terminan en el orden contrario a como se llaman

LuisHernndezYez

V U E LTAS

int funcB(...){
...
...funcC(...)
}
int funcA(...){
...
...funcB(...)
}
int main(){
...
cout<<funcA(...);
...

Fundamentosdelaprogramacin:Introduccinalarecursin

LLAMADAS

...
int funcC(...){
...
}

funcC
funcB
funcA
Pila

Pgina 1004

longlong int factorial(int n){


longlong intresultado;
if (n==0){//Caso base
resultado =1;
}
else {
resultado =n*factorial(n 1);
}
return resultado;
}

LuisHernndezYez

cout<<factorial(5)<<endl;

Obviaremos las direcciones de vuelta en la pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1005

factorial(5)

LuisHernndezYez

resultado=?
n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1006

factorial(5)
factorial(4)

resultado =?
n=4
LuisHernndezYez

resultado=?
n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1007

factorial(5)
factorial(4)
factorial(3)

resultado=?
n=3
resultado =?
n=4
LuisHernndezYez

resultado=?
n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1008

factorial(5)
factorial(4)
factorial(3)
factorial(2)

resultado=?
n=2
resultado=?
n=3
resultado =?
n=4
LuisHernndezYez

resultado=?
n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1009

factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
resultado=?
n=1
resultado=?
n=2
resultado=?
n=3
resultado =?
n=4
LuisHernndezYez

resultado=?
n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1010

factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)

resultado=1
n=0
resultado=?
n=1
resultado=?
n=2
resultado=?
n=3
resultado =?
n=4

LuisHernndezYez

resultado=?
n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1011

factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)

resultado=1
n=1

resultado=?
n=2
resultado=?
n=3
resultado =?
n=4

LuisHernndezYez

resultado=?
n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1012

factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)
1
1

resultado=2
n=2
resultado=?
n=3
resultado =?
n=4

LuisHernndezYez

resultado=?
n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1013

factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)
1
1
2

resultado=6
n=3
resultado =?
n=4

LuisHernndezYez

resultado=?
n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1014

factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)
1
1
2
resultado =24

n=4

LuisHernndezYez

resultado=?
n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1015

factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)
1
1
2

LuisHernndezYez

6
24

resultado=120
n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1016

factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)
1
1
2
24
120

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1017

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1018

LuisHernndezYez

LuisHernndezYez

Slo hay una llamada recursiva


Ejemplo: Clculo del factorial de un nmero entero positivo
longlong int factorial(int n){
longlong intresultado;
if (n==0){//Caso base
resultado =1;
}
else {
resultado =n*factorial(n 1);
}
return resultado;
}
LuisHernndezYez

Una sola llamada recursiva

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1019

Varias llamadas recursivas


Ejemplo: Clculo de los nmeros de Fibonacci

Fib(n)

si n = 0

si n = 1

Fib(n1) + Fib(n2)

si n > 1

LuisHernndezYez

Dos llamadas recursivas

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1020

fibonacci.cpp

LuisHernndezYez

...
int main(){
for(int i=0;i<20;i++){
cout<<fibonacci(i)<<endl;
}
return 0;
}

Fib(n)

si n = 0

si n = 1

Fib(n1) + Fib(n2)

si n > 1

int fibonacci(int n){


int resultado;
if (n==0){
resultado=0;
}
elseif (n==1){
resultado=1;
}
else {
resultado=fibonacci(n 1)+fibonacci(n 2);
}
returnresultado;
}
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1021

En una llamada recursiva alguno de los argumentos es otra llamada


Ejemplo: Clculo de los nmeros de Ackermann:

Ack(m, n)

n + 1

si m = 0

Ack(m1, 1)

si m > 0 y n = 0

Ack(m1, Ack(m, n1))

si m > 0 y n > 0

LuisHernndezYez

Argumento que es una llamada recursiva

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1022

ackermann.cpp

LuisHernndezYez

Nmeros de Ackermann

Ack(m, n)

n + 1

si m = 0

Ack(m1, 1)

si m > 0 y n = 0

Ack(m1, Ack(m, n1))


si m > 0 y n > 0
...
int ackermann(int m,int n){
intresultado;
if (m==0){
resultado =n+1;
}
elseif(n==0){
resultado =ackermann(m 1,1);
}
else{
resultado =ackermann(m 1,ackermann(m,n 1));
}
return resultado;
}
Prubalo con nmeros muy bajos:

Se generan MUCHAS llamadas recursivas


Fundamentosdelaprogramacin:Introduccinalarecursin

Nmeros de Ackermann

Ack(m, n)

ackermann(1,1)

Pgina 1023

n + 1

si m = 0

Ack(m1, 1)

si m > 0 y n = 0

Ack(m1, Ack(m, n1))

si m > 0 y n > 0

ackermann(0,ackermann(1,0))

2
3

ackermann(0,1)

LuisHernndezYez

ackermann(0,2)

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1024

Nmeros de Ackermann

Ack(m, n)

ackermann(2,1)

n + 1

si m = 0

Ack(m1, 1)

si m > 0 y n = 0

Ack(m1, Ack(m, n1))

si m > 0 y n > 0

ackermann(1, ackermann(2,0))

3
ackermann(1,1)

ackermann(0,ackermann(1,0))

ackermann(0,1)
ackermann(0,2)

ackermann(1,3)

ackermann(0, ackermann(1,1))
ackermann(0,ackermann(1,0))

3
ackermann(0,3)

ackermann(0,1)
ackermann(0,2)

ackermann(0,4)
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1025

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1026

LuisHernndezYez

LuisHernndezYez

ackermann(0,ackermann(1,2))

Cdigo anterior y posterior a la llamada recursiva


{
Cdigo anterior
Llamada recursiva
Cdigo posterior
}
Cdigo anterior
Se ejecuta para las distintas entradas antes que el cdigo posterior
Cdigo posterior

LuisHernndezYez

Se ejecuta para las distintas entradas tras llegarse al caso base


El cdigo anterior se ejecuta en orden directo para las distintas
entradas, mientras que el cdigo posterior lo hace en orden inverso
Si no hay cdigo anterior: recursin por delante
Si no hay cdigo posterior: recursin por detrs
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1027

Cdigo anterior y posterior a la llamada recursiva


void func(int n){
if (n>0){//Casobase:n==0
cout<<"Entrando(" <<n<<")" <<endl;//Cdigoanterior
func(n 1);//Llamadarecursiva
cout<<"Saliendo(" <<n<<")" <<endl;//Cdigoposterior
}
}

LuisHernndezYez

func(5);
El cdigo anterior se ejecuta
para los sucesivos valores de n (5, 4, 3, ...)
El cdigo posterior al revs (1, 2, 3, ...)

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1028

directo.cpp

Recorrido de los elementos de una lista (directo)


El cdigo anterior a la llamada procesa la lista en su orden:
...
void mostrar(tLista lista,int pos);
int main(){
tLista lista;
lista.cont =0;
//Cargadelarray...
mostrar(lista,0);
return 0;

LuisHernndezYez

}
void mostrar(tLista lista,int pos){
if (pos<lista.cont){
cout<<lista.elementos[pos]<<endl;
mostrar(lista,pos+1);
}
}
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1029

inverso.cpp

Recorrido de los elementos de una lista (inverso)


El cdigo posterior procesa la lista en el orden inverso:
...
void mostrar(tLista lista,int pos);
int main(){
tLista lista;
lista.cont =0;
//Cargadelarray...
mostrar(lista,0);
return 0;

LuisHernndezYez

}
void mostrar(tLista lista,int pos){
if (pos<lista.cont){
mostrar(lista,pos+1);
cout<<lista.elementos[pos]<<endl;
}
}
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1030

LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1031

Parmetros por valor y por referencia

LuisHernndezYez

Parmetros por valor: cada llamada usa los suyos propios


Parmetros por referencia: misma variable en todas las llamadas
Recogen resultados que transmiten entre las llamadas
void factorial(int n,int&fact){
if (n==0){
fact =1;
}
else {
factorial(n 1,fact);
fact =n*fact;
}
}

Cuando n es 0, el argumento de fact toma el valor 1


Al volver se le va multiplicando por los dems n (distintos)
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1032

LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1033

LuisHernndezYez

Parte el problema en subproblemas ms pequeos


Aplica el mismo proceso a cada subproblema
Naturaleza recursiva (casos base: encontrado o no queda lista)
Partimos de la lista completa
Si no queda lista... terminar (lista vaca: no encontrado)
En caso contrario...
Comprobar si el elemento en la mitad es el buscado
Si es el buscado... terminar (encontrado)
Si no...
Si el buscado es menor que el elemento mitad...
Repetir con la primera mitad de la lista
Si el buscado es mayor que el elemento mitad...
Repetir con la segunda mitad de la lista
La repeticin se consigue con las llamadas recursivas
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1034

Dos ndices que indiquen el inicio y el final de la sublista:


int buscar(tLista lista,int buscado,int ini,int fin)
//Devuelveelndice(0,1,...)o1sinoest

LuisHernndezYez

Cules son los casos base?


Que ya no quede sublista (ini>fin) No encontrado
Que se encuentre el elemento

Repasa en el Tema 7 cmo funciona y cmo se implement


iterativamente la bsqueda binaria (comprala con esta)

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1035

LuisHernndezYez

binaria.cpp
int buscar(tLista lista,int buscado,int ini,int fin){
int pos=1;
if (ini<=fin){
int mitad=(ini+fin)/2;
if (buscado==lista.elementos[mitad]){
pos=mitad;
}
elseif(buscado<lista.elementos[mitad]){
pos=buscar(lista,buscado,ini,mitad 1);
}
else{
pos=buscar(lista,buscado,mitad+1,fin);
}
}
return pos;
}

Llamada: pos=buscar(lista,valor,0,lista.cont 1);


Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1036

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
tamaos y colocados por orden de tamao con el mayor debajo

LuisHernndezYez

Torre de ocho discos (wikipedia.org)

Cada monje, en su turno, deba mover un nico disco de un pilar


a otro, para con el tiempo conseguir entre todos llevar la torre del
pilar inicial a uno de los otros dos; respetando una nica regla:
nunca poner un disco sobre otro de menor tamao
Cuando lo hayan conseguido, se acabar el mundo!
[Se requieren al menos 2641 movimientos; si se hiciera uno por segundo,
se terminara en ms de 500 mil millones de aos]
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1037

Queremos resolver el juego en el menor nmero de pasos posible


Qu disco hay que mover en cada paso y a dnde?
Identifiquemos los elementos (torre de cuatro discos):

LuisHernndezYez

Cada pilar se identifica con una letra


Mover del pilar X al pilar Y:
Coger el disco superior de X y ponerlo encima de los que haya en Y

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1038

LuisHernndezYez

Resolucin del problema en base


a problemas ms pequeos
Mover N discos del pilar A al pilar C:
Mover N1 discos del pilar A al pilar B
Mover el disco del pilar A al pilar C
Mover N1 discos del pilar B al pilar C
Para llevar N discos de un pilar origen a
otro destino se usa el tercero como auxiliar
Mover N1 discos del origen al auxiliar
Mover el disco del origen al destino
Mover N1 discos del auxiliar al destino

Mover 4 discos de A a C

Fundamentosdelaprogramacin:Introduccinalarecursin

Mover N1 discos se hace igual, pero


usando ahora otros origen y destino
Mover N1 discos del pilar A al pilar B:
Mover N2 discos del pilar A al pilar C
Mover el disco del pilar A al pilar B
Mover N2 discos del pilar C al pilar B

Pgina 1039

Mover 3 discos de A a B

LuisHernndezYez

Naturaleza recursiva de la solucin

Simulacin para 4 discos (wikipedia.org)

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1040

hanoi.cpp

Caso base: no quedan discos que mover

int main(){
int n;
cout<<"Nmerodetorres:";
cin>>n;
hanoi(n,'A','C','B');
return 0;
}
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1041

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1042

LuisHernndezYez

LuisHernndezYez

...
void hanoi(int n,char origen,char destino,char auxiliar){
if (n>0){
hanoi(n 1,origen,auxiliar,destino);
cout<<origen<<">"<<destino<<endl;
hanoi(n 1,auxiliar,destino,origen);
}
}

longlong int factorial(int n){


longlong intfact;

longlong int factorial(int n){


longlong int fact=1;

assert(n>=0);

assert(n>=0);

if (n==0){
fact=1;
}
else {
fact=n*factorial(n 1);
}

for (int i=1;i<=n;i++){


fact=fact*i;
}
return fact;
}

return fact;

LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1043

LuisHernndezYez

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 versin iterativa sencilla, ser preferible a la recursiva
En ocasiones la versin recursiva es mucho ms simple
Ser preferible si no hay requisitos de rendimiento
Compara las versiones recursivas del factorial o de los nmeros
de Fibonacci con sus equivalentes iterativas
Y qu tal una versin iterativa para los nmeros de Ackermann?

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1044

LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1045

Definicin recursiva de listas


Ya hemos definido de forma recursiva alguna estructura de datos:
Secuencia

elemento seguido de una secuencia


secuencia vaca (ningn elemento)

Las listas son secuencias:


elemento seguido de una lista

LuisHernndezYez

Lista

lista vaca (ningn elemento)

(Caso base)

La lista 1, 2, 3 consiste en el elemento 1 seguido de la lista 2, 3, que,


a su vez, consiste en el elemento 2 seguido de la lista 3, que, a su vez,
consiste en el elemento 3 seguido de la lista vaca (caso base)
Hay otras estructuras con naturaleza recursiva (p.e., los rboles)
que estudiars en posteriores cursos
Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1046

Procesamiento de estructuras de datos recursivas


Naturaleza recursiva de las estructuras: procesamiento recursivo
Procesar (lista):
Si lista no vaca (caso base):
Procesar el primer elemento de la lista // Cdigo anterior
Procesar (resto(lista))
Procesar el primer elemento de la lista // Cdigo posterior

LuisHernndezYez

resto(lista): sublista tras quitar el primer elemento

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1047

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1048

Fundamentosdelaprogramacin

AP
Grado en Ingeniera Informtica
Grado en Ingeniera del Software
Grado en Ingeniera de Computadores
Luis Hernndez Yez

Facultad de Informtica
Universidad Complutense

LuisHernndezYez

Flujos
Archivosbinarios
Tamaodelosdatos:Eloperadorsizeof()
Aperturadearchivosbinarios
Lecturadearchivosbinarios(accesosecuencial)
Escrituraenarchivosbinarios(accesosecuencial)
Accesodirectooaleatorio
Ejemplosdeusodearchivosbinarios
Ordenacindelosregistrosdelarchivo
Bsquedabinaria
Insercinenunarchivobinarioordenado
Cargadelosregistrodeunarchivoenunatabla
Almacenamientodeunatablaenunarchivo

Fundamentosdelaprogramacin:Archivosbinarios

1051
1054
1056
1059
1061
1066
1070
1078
1079
1085
1088
1092
1093

LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1051

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
Siempre por medio de flujos
Dispositivos/archivos
de salida

LuisHernndezYez

Dispositivos/archivos
de entrada

Programa

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1052

Flujos de texto y binarios


Flujo de texto: contiene una secuencia de caracteres
T

Flujo binario: contiene una secuencia de cdigos binarios.


A0

25

2F

04

D6

FF

00

27

6C

CA

49

07

5F

A4

(Cdigos representados en notacin hexadecimal.)

En ambos casos se trata de una secuencia de caracteres


En el segundo caso se interpretan como cdigos binarios
Sin contemplar caracteres especiales como \n o \t
Ya hemos usado flujos de texto para E/S por consola/archivos

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1053

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1054

LuisHernndezYez

LuisHernndezYez

Lo que signifiquen los cdigos depender del programa que use el archivo

Codificacin textual y binaria


Datos numricos: se pueden guardar en forma textual o binaria
int dato=124567894;

Representacin como texto: caracteres '1''2''4''5''6'...


Flujo de texto

9 caracteres (se guarda el cdigo ASCII de cada uno)


Representacin binaria:

LuisHernndezYez

00000111011011001100000101010110Hex: 076CC156
Flujo binario

07

6C

C1

56

4 caracteres interpretados como cdigos binarios

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1055

El operador sizeof()

LuisHernndezYez

En los archivos binarios se manejan cdigos binarios (bytes)


sizeof() (palabra clave): bytes que ocupa en memoria algo
Se aplica a un dato o a un tipo
char byte
constint Max=80;
typedefchar tCadena[Max];
typedef struct {
int codigo;
tCadena item;
double valor;
} tRegistro;
const int SIZE=sizeof(tRegistro);

En un archivo binario un dato del tipo tRegistro


ocupar exactamente SIZE caracteres
Fundamentosdeprogramacin:Archivosbinarios

Pgina 1056

typedef struct {
int cod;
double val;
} tRegistro;
tRegistro reg;
const int SIZE=sizeof(reg);

MEMORIA
...

reg

...

Posiciones de memoria usadas

SIZE
(12)

LuisHernndezYez

Se guardan los SIZE bytes:


Flujo binario
00

00

00

05

0A

37

1C

DF

03

92

Fundamentosdeprogramacin:Archivosbinarios

0F03:1A38

00

0F03:1A39

00

0F03:1A3A

00

0F03:1A3B

05

0F03:1A3C

0A

0F03:1A3D

37

0F03:1A3E

1C

0F03:1A3F

DF

0F03:1A40

03

0F03:1A41

92

0F03:1A42

99

0F03:1A43

0E

0F03:1A44

...

99

reg.cod
(4)

reg.val
(8)

0E

Pgina 1057

Por eficiencia, algunos campos de una estructura se pueden


forzar a ocupar un mltiplo del tamao de palabra del sistema
Tamao de palabra (4, 8, 16, ... bytes): dato ms pequeo que se
lee de la memoria (aunque se usen slo algunos de los bytes)
As, el tamao real de las estructuras puede ser mayor que la
simple suma de los tamaos de cada tipo
Por ejemplo:

LuisHernndezYez

typedef struct {
char c;
int i;
} tRegistro;
const int SIZE=sizeof(tRegistro);

char (1 byte) + int (4 bytes)


char + int + double

SIZE toma el valor 8 (4 + 4), no 5


24 bytes (8 + 8 + 8)

NOTA: El tamao de palabra y los tamaos de los tipos dependen del sistema concreto
Fundamentosdeprogramacin:Archivosbinarios

Pgina 1058

LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1059

Biblioteca fstream

LuisHernndezYez

Archivos binarios: tipo fstream


Apertura: funcin open(nombre,modo)
Nombre: char[] (funcin c_str() para cadenas de tipo string)
Modos de apertura del archivo:
Modo

Significado

ios::app

Aadir: permite seguir escribiendo a partir del final

ios::binary

Binario: tratar el archivo como archivo binario

ios::in

Entrada: archivo para leer de l

ios::out

Salida: archivo para escribir en l

ios::trunc

Truncar: borrar todo lo que haya y empezar de nuevo

Concatenacin de modos: operador | (O binaria: suma bit a bit)


archivo.open("entrada.dat",ios::in|ios::binary);
Fundamentosdeprogramacin:Archivosbinarios

Pgina 1060

LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1061

archivo.read(puntero_al_bfer,nmero)
bfer: variable destino de los caracteres ledos
Pasado como puntero a secuencia de caracteres
Referencia (&) a la variable destino
Molde de puntero a carcter (char *)
nmero: cantidad de caracteres a extraer del archivo
Operador sizeof()
Archivo abierto con los modos ios::in e ios::binary
LuisHernndezYez

archivo.read((char *)&registro,sizeof(tRegistro));

Los caracteres ledos se interpretan como cdigos binarios

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1062

xito o fallo de la lectura

LuisHernndezYez

Funcin gcount()
N de caracteres realmente ledos en la ltima operacin
Si coincide con el nmero que se solicitaron leer: OK
Si son menos, se ha alcanzado el final del archivo: Fallo
tRegistro registro;
fstream archivo;
archivo.open("entrada.dat",ios::in|ios::binary);
archivo.read((char *)&registro,sizeof(tRegistro));
if (archivo.gcount()<sizeof(tRegistro)){
//Falloenlalectura
}
else {
//LecturaOK
...
Fundamentosdeprogramacin:Archivosbinarios

Pgina 1063

leer.cpp

LuisHernndezYez

#include<iostream>
usingnamespacestd;
#include<fstream>
#include"registro.h"
int main(){
tRegistro registro;
fstream archivo;
archivo.open("bd.dat",ios::in |ios::binary);
archivo.read((char *)&registro,SIZE);
int cuantos=archivo.gcount();
while (cuantos==SIZE){
mostrar(registro);
archivo.read((char *)&registro,SIZE);
cuantos=archivo.gcount();
}
archivo.close();
No olvides cerrar el archivo!
return 0;
}
Fundamentosdeprogramacin:Archivosbinarios

Pgina 1064

registro.h

El tipo tRegistro

Por qu usamos cadenas al estilo de C?


string: tamao variable en memoria
Requieren un proceso de serializacin
Las cadenas al estilo de C siempre ocupan lo mismo en memoria

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1065

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1066

LuisHernndezYez

LuisHernndezYez

constint Max=80;
typedefchar tCadena[Max];
typedef struct {
int codigo;
tCadena item;
double valor;
}tRegistro;
const int SIZE=sizeof(tRegistro);

archivo.write(puntero_al_bfer,nmero)
bfer: origen de los caracteres a escribir en el archivo
Pasado como puntero a secuencia de caracteres
Referencia (&) a la variable destino
Molde de puntero a carcter (char *)
nmero: cantidad de caracteres a escribir en el archivo
Operador sizeof()
Archivo abierto con los modos ios::out e ios::binary
LuisHernndezYez

archivo.write((char *)&registro,sizeof(tRegistro));

Se escriben tantos caracteres como celdas de memoria ocupe


la variable registro

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1067

escribir.cpp

LuisHernndezYez

#include<iostream>
usingnamespace 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<<"Cdigo:";
cin.sync();
cin>>registro.codigo;
cout<<"Nombre:";
cin.sync();
cin.getline(registro.item,Max);//Mx:80
...

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1068

cout<<"Precio:";
cin.sync();
cin>>registro.valor;
archivo.write((char *)&registro,SIZE);
cout<<"Otro[S/N]?";
charc;
cin>>c;
if ((c=='n')||(c=='N')){
seguir=false;
}
}
archivo.close();

No olvides cerrar el archivo!


(prdida de datos!)

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1069

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1070

LuisHernndezYez

LuisHernndezYez

return 0;

LuisHernndezYez

Acceso secuencial: empezando en el primero pasando a siguiente


Acceso directo (tambin llamado aleatorio):
Para localizar registros individuales necesitamos otras rutinas:
tellg(): lugar donde se encuentra el puntero del archivo
Siguiente posicin donde se realizar una lectura o escritura
seekg(desplazamiento,origen):
Lleva el puntero del archivo a una posicin concreta:
desplazamiento caracteres desde el origen indicado
Origen:
ios::beg: principio del archivo
ios::cur: posicin actual
ios::end: final del archivo

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1071

ios::beg
0

ios::end
SIZE

2*SIZE

3*SIZE

4*SIZE

6*SIZE

5*SIZE

SIZE

SIZE

SIZE

SIZE

SIZE

SIZE

tRegistro

tRegistro

tRegistro

tRegistro

tRegistro

tRegistro

const int SIZE=sizeof(tRegistro);

Cada registro ocupa SIZE caracteres en el archivo


Cuntos registros hay en el archivo?
LuisHernndezYez

archivo.seekg(0,ios::end);//0car.desdeelfinal>final
int pos=archivo.tellg();//Totaldecaracteresdelarchivo
int numReg =pos/SIZE;

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1072

ios::beg
0

ios::end
SIZE

2*SIZE

3*SIZE

4*SIZE

6*SIZE

5*SIZE

SIZE

SIZE

SIZE

SIZE

SIZE

SIZE

tRegistro

tRegistro

tRegistro

tRegistro

tRegistro

tRegistro

const int SIZE=sizeof(tRegistro);

Poner el puntero del archivo en un n de registro:

LuisHernndezYez

archivo.seekg((num 1)*SIZE,ios::beg);

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1073

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 aadir (escribir) un nuevo registro
Archivos binarios de lectura/escritura:
Se han de abrir con los modos ios::in, ios::out e ios::binary
archivo.open("bd.dat",ios::in |ios::out |ios::binary);

LuisHernndezYez

Ahora podemos tanto leer como escribir

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1074

actualizar.cpp
//Actualizacindeunregistro
#include<iostream>
usingnamespacestd;
#include<fstream>
#include"registro.h"

LuisHernndezYez

int main(){
tRegistro registro;
fstream archivo;
archivo.open("bd.dat",ios::in |ios::out |ios::binary);
archivo.seekg(0,ios::end);
int pos=archivo.tellg();
int numReg =pos/SIZE;
cout<<"Nmeroderegistros:" <<numReg <<endl;
int num;
cout<<"Registronmero?";
cin>>num;
...

LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1075

if ((num>0)&&(num<=numReg)){
archivo.seekg((num 1)*SIZE,ios::beg);
archivo.read((char *)&registro,SIZE);
mostrar(registro);
cout<<endl<<"Cambiarnombre[S/N]?";
char c;
cin.sync();
cin>>c;
if ((c=='s')||(c=='S')){
cout<<"Nombre:";
cin.sync();
cin.getline(registro.item,80);
}
cout<<endl<<"Cambiarprecio[S/N]?";
cin.sync();
cin>>c;
if ((c=='s')||(c=='S')){
cout<<"Precio:";
cin>>registro.valor;
}
...
Fundamentosdeprogramacin:Archivosbinarios

Pgina 1076

archivo.seekg((num 1)*SIZE,ios::beg);
archivo.write((char *)&registro,SIZE);
cout<<endl<<"Registroactualizado:" <<endl;
archivo.seekg((num 1)*SIZE,ios::beg);
archivo.read((char *)&registro,SIZE);
mostrar(registro);
}
archivo.close();
return 0;

LuisHernndezYez

Pgina 1077

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1078

LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios

ordenar.cpp

Mediante un acceso directo a los registros del archivo


Ordenaremos por el campo item
#include<iostream>
usingnamespacestd;
#include<fstream>
#include<iomanip>
#include<cstring>
#include"registro.h"
const char BD[]="lista.dat";

LuisHernndezYez

void mostrar();
...

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1079

void mostrar(){
fstream archivo;
tRegistro registro;
int cuantos;

LuisHernndezYez

archivo.open(BD,ios::in |ios::binary);
archivo.read((char *)&registro,SIZE);
cuantos=archivo.gcount();
while (cuantos==SIZE){
mostrar(registro);
archivo.read((char *)&registro,SIZE);
cuantos=archivo.gcount();
}
archivo.close();
}
...

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1080

int main(){

LuisHernndezYez

mostrar();

Orden inicial

fstream archivo;
archivo.open(BD,ios::in |ios::out |ios::binary);
archivo.seekg(0,ios::end);
int pos=archivo.tellg();
int numReg =pos/SIZE;
...

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1081

//Ordenamosconelmtododeseleccindirecta
tRegistro regMenor,reg;
for (int i=0;i<numReg 1;i++){
int menor=i;
for (int j=i+1;j<numReg;j++){
archivo.seekg(menor*SIZE,ios::beg);
archivo.read((char *)&regMenor,SIZE);
archivo.seekg(j*SIZE,ios::beg);
archivo.read((char *)&reg,SIZE);
if(strcmp(reg.item,regMenor.item)<0){
menor=j;
}
}
regMenor
reg
...
j

LuisHernndezYez

menor
i

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1082

if (menor>i){//Intercambiamos
archivo.seekg(i*SIZE,ios::beg);
archivo.read((char *)&reg,SIZE);
archivo.seekg(menor*SIZE,ios::beg);
archivo.read((char *)&regMenor,SIZE);
archivo.seekg(i*SIZE,ios::beg);
archivo.write((char *)&regMenor,SIZE);
archivo.seekg(menor*SIZE,ios::beg);
archivo.write((char *)&reg,SIZE);
}
}
...

reg

Fundamentosdeprogramacin:Archivosbinarios

regMenor

LuisHernndezYez

menor

Pgina 1083

archivo.close();
cout<<endl<<"Trasordenar:"<<endl<<endl;
mostrar();
return 0;

LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1084

buscar.cpp

Archivo binario ordenado; por cdigo


#include<iostream>
usingnamespacestd;
#include<fstream>
#include"registro.h"
const char BD[]="ord.dat";

LuisHernndezYez

void mostrar();
int main(){
mostrar();
tRegistro registro;
fstream archivo;
...

LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1085

archivo.open(BD,ios::in|ios::binary);
archivo.seekg(0,ios::end);
int pos=archivo.tellg();
int numReg =pos/SIZE;
int buscado;
cout<<"Cdigoabuscar:";
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 *)&registro,SIZE);
if (buscado==registro.codigo){
encontrado=true;
}
elseif(buscado<registro.codigo){
fin=mitad 1;
}
...
Fundamentosdeprogramacin:Archivosbinarios

Pgina 1086

else{
ini=mitad+1;
}

LuisHernndezYez

}
if (encontrado){
int pos=mitad+1;
cout<<"Encontradoenlaposicin" <<pos<<endl;
mostrar(registro);
}
else{
cout<<"Noencontrado!" <<endl;
}
archivo.close();
return 0;
}
...

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1087

insertar.cpp

Ordenado por el campo codigo


#include<iostream>
usingnamespacestd;
#include<fstream>
#include"registro.h"
const char BD[]="ord2.dat";

LuisHernndezYez

void mostrar();
int main(){
mostrar();
tRegistro nuevoRegistro =nuevo(),registro;
fstream archivo;
archivo.open(BD,ios::in|ios::out |ios::binary);
archivo.seekg(0,ios::end);
int pos=archivo.tellg();
int numReg =pos/SIZE;
...
Fundamentosdeprogramacin:Archivosbinarios

Pgina 1088

LuisHernndezYez

pos=0;
bool encontrado=false;
archivo.seekg(0,ios::beg);
while ((pos<numReg)&&!encontrado){
archivo.read((char *)&registro,SIZE);
if (registro.codigo >nuevoRegistro.codigo){
encontrado=true;
}
else {
pos++;
}
}
if (pos==numReg){//Debeiralfinal
archivo.seekg(0,ios::end);
archivo.write((char *)&nuevoRegistro,SIZE);
}
...

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1089

else {//Hayquehacerhueco
for (int i=numReg 1;i>=pos;i){
archivo.seekg(i*SIZE,ios::beg);
archivo.read((char *)&registro,SIZE);
archivo.seekg((i+1)*SIZE,ios::beg);
archivo.write((char *)&registro,SIZE);
}
archivo.seekg(pos*SIZE,ios::beg);
archivo.write((char *)&nuevoRegistro,SIZE);
}
archivo.close();

LuisHernndezYez

mostrar();

nuevoRegistro

return 0;
}

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1090

Al principio

LuisHernndezYez

Por el medio

Al final
Fundamentosdeprogramacin:Archivosbinarios

Pgina 1091

LuisHernndezYez

tabla.cpp
void cargar(tTabla &tabla,bool &ok){
ok=true;
fstream archivo;
archivo.open(BD,ios::in |ios::binary);
if (!archivo.is_open()){
ok=false;
}
else {
archivo.seekg(0,ios::end);
int pos=archivo.tellg();
int numReg =pos/SIZE;
tabla.cont =0;
tRegistroregistro;
archivo.seekg(0,ios::beg);
for (int i=0;i<numReg;i++){
archivo.read((char *)&registro,SIZE);
tabla.registros[tabla.cont]=registro;
tabla.cont++;
}
archivo.close();
}
}
Fundamentosdeprogramacin:Archivosbinarios

Pgina 1092

tabla.cpp

LuisHernndezYez

void guardar(tTabla tabla){


fstream archivo;
archivo.open(BD,ios::out |ios::binary |ios::trunc);
for (int i=0;i<tabla.cont;i++){
archivo.write((char *)&tabla.registros[i],SIZE);
}
archivo.close();
}

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1093

bd.cpp

LuisHernndezYez

#include<iostream>
usingnamespacestd;
#include"registro.h"
#include"tabla.h"
int main(){
tTabla tabla;
tTabla ok;
cargar(tabla,ok);
if(!ok){
cout<<"Erroralabrirelarchivo!"<<endl;
}
else {
mostrar(tabla);
insertar(tabla,nuevo(),ok);
mostrar(tabla);
guardar(tabla);
}
return 0;
}
Fundamentosdeprogramacin:Archivosbinarios

Pgina 1094

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas
bajo ciertas condiciones.
Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.

LuisHernndezYez

No comercial (Non commercial):


La explotacin de la obra queda limitada a usos no comerciales.
Compartir igual (Share alike):
La explotacin autorizada incluye la creacin de obras derivadas
siempre que mantengan la misma licencia al ser divulgadas.

Pulsa en la imagen de arriba a la derecha para saber ms.


Fundamentosdeprogramacin:Archivosbinarios

Pgina 1095

También podría gustarte