You are on page 1of 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

Tema1 Computadorasyprogramacin 1
Tema2 TiposeinstruccionesI 48
Anexo:Detallestcnicosdelostipos 212
Tema3 TiposeinstruccionesII 225
AnexoI:Eloperadorternario? 398
AnexoII:Ejemplosdesecuencias 402
Tema4 Laabstraccinprocedimental 425
Anexo:Mssobresubprogramas 496
Tema5 Tiposdedatosestructurados 512
Anexo:CadenasalestilodeC 580
Tema6 Recorridoybsquedaenarrays 588
Tema7 Algoritmosdeordenacin 649
Anexo:Mssobreordenacin 742
Tema8 Programacinmodular 755
Anexo:Ejemplodemodularizacin 832
LuisHernndezYez

Tema9 Punterosymemoriadinmica 847


Anexo:Punterosymemoriadinmica 938
Tema10 Introduccinalarecursin 981
Apndice:Archivosbinarios 1049

Fundamentosdelaprogramacin
Informtica,computadorasyprogramacin 3
Lenguajemquinayensamblador 12
Lenguajesdeprogramacindealtonivel 15
Unpocodehistoria 19
ProgramacineIngenieradelSoftware 24
EllenguajedeprogramacinC++ 27
Sintaxisdeloslenguajesdeprogramacin 30
UnprimerprogramaenC++ 35
Herramientasdedesarrollo 39
C++:UnmejorC 45
LuisHernndezYez

Fundamentosdelaprogramacin

Unejemplodeprogramacin 50 Operadoresrelacionales 177


ElprimerprogramaenC++ 64 Tomadedecisiones(if) 180
Laslneasdecdigodelprograma 80 Bloquesdecdigo 183
Clculosenlosprogramas 86 Bucles(while) 186
Variables 92 Entrada/salidaporconsola 190
Expresiones 98 Funcionesdefinidas
Lecturadedatosdesdeelteclado 108 porelprogramador 199
Resolucindeproblemas 119
Losdatosdelosprogramas 127
Identificadores 129
Tiposdedatos 133
Declaracinyusodevariables 142
Instruccionesdeasignacin 147
Operadores 152
Mssobreexpresiones 160
LuisHernndezYez

Constantes 167
Labibliotecacmath 171
Operacionesconcaracteres 174

Fundamentosdelaprogramacin
int 214
float 216
Notacincientfica 217
double 218
char 220
bool 221
string 222
Literalesconespecificacindetipo 223
LuisHernndezYez

Fundamentosdelaprogramacin

Tipos,valoresyvariables 227 Elbuclefor 321


Conversindetipos 232 Buclesanidados 331
Tiposdeclaradosporelusuario 236 mbitoyvisibilidad 339
Tiposenumerados 238 Secuencias 349
Entrada/Salida Recorridodesecuencias 355
conarchivosdetexto 248 Secuenciascalculadas 363
Lecturadearchivosdetexto 253 Bsquedaensecuencias 370
Escrituraenarchivosdetexto 266 Arraysdedatossimples 374
Flujodeejecucin 272 Usodevariablesarrays 379
Seleccinsimple 276 Recorridodearrays 382
Operadoreslgicos 282 Bsquedaenarrays 387
Anidamientodeif 286 Arraysnocompletos 393
Condiciones 290
Seleccinmltiple 293
Laescalaifelseif 295
LuisHernndezYez

Lainstruccinswitch 302
Repeticin 313
Elbuclewhile 316

Fundamentosdelaprogramacin
Eloperadorternario? 399

Recorridos 404
Unaparcamiento 405
Parntesisbienemparejados? 409
Dossecuenciasiguales? 412
NmerosprimosmenoresqueN 413
Bsquedas 417
Bsquedadeunnmeroenunarchivo 419
Bsquedasensecuenciasordenadas 420
LuisHernndezYez

Fundamentosdelaprogramacin

Diseodescendente:Tareasysubtareas 427
Subprogramas 434
Subprogramasydatos 441
Parmetros 446
Argumentos 451
Resultadodelafuncin 467
Prototipos 473
Ejemploscompletos 475
Funcionesdeoperador 477
Diseodescendente(unejemplo) 480
Precondicionesypostcondiciones 490
LuisHernndezYez

Fundamentosdelaprogramacin
Archivoscomoparmetros 498
Lafuncinmain() 501
Argumentosimplcitos 504
Sobrecargadesubprogramas 508
LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Tiposdedatos 514
Arraysdenuevo 517
Arraysybuclesfor 520
Mssobrearrays 522
Inicializacindearrays 523
Enumeradoscomondices 524
Pasodearraysasubprogramas 525
Implementacindelistas 528
Cadenasdecaracteres 531
Cadenasdecaracteresdetipostring 535
Entrada/salidaconstring 539
Operacionesconstring 541
Estructuras 543
Estructurasdentrodeestructuras 549
Arraysdeestructuras 550
LuisHernndezYez

Arraysdentrodeestructuras 551
Listasdelongitudvariable 552
Unejemplocompleto 558
Elbucledo..while 562

Fundamentosdelaprogramacin
CadenasalestilodeC 582
E/SconcadenasalestilodeC 583
Labibliotecacstring 584
Ejemplo 585
LuisHernndezYez

Fundamentosdelaprogramacin

Recorridodearrays 590
Arrayscompletos 593
Arraysnocompletosconcentinela 594
Arraysnocompletosconcontador 595
Ejemplos 597
Generacindenmerosaleatorios 601
Bsquedasenarrays 604
Arrayscompletos 606
Arraysnocompletosconcentinela 607
Arraysnocompletosconcontador 608
Ejemplo 610
Recorridosybsquedasencadenas 614
Msejemplosdemanejodearrays 617
Arraysmultidimensionales 630
Inicializacindearraysmultidimensionales 638
LuisHernndezYez

Recorridodeunarraybidimensional 641
RecorridodeunarrayNdimensional 644
Bsquedaenunarraymultidimensional 647

Fundamentosdelaprogramacin
Algoritmosdeordenacin 651
Algoritmodeordenacinporinsercin 654
Ordenacindearraysporinsercin 665
Algoritmodeordenacinporinsercin
conintercambios 672
Clavesdeordenacin 680
Estabilidaddelaordenacin 688
Complejidadyeficiencia 692
Ordenacionesnaturales 694
Ordenacinporseleccindirecta 701
Mtododelaburbuja 716
Listasordenadas 722
Bsquedasenlistasordenadas 729
Bsquedabinaria 731
LuisHernndezYez

Fundamentosdelaprogramacin

Ordenacinporintercambio 744
Mezcladedoslistasordenadas 747
LuisHernndezYez

Fundamentosdelaprogramacin
Programasmultiarchivoycompilacinseparada 757
Interfazfrenteaimplementacin 762
Usodemdulosdebiblioteca 768
Ejemplo:GestindeunalistaordenadaI 770
Compilacindeprogramasmultiarchivo 778
Elpreprocesador 780
Cadacosaensumdulo 782
Ejemplo:GestindeunalistaordenadaII 784
Elproblemadelasinclusionesmltiples 789
Compilacincondicional 794
Proteccinfrenteainclusionesmltiples 795
Ejemplo:GestindeunalistaordenadaIII 796
Implementacionesalternativas 804
Espaciosdenombres 808
Implementacionesalternativas 817
LuisHernndezYez

Calidadyreutilizacindelsoftware 827

Fundamentosdelaprogramacin

Modularizacindeunprograma 833
LuisHernndezYez

Fundamentosdelaprogramacin
Direccionesdememoriaypunteros 849
Operadoresdepunteros 854
Punterosydireccionesvlidas 864
Punterosnoinicializados 866
Unvalorseguro:NULL 867
Copiaycomparacindepunteros 868
Tipospuntero 873
Punterosaestructuras 875
Punterosaconstantesypunterosconstantes 877
Punterosypasodeparmetros 879
Punterosyarrays 883
Memoriaydatosdelprograma 886
Memoriadinmica 891
Punterosydatosdinmicos 895
Gestindelamemoria 907
LuisHernndezYez

Errorescomunes 911
Arraysdedatosdinmicos 916
Arraysdinmicos 928

Fundamentosdelaprogramacin

Aritmticadepunteros 940
Recorridodearraysconpunteros 953
Referencias 962
Listasenlazadas 964
LuisHernndezYez

Fundamentosdelaprogramacin
Conceptoderecursin 983
Algoritmosrecursivos 986
Funcionesrecursivas 987
Diseodefuncionesrecursivas 989
Modelodeejecucin 990
Lapiladelsistema 992
Lapilaylasllamadasafuncin 994
Ejecucindelafuncinfactorial() 1005
Tiposderecursin 1018
Recursinsimple 1019
Recursinmltiple 1020
Recursinanidada 1022
Recursincruzada 1026
Cdigodelsubprogramarecursivo 1027
Parmetrosyrecursin 1032
Ejemplosdealgoritmosrecursivos 1034
LuisHernndezYez

Bsquedabinaria 1035
TorresdeHanoi 1038
Recursinfrenteaiteracin 1043
Estructurasdedatosrecursivas 1045

Fundamentosdelaprogramacin

Flujos 1051
Archivosbinarios 1054
Tamaodelosdatos:Eloperadorsizeof() 1056
Aperturadearchivosbinarios 1059
Lecturadearchivosbinarios(accesosecuencial) 1061
Escrituraenarchivosbinarios(accesosecuencial) 1066
Accesodirectooaleatorio 1070
Ejemplosdeusodearchivosbinarios 1078
Ordenacindelosregistrosdelarchivo 1079
Bsquedabinaria 1085
Insercinenunarchivobinarioordenado 1088
Cargadelosregistrodeunarchivoenunatabla 1092
Almacenamientodeunatablaenunarchivo 1093
LuisHernndezYez

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

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

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
LuisHernndezYez

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


Introduccin a la programacin en C++ con explicaciones sencillas y
una organizacin clara
LuisHernndezYez

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

Informtica,computadorasyprogramacin 3
Lenguajemquinayensamblador 12
Lenguajesdeprogramacindealtonivel 15
Unpocodehistoria 19
ProgramacineIngenieradelSoftware 24
EllenguajedeprogramacinC++ 27
Sintaxisdeloslenguajesdeprogramacin 30
UnprimerprogramaenC++ 35
Herramientasdedesarrollo 39
C++:UnmejorC 45
LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin
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

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
LuisHernndezYez

mediante la ejecucin de programas informticos

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 4
En todas partes y con muchas formas
LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 5

Hardware
Componentes que integran
la parte material
de una computadora

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

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 6
Programar
Indicar a la computadora qu es lo que tiene que hacer

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

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 7

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

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 8
Esquema general

Memoria
temporal

UnidadCentraldeProceso
CentralProcessorUnit

Dispositivos Dispositivos
C.P.U.
de entrada de salida

Teclado Monitor
Ratn Impresora
Escner Altavoz
LuisHernndezYez

Tctil Almacenamiento
permanente

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 9

La arquitectura de Von Neumann

Dispositivos de E/S

UnaALUde2bits(Wikipedia)
C.P.U. (Procesador)

A.L.U.
Unidad AritmticoLgica
Memoria
LuisHernndezYez

Unidad de Control

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 10
La memoria
Memoria Cada celda en una direccin
01 Celdas de 8 / 16 / 32 / 64 bits
02
03
Informacin voltil
04

Bus 05 1 Bit = 0 / 1
de 06 1 Byte = 8 bits = 1 carcter
datos 07
1 Kilobyte (KB) = 1024 Bytes
08
1 Megabyte (MB) = 1024 KB
...
1 Gigabyte (GB) = 1024 MB
1 Terabyte (TB) = 1024 GB
1 Petabyte (PB) = 1024 TB
LuisHernndezYez

Direccin
210 =1024 1000

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 11
LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 12
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
Instruccin Significado Lenguajedebajonivel
A02F Acceder a la celda de memoria 2F Dependientedelamquina
3E01 Copiarlo el registro 1 de la ALU Programacindifcil
A030 Acceder a la celda de memoria 30
LuisHernndezYez

3E02 Copiarlo en el registro 2 de la ALU


1D Sumar
B331 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 Cdigo fuente
REG01 (lenguaje ensamblador)
READ30
REG02
ADD Programa
WRITE31 ensamblador

Lenguaje de nivel medio


Cdigo objeto
LuisHernndezYez

(lenguaje mquina)

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 14
LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 15

Ms cercanos a los lenguajes natural y matemtico


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

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 16
Traduccin #include<iostream>
usingnamespacestd;
Cdigo fuente intmain()
{
cout<<"HolaMundo!"<<endl;
Compiladores: }
return0;

Compilan y enlazan Compilador


programas completos

Intrpretes: Cdigo objeto 0100010100111010011100


Compilan, enlazan
y ejecutan instruccin Cdigo
Enlazador objeto de
a instruccin
biblioteca
LuisHernndezYez

Programa Paraunaarquitecturaconcreta
ejecutable yunsistemaoperativo

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 17

Genealoga de lenguajes Versiones/Estndares


Prolog
1970 Java
COBOL PL/I C++
1959 1995
1964 1983
FORTRAN C#
1954 CPL C
2000
1963 1971
Python
ALGOL Pascal Modula 1991
1958 1970 1975
BASIC
1964
Ada Eiffel
1979 1986
Simula
Fuente: 1964 Smalltalk
http://www.levenez.com/lang/ Ruby
1971 1993
LuisHernndezYez

Haskell
Lisp Scheme 1987
1958 1975
Logo
1968

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 18
LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 19

La prehistoria
El baco

Siglo XIX (Wikipedia)


Mquina analtica de Charles Babbage

Lady Ada Lovelace


es considerada
la primera
programadora
LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 20
Siglo XX
1936 Mquina de Turing
1946 ENIAC: Primera computadora digital
de propsito general
1947 El transistor
ENIAC(Wikipedia)
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)
LuisHernndezYez

Lenguaje de programacin C
1974 Protocolo TCP. Primera red local

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 21

1975 Se funda Microsoft


1976 Se funda Apple
1979 Juego Pacman
1981 IBM PC
Sistema operativo MSDOS AppleII(Wikipedia)

1983 Lenguaje de programacin C++


1984 CDROM
1985 Windows 1.0
1990 Lenguaje HTML
World Wide Web Linux
LuisHernndezYez

IBMPC(Wikipedia)
1991 Sistema operativo Linux

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 22
1992 Windows 3.1
1995 Lenguaje de programacin Java
DVD
1998 Se funda Google
1999 MSN Messenger

Siglo XXI
2001 Windows XP
Mac OS X
2002 Mozilla Firefox
2007 iPhone
LuisHernndezYez

2008 Android ...

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 23
LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 24
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

Entrada Programa Salida

Algoritmo: Secuencia de pasos y operaciones que debe realizar


LuisHernndezYez

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,

Anlisis Qu?

Diseo Cmo?

Programacin Implementacin

Prueba y depuracin
LuisHernndezYez

Mantenimiento

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 26
LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 27

Bjarne Stroustrup (1983)


HolaMundo!

#include<iostream>
usingnamespacestd;

int main()
{
cout<<"HolaMundo!"<<endl;
//MuestraHolaMundo!
LuisHernndezYez

return 0;
}

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 28
Instrucciones
Datos: literales, variables, tipos
Subprogramas (funciones)
Comentarios
Directivas Directiva
#include<iostream>
...
usingnamespacestd;

Subprograma int main()


{ Dato
Instruccin cout<<"HolaMundo!"<<endl;
//MuestraHolaMundo!
LuisHernndezYez

Comentario
Dato
Instruccin return 0;
}

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina29
LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 30
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
<numeroentero>::=<signoopcional><secuenciadedgitos>
<signoopcional>::=+||<nada>
<secuenciadedgitos>::=<dgito>|<dgito><secuenciadedgitos>
<dgito>::=0|1|2|3|4|5|6|7|8|9 +23
<nada>::= |significa
159
1374
134
+
3.4
LuisHernndezYez

0..9 002

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 32
<numeroentero>::=<signoopcional><secuenciadedgitos>
<signoopcional>::=+||<nada>
<secuenciadedgitos>::=<dgito>|<dgito><secuenciadedgitos>
<dgito>::=0|1|2|3|4|5|6|7|8|9
<nada>::=
+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
LuisHernndezYez

134
<numeroentero>::=<signoopcional><secuenciadedgitos>
::=<secuenciadedgitos>::=<dgito><secuenciadedgitos>
::=1<secuenciadedgitos>::=ERROR ( noes<dgito>)

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 33

+23 +


0..9 +23

1374 +


0..9 1374

134 + ?
0..9 1
LuisHernndezYez

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
{
cout<<"HolaMundo!"<<endl;//MuestraHolaMundo!
LuisHernndezYez

return 0;
}

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 36
Anlisis del programa
Biblioteca

Directiva #include<iostream> Espaciodenombres

Instruccin usingnamespacestd;
Coloreado sintctico
Tipo Palabrasreservadas

Declaracin int main() Cabeceradelafuncin

{
Bloquedecdigo

Variable Cadenadecaracteres Constante


Instruccin cout<<"HolaMundo!" <<endl;
Operador Operador
Datosliterales
return0;
LuisHernndezYez

Instruccin
Nmero
} Cuerpodelafuncin

Lasinstruccionesterminanen;

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 37

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

La infraestructura (notacin, bibliotecas y otro soporte)


hace nuestro cdigo simple, completo, confiable y eficiente

El estilo importa!
LuisHernndezYez

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

Instalacin y uso:
Seccin
Herramientasdedesarrollo
en el Campus Virtual
LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 40
hola.cpp Compilador hola.obj
(cdigofuente) (cdigoobjeto)

Cdigo objeto de
Enlazador
la biblioteca iostream

HolaMundo!

Cargador hola.exe
LuisHernndezYez

(ejecutable)

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 41

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

Instalacin y uso:
Seccin
Herramientasdedesarrollo
en el Campus Virtual
LuisHernndezYez

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

Instalacin y uso:
Seccin
Herramientasdedesarrollo
en el Campus Virtual
LuisHernndezYez

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

Inicio
Pantalla(cout)
_ HolaMundo!
cout<<"HolaMundo!" <<endl; _
Muestra HolaMundo!
en la pantalla y salta de lnea
return0;
Devuelve 0 como cdigo
LuisHernndezYez

de terminacin del programa


Fin

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 44
LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 45

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
LuisHernndezYez

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

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


Facultad de Informtica
Universidad Complutense

Unejemplodeprogramacin 50 Operadoresrelacionales 177


ElprimerprogramaenC++ 64 Tomadedecisiones(if) 180
Laslneasdecdigodelprograma 80 Bloquesdecdigo 183
Clculosenlosprogramas 86 Bucles(while) 186
Variables 92 Entrada/salidaporconsola 190
Expresiones 98 Funcionesdefinidas
Lecturadedatosdesdeelteclado 108 porelprogramador 199
Resolucindeproblemas 119
Losdatosdelosprogramas 127
Identificadores 129
Tiposdedatos 133
Declaracinyusodevariables 142
Instruccionesdeasignacin 147
Operadores 152
Mssobreexpresiones 160
LuisHernndezYez

Constantes 167
Labibliotecacmath 171
Operacionesconcaracteres 174

Fundamentosdelaprogramacin:TiposeinstruccionesI
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
Ejemplos:
Start;
LuisHernndezYez

Go North3Blocks;
Stop;

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 51
Sintaxis del lenguaje de programacin
= Literales
Start

instruccin Stop ;

avanzar

avanzar Go direccin num Blocks

North 1

East 2
LuisHernndezYez

direccin num 3
South
4
West
5

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 52

N
El problema a resolver
Estando el coche en la posicin A,
conseguir llegar al Cine Tvoli (B) B

Qu pasos hay que seguir?


Arrancar
Ir un bloque al Norte
Ir dos bloques al Este
Ir cinco bloques al Norte A
Ir dos bloques al Este
Parar Bloque:
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 53
N
El algoritmo
Secuencia de pasos que hay que

seguir para resolver el problema

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
LuisHernndezYez

Esos pasos sirven tanto para


una persona como para una computadora.

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 54

N
El programa
Instrucciones escritas en
el lenguaje de programacin B

Start;
Go North1Blocks;
Go East2Blocks;
Go North5Blocks;
A
Go East2Blocks;
Stop;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 55
El programa
Escribimos el cdigo del programa en un editor
y lo guardamos en un archivo:

Stat;
Go North1Blocks Copiamos el archivo
Go EastBlocks; en una llave USB
Go Noth 5Blocks; y lo llevamos al coche
Go West2Blocks;
LuisHernndezYez

Stop;

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 56

La compilacin
Introducimos la llave USB en el coche
y pulsamos el botn de ejecutar el programa:

Stat;
^Unknown word.
Go North1Blocks
^;missing.
Go EastBlocks; Errores
^Number missing.
de sintaxis
Go Noth 5Blocks;
^Unknown word.
Go West2Blocks;
LuisHernndezYez

Stop;
There areerrors.Impossible to run the program.

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 57
Depuracin
Editamos el cdigo para corregir los errores sintcticos:

Stat; Start;
Go North1Blocks Go North1Blocks;
Go EastBlocks; Go East3 Blocks;
Go Noth 5Blocks; Go North5Blocks;
Go West2Blocks; Go West2Blocks;
Stop; Stop;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 58

N
La ejecucin
Se realiza lo que pide
cada instruccin: B
Start;
Go North1Blocks;
Go East3Blocks;
!

Error de ejecucin
LuisHernndezYez

Una instruccin no se puede ejecutar!

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 59
Depuracin
Editamos el cdigo para arreglar el error de ejecucin:

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

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 60

N
La ejecucin
Se realiza lo que pide ?
cada instruccin: B
Start;
Go North1Blocks;
Go East2Blocks;
Go North5Blocks;
Go West2Blocks;
Stop;
LuisHernndezYez

Error lgico
El programa no llega al resultado deseado!

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 61
Depuracin
Editamos el cdigo para arreglar el error lgico:

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

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 62

N
La ejecucin

Se realiza lo que pide
cada instruccin:

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

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;

return 0;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 65
Hola Mundo!
La nica instruccin que produce algo tangible:
#include<iostream>
usingnamespacestd;

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

return0;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 66

cout (iostream) character output stream


Visualizacin en la pantalla: operador << (insertor)

cout<<"HolaMundo!"<<endl;

cout <<"HolaMundo!" <<endl;

HolaMundo!
_

endl end line


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 67
Pantalla en modo texto
Lneas de 80 caracteres (textos)

Aplicacinenmodotexto

80caracteres
LuisHernndezYez

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

Recuerda:lasinstruccionesterminanen;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 70

Con el insertor << podemos mostrar...


Cadenas de caracteres literales
Textos encerrados entre comillas dobles: "..."
cout<<"HolaMundo!";
Lascomillasnosemuestran!
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
LuisHernndezYez

endl Puntodecimal,NOcoma!

Fundamentosdelaprogramacin:TiposeinstruccionesI 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;
...
Hasta el final de la lnea: // Comentariodeunalnea
LuisHernndezYez

De varias lneas: /* 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?
#include<iostream>
usingnamespacestd; Es una instruccin: termina en ;
LuisHernndezYez

Siempre usaremos el espacio de nombres estndar (std)


Muchas bibliotecas no tienen espacios de nombres

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 76

Compilacin y enlace
Amenudoenunpaso

hola.cpp Compilador hola.obj


(cdigofuente) (cdigoobjeto)

Cdigo objeto de
Enlazador
la biblioteca iostream

HolaMundo!
LuisHernndezYez

Cargador hola.exe
(ejecutable)

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 77
Elementos del programa
Biblioteca

Directiva #include<iostream> Espaciodenombres

Instruccin usingnamespacestd; Coloreadosintctico:


DirectivasTipos
Palabrasreservadasgenerales
Tipo Palabrasreservadas DatosliteralesComentarios

Declaracin int main() Cabeceradelafuncin

{
Bloquedecdigo

Variable Cadenadecaracteres Constante


Instruccin cout<<"HolaMundo!" <<endl;
Operador Operador
Datosliterales
Instruccin return0;
LuisHernndezYez

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
#include<iostream>usingnamespacestd;
intmain(){cout<<"HolaMundo!"<<endl;
return0;}
#include<iostream>
usingnamespacestd;

intmain()
{ Cul se lee mejor?
cout<<"HolaMundo!"<<endl;
LuisHernndezYez

return0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 79
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 80

Programa con E/S por consola


Una plantilla para empezar:
#include<iostream>
usingnamespacestd;

int main()
{

Tu cdigo aqu!
LuisHernndezYez

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;
cout<<"nohamuchotiempoquevivaunhidalgodelosde
lanzaenastillero,..." <<endl;
LuisHernndezYez

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;
cout<<"nohamuchotiempoquevivaunhidalgodelosde
lanzaenastillero,..." <<endl;
LuisHernndezYez

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


No se entiende los (2 lnea)!
LuisHernndezYez

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;

mejor que
cout<<"EnunlugardelaMancha,"<<endl;

Usa sangra (indentacin) para el cdigo de un bloque:


{
Tab cout<<"EnunlugardelaMancha," <<endl;
...
3 esp. return 0;
LuisHernndezYez

}
El estilo importa!
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 85
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 86

Operadores aritmticos
+ Suma
Resta
* Multiplicacin
/ Divisin
Operadores binarios
operando_izquierdo operadoroperando_derecho

Operacin Resultado
3 +4 7
2.56 3 0.44
LuisHernndezYez

143 *2 286
45.45 /3 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


Reales: con parte decimal
Signo negativo (opcional) + secuencia de dgitos
+ punto decimal + secuencia de dgitos
3.1416357.01.3332345.6789404.1
LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 88

clculos.cpp

Ejemplo
#include<iostream>
usingnamespacestd;

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
LuisHernndezYez

return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 89
Divisin entera
LuisHernndezYez

Divisin real

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 90

Divisin entera o divisin real?


Ambos operandos enteros Divisin entera
Algn operando real Divisin real

Divisin Resultado
500 /3 166
500.0 /3 166.667
500 /3.0 166.667
500.0 /3.0 166.667

Comprueba siempre que el tipo de divisin sea el que quieres


LuisHernndezYez

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

Declaracin: tipo nombre;

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 93
Declaracin de variables tipo nombre;
int cantidad;
Memoria
double precio; cantidad ?
Se reserva espacio suficiente precio ?

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

Habitualmente al principio de la funcin

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 94

Declaracin de variables Memoria

#include<iostream> cantidad ?
usingnamespacestd;
precio ?

int main()
total ?
{
int cantidad; ...
double precio,total;

Podemos declarar varias de un mismo tipo


return 0; separando los nombres con comas
LuisHernndezYez

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

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


LuisHernndezYez

Problemas de precisin

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 96

Asignacin de valores a las variables (operador =)


variable = expresin; Instruccin: termina en ;

cantidad=12; //int cantidad 12


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

Concordancia de tipos: cantidad=12.5;


LuisHernndezYez

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
A igual prioridad se evalan de izquierda a derecha

Parntesis para forzar ciertas operaciones


total=cantidad1+cantidad2*precio;
total=(cantidad1+cantidad2)*precio;
LuisHernndezYez

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

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
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 100

variables.cpp

Ejemplo de uso de variables y expresiones


#include<iostream>
usingnamespacestd;

int main()
{
int cantidad;
double precio,total;
cantidad=12;
precio=39.95;
total=cantidad*precio;
cout<<cantidad<<"x"<<precio<<"="
<<total<<endl;
LuisHernndezYez

return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 101


Ejemplo de uso de variables Memoria

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

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 102

Ejemplo de uso de variables Memoria

#include<iostream> cantidad 12
usingnamespacestd;
precio ?
intmain()
{
total ?
intcantidad;
doubleprecio,total;
cantidad=12; ...
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 103


Ejemplo de uso de variables Memoria

#include<iostream> cantidad 12
usingnamespacestd;
precio 39.95
intmain()
{
total ?
intcantidad;
doubleprecio,total;
cantidad=12; ...
precio=39.95;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 104

Ejemplo de uso de variables Memoria

#include<iostream> cantidad 12
usingnamespacestd;
precio 39.95
intmain()
{
total 479.4
intcantidad;
doubleprecio,total;
cantidad=12; ...
precio=39.95;
total=cantidad*precio;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 105


Ejemplo de uso de variables Memoria

#include<iostream> cantidad 12
usingnamespacestd;
precio 39.95
intmain()
{
total 479.4
intcantidad;
doubleprecio,total;
cantidad=12; ...
precio=39.95;
total=cantidad*precio;
cout<<cantidad<<"x"<<precio<<"="
<<total<<endl;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 106

Ejemplo de uso de variables


#include<iostream>
usingnamespacestd;

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

return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 107


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 108

cin (iostream) character input stream


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

cin>>cantidad;
Memoria
cin >>cantidad; cantidad 12
?
...

12
1 2 _
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!

Se ignoran los espacios en blanco iniciales


LuisHernndezYez

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
39.95.5abc 39.95abc 39.95
LuisHernndezYez

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

Para evitar errores, lee cada dato en una instruccin aparte


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 112

Qu pasa si el usuario se equivoca?


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

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

Lectura correcta!!!
LuisHernndezYez

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)
3. Realizar la divisin, guardando el resultado
Variableresultado (double)
LuisHernndezYez

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

3. Calcular divisin en resultado


LuisHernndezYez

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;
3. Calcular divisin en resultado

resultado=numerador/denominador;
LuisHernndezYez

4. Mostrar resultado

cout<<resultado;

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 117


Divisin de dos nmeros divisin.cpp

#include<iostream> Numerador:_129
usingnamespacestd; _
Denominador:_
2
_
Resultado:_
64.5
64.5
int main() _
{
Declaraciones double numerador,denominador,resultado;
cout<<"Numerador:";
cin>>numerador;
Entrada
cout<<"Denominador:";
cin>>denominador;
Procesamiento resultado=numerador/denominador;
LuisHernndezYez

Salida cout<<"Resultado:" <<resultado<<endl;


return0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 118


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 119


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

Refinamiento

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

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 120

Objetos: Datos que maneja el programa


variable cin
cout cadena literal

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.

cadena literal variable


variable
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 121


Datos que maneja el programa: tipos
Objeto Tipo Vara? Nombre
Pantalla Variable cout
"Introduzcalabasedeltringulo:" Constante ninguno
Basedeltringulo double Variable base
Teclado Variable cin
"Introduzcalaalturadeltringulo:" Constante ninguno
Alturadeltringulo double Variable altura
readeltringulo double Variable area
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 122

Operaciones (acciones)

cout<<... cin>>...

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
LuisHernndezYez

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
6. Mostrar el rea del tringulo
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 124

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

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

traducido 3. Mostrar en la pantalla el texto que pida la altura del tringulo


a cdigo 4. Leer del teclado el valor para la altura del tringulo
en C++ 5. Calcular el rea del tringulo
6. Mostrar el rea del tringulo
LuisHernndezYez

return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 125


tringulo.cpp

El programa: implementacin
#include<iostream>
usingnamespacestd; 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
cout<<"Elreadeuntringulodebase" <<base //6
<<"yaltura"<<altura<<"es:" <<area <<endl;
LuisHernndezYez

return 0;
} Recuerda: las instrucciones terminan en ;

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 126


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 127


Variabilidad de los datos
"Introduzcalabasedeltringulo:"
3.141592653589

Literales

Constantes

Con nombre
Datos

Pi=3.141592653589
Variables
LuisHernndezYez

base,altura,area Identificadores

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 128


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 129


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,_

cantidadprrecio totalbasealturaarea numerador


LuisHernndezYez

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 returnshort
signedsizeofstaticstatic_cast structswitch
templatethisthrowtruetrytypedeftypeid
LuisHernndezYez

typename unionunsignedusingvirtualvoid
volatilewhile

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 131


a..z,A..Z,_

Qu identificadores son vlidos? 0..9,a..z,A..Z,_

balance interesAnual
_base_imponible aos
EDAD12 salario_1_mes
clculoNmina
__edad

valor%100 AlgunValor

100caracteres valor?
LuisHernndezYez

_12_meses
____valor

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 132
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 133


Tipos 125
true
Cada dato, de un tipo concreto 'a'
3.14159
Cada tipo establece: "Hola"
El conjunto (intervalo) de valores vlidos
El conjunto de operaciones que se pueden realizar

Expresiones con datos de distintos tipos (compatibles):


Transformacin automtica de tipos (promocin de tipo)
LuisHernndezYez

Anexo del Tema 2: detalles tcnicos

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 134

int
Nmeros enteros (sin decimales)
float
1363, 12, 49
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!"
LuisHernndezYez

void
Nada, ausencia de tipo, ausencia de dato (funciones)

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 135


Caracteres
Intervalo de valores: Juego de caracteres (ASCII) 1 byte
Literales:
'a''%''\t'
Constantes de barra invertida (o secuencias de escape):
Caracteres de control
'\t' = tabulador '\n' = salto de lnea

ISO88591
LuisHernndezYez

(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

Cualquier nmero distinto de 0 es equivalente a true


El 0 es equivalente a false
LuisHernndezYez

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

True o TRUE no son palabras reservadas de C++


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 138

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

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

Las comillas tipogrficas (apertura/cierre) NO sirven


LuisHernndezYez

Asegrate de utilizar comillas rectas: ""

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 139


tipos.cpp

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

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
unsignedshortint 0 .. 65535
longint 2147483648 .. 2147483647
unsignedlongint 0 .. 4294967295
+| 2.23e308 .. 1.79e+308
LuisHernndezYez

double
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

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

Programacin con buen estilo:


Identificadores descriptivos
Espacio tras cada coma
LuisHernndezYez

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

int inicio; Memoria


01

shortintunidades; inicio
02

03
double balance; 04

05
unidades
06

07
balance
08

09

10

11

12

13
LuisHernndezYez

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:

Identificador = Expresin Expresin: valor compatible

int i=0,j,l=26;
LuisHernndezYez

Enparticular,unaexpresin
shortintunidades=100; puedeserunliteral

Fundamentosdelaprogramacin:TiposeinstruccionesI 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


Nombre de la variable a la izquierda del =
balance =1214;
porcentaje =valor/30;

Las variables han de haber sido previamente declaradas


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 146


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 147


El operador =
Variable = Expresin ;

A la izquierda, SIEMPRE una variable

int i,j=2;
i=23 +j*5;//itomaelvalor33
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 148

Errores
int a,b,c;

5 =a;
//ERROR:unliteralnopuederecibirunvalor
a+23 =5;
//ERROR:nopuedehaberunaexpresinalaizda.
b="abc";
//ERROR:unenteronopuedeguardarunacadena
c=23 5;
//ERROR:expresinnovlida(faltaoperador)
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 149


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

Memoria Memoria
01 01

i i
02

03

04
? 23 +2 *5
02

03

04
33
05 05
j j
2 2
06 06

07 07

08 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 a 3.45
b 127.5 aux=a; b 127.5
aux ? aux 3.45

a 127.5
a=b; b 127.5
aux 3.45

a 127.5
LuisHernndezYez

b=aux; b 3.45
aux 3.45

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 151


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 152

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:


LuisHernndezYez

Asignacin (=)

Operadores relacionales (menor, mayor, igual, ...)

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 153


Operadores para tipos de datos numricos

Operador Operandos Posicin int float / double


1(monario) Prefijo Cambiodesigno
+ 2(binario) Infijo Suma
2(binario) Infijo Resta
* 2(binario) Infijo Producto
/ 2(binario) Infijo Div.entera Divisinreal
% 2(binario) Infijo Mdulo Noaplicable
++ 1(monario) Prefijo/postfijo Incremento
1(monario) Prefijo/postfijo Decremento
LuisHernndezYez

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):
++interes mesesj++ //1ms1menos

Operadores binarios
Operando izquierdo operador operando derecho
Operandos: literales, constantes, variables o expresiones
LuisHernndezYez

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

Algn operando real: divisin real


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

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

Divisin entera:
No se obtienen decimales Queda un resto

123 5
3 24
LuisHernndezYez

123 %5

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 157


Operadores de incremento y decremento ++/
Incremento/decremento de la variable numrica en una unidad
Prefijo: Antes de acceder
int i=10,j;
i=i+1;
j=++i;//Incrementaantesdecopiar
j=i;
cout<<i<<" "<<j;//Muestra11 11
Postfijo: Despus de acceder
int i=10,j;
j=i; j=i++;//Copiaydespusincrementa
i=i+1;
cout<<i<<" "<<j;//Muestra11 10
LuisHernndezYez

No mezcles ++ y con otros operadores

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 158

#include<iostream> operadores.cpp
usingnamespacestd;

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++):"
LuisHernndezYez

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

Precedencia de los operadores (prioridad):


Se evalan antes los de mayor precedencia
Y si tienen igual prioridad?
Normalmente, de izquierda a derecha
LuisHernndezYez

Parntesis: fuerzan a evaluar su subexpresin

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 161


Precedencia Operadores
Mayor prioridad ++ (postfijos)
++ (prefijos)
(cambio de signo)
*/%
Menor prioridad +

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

Misma precedencia: Mayor Misma precedencia:


LuisHernndezYez

Izquierda antes precedencia Izquierda antes

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 162

((3 + 5)*4 +12)/4 (3 * 2 1) Primero, los parntesis...


* antes que
(8 *4 +12)/4 (6 1)
* antes que +
(32 +12)/4 5

44 /4 5
/ antes que
11 5 Pon espacio antes y despus
de cada operador binario
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 163


frmula.cpp

#include<iostream>
usingnamespacestd;

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

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
variable operador=op_derecho;

Asignacin Abreviatura
a=a+12; a+=12;
Igual precedencia
a=a*3; a*=3; que la asignacin
a=a 5; a=5;
a=a/37; a/=37; De momento,
mejor evitarlas
LuisHernndezYez

a=a%b; a%=b;

Fundamentosdelaprogramacin:TiposeinstruccionesI 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 1 1 1 1 1 1 1 1 32767


0 = positivo
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 + 1
1 = negativo
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32768
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 166


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 167


Declaracin de constantes Modificador de acceso const
Variables inicializadas a las que no dejamos variar

const Declaracindevariableconinicializador

constshortintMeses=12;
La constante no podr volver a
constdouble Pi=3.141592,
aparecer a la izquierda de un =
RATIO=2.179 *Pi;

Programacin con buen estilo:


LuisHernndezYez

Pon en mayscula la primera letra


de una constante o todo su nombre

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 168

Aumentan la legibilidad del cdigo


cambioPoblacion =(0.1758 0.1257)*poblacion; vs.
cambioPoblacion =(RatioNacimientos RatioMuertes)*poblacion;

Facilitan la modificacin del cdigo


double compra1=bruto1*18 /100;
double compra2=bruto2*18 /100; 3 cambios
double total=compra1+compra2;
cout<<total<<"(IVA:"<<18 <<"%)" <<endl;

constint IVA=18; Cambio del IVA al 21%?


double compra1=bruto1*IVA/100;
double compra2=bruto2*IVA/100; 1 cambio
LuisHernndezYez

double total=compra1+compra2;
cout<<total<<"(IVA:"<<IVA<<"%)" <<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 169


constantes.cpp

#include<iostream>
usingnamespacestd;

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

total=neto+porIVA;
cout<<"Totalcompra:"<<total<<endl;
return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 170


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 171


#include<cmath>

Algunas ... abs(x) Valor absoluto de x


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
Tangente de x
LuisHernndezYez

tan(x)
round(x) Redondeo al entero ms prximo
trunc(x) Prdida de la parte decimal (entero)

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 172

mates.cpp

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

}
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) true si c es una letra o un dgito
isalpha(c) true si c es una letra
isdigit(c) true si c es un dgito
islower(c) true si c es una letra minscula
isupper(c) true si c es una letra mayscula
false en caso contrario
toupper(c) devuelve la mayscula de c
LuisHernndezYez

tolower(c) devuelve la minscula de c


Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 175


caracteres.cpp

...
#include<cctype>
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;
LuisHernndezYez

cout<<"Alfabtico?"<<isalpha(caracter3)<<endl;
cout<<"Dgito?"<<isdigit(caracter3)<<endl;
return 0;
} 1 true / 0 false
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 176
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 177


Operadores relacionales
Comparaciones (condiciones)
Condicin simple ::= Expresin Operador_relacional Expresin
Concordancia de tipo entre las expresiones
Resultado: bool (true o false)

Operadores(prioridad)
< menor que
...
<= menor o igual que
*/%
> mayor que
+
>= mayor o igual que
LuisHernndezYez

< <=>>=
== igual que
==!=
!= distinto de
=+==*=/=%=

Fundamentosdelaprogramacin:TiposeinstruccionesI 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
resultado=a+b== c+1;//5==5 true

No confundas el operador de igualdad (==)


LuisHernndezYez

con el operador de asignacin (=)

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 179


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 180

Seleccin: bifurcacin condicional


if (condicin) {
true false cdigoT
Condicin
}
cdigoT cdigoF
else{
cdigoF
int num; }
cout<<"Nmero:";
Opcional:puedenohaberelse
cin>>num;
if (num%2 ==0){
cout<<num<<"espar";
LuisHernndezYez

}
else {
cout<<num<<"esimpar";
}
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 181
seleccin.cpp

#include<iostream>
usingnamespacestd;

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

}
return0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 182


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 183


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

{ instruccin } {
intruccin1
Tab intruccin2
3 esp. ...
int num,total=0; intruccinN
cin>>num; }
if (num>0)
{
cout<<"Positivo"; mbito local
total=total+num; (declaraciones locales)
LuisHernndezYez

}
cout<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 184

Posicin de las llaves: cuestin de estilo


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

No necesitamos las llaves si slo hay una instruccin


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

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 false
Condicin
while (condicin) {
Cuerpo cuerpo
}
LuisHernndezYez

Si la condicin es false al empezar,


no se ejecuta el cuerpo ninguna vez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 187


serie.cpp

#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 <<")="
LuisHernndezYez

<<suma<<endl;
return0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 188

Iteracin condicional
while(i<=n){
suma=suma+i;
i++;
}
n 5
i 6
2
3
4
5
1
true false suma 15
10
1
3
60
i<=n

suma+=i;
i++;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 189


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 190

#include<iostream>
Flujos de texto (streams) usingnamespacestd;
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 cout
7 3 5 . 3 5 1 Programa 1 6 = l a t o T

Biblioteca iostream con espacio de nombres std


LuisHernndezYez

Extractor Flujodeentrada >> Variable

Insertor Flujodesalida << Expresin

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 191


cin >> Variable

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
LuisHernndezYez

cout<<"Introducetuedad:";
cin>>edad;

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 192

#include<string>
usingnamespacestd;

cin>>cadena termina con el primer espacio en blanco


cin.sync() descarta la entrada pendiente
string nombre,apellidos; string nombre,apellidos;
cout<<"Nombre:"; cout<<"Nombre:";
cin>>nombre; cin>>nombre;
cout<<"Apellidos:"; cin.sync();
cin>>apellidos; cout<<"Apellidos:";
cout<<"Nombrecompleto:" cin>>apellidos;
<<nombre<<"" cout<<...
<<apellidos<<endl;

apellidos recibe "Antonio"


LuisHernndezYez

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);
Lee todo lo que haya hasta el final de la lnea (Intro)
LuisHernndezYez

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!

cout<<d;
5 4 . 3 2 1
La biblioteca iostream
LuisHernndezYez

define la constante endl Un texto!


como un salto de lnea (secuencia de caracteres)

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 195


cout << Expresin

T o t a l : 1 2 3 . 4 5 M e s e s : 7 Programa
cout

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

cout<<123.45 <<endl<<"Meses:"<<meses;

cout<<endl<<"Meses:"<<meses;

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

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 Propsito


showpoint/ Mostrar o no el punto decimal para reales sin
iostream
noshowpoint 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)
iomanip setw(anchura)* N de caracteres (anchura) para el dato
Precisin: N de dgitos (en total)
setprecision(p)
Con fixed o scientific, n de decimales
LuisHernndezYez

*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|
double e=96;
cout<<e<<" "<<showpoint<<e<<endl; 96 96.0000
LuisHernndezYez

cout<<scientific<<d<<endl; 1.234500e+002
cout<<fixed<<setprecision(8)<<d<<endl; 123.45000000

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 198


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 199


Los programas pueden incluir otras funciones adems de main()
Forma general de una funcin en C++:
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!
LuisHernndezYez

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

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)

Se copian los valores resultantes de las expresiones


en los correspondientes parmetros
Llamadas a la funcin: en expresiones de otras funciones
LuisHernndezYez

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
} d 3.0
...
int main(){
int i=124;
...
double d=3; x 124
funcion(i,33 *d); a 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);
x=x*x;
LuisHernndezYez

} return 0; 256
Esta instruccin }
no se ejecutar nunca

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


Prototipo de funcin: Cabecera de la funcin terminada en ;
double f(intx,int y);
int funcion(int x,double a)
LuisHernndezYez

int cuad(int x);


... main() es la nica funcin
que no hay que prototipar

Fundamentosdeprogramacin:TiposeinstruccionesI Pgina 205


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

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

if (par(numero)){
cout<<"Par";
}
...

Fundamentosdeprogramacin:TiposeinstruccionesI Pgina 206

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
LuisHernndezYez

return 0;
}
...

Fundamentosdeprogramacin:TiposeinstruccionesI Pgina 207


//Implementacindelasfuncionespropias

boolpar(int num){
bool esPar;

if (num%2==0){
esPar =true;
}
else {
esPar =false;
}

return esPar;
}
LuisHernndezYez

...

Fundamentosdeprogramacin:TiposeinstruccionesI Pgina 208

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

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

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

int 214
float 216
Notacincientfica 217
double 218
char 220
bool 221
string 222
Literalesconespecificacindetipo 223
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)
Nmeros enteros

Intervalo de valores:
2147483648 .. 2147483647
Bytes de memoria: 4* (*) Depende de la mquina 01
4 bytes es lo ms habitual 02
Literales: Se puede saber cuntos 03

1363, 12, 010 , 0x1A se usan con la funcin 04


sizeof(int) 05
06
+ 07
0..9 08
0..9 09
...
Notacin octal 0 0..7
LuisHernndezYez

Notacin hexadecimal x 0..9,A..F

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo) Pgina 214

Nmeros enteros

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
LuisHernndezYez

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
Bytes de memoria: 4* (*) sizeof(float) 01

Punto flotante. Precisin: 7 dgitos


02
03
Literales (punto decimal): 04

Notacin normal: 134.45, 1.1764 05


06
07
+
08
0..9 . 0..9 09
...

Notacin cientfica: 1.4E2, 5.23e02


LuisHernndezYez

+ +
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.3333e+06 3,3333 x 106 3.333.300
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo) Pgina 217


Nmeros reales (con decimales)

Intervalo de valores:
+/ 2.23e308 .. 1.79e+308
Bytes de memoria: 8* (*) sizeof(double) 01

Punto flotante. Precisin: 15 dgitos


02
03
Literales (punto decimal): 04

Notacin normal: 134.45, 1.1764 05


06
07
+
08
0..9 . 0..9 09
...

Notacin cientfica: 1.4E2, 5.23e02


LuisHernndezYez

+ +
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) 01

Literales: 02
03
'a', '%', '\t' 04
Constantes de barra invertida: 05

(O secuencias de escape) 06

Para caracteres de control 07


08
'\t' = tabulador, '\n' = salto de lnea, 09
...
\ n,t,v,b,r,f,a,\
' '
LuisHernndezYez

Carcter

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo) Pgina 219


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

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo) Pgina 220

Valores lgicos

Slo dos valores posibles:


Verdadero (true)

Falso (false) 01
02
Bytes de memoria: 1 (FC) 03

Literales: 04
05
true, false 06

En realidad, cualquier nmero 07

distinto de 0 es equivalente a true 08


09
y el nmero 0 es equivalente a false ...
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo) Pgina 221


Cadenas de caracteres

"Hola", "Introduceelnumerador:", "X142FG5TX?%A"

" Carcter "

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

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

Abreviaturas para modificadores de tipos


short shortint
long longint
Es preferible evitar el uso de tales abreviaturas:
LuisHernndezYez

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

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


Facultad de Informtica
Universidad Complutense

Tipos,valoresyvariables 227 Elbuclefor 321


Conversindetipos 232 Buclesanidados 331
Tiposdeclaradosporelusuario 236 mbitoyvisibilidad 339
Tiposenumerados 238 Secuencias 349
Entrada/Salida Recorridodesecuencias 355
conarchivosdetexto 248 Secuenciascalculadas 363
Lecturadearchivosdetexto 253 Bsquedaensecuencias 370
Escrituraenarchivosdetexto 266 Arraysdedatossimples 374
Flujodeejecucin 272 Usodevariablesarrays 379
Seleccinsimple 276 Recorridodearrays 382
Operadoreslgicos 282 Bsquedaenarrays 387
Anidamientodeif 286 Arraysnocompletos 393
Condiciones 290
Seleccinmltiple 293
Laescalaifelseif 295
LuisHernndezYez

Lainstruccinswitch 302
Repeticin 313
Elbuclewhile 316

Fundamentosdelaprogramacin:TiposeinstruccionesII
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

Declaracin
Instruccin que identifica un nombre

Definicin
Declaracin que asigna memoria a una variable o constante
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 228


Memoria suficiente para su tipo de valores
shortinti=3; i 3

int j=9; j 9

char c='a'; c a

double x=1.5; x 1.5

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


00000000000000000000000001111000
Interpretado como int es el entero 120
LuisHernndezYez

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

Estructurados (Tema 5)
Colecciones homogneas: arrays
Todos los elementos de la coleccin de un mismo tipo

Colecciones heterogneas: estructuras


LuisHernndezYez

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
bool
Definicin de variables:
tipo nombre [=expresin][,...];
LuisHernndezYez

Definicin de constantes con nombre:


consttipo nombre =expresin;

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 231


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 232


Promocin de tipos
Dos operandos de tipos distintos:
El valor del tipo menor se promociona al tipo mayor
shortinti=3; long double
int j=2;

Promocin
double
double a=1.5,b; float
long int
b=a+i*j;
int
short int
b=a+3 *2;
Valor 3 shortint (2 bytes) int (4 bytes)
LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 233

Conversin segura: long double


De un tipo menor a un tipo mayor double
shortint int longint ... float
long int
Conversin no segura:
int
De un tipo mayor a un tipo menor short int
intentero=1234;
char caracter;
caracter =entero;//Conversinnosegura
Menor memoria: Prdida de informacin en la conversin
LuisHernndezYez

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)

Tienen la mayor prioridad


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 235


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 236


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
Los colorearemos en naranja, para remarcar que son tipos

typedefdescripcintMiTipo;
typedefdescripcintMoneda;
typedefdescripcintTiposDeCalificacion;
LuisHernndezYez

Declaracin de tipo frente a definicin de variable

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 237


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 238


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 }
Valores literales que pueden tomar las variables (en amarillo)
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 239

Mejoran la legibilidad

typedefdescripcinnombre_de_tipo;
Elegimos un nombre para el tipo: tMoneda 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;
LuisHernndezYez

moneda1 dos_centimos

moneda2 euro
(Internamente se usan enteros)

Fundamentosdelaprogramacin:TiposeinstruccionesII 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

Y si se escribe la variable en la pantalla:


cout<<mes;
Se ver un nmero entero
LuisHernndezYez

Cdigo de entrada/salida especfico

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 241

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

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;

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

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

No admiten operadores de incremento y decremento


Emulacin con moldes:
int i=int(dia);//dia nohadevalerdomingo!
LuisHernndezYez

i++;
dia =tDiaSemana(i);

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 244


#include<iostream> Si los tipos se usan en varias funciones,
usingnamespacestd; 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;

string cadMes(tMes mes);


string cadDia(tDiaSemana dia);

int main(){
tDiaSemana hoy=lunes;
LuisHernndezYez

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;

cout<<"Pasadalamedianoche..."<<endl;
dia++;
inti=int(hoy);
i++;
hoy=tDiaSemana(i);

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

return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 246


fechas.cpp

string cadMes(tMes mes){ string cadDia(tDiaSemana dia);


string cad; string cad;

if (mes==enero){ if (dia ==lunes){


cad ="enero"; cad ="lunes";
} }
if (mes==febrero){ if (dia ==martes){
cad ="febrero"; cad ="martes";
} }
... ...
if (mes==diciembre){ if (dia ==domingo){
cad ="diciembre"; cad ="domingo";
} }

return cad; return cad;


LuisHernndezYez

} }

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 247


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 248


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

Mantienen la informacin en archivos


Secuencias de datos
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 249

Archivo de texto: secuencia de caracteres


T o t a l : 1 2 3 . 4 A

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)

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)


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 250


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
LuisHernndezYez

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

Biblioteca fstream (sin espacio de nombres)


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 252


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 253

Flujos de texto de entrada 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
4 Desliga la variable del archivo de texto (cierre el archivo)
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 254


Apertura del archivo
Conecta la variable con el archivo de texto del dispositivo
flujo.open(cadena_literal);
El archivo debe existir!
ifstream archivo;
is_open():
archivo.open("abc.txt");
true si el archivo
if(archivo.is_open())...
se ha podido abrir
false en caso contrario
Cierre del archivo
Desconecta la variable del archivo de texto del dispositivo
flujo.close();
LuisHernndezYez

archivo.close();

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 255

Operaciones de lectura
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
LuisHernndezYez

Hasta el siguiente salto de lnea (descartndolo)


Con los archivos no tiene efecto la funcin sync()

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 256


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

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)

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
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 258


string nif,producto;
int unidades;
double precio;
char aux;

1 ifstream archivo; 7
6
Flujo de entrada
2 archivo.open("compras.txt");//Apertura 5
archivo
4

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

Programa
4 archivo.close();//Cierre
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 259

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

getline() no salta espacios


12345678F2123.95ReproductordeDVD
El extractor salta los espacios

nif 12345678F unidades 2


LuisHernndezYez

producto ReproductordeDVD 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)

nif 12345678F unidades 2


LuisHernndezYez

producto ReproductordeDVD precio 123.95

Sin espacio

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 261

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
LuisHernndezYez

Calcular y mostrar el total


Leer el siguiente NIF

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 262


#include<iostream> leer.cpp
#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;
LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII 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.:"
LuisHernndezYez

<<iva <<" Total:" <<total<<endl;


archivo>>nif;//SiguienteNIF
}...

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 264


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

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 265


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 266


Flujos de texto de salida ofstream

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)

Atencin!
Si el archivo ya existe, se borra todo lo que hubiera
LuisHernndezYez

Atencin!
Si no se cierra el archivo se puede perder informacin

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 267

int valor=999;
Programa
2
1 ofstream archivo; 1

Flujo de salida
2 archivo.open("output.txt");//Apertura ! archivo
a
l
3 archivo<<'X' <<"Hola!" <<123.45 o

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

X
4 archivo.close();//Cierre
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 268


escribir.cpp

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

int main(){
string nif,producto;
int unidades;
double precio;
char aux;
ofstream archivo;

archivo.open("output.txt");//Apertura(creacin)
LuisHernndezYez

cout<<"NIFdelcliente(Xparaterminar):";
cin>>nif;
...

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):";
LuisHernndezYez

cin>>nif;
}
...

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 270


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

return 0;
}
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 271


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 272


{
double oper1,oper2,prod;

Instruccin1 cout<<"Operando1:";
Flujo de ejecucin

Instruccin2 cin>>oper1;

Instruccin3 cout<<"Operando2:";

...

cout<<"Producto:" <<prod;
LuisHernndezYez

InstruccinN return 0;

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 273

Uno entre dos o ms caminos de ejecucin


Seleccin simple (2 caminos) Seleccin mltiple (> 2 caminos)

true

true false false


Condicin true

false
InstruccinT InstruccinF
true

false

if true
ifelseif
LuisHernndezYez

false
switch
Diagramasdeflujo

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 274


Repetir la ejecucin de una o ms instrucciones
Acumular, procesar colecciones, ...

Inicializacin

S No
Iterar?

Cdigo
LuisHernndezYez

while for

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 275


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 276


La instruccin if
if (condicin){ true false
Condicin
cdigoT
} BloqueT BloqueF
Opcional
[else {
cdigoF
}]
condicin: expresin bool
Clusula else opcional
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 277

signo.cpp

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

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
?

cout<<"Positivo";
LuisHernndezYez

cout<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 279

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

cout<<"Negativo";
LuisHernndezYez

cout<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 280


divisin.cpp

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


#include<iostream>
usingnamespacestd;

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

cout<<"Resultado:" <<resultado<<endl;
}
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 281
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 282


Se aplican a valores bool (condiciones)
El resultado es de tipo bool

Operadores(prioridad)
! NO Monario
...
&& Y Binario
!
|| O Binario
*/%
+
< <=>>=
==!=
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
cond1=(a*b+c)>=12;//10>=12 false
cond2=(a*(b+c))>=12;//14>=12 true
LuisHernndezYez

resultado=cond1&&cond2;//false&&true false
resultado=cond1||cond2;//false||true true

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 284


condiciones.cpp

#include<iostream>
usingnamespacestd;

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

}
((num >0)&&(num <11))
Encierra las condiciones ((num >=1)&&(num <11))
simples entre parntesis! ((num >0)&&(num <=10))

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 285


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 286


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

}
else{
dias =30;
}
}
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 287

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

esBisiesto =false;
}
return esBisiesto;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 288


Cada else se asocia al if anterior ms cercano sin asociar (mismo bloque)
if (condicin1){
if (condicin2){...} Una mala sangra puede confundir
if (x>0){
else {...}
if (y>0){...}
}
else {...}
else{
if (condicin3){
if (condicin4){...} if (x>0){
if (condicin5){...} if (y>0){...}
else {...} else {...}

}
LuisHernndezYez

else {...

La sangra ayuda a asociar los else con sus if

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 289


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 290


Condicin simple: Expresin lgica (true/false)
Sin operadores lgicos
num<0
car=='a' Compatibilidad con el lenguaje C:
isalpha(car) 0 es equivalente a false
12 Cualquier valor distinto de 0 es equivalente a true

Condicin compuesta:
Combinacin de condiciones simples y operadores lgicos
!isalpha(car)
(num<0)|| (car=='a')
(num<0)&& ((car=='a')||!isalpha(car))
LuisHernndezYez

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!

false && X false


(n!=0)&&(x<1.0 /n)
Si n es 0: divisin por cero? (segunda condicin)
LuisHernndezYez

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

false
LuisHernndezYez

ifelseif
switch

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 294


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 295

Ejemplo:
Calificacin (en letras)
de un estudiante en base
a su nota numrica (010) ==10
true
cout<<"MH"
false
true
>=9 cout<<"SB"
Si nota==10 entonces MH false
true
si no, si nota>=9 entonces SB >=7 cout<<"NT"
false
si no, si nota>=7 entonces NT >=5
true
cout<<"AP"
si no, si nota>=5 entonces AP false
cout<<"SS"
si no SS
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 296


nota.cpp

double nota; double nota;


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

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

Cuidado con el orden de las condiciones!


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

double nota; No se ejecutan nunca!


cin>>nota;


if (nota>=5){cout<<"AP";}
else if (nota>=7){cout<<"NT";}
LuisHernndezYez

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 5 AP 7 NT 9 SB 10
if (nota==10){cout<<"MH";} MH
else if ((nota<10)&&(nota>=9)){cout<<"SB";}
else if ((nota<9)&&(nota>=7)){cout<<"NT";}
else if ((nota<7)&&(nota>=5)){cout<<"AP";}
else if (nota<5){cout<<"SS";}
Siempre true: ramas else
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
LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 299

nivel.cpp

#include<iostream> Sinum==4 entoncesMuyalto


usingnamespacestd; Sinum==3 entoncesAlto
int main(){
int num; Sinum==2 entoncesMedio
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;
}
LuisHernndezYez

else{
cout<<"Valornovlido" <<endl;
}
return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 300
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;}

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

elsecout<<"Valornovlido";
cout<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 301


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 302


Seleccin entre valores posibles de una expresin
switch (expresin){ case constanteN:
case constante1: {
{ cdigoN
cdigo1 }
} [break;]
[break;] [default:
case constante2: {
{ cdigoDefault
cdigo2 }]
} }
[break;]
LuisHernndezYez

...

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 303

nivel2.cpp

switch (num){
case 4:
Si num==4 Muy alto
{ Si num==3 Alto
}
cout<<"Muyalto"; Si num==2 Medio
break; Si num==1 Bajo
case 3:
{
cout<<"Alto";
}
break;
case 2:
{
cout<<"Medio";
}
break;
case 1:
{
cout<<"Bajo";
}
break;
LuisHernndezYez

default:
{
cout<<"Valornovlido";
}
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 304


Interrumpe el switch; contina en la instruccin que le siga
switch (num){
...
case 3:
{
cout<<"Alto";
Num:3
}
Alto
break;
case 2:
{
cout<<"Medio";
}
break;
LuisHernndezYez

...
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 305

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

{
cout<<"Valornovlido";
}
}
Fundamentosdelaprogramacin:TiposeinstruccionesII 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 Bajo break;
false Sin break;

Novlido
LuisHernndezYez

default

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 307

int menu(){ 1 Nuevocliente


int op =1;//Cualquieranovlida 2 Editarcliente
3 Bajacliente
4 Vercliente
while ((op <0)||(op >4)){
0 Salir
cout<<"1 Nuevocliente" <<endl; Opcin:5
cout<<"2 Editarcliente" <<endl; Opcinnovlida!
cout<<"3 Bajacliente" <<endl; 1 Nuevocliente
2 Editarcliente
cout<<"4 Vercliente" <<endl; 3 Bajacliente
cout<<"0 Salir" <<endl; 4 Vercliente
cout<<"Opcin:"; 0 Salir
Opcin:3
cin>>op;

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


cout<<"Opcinnovlida!"<<endl;
}
LuisHernndezYez

return op;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 308


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

{
cout<<"Enlaopcin4..." <<endl;
}//Enlaltimanonecesitamosbreak
}

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

opcion =menu();
} //while

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 310


nota2.cpp

int nota;//Sindecimales case 7:


cout<<"Nota(010):"; case 8:
cin>>nota; {
switch (nota){ cout<<"Notable";
case 0: }
case 1: break;//7u8:NT
case 2: case 9:
case 3: case 10:
case 4: {
{ cout<<"Sobresaliente";
cout<<"Suspenso"; }
} break;//9o10:SB
break;//De0a4:SS default:
case 5: {
case 6: cout<<"Novlida!";
{ }
LuisHernndezYez

cout<<"Aprobado"; }
}
break; //5o6:AP

Fundamentosdelaprogramacin:TiposeinstruccionesII 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;
...
LuisHernndezYez

case diciembre:
{
cout<<"diciembre";
}
}
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 312
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 313

Inicializacin

S No
Iterar?

Cuerpo

Bucles while y for


LuisHernndezYez

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
LuisHernndezYez

Ejecuta el cuerpo mientras la condicin sea true


Se usa una variable contadora entera

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 315


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 316


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++;
}
Muestra los nmeros del 1 al 100
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 317

int i=1;
true false
while(i<=100){ Condicin
cout<<i<<endl; Cuerpo
i++;
}
i=1

i 100
101
99
?3
2
1
4 _
1
true false 2
i<=100
3

cout<<i<<endl;
99
100
LuisHernndezYez

i++ _

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 318


Y si la condicin es falsa al comenzar?
No se ejecuta el cuerpo del bucle ninguna vez
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
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 319

primero.cpp

Primer entero cuyo cuadrado es mayor que 1.000


#include<iostream> Ejecuta el programa para
usingnamespacestd; saber cul es ese nmero!
int main(){
int num=1; Empezamosen1
while(num*num<=1000){
num++; Incrementamosen1
}

cout<<"1er.enteroconcuadradomayorque1.000:"
<<num<<endl;
LuisHernndezYez

return 0;
}
Recorre la secuencia de nmeros 1, 2, 3, 4, 5, ...
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 320
sumamedia.cpp

#include<iostream>
usingnamespacestd; Recorre la secuencia
int main(){ de nmeros introducidos
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;
}
LuisHernndezYez

cout<<"Suma="<<suma<<endl;
cout<<"Media="<<media<<endl;
return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 321


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 322


Nmero de iteraciones prefijado
Variable contadora que determina el nmero de iteraciones:
for ([int]var =ini;condicin;paso)cuerpo
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


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 323

for(inicializacin;condicin;paso)cuerpo
for(int i=1;i<=100;i++){
cout<<i;
}
i=1

true false
i<=100

cout<<i;

i++
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 324


for1.cpp

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

i 2?3
100
101
1
1
... i=1 2
3
true false
i<=100
99
cout<<i<<endl; 100
_
i++
LuisHernndezYez

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

Garanta de terminacin
Todo bucle debe terminar su ejecucin
LuisHernndezYez

Bucles for: la variable contadora debe converger al valor final

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 326


suma.cpp

#include<iostream>
usingnamespacestd;
longlong int suma(intn);
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;
LuisHernndezYez

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

Bucles infinitos
for(int i=1;i<=100;i)...
101234567891011...
LuisHernndezYez

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


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

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++;
}
La inversa no es siempre posible:
int i;
cin>>i; Bucle for equivalente?
while(i!=0){
LuisHernndezYez

cuerpo No sabemos cuntos nmeros


cin>>i; introducir el usuario!
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 330


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 331

Un bucle for en el cuerpo de otro bucle for


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

3 1
...

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 332


tablas.cpp

#include<iostream>
usingnamespacestd; 1x1=1
#include<iomanip> 1x2=2
1x3=3
1x4=4
int main(){
...
for(int i=1;i<=10;i++){ 1x10=10
for(int j=1;j<=10;j++){ 2x1=2
cout<<setw(2)<<i<<"x" 2x2=4
<<setw(2)<<j<<"=" ...
10x7=70
<<setw(3)<<i*j<<endl; 10x8=80
} 10x9=90
} 10x10=100
LuisHernndezYez

return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 333

tablas2.cpp

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

return 0;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 334
men.cpp

#include<iostream>
usingnamespacestd;
#include<iomanip>
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<<"="
LuisHernndezYez

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


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++){
LuisHernndezYez

total=total+i;
}
return total;
}
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)){
LuisHernndezYez

...
} menu()
}
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 338
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 339

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

cout<<"Media="<<suma/cont<<endl;
return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 340


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(){
double d; mbito de la variable d
if(...){
int cont=0;
for(int i=0;i<=10;i++){
...
}
}
char c;
if(...){
double x;
...
LuisHernndezYez

}
return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 342


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

}
return 0;
}

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

}
return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 344


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

}
return 0;
}

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
LuisHernndezYez

}
return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 346


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(){
int i,x; Oculta , en su mbito, a la i anterior
if(...){
int i=0; Oculta , en su mbito, a la i anterior
for(int i=0;i<=10;i++){
...
}
}
char c;
if(...){
double x; Oculta , en su mbito, a la x anterior
...
LuisHernndezYez

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

(Secuencia vaca) elemento

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
LuisHernndezYez

(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:


Datos introducidos por el teclado o ledos de un archivo
Con un elemento especial al final de la secuencia (centinela)
LuisHernndezYez

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

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

12 4 37 23 8 19 83 63 2 35 17 76 15 1

Fundamentosdelaprogramacin:TiposeinstruccionesII 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)
ltimo elemento
LuisHernndezYez

12 4 37 23 8 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

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
LuisHernndezYez

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


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
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 356


Inicializacin

true
Al final?
false No sabemos cuntos
elementos hay
Obtener elemento
No podemos
Procesar elemento implementar con for
LuisHernndezYez

Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 357

Implementacin con while


Inicializacin
Inicializacin
Obtener el primer elemento Obtener 1

Mientras no sea el centinela:


Procesar el elemento true
Centinela?
Obtener el siguiente elemento false
Finalizacin
Procesar elemento

Obtener siguiente
LuisHernndezYez

Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 358


Secuencia de nmeros positivos
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;
LuisHernndezYez

}
cout<<"Suma="<<suma<<endl; Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 359

Longitud de una secuencia de caracteres longitud.cpp

Centinela: carcter punto (.)

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

return l;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 360


Cuntas veces aparece un carcter en una cadena?
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){
cont++; Procesar elemento
}
cin>>c; Siguiente elemento
LuisHernndezYez

}
cout<<buscado<<"aparece" <<cont
<<"veces.";
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 361

Suma de los nmeros de la secuencia suma2.cpp

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

archivo.close();
}
return suma;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 362
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 363

sumatorio.cpp

Recurrencia: ei+1 = ei + 1 e1 = 1
12345678...
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++){
LuisHernndezYez

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;
n 5
?

sumatorio 15
10
01
3
6 false
i<=n
i 2
51
4
3
6 21
1
54321
4321
321
true
sumatorio+=i;
Secuencia
LuisHernndezYez

i=i+1;

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 365

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

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

0112358132134

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 366


fibonacci.cpp

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

}
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;
}
num 100
?
01 1 2 3 5 ...
fib 5
2
3
1
?

fibMenos1 3
1
2
?
LuisHernndezYez

fibMenos2 2
1
0
?

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 368


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 369

Localizacin del primer elemento con una propiedad


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
LuisHernndezYez

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 true
encontrado?
false

Obtener elemento

Encontrado?
LuisHernndezYez

Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 371

Implementacin con while


Inicializacin Inicializacin
Obtener el primer elemento Obtener 1
Mientras ni encontrado ni el centinela:
Obtener el siguiente elemento Encontrado
true
Finalizacin (encontrado?) o centinela?
false

Obtener siguiente
LuisHernndezYez

Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 372


Primer nmero mayor que uno dado busca.cpp

Centinela: 1
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{
LuisHernndezYez

cout<<"Siguiente(1paraterminar):";
cin>>d; //Obtenerelsiguienteelemento
}
}
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 373
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 374


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...
vLun vMar vMie vJue vVie vSab vDom
125.40 76.95 328.80 254.62 435.00 164.29 0.00

... declaramos una tabla de N valores:


LuisHernndezYez

ventas 125.40 76.95 328.80 254.62 435.00 164.29 0.00


ndices 0 1 2 3 4 5 6

Fundamentosdelaprogramacin:TiposeinstruccionesII 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 76.95 328.80 254.62 435.00 164.29 0.00
0 1 2 3 4 5 6
Acceso directo
A cada elemento se accede a travs de su ndice:
ventas[4] accede al 5 elemento (contiene el valor 435.00)
LuisHernndezYez

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:
typedef double tTemp[7];
typedef shortint tDiasMes[12];
typedef char tVocales[5];
typedef double tVentas[31];
typedef tMoneda tCalderilla[15];//EnumeradotMoneda

Recuerda: Adoptamos el convenio de comenzar


LuisHernndezYez

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
double tTemp[7];
shortint tDiasMes[12];
typedef char tVocales[5];
tipo nombre; typedef double tVentas[31];

Ejemplos:
tTemp tempMax; tempMax ? ? ? ? ? ? ?
0 1 2 3 4 5 6

tDiasMes diasMes; diasMes ? ? ? ? ? ? ? ? ? ? ? ?


0 1 2 3 4 5 6 7 8 9 10 11

tVocales vocales; vocales ? ? ? ? ?


0 1 2 3 4

ventasFeb ? ? ? ? ? ? ? ? ? ? ? ? ? ... ?
tVentas ventasFeb;
LuisHernndezYez

0 1 2 3 4 5 6 7 8 9 10 11 12 30

NO se inicializan los elementos automticamente

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 378


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 379

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

vocales 'a' 'e' 'i' 'o' 'u'


0 1 2 3 4

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
cout<<vocales[4];
LuisHernndezYez

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
ventas[0]ventas[1]ventas[2]...ventas[98]ventas[99]

Qu es ventas[100]? O ventas[1]? O ventas[132]?


Memoria de alguna otra variable del programa!
LuisHernndezYez

Define los tamaos de los arrays con constantes

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 381


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 382


Arrays: tamao fijo Bucle de recorrido fijo (for)
Ejemplo: Media de un array de temperaturas
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;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 383

12.40 10.96 8.43 11.65 13.70 13.41 14.07


0 1 2 3 4 5 6

tTemp temp;
double media,total=0; Memoria
... Dias 7
for(int i=0;i<Dias;i++){ temp[0] 12.40
total=total+temp[i];
temp[1] 10.96
}
temp[2] 8.43
i=0 temp[3] 11.65
temp[4] 13.70

true false temp[5] 13.41


i<Dias
temp[6] 14.07
media ?
total+=temp[i]
... total 23.36
31.79
84.62
12.40
0.00
43.44
LuisHernndezYez

i++ i 3
70
2
4
1

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 384


mediatemp.cpp

#include<iostream>
usingnamespacestd;

const int Dias =7;


typedef double tTemp[Dias];

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

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

Los arrays se pasan a las funciones como constantes


Las funciones no pueden devolver arrays
LuisHernndezYez

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];
string aCadena(tMoneda moneda);
//Devuelvelacadenacorrespondientealvalordemoneda

tCalderilla bolsillo;//ExactamentellevoCuantasmonedas
bolsillo[0]=euro;
bolsillo[1]=cinco_centimos;
bolsillo[2]=medio_euro;
bolsillo[3]=euro;
bolsillo[4]=centimo;
...
LuisHernndezYez

for(int moneda=0;moneda<Cuantas;moneda++)
cout<<aCadena(bolsillo[moneda])<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 387


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 388


buscaarray.cpp

Qu da las ventas superaron los 1.000 ?


constint Dias =365;//Aonobisiesto
typedef doubletVentas[Dias];
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++;
}
}
LuisHernndezYez

if (!encontrado){
ind =1;
}
returnind;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 389
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 390


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
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 391

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


array2=array1;//NOCOPIALOSELEMENTOS!!!

Han de copiarse los elementos uno a uno:


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

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

Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 394


lista.cpp

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

const int Max=100;


typedef double tArray[Max];

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

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

double media(const tArray lista,int cont){


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

med =total/cont;
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.
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.
LuisHernndezYez

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

Expresin condicional Condicin ? Exp1 : Exp2


Dos alternativas
Condicin: Expresin lgica Operadores(prioridad)
++ (postfijos)
Exp1 y Exp2: Expresiones Llamadas a funciones
Moldes
Si Condicin se evala a true,
++ (prefijos) !
el resultado es Exp1; (cambio de signo)
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; ||
LuisHernndezYez

?:
c=false ?2 :3; =+==*=/=%=
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"))))
Esto es equivalente a la escala ifelseif de la siguiente seccin.
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoI) Pgina 400

Escala if ... elseif ... equivalente


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

"SS"
else if (nota>=5){cout<<"AP";}
else {cout<<"SS";}

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoI) 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

Recorridos 404
Unaparcamiento 405
Parntesisbienemparejados? 409
Dossecuenciasiguales? 412
NmerosprimosmenoresqueN 413
Bsquedas 417
Bsquedadeunnmeroenunarchivo 419
Bsquedasensecuenciasordenadas 420
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 404

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
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 405


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

}
return 0;
}

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

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
Errores:
Contador 1: parntesis de cierre sin uno de apertura pendiente
abc)de(fgh(ij))#
LuisHernndezYez

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


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

if (!error){
cin>>c;
}
}
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 410

parentesis.cpp

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

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 411


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
LuisHernndezYez

sec1.close(); y por secuencia4.txt para comprobar otros casos


sec2.close();
return sonIguales;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 412

primos.cpp

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

}
}
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
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){
LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 416


LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 417


#include<iostream> buscaarch.cpp
usingnamespacestd;
#include<fstream>

int busca(int n);


//Devuelvelalneaenlaqueseencuentrao1sinoest

intmain(){
intnum,linea;

cout<<"Valoralocalizar:";
cin>>num;
linea =busca(num);
if(linea !=1){
cout<<"Encontrado(lnea" <<linea <<")" <<endl;
}
else{
LuisHernndezYez

cout<<"Noencontrado" <<endl;
}
return 0;
}

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 418

int busca(int n){


int i,linea =0;
bool encontrado=false;
ifstream archivo;
archivo.open("enteros.txt");
if (!archivo.is_open()){
linea =1;
}
else {
archivo>>i;
while ((i!=0)&&!encontrado){
linea++;
if (i==n){
encontrado=true;
}
archivo>>i; Centinela
}
if (!encontrado){
linea =1;
LuisHernndezYez

}
archivo.close();
}
return linea;
}
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 419
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 420

Secuencia ordenada de menor a mayor: buscaord.cpp


paramos al encontrar uno mayor o igual al buscado
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 {
LuisHernndezYez

cout<<"Noencontrado";
}
cout<<endl;
archivo.close();
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 421
Si el elemento est: procesamiento similar a secuencias desordenadas

2 5 9 15 16 24 41 73 78 82 123 153 159 ...

archivo>>i;

num 9
?

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

i 9
5
?
2 true

cont++;
archivo>>i;
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 422

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

No se procesa
2 5 9 15 16 24 41 73 78 82 123 153 159 ...
el resto
de la secuencia
archivo>>i;

num 10
?

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

i 5
2
9
?
15 true

cont++;
archivo>>i;
LuisHernndezYez

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

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

Diseodescendente:Tareasysubtareas 427
Subprogramas 434
Subprogramasydatos 441
Parmetros 446
Argumentos 451
Resultadodelafuncin 467
Prototipos 473
Ejemploscompletos 475
Funcionesdeoperador 477
Diseodescendente(unejemplo) 480
Precondicionesypostcondiciones 490
LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental
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

Ejemplos:

Dibujar
LuisHernndezYez

Mostrar la cadena HOLA MAMA en letras gigantes

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 428


1. Dibujar

2. Dibujar 1. Dibujar
Misma tarea
3. Dibujar 2. Dibujar

2.1. Dibujar

REFINAMIENTO 2.2. Dibujar


LuisHernndezYez

3. Dibujar

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 429

1. Dibujar

2. Dibujar

2.1. Dibujar
4tareas,perodosdeellassoniguales
2.2. Dibujar Nosbastaconsabercmodibujar:

3. Dibujar
LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 430


void dibujarCirculo()
{...}

void dibujarSecantes()
Dibujar
{...}

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

int main(){
dibujarCirculo();
LuisHernndezYez

dibujarTriangulo();
dibujarSecantes();
return 0;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 431

Mostrar la cadena HOLA MAMA en letras gigantes

MostrarHOLAMAMA

MostrarHOLA Espacioenblanco MostrarMAMA

H O L A M A

Tareas bsicas
LuisHernndezYez

H O L A Espacioenblanco M

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 432


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

{...}
return0;
void mostrarA() }
{...}

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 433


LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 434


Subprogramas
Pequeos programas dentro de otros programas
Unidades de ejecucin independientes
Encapsulan cdigo y datos
Se comunican con otros subprogramas (datos)
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
LuisHernndezYez

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

void mostrarH()
{

}
...

void mostrarO()
LuisHernndezYez

{
}
...

...

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
Cuerpo: Un bloque de cdigo!
LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 437

Tipos de subprogramas
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;
LuisHernndezYez

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
...
int menu() intmain()
{
{
int op;
cout<<"1 Editar"<<endl; ...
cout<<"2 Combinar"<<endl; int opcion;
cout<<"3 Publicar"<<endl; opcion =menu();
cout<<"0 Cancelar"<<endl; ...
cout<<"Elija:";
cin>>op;
returnop;
}
LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 439

Procedimientos
Subprogramas de tipo void
...
void menu() intmain()
{
{
int op;
cout<<"1 Editar"<<endl; ...
cout<<"2 Combinar"<<endl; menu();
cout<<"0 Cancelar"<<endl; ...
cout<<"Opcin:";
cin>>op;
if(op ==1){
editar();
}
LuisHernndezYez

elseif(op ==2){
combinar();
}
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 440


LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 441

De uso exclusivo del subprograma


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

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
LuisHernndezYez

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
mbito de los datos locales: resto del subprograma
No se conocen fuera del subprograma
LuisHernndezYez

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; Datos globales op de proc()
es distinta
... de op de main()
void proc(){
int op;
Datos locales a proc()
double ingresos;
... Se conocen MAX (global), op (local)
} e ingresos (local que oculta la global)

int main(){
int op;
Datos locales a main()
LuisHernndezYez

...
return 0; Se conocen MAX (global), op (local)
} e ingresos (global)

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 444


Sobre el uso de datos globales en los subprogramas
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

Excepciones:
Constantes globales (valores inalterables)
LuisHernndezYez

Tipos globales (necesarios en varios subprogramas)

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 445


LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 446


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

Datos de entrada: Aceptados Subprograma


Subprograma que dado un nmero x
muestra en la pantalla su cuadrado: cuadrado()
5

Datos de salida: Devueltos Subprograma


Subprograma que dado un nmero x y (=x2)
devuelve su cuadrado: cuadrado()
5

Datos de entrada/salida:
Subprograma
Aceptados y modificados
LuisHernndezYez

Subprograma que dada una variable x x


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)

&
De salida
LuisHernndezYez

parmetros tipo identificador

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

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
Puede haber tanto por valor como por referencia

Atencin! Los arrays se pasan por referencia sin utilizar &


LuisHernndezYez

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

Se hacen corresponder los argumentos pasados por referencia


(variables) con sus correspondientes parmetros
LuisHernndezYez

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

void proc(int x,double a) Memoria

{...} i 124
d 3.0
int main() ...
{
int i=124;
...
double d=3; x 124
proc(i,33 *d); a 99.0
... ...

return0;
LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 454


void proc(int&x,double&a) Memoria
x i 124
{...}
a d 3.0
int main() ...
{
int i=124;
double d=3;
proc(i,d);
...

return0;
LuisHernndezYez

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(3,i,d); N de argumentos N de para metros
proc(i,d);
proc(3*i+12,d);
proc(i,23); Parmetro por referencia variable!
proc(d,i); Argumento double para parmetro int!
proc(3.5,d); Argumento double para parmetro int!
LuisHernndezYez

proc(i); N de argumentos N de para metros

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 456


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

return 0;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 457

...
void divide(int op1,int op2,int&div,int&rem){
//Divideop1entreop2ydevuelveelcocienteyelresto
div =op1/op2;
rem=op1%op2; Memoria
} cociente ?
resto ?
int main(){
int cociente,resto; i 1
for (int j=1;j<=4;j++){ j 1
for (int i=1;i<=4;i++){ ...
divide(i,j,cociente,resto);
...
}
}
LuisHernndezYez

return 0;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 458


...
void divide(int op1,int op2,int&div,int&rem){
//Divideop1entreop2ydevuelveelcocienteyelresto
div =op1/op2;
rem=op1%op2; Memoria
} div cociente ?
rem resto ?
int main(){
int cociente,resto; i 1
for (int j=1;j<=4;j++){ j 1
for (int i=1;i<=4;i++){ ...
divide(i,j,cociente,resto);
...
} op1 1
}
op2 1
LuisHernndezYez

return 0; ...
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 459

...
void divide(int op1,int op2,int&div,int&rem){
//Divideop1entreop2ydevuelveelcocienteyelresto
div =op1/op2;
rem=op1%op2; Memoria
} div cociente 1
rem resto 0
int main(){
int cociente,resto; i 1
for (int j=1;j<=4;j++){ j 1
for (int i=1;i<=4;i++){ ...
divide(i,j,cociente,resto);
...
} op1 1
}
op2 1
LuisHernndezYez

return 0; ...
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 460


...
void divide(int op1,int op2,int&div,int&rem){
//Divideop1entreop2ydevuelveelcocienteyelresto
div =op1/op2;
rem=op1%op2; Memoria
} cociente 1
resto 0
int main(){
int cociente,resto; i 1
for (int j=1;j<=4;j++){ j 1
for (int i=1;i<=4;i++){ ...
divide(i,j,cociente,resto);
...
}
}
LuisHernndezYez

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 ?
}
...
int main(){
double num1,num2;
cout<<"Valor1:"; Memoriademain()
cin>>num1; valor1 num1 13.6
cout<<"Valor2:";
valor2 num2 317.14
cin>>num2;
intercambia(num1,num2); ...
LuisHernndezYez

cout<<"Ahoraelvalor1es" <<num1
<<"yelvalor2es" <<num2<<endl;
return 0;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 462


...
//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"
LuisHernndezYez

<<cent1<<"x1c." <<endl;

return 0;
}

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;
cantidad=cantidad%20; Adams/Leestma/Nyhoff
cent10=cantidad/10;
cantidad=cantidad%10;
cent5=cantidad/5;
cantidad=cantidad%5;
LuisHernndezYez

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

error=true;
}
else{
error=false;
...
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 465

cambio.cpp

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

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);
x=x*x;
} Esta instruccin
return 0; 256
LuisHernndezYez

no se ejecutar nunca }

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 468


factorial.cpp

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

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++){
LuisHernndezYez

fact =fact *i;


}
}
return fact;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 469

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

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 470


int compara(int val1,int val2){
//1sival1<val2,0siiguales,+1sival1>val2
int resultado;

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

return resultado; Punto de salida nico


LuisHernndezYez

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)

Nuestros subprogramas siempre terminarn al final:


No usaremos return en los procedimientos
Funciones: slo un return y estar al final
LuisHernndezYez

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?

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


Prototipo: cabecera del subprograma terminada en ;
void dibujarCirculo();
void mostrarM(); main() es el nico subprograma
LuisHernndezYez

void proc(double&a); que no hay que prototipar


int cuad(int x);
...

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 474


intercambia.cpp

#include<iostream>
usingnamespace std;

void intercambia(double&valor1,double&valor2);//Prototipo

int main(){
double num1,num2;
cout<<"Valor1:"; Asegrate de que los prototipos
cin>>num1; coincidan con las implementaciones
cout<<"Valor2:";
cin>>num2;
intercambia(num1,num2);
cout<<"Ahoraelvalor1es" <<num1
<<"yelvalor2es" <<num2<<endl;
return 0;
}

void intercambia(double&valor1,double&valor2){
LuisHernndezYez

double tmp;//Variablelocal(temporal)
tmp=valor1;
valor1=valor2;
valor2=tmp;
}

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 475

mates.cpp

#include<iostream> longlong int factorial(int n){


usingnamespace std; longlong int fact =1;

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

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:
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):
LuisHernndezYez

+, , *, /, , <<, %, ...

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;

La implementacin ser exactamente la misma!


LuisHernndezYez

Mayor aproximacin al lenguaje matemtico

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 479


LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 480


Especificacin inicial (Paso 0).
Desarrollar un programa que haga operaciones de conversin
de medidas hasta que el usuario decida que no quiere hacer ms

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
LuisHernndezYez

Grados Fahrenheit a centgrados


Galones a litros

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 481

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

Men, cuatro funciones de conversin y main()

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 482


Paso 2.

Conversiones

Men Pulgadasacm. Librasagr. FaC Galonesal. main()


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
LuisHernndezYez

Programa principal (main())

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 484


Paso 3. Cada tarea, un subprograma

Comunicacin entre los subprogramas:

Funcin Entrada Salida Valordevuelto


menu() int
pulgACm() double pulg double
lbAGr() double libras double
grFAGrC() double grF double
galALtr() double galones double
main() int
LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 485

Paso 4. Algoritmos detallados de cada subprograma Programar


#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:
{
LuisHernndezYez

cout<<"Pulgadas:";
cin>>valor;
cout<<"Son" <<pulgACm(valor)<<"cm." <<endl;
}
. . .
break;
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 486
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;
}
LuisHernndezYez

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

double galALtr(double galones){


constdouble ltrPorGal =4.54609;
return galones*ltrPorGal;
}
LuisHernndezYez

. . .
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 489
LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 490


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

Aserciones:
Condiciones que si no se cumplen interrumpen la ejecucin
LuisHernndezYez

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;


}
La funcin tiene una precondicin: pulg debe ser positivo

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


LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 492


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

}
else{ //Secumplelaprecondicin...
...

Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 493

Postcondiciones
Un subprograma puede garantizar condiciones al terminar:
int menu(){
int op =1;
while ((op <0)||(op >4)){
...
cout<<"Elige:";
cin>>op;
if ((op <0)||(op >4)){
cout<<"Opcinnovlida"<<endl;
}
}
assert ((op >=0)&&(op <=4));
LuisHernndezYez

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

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

Archivoscomoparmetros 498
Lafuncinmain() 501
Argumentosimplcitos 504
Sobrecargadesubprogramas 508
LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)
LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo) Pgina 498

#include<iostream>
usingnamespacestd;
#include<fstream>
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();
LuisHernndezYez

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

Los archivos siempre se pasan por referencia


LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo) Pgina 500


LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo) Pgina 501


Comunicacin con el sistema operativo
Parmetros opcionales de la funcin main():
int main(int argc,char*argv[])

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)


LuisHernndezYez

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:


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

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
p(3,9,12);//itoma3,jtoma9yktoma12
LuisHernndezYez

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;
cout<<"X="; No podemos dejar signo por defecto
cin>>x; y concretar delta
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;

return 0;
}
LuisHernndezYez

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
abs(3L) //argumentolongint>tercerafuncin
LuisHernndezYez

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

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo) Pgina 509


inter.cpp

#include<iostream> void intercambia(char&x,char&y){


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

tmp=x; cout<<d1<<" " <<d2<<endl;


x=y; cout<<c1<<" " <<c2<<endl;
y=tmp; 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.
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.
LuisHernndezYez

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


Facultad de Informtica
Universidad Complutense

Tiposdedatos 514
Arraysdenuevo 517
Arraysybuclesfor 520
Mssobrearrays 522
Inicializacindearrays 523
Enumeradoscomondices 524
Pasodearraysasubprogramas 525
Implementacindelistas 528
Cadenasdecaracteres 531
Cadenasdecaracteresdetipostring 535
Entrada/salidaconstring 539
LuisHernndezYez/PabloMorenoGer

Operacionesconstring 541
Estructuras 543
Estructurasdentrodeestructuras 549
Arraysdeestructuras 550
Arraysdentrodeestructuras 551
Listasdelongitudvariable 552
Unejemplocompleto 558
Elbucledo..while 562

Fundamentosdelaprogramacin:Tiposdedatosestructurados
LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 514

Clasificacin de tipos
Simples
Estndar: int, float, double, char, bool
Conjunto de valores predeterminado
Definidos por el usuario: enumerados
Conjunto de valores definido por el programador
Estructurados
LuisHernndezYez/PabloMorenoGer

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
Arrays (tablas)
Elementos organizados por posicin: 0, 1, 2, 3, ...
Acceso por ndice: 0, 1, 2, 3, ...
LuisHernndezYez/PabloMorenoGer

Una o varias dimensiones


Estructuras (tuplas, registros)
Elementos (campos) sin orden establecido
Acceso por nombre

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 516


LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 517


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 76.95 328.80 254.62 435.00 164.29 0.00
0 1 2 3 4 5 6
LuisHernndezYez/PabloMorenoGer

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];
Declaracin de variables de tipos array: como cualquier otra
LuisHernndezYez/PabloMorenoGer

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


Arrays: tamao fijo Bucles de recorrido fijo (for)
tVentas ventas; constint Dias =7;
LuisHernndezYez/PabloMorenoGer

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


0 1 2 3 4 5 6

tVentas ventas;
Memoria
double media,total=0;
Dias 7
...
ventas[0] 12.40
for(int i=0;i<Dias;i++){
ventas[1] 10.96
total=total+ventas[i];
} ventas[2] 8.43
ventas[3] 11.65
i=0 ventas[4] 13.70
LuisHernndezYez/PabloMorenoGer

ventas[5] 13.41
true false ventas[6] 14.07
i<Dias
media ?
... total 84.62
23.36
31.79
12.40
0.00
43.44
total+=ventas[i]
i 3
2
70
4
1
i++

Fundamentosdelaprogramacin:Tiposdedatosestructurados 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:


i[0]i[1]i[2]i[3]i[4]...i[9]
LuisHernndezYez/PabloMorenoGer

1 2 3 4 5...10

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


tTabla i={0};//Ponetodosloselementosa0

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 523


constintColores=3,
typedefenum{rojo,verde, azul}tRGB;
typedefint tColor[Colores];
tColor color;
...
cout<<"Cantidadderojo(0255):";
cin>>color[rojo];
cout<<"Cantidaddeverde(0255):";
cin>>color[verde];
LuisHernndezYez/PabloMorenoGer

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];
void inicializa(tTabla tabla);//Sinponer&

Las modificaciones del array quedan reflejadas en el argumento


LuisHernndezYez/PabloMorenoGer

inicializa(array);
Si inicializa() modifica algn elemento de tabla,
automticamente queda modificado ese elemento de array

Son el mismo array!

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 525


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

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);
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
LuisHernndezYez/PabloMorenoGer

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;

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

...
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
Recorrido de la lista:
for(int i=0;i<contador;i++){
LuisHernndezYez/PabloMorenoGer

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

Array y contador por separado? Estructuras

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 530


LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 531


Arrays de caracteres
Cadenas: secuencias de caracteres de longitud variable
"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:
LuisHernndezYez/PabloMorenoGer

H o l a
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

Longitud actual: 4

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 532

Longitud de la cadena
A d i s
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

Longitud: 5

S u p e r c a l i f r a g i l s t i c o
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

Longitud: 21
LuisHernndezYez/PabloMorenoGer

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 d i s \0
0 1 2 3 4 5 6 7 8 9 10

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 533


Cadenas de caracteres en C++
Dos alternativas para el manejo de cadenas:
Cadenas al estilo de C (terminadas en nulo)
Tipo string

Cadenas al estilo de C Anexo del tema


Arrays de tipo char con una longitud mxima
Un ltimo carcter especial al final: '\0'
LuisHernndezYez/PabloMorenoGer

Tipo string
Cadenas ms sofisticadas
Sin longitud mxima (gestin automtica de la memoria)
Multitud de funciones de utilidad (biblioteca string)

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 534


LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 535


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
Biblioteca string
Requiere establecer el espacio de nombres a std

Se pueden inicializar en la declaracin


LuisHernndezYez/PabloMorenoGer

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

#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
LuisHernndezYez/PabloMorenoGer

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:


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
LuisHernndezYez/PabloMorenoGer

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:
getline(cin,cadena)
LuisHernndezYez/PabloMorenoGer

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

#include<iostream>
#include<string>
usingnamespacestd;

int main(){
string nombre,apellidos;
cout<<"Introduzcaunnombre:";
cin>>nombre;
cout<<"Introduzcalosapellidos:";
cin.sync();
getline(cin,apellidos);
LuisHernndezYez/PabloMorenoGer

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
cadena.find(subcadena)
Posicin de la primera ocurrencia de subcadena en cadena
string cad ="Olala";
cout<<cad.find("la");//Muestra1
LuisHernndezYez/PabloMorenoGer

(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
string cad ="abcdefgh";
cad.insert(3,"123");//cad ahoracontiene"abc123defgh"
LuisHernndezYez/PabloMorenoGer

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

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 542


LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 543


Colecciones heterogneas (tuplas, registros)
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.)
LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 544

typedefstruct {
...//declaracionesdecampos(comovariables)
}tTipo;//nombredetipo alfinal!
typedefstruct {
string nombre;
string apellidos;
int edad;
string nif;
}tPersona;
LuisHernndezYez/PabloMorenoGer

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)
persona.apellidos //unacadena(string)
persona.edad //unentero(int)
persona.nif //unacadena(string)
LuisHernndezYez/PabloMorenoGer

Podemos copiar dos estructuras directamente:


tPersona persona1,persona2;
...
persona2=persona1;
Se copian todos los campos a la vez

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 546

typedefstruct {
string nombre;
string apellidos; Memoria
int edad;
string nif; Luis
}tPersona; persona.nombre
Antonio
tPersona persona;

persona
Hernndez
persona.apellidos
Yez
nombre LuisAntonio
LuisHernndezYez/PabloMorenoGer

persona.edad 22
apellidos HernndezYez
persona.nif 00223344F
edad 22

nif 00223344F

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 547


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 .)
LuisHernndezYez/PabloMorenoGer

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 Pgina 548

typedefstruct { typedefstruct {
stringdni; ...
char letra; tNif nif;
} tNif; }tPersona;

tPersona persona; tPersona


nombre
Acceso al NIF completo: apellidos
persona.nif //Otraestructura edad
tNif
LuisHernndezYez/PabloMorenoGer

nif
Acceso a la letra del NIF: dni
letra
persona.nif.letra

Acceso al DNI:
persona.nif.dni

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 549


const intDIM =100; tPersona personal
typedefstruct { nombre
nombre
apellidos
string nombre; 0 edad
apellidos
nif
string apellidos; edad
nombre
int edad; nif apellidos
1
string nif; edad
nif
}tPersona;
nombre
typedeftPersona tArray[DIM]; 2 apellidos
edad
tArray personal; nif
LuisHernndezYez/PabloMorenoGer

Nombre de la tercera persona:


personal[2].nombre nombre

Edad de la duodcima persona:


apellidos
DIM1 edad
nif
personal[11].edad
NIF de la primera persona:
personal[0].nif

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 550

const intMAX=100; lista elementos contador


typedefstruct { nombre
apellidos
string nombre; 0 edad
nif
string apellidos; nombre
int edad; 1
apellidos
edad
string nif; nif

}tPersona; 2
nombre
apellidos
edad
typedeftPersona tArray[MAX]; nif

typedefstruct {
tArray elementos;
LuisHernndezYez/PabloMorenoGer

int contador; MAX1


nombre
apellidos
edad
}tLista; nif

tLista lista;
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
/PabloMorenoGer
LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 552

Estructura que agrupe el array y el contador:


const intMAX=10;
typedefdoubletArray[MAX];
typedefstruct {
Elementos sin usar
tArray elementos;
(datos basura)
int contador;
}tLista;

elementos
LuisHernndezYez/PabloMorenoGer

12.0 2.2 5.4 0.0 36.2 35.0 X X X X


0 1 2 3 4 5 6 7 8 9

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
12.0 2.2 5.4 0.0 36.2 35.0 X X X X
nuevo
0 1 2 3 4 5 6 7 8 9
3 6
pos

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


LuisHernndezYez/PabloMorenoGer

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

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++;
}
LuisHernndezYez/PabloMorenoGer

42.0
12.0 2.2 5.4 42.0 0.0 36.2 35.0 X X X
nuevo
0 1 2 3 4 5 6 7 8 9
3 7
pos

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 555


Eliminar el elemento en una posicin
Posiciones vlidas: 0 a contador1

12.0 2.2 5.4 0.0 36.2 35.0 X X X X


3 0 1 2 3 4 5 6 7 8 9
pos 6

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


LuisHernndezYez/PabloMorenoGer

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;

12.0 2.2 5.4 0.0 36.2 35.0 X X X X


3 0 1 2 3 4 5 6 7 8 9
pos 6
LuisHernndezYez/PabloMorenoGer

12.0 2.2 5.4 36.2 35.0 35.0 X X X X


3 0 1 2 3 4 5 6 7 8 9
pos 5

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 557


LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 558

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:
LuisHernndezYez/PabloMorenoGer

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

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

const int MAX=100;


typedef struct {
string nombre;
string apellidos;
int edad;
string nif;
LuisHernndezYez/PabloMorenoGer

double nota; Declaraciones de constantes


} tEstudiante; y tipos globales
typedef tEstudiantetArray[MAX]; Tras las bibliotecas
typedef struct{
tArray elementos;
int contador;
} tLista;

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
LuisHernndezYez/PabloMorenoGer

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); Condicin al final del bucle

do cuerpo while ( condicin ) ;

int i=1;
do {
cout<<i<<endl;
LuisHernndezYez/PabloMorenoGer

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 {
Cuerpo
cout<<i<<endl;
i++; true
Condicin
}while(i<=100); false

i=1;

El cuerpo
LuisHernndezYez/PabloMorenoGer

cout<<i<<endl;
se ejecuta
i++;
al menos
true una vez
i<=100
false

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 564

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


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

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

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 565


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

}while((op <0)||(op >4));

return op;
}

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 566

El archivo clase.txt
Un dato en cada lnea


Por cada estudiante:


Nombre (cadena)


Apellidos (cadena)


Edad (entero)


NIF (cadena)

LuisHernndezYez/PabloMorenoGer


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 (>>)
Nota extractor (>>)
Queda pendiente de leer el Intro
LuisHernndezYez/PabloMorenoGer

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

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

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

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

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
LuisHernndezYez/PabloMorenoGer

cin.sync(); //Descartamoscualquierentradapendiente
}

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 571


voidinsertarEstudiante(tLista&lista,tEstudianteestudiante,
bool&ok){

ok=true;
if(lista.contador==MAX){
ok=false;
}
else {
lista.elementos[lista.contador]=estudiante;
//Insertamosalfinal
lista.contador++;
LuisHernndezYez/PabloMorenoGer

}
}

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 572

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];
}
LuisHernndezYez/PabloMorenoGer

lista.contador;
}
}

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 573


string nombreCompleto(tEstudiante estudiante){
return estudiante.nombre+"" +estudiante.apellidos;
}

voidcalificar(tLista&lista){

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

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 574

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

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


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]);
LuisHernndezYez/PabloMorenoGer

if(i==mayor){
cout<<"<<<Mayornota!";
}
cout<<endl;
}
cout<<"Mediadelaclase:"<<fixed <<setprecision(1)
<<media<<endl<<endl;
}

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 576

int main(){
tLista lista;
tEstudiante estudiante;
bool exito;
int op,pos;

cargar(lista,exito);
if (!exito){
cout<<"Nosehapodidocargarlalista!" <<endl;
}
else {
do {//Elbucledoevitatenerqueleeranteslaprimeraopcin
op =menu();
LuisHernndezYez/PabloMorenoGer

switch(op){
case1:
{
leerEstudiante(estudiante);
insertarEstudiante(lista,estudiante,exito);
if(!exito){
cout<<"Listallena:imposibleinsertar" <<endl;
}
}
break;

Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 577


case2:
{
cout<<"Posicin:";
cin>>pos;
eliminarEstudiante(lista,pos 1,exito);
if(!exito){
cout<<"Elementoinexistente!" <<endl;
}
}
break;
case3:
{
calificar(lista);
}
break;
LuisHernndezYez/PabloMorenoGer

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:

Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.
No comercial (Non commercial):
LuisHernndezYez/PabloMorenoGer

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

CadenasalestilodeC 582
E/SconcadenasalestilodeC 583
Labibliotecacstring 584
Ejemplo 585
LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo)
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)
cadena A d i s \0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
LuisHernndezYez/PabloMorenoGer

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)
cin>>setw(15)>>cadena;
cin.getline(cadena_estilo_C,mx):
Para leer tambin los espacios en blanco y no ms de mx1
LuisHernndezYez/PabloMorenoGer

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++");
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
LuisHernndezYez/PabloMorenoGer

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

#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
LuisHernndezYez/PabloMorenoGer

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


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

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

Reconocimiento (Attribution):
En cualquier explotacin de la obra autorizada por la licencia
har falta reconocer la autora.
No comercial (Non commercial):
LuisHernndezYez/PabloMorenoGer

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


Facultad de Informtica
Universidad Complutense

Recorridodearrays 590
Arrayscompletos 593
Arraysnocompletosconcentinela 594
Arraysnocompletosconcontador 595
Ejemplos 597
Generacindenmerosaleatorios 601
Bsquedasenarrays 604
Arrayscompletos 606
Arraysnocompletosconcentinela 607
Arraysnocompletosconcontador 608
Ejemplo 610
Recorridosybsquedasencadenas 614
Msejemplosdemanejodearrays 617
Arraysmultidimensionales 630
Inicializacindearraysmultidimensionales 638
LuisHernndezYez

Recorridodeunarraybidimensional 641
RecorridodeunarrayNdimensional 644
Bsquedaenunarraymultidimensional 647

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays
LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 590

Esquema de recorrido
Inicializacin Inicializacin

Mientras no al final de la secuencia:


Obtener el siguiente elemento true
Al final?
Procesar el elemento
false
Finalizacin
Obtener elemento

Procesar elemento
LuisHernndezYez

Finalizacin

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 591


Recorrido de secuencias en arrays
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:
LuisHernndezYez

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;
...
ventas 125.40 76.95 328.80 254.62 435.00 164.29 316.05 219.99 93.45 756.62
0 1 2 3 4 5 6 7 8 9

double elemento;
for(int i=0;i<N;i++){
elemento=ventas[i];
LuisHernndezYez

//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 328.80 254.62 435.00 164.29 316.05 1.0
0 1 2 3 4 5 6 7 8 9

int i=0;
int i=0; double elemento;
double elemento=datos[i]; do {
while(elemento!=1){ elemento=datos[i];
LuisHernndezYez

//Procesarelelemento... if(elemento!=1){
//Procesarelelemento...
i++; i++;
elemento=datos[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
elementos
125.40 76.95 328.80 254.62 435.00 164.29 316.05
0 1 2 3 4 5 6 7 8 9
LuisHernndezYez

contador 7

N de elementos (primer ndice sin elemento)

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 595


Recorrido de arrays no completos con contador
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...
LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 596


LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 597


fibonacci.cpp

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]<<"";
}
LuisHernndezYez

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
const intNUM=100;
typedef inttNum[NUM];//Exactamente100nmeros
tNum numeros;
const intDIG =5;
typedef inttDig[DIG];//i>nmerosdei+1dgitos
tDig numDig ={0 };

numeros 123 2 46237 2345 236 11234 33 999 ... 61


LuisHernndezYez

0 1 2 3 4 5 6 7 99

numDig 0 0 0 0 0 0
0 1 2 3 4 5

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 599


Cuenta de valores con k dgitos
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;
}
LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 600

Generacin de nmeros pseudoaleatorios


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
LuisHernndezYez

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

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
LuisHernndezYez

srand(time(NULL)); //Inicialasecuenciaaleatoria
...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 602

for (int i=0;i<NUM;i++){//Creamoslasecuencia


numeros[i]=rand();//Entre0y32766
}

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

int digitos(int dato){


...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 603


LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 604

Esquema de bsqueda
Inicializacin / encontrado=false;
Inicializacin
Mientras no se encuentre el elemento
true
y no se est al final de la secuencia: Al final o
encontrado?
Obtener el siguiente elemento false

Comprobar si el elemento
Obtener elemento
satisface la condicin
Finalizacin Encontrado?
(tratar el elemento encontrado
o indicar que no se ha encontrado)
LuisHernndezYez

Finalizacin

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 605


Todas las posiciones ocupadas const intN=100;
typedef inttArray[N];
int buscado; tArray lista;
bool encontrado=false;
cout<<"Valorabuscar:";
cin>>buscado;
int pos=0;
while((pos<N)&&!encontrado){
//Mientrasnoselleguealfinalynoencontrado
if(lista[pos]==buscado){
encontrado=true;
}
else{
pos++;
}
LuisHernndezYez

}
if(encontrado)//...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 606

Con centinela
const intN=10;
typedef inttArray[N];
int buscado; tArray array;
cout<<"Valorabuscar:"; constint centinela=1;
cin>>buscado;
int pos=0;
bool encontrado=false;
while((array[pos]!=centinela)&&!encontrado){
if(array[pos]==buscado){
encontrado=true;
}
else{
pos++;
}
}
LuisHernndezYez

if(encontrado)//...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 607


Con contador
const intN=10;
typedefdoubletArray[N];
int buscado; typedefstruct {
cout<<"Valorabuscar:"; tArray elementos;
cin>>buscado; int contador;
int pos=0; }tLista;
bool encontrado=false; tLista miLista;
while((pos<miLista.contador)
&&!encontrado){
//Mientrasnoalfinalynoencontrado
if(miLista.elementos[pos]==buscado){
encontrado=true;
}
else{
pos++;
LuisHernndezYez

}
}
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
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:
LuisHernndezYez

anual[2].ventas[3][0]

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 609


LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 610

#include<iostream> umbral.cpp
usingnamespacestd;
#include<fstream>

const intN=100;
typedefdoubletArray[N];
typedefstruct {
tArray elementos;
int contador;
}tLista;

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

int main(){
tLista lista;
bool ok;
LuisHernndezYez

cargar(lista,ok);
if (!ok){
cout<<"Error:nohayarchivoodemasiadosdatos"
<<endl;
}
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 611
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 {
LuisHernndezYez

cout<<"Noencontrado!"<<endl;
}
}
return0;
}
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;
}
LuisHernndezYez

}
archivo.close();
}
ok=abierto&&!overflow;
}
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 613
LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 614

inversa.cpp

Recorridos y bsquedas en cadenas de caracteres


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

inversa=car+inversa;//Insertacaralprincipio
pos++;
}//...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 615


busca.cpp

Bsqueda de un carcter en una cadena


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

pos++;
}
}
if(encontrado)//...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 616


LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 617


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

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

int sumaPares(const tVector v){


int suma=0;

for (int i=0;i<N;i=i+2){


suma=suma+v[i];
}
LuisHernndezYez

return suma;
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 619


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

i++;
}
return !encontrado;
}
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;
LuisHernndezYez

}
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'
El resultado sera cierto, ya que todos los elementos de v1 estn
en v2
LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 623


incluidos.cpp

#include<iostream>
usingnamespacestd;

const int N=3;


const int M=10;
typedef chartVector1[N];
typedefchartVector2[M];

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

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

bool vectorIncluido(const tVector1 v1,const tVector2 v2){


int i=0;
bool encontrado=esta(v1[0],v2);

while(encontrado&&(i<N 1)){
i++;
LuisHernndezYez

encontrado=esta(v1[i],v2);
}

return encontrado;
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 625


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

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 626

anagramas.cpp

#include<iostream>
#include<string>
usingnamespace std;

int buscaCaracter(string cad,char c);//ndiceo1sinoest

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

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

if (sonAnagramas){
cout<<"Laspalabrasintroducidassonanagramas" <<endl;
}
else {
cout<<"LaspalabrasintroducidasNOsonanagramas" <<endl;
}
LuisHernndezYez

return 0;
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 628

int buscaCaracter(string cad,char c){


int pos=0,lon=cad.length();
bool encontrado=false;

while ((pos<lon)&&!encontrado){
if (cad.at(pos)==c){
encontrado=true;
}
else {
pos++;
}
}
if (!encontrado){
pos=1;
}

return pos;
LuisHernndezYez

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:
0 1 2 3 ... 98 99
0 ...
1 ...
2 ...
LuisHernndezYez

... ... ... ... ... ... ... ...


48 ...
49 ...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays 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];

0 1 2 3 ... 98 99
0 ...
1 ...
2 ...
... ... ... ... ... ... ... ...
LuisHernndezYez

48 ...
49 ...

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:
cout<<matriz[2][9][15][6];
LuisHernndezYez

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;
Ahora:
temp[i][0] es la temperatura mnima del da i+1
temp[i][1] es la temperatura mxima del da i+1
LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 634

temp.cpp

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

else {
archivo>>min>>max;
//Elarchivoterminacon9999
...

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 635


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

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

Para cada valor del primer ndice: todos los valores del segundo
LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 638

Inicializacin de un array bidimensional


typedefinttArray[5][2];
tArray cuads ={1,1,2,4,3,9,4,16,5,25};
Memoria 0 1

cuads[0][0] 1 0 1 1
1 2 4
cuads[0][1] 1
2 3 9
cuads[1][0] 2
3 4 16
cuads[1][1] 4
4 5 25
cuads[2][0] 3
cuads[2][1] 9 Si hay menos valores que elementos,
cuads[3][0] 4 el resto se inicializan a cero
cuads[3][1] 16 Inicializacin a cero de todo el array:
LuisHernndezYez

cuads[4][0] 5 int cuads[5][2]={0 };


cuads[4][1] 25

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 639


typedefdouble tMatriz[3][4][2][3];
tMatriz matriz=
{1,2,3,4,5,6, Memoria
matriz[0][0][0][0] 1
7,8,9,10,11,12};
matriz[0][0][0][1] 2
matriz[0][0][0][2] 3
matriz[0][0][1][0] 4
matriz[0][0][1][1] 5
matriz[0][0][1][2] 6
matriz[0][1][0][0] 7
matriz[0][1][0][1] 8
matriz[0][1][0][2] 9
matriz[0][1][1][0] 10
LuisHernndezYez

matriz[0][1][1][1] 11
matriz[0][1][1][2] 12
matriz[0][2][0][0] 0
... 0

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 640

const intFILAS=10;
const intCOLUMNAS=5;
typedefdouble tMatriz[FILAS][COLUMNAS];
tMatriz matriz;

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

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 641


Ventas de todos los meses de un ao
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
LuisHernndezYez

<<"delmes"<<mes+1 <<":";
cin>>ventas[mes][dia];
}
}
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 642

Ventas de todos los meses de un ao


Das

0 1 2 3 4 ... 28 29 30
0 201 125 234 112 156 ... 234 543 667
1 323 231 675 325 111 ...
2 523 417 327 333 324 ... 444 367 437
3 145 845 654 212 562 ... 354 548
4 327 652 555 222 777 ... 428 999 666
Celdas no
5 854 438 824 547 175 ... 321 356
Meses utilizadas
6 654 543 353 777 437 ... 765 678 555
7 327 541 164 563 327 ... 538 159 235
8 333 327 432 249 777 ... 528 529
LuisHernndezYez

9 524 583 333 100 334 ... 743 468 531


10 217 427 585 218 843 ... 777 555
11 222 666 512 400 259 ... 438 637 879

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 643


const intDIM1=10;
const intDIM2=5;
const intDIM3=25;
const intDIM4=50;

typedefdouble tMatriz[DIM1][DIM2][DIM3][DIM4];

tMatriz matriz;
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]
}
LuisHernndezYez

}
}
}

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
const intDIAS=31;
const intSUCURSALES=4;
typedefdouble tVentaMes[DIAS][SUCURSALES];
typedefstruct {
tVentaMes ventas; anual tVentaAnual
anual[i] tMes
int dias;
anual[i].dias int
}tMes;
anual[i].ventas tVentaMes
LuisHernndezYez

anual[i].ventas[j][k] double
const intMESES=12;
typedeftMes tVentaAnual[MESES];
tVentaAnual anual;

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 645


const intDIAS =31;
const intSUCURSALES=4;
Clculo de las ventas typedefdouble
tVentaMes[DIAS][SUCURSALES];
de todo el ao: typedefstruct {
Para cada mes... tVentaMes ventas;
int dias;
Para cada da del mes... }tMes;

Para cada sucursal... const intMESES=12;


typedeftMes tVentaAnual[MESES];
Acumular las ventas 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];
LuisHernndezYez

}
}
}

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 646

boolencontrado=false; Primer valor > umbral


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

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

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

Algoritmosdeordenacin 651
Algoritmodeordenacinporinsercin 654
Ordenacindearraysporinsercin 665
Algoritmodeordenacinporinsercin
conintercambios 672
Clavesdeordenacin 680
Estabilidaddelaordenacin 688
Complejidadyeficiencia 692
Ordenacionesnaturales 694
Ordenacinporseleccindirecta 701
Mtododelaburbuja 716
Listasordenadas 722
Bsquedasenlistasordenadas 729
Bsquedabinaria 731
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin
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
0 1 2 3 4 5 6 7 8 9

Algoritmo de ordenacin
(de menor a mayor)

array
76.95 93.45 125.40 164.29 219.99 254.62 316.05 328.80 435.00 756.62
0 1 2 3 4 5 6 7 8 9

array[i]<=array[i+1]
LuisHernndezYez

Mostrar los datos en orden, facilitar las bsquedas, ...


Variadas formas de hacerlo (algoritmos)

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 652


Ordenacin de listas
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
LuisHernndezYez

Hay otros algoritmos de ordenacin mejores

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 653


LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 654


Algoritmo de ordenacin por insercin
Partimos de una lista vaca
Vamos insertando cada elemento en el lugar que le corresponda

6
1 Baraja de nueve cartas numeradas del 1 al 9
3
8
2
9
Las cartas estn desordenadas

4
7
LuisHernndezYez

Ordenaremos de menor a mayor (ascendente)


5
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 655

Algoritmo de ordenacin por insercin

6
1 Colocamos el primer elemento en la lista vaca
3
8
2
9
4
7
5 Lista ordenada:

5
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 656


Algoritmo de ordenacin por insercin

6
1 El 7 es mayor que todos los elementos de la lista
3
8 Lo insertamos al final
2
9
4
7
Lista ordenada:

5 7
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 657

Algoritmo de ordenacin por insercin

6
1 Primer elemento (5) mayor que el nuevo (4):
3
8 Desplazamos todos una posicin a la derecha
2
9
Insertamos el nuevo en la primera posicin

4 Hemos insertado el elemento en su lugar

Lista ordenada:

5 5
4 7 7
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 658


Algoritmo de ordenacin por insercin

6
1 9 es mayor que todos los elementos de la lista
3
8 Lo insertamos al final
2
9
Lista ordenada:

4 5 7 9
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 659

Algoritmo de ordenacin por insercin

6
1 Primer elemento (4) mayor que el nuevo (2):
3
8 Desplazamos todos una posicin a la derecha
2 Insertamos el nuevo en la primera posicin

Lista ordenada:

4 4
2 5 5
7 7
9 9
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 660


Algoritmo de ordenacin por insercin

6
1 El 9 es el primer elemento mayor que el nuevo (8):
3
8 Desplazamos desde ese hacia la derecha
Insertamos donde estaba el 9

Lista ordenada:

2 4 5 7 8
4 9 9
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 661

Algoritmo de ordenacin por insercin

6
1 Segundo elemento (4) mayor que el nuevo (3):
3 Desplazamos desde ese hacia la derecha
Insertamos donde estaba el 4

Lista ordenada:

2 3
4 4 4
5 5
7 7
8 8
9 9
LuisHernndezYez

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:

2 2
1 3 3
4 4
5 5
7 7
8 8
9 9
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 663

Algoritmo de ordenacin por insercin

6 El 7 es el primer elemento mayor que el nuevo (6):


Desplazamos desde ese hacia la derecha
Insertamos donde estaba el 7

LISTA ORDENADA !!!


Lista ordenada:

1 2 3 4 5 6
7 7
8 8
9 9
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 664


Ordenacin de arrays por insercin
El array contiene inicialmente la lista desordenada:
20 7 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

A medida que insertamos: dos zonas en el array


Parte ya ordenada y elementos por procesar

7 14 20 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

Parte ya ordenada Elementos por insertar


LuisHernndezYez

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 7 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

Desde el segundo elemento del array hasta el ltimo:


Localizar el primer elemento mayor en lo ya ordenado

20 7 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
LuisHernndezYez

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 7 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

nuevo 7

7 20 14 32 5 14 27 12 13 15
LuisHernndezYez

0 1 2 3 4 5 6 7 8 9

nuevo 7

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 667

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

}
lista[pos]=nuevo;
}

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 668


20 7 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

i 1 pos 0 nuevo 7

20 7 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

20 20 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

7 20 14 32 5 14 27 12 13 15
LuisHernndezYez

0 1 2 3 4 5 6 7 8 9

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 669

7 14 20 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

i 4 pos 0 nuevo 5

7 14 20 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

7 7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

5
LuisHernndezYez

7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 670


5 7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

i 5 pos 3 nuevo 14

5 7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

5 7 14 20 20 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9

14 20
LuisHernndezYez

5 7 14 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 671


LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 672


La insercin de cada elemento se puede realizar
con comparaciones e intercambios

Desde el segundo elemento hasta el ltimo:


Desde la posicin del nuevo elemento a insertar:
Mientras el anterior sea mayor, intercambiar

5 7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

5 7 14 20 14 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9
LuisHernndezYez

5 7 14 14 20 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 673

7 14 20 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

7 14 20 5 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

7 14 5 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

7 5 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9
LuisHernndezYez

5 7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 674


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
LuisHernndezYez

}
}

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 675

#include<iostream> insercion.cpp
usingnamespacestd;
#include<fstream>

const int N=100;


typedef inttArray[N];
typedefstruct{ //Listadelongitudvariable
tArray elementos;
int contador;
}tLista;

int main(){
tLista lista;
ifstream archivo;
LuisHernndezYez

int dato,pos,tmp;
lista.contador =0;
...

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 676


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

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


cout<<lista.elementos[i]<<"";
}
cout<<endl;...
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]<<"";
}
LuisHernndezYez

cout<<endl;
}
return 0;
}
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 678
Consideracin de implementacin
Operador relacional adecuado?
lista[pos 1] > o >= ? lista[pos]
Con >= se realizan intercambios intiles:

5 7 14 20 32 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

5 7 14 20 14 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9
LuisHernndezYez

5 7 14 14 20 32 27 12 13 15
0 1 2 3 4 5 6 7 8 9

Intercambio intil!

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 679


LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 680


Claves de ordenacin
Elementos que son estructuras con varios campos:
constintN=15;
typedefstruct {
intcodigo;
stringnombre;
doublesueldo;
} tDato;
typedeftDatotLista[N];
tListalista;

Clave de ordenacin:
LuisHernndezYez

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

Comparacin: campo concreto


Intercambio: elementos completos
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 682


Claves de ordenacin
Funcin para la comparacin:
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;
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 683

claves.cpp

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

int cont;
}tLista;
...

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 684


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

lista.cont++;
archivo>>dato.codigo;
}
archivo.close();...
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;
LuisHernndezYez

mostrar(lista);
}
return 0;
} ...
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 686
void mostrar(tLista lista){
for (int i=0;i<lista.cont;i++){
cout<<setw(10)
<<lista.datos[i].codigo
<<setw(20)
<<lista.datos[i].nombre
<<setw(12)
<<fixed
<<setprecision(2)
<<lista.datos[i].sueldo
<<endl;
}
}

bool operator>(tDato opIzq,tDato opDer){


LuisHernndezYez

return (opIzq.nombre >opDer.nombre);


}

Cambia a codigo o sueldo para ordenar por otros campos

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 687


LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 688


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
Sueldo 21112Domnguez90000
11111Durn120000
22222Fernndez120000
12345Gmez100000
Lista ordenada por Nombre 10000Hernndez150000
21112Jimnez100000
11111Prez90000
12345Snchez90000
LuisHernndezYez

10000Sergei100000
33333Tarazona120000
12345Turgano100000
11111Urpiano90000

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 689

Ordenamos ahora por el campo Codigo:

10000Sergei100000 10000Hernndez150000
10000Hernndez150000 10000Sergei100000
11111Urpiano 90000 11111Bentez 100000
11111Bentez 100000 11111Durn 120000
11111Prez 90000 11111Prez 90000
11111Durn 120000 11111Urpiano 90000
12345Snchez90000 12345lvarez120000
12345lvarez120000 12345Gmez100000
12345Turgano100000 12345Snchez90000
12345Gmez100000 12345Turgano100000
21112Domnguez90000 21112Domnguez90000
21112Jimnez100000 21112Jimnez100000
22222Fernndez120000 22222Fernndez120000
33333Tarazona120000 33333Tarazona120000

No estable: Estable:
LuisHernndezYez

Los nombres no mantienen Los nombres mantienen


sus posiciones relativas sus posiciones relativas

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 690


Ordenacin por insercin
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
10000Hernndez150000 11111Prez90000
10000Sergei100000 11111Urpiano90000
11111Bentez100000 12345Snchez90000
11111Durn120000 21112Domnguez90000
11111Prez90000 10000 Sergei100000
11111Urpiano90000 11111 Bentez100000
12345lvarez120000 12345 Gmez 100000
12345Gmez100000 12345 Turgano 100000
12345Snchez90000 21112 Jimnez100000
12345Turgano100000 11111Durn120000
LuisHernndezYez

21112Domnguez90000 12345lvarez120000
21112Jimnez100000 22222Fernndez120000
22222Fernndez120000 33333Tarazona120000
33333Tarazona120000 10000Hernndez150000

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 691


LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 692


Casos de estudio para los algoritmos de ordenacin
Lista inicialmente ordenada
5 7 12 13 14 14 15 20 27 32
0 1 2 3 4 5 6 7 8 9

Lista inicialmente ordenada al revs


32 27 20 15 14 14 13 12 7 5
0 1 2 3 4 5 6 7 8 9

Lista con disposicin inicial aleatoria


13 20 7 14 12 32 27 14 5 15
0 1 2 3 4 5 6 7 8 9
LuisHernndezYez

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
Versin con intercambios:
Trabaja mucho menos; basta una comparacin cada vez
Comportamiento natural
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 694


Eleccin de un algoritmo de ordenacin
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
LuisHernndezYez

Intercambios
Asumimos que tardan un tiempo similar

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 695

Clculo de la complejidad
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
}
LuisHernndezYez

}
Intercambios y comparaciones:
Tantos como ciclos realicen los correspondientes bucles

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 696


Clculo de la complejidad

... N 1 ciclos
for(int i=1;i<N;i++){
int pos=i; N variable de ciclos
while((pos>0)&&(lista[pos 1]>lista[pos])){
int tmp;
tmp=lista[pos];
lista[pos]=lista[pos 1];
lista[pos 1]=tmp;
pos;
}
LuisHernndezYez

}
Caso en el que el while se ejecuta ms: caso peor
Caso en el que se ejecuta menos: caso mejor

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 697

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
LuisHernndezYez

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)

Hay algoritmos de ordenacin mejores


LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 699

rdenes de complejidad
O(log N) < O(N) < O(N log N) < O(N2) < O(N3) ...

Nlog2 NN2

101
214
4216
8364
164256
3251024
6464096
LuisHernndezYez

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

Lista desordenada: 5 7 4 9 2 8 3 1 6

Lista ordenada:
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 702


Algoritmo de ordenacin por seleccin directa

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada: 5 7 4 9 2 8 3 6

Lista ordenada: 1
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 703

Algoritmo de ordenacin por seleccin directa

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada: 5 7 4 9 8 3 6

Lista ordenada: 1 2
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 704


Algoritmo de ordenacin por seleccin directa

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada: 5 7 4 9 8 6

Lista ordenada: 1 2 3
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 705

Algoritmo de ordenacin por seleccin directa

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada: 5 7 9 8 6

Lista ordenada: 1 2 3 4
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 706


Algoritmo de ordenacin por seleccin directa

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada: 7 9 8 6

Lista ordenada: 1 2 3 4 5
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 707

Algoritmo de ordenacin por seleccin directa

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada: 7 9 8

Lista ordenada: 1 2 3 4 5 6
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 708


Algoritmo de ordenacin por seleccin directa

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada: 9 8

Lista ordenada: 1 2 3 4 5 6 7
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 709

Algoritmo de ordenacin por seleccin directa

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada: 9

Lista ordenada: 1 2 3 4 5 6 7 8
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 710


Algoritmo de ordenacin por seleccin directa

Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

LISTA ORDENADA !!!

Lista ordenada: 1 2 3 4 5 6 7 8 9
LuisHernndezYez

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 m

20 7 14 32 5 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

im
Slo intercambiamos si no es la misma posicin
LuisHernndezYez

5 7 14 32 20 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 712


Ordenacin de un array por seleccin directa
i m

5 7 14 32 20 14 27 12 13 15
0 1 2 3 4 5 6 7 8 9

i m

5 7 12 32 20 14 27 14 13 15
0 1 2 3 4 5 6 7 8 9

i m
LuisHernndezYez

5 7 12 13 20 14 27 14 32 15
0 1 2 3 4 5 6 7 8 9

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 713

seleccion.cpp

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

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)
Mismo nmero de comparaciones en todos los casos
Complejidad: O(N2) Igual que el mtodo de insercin
Algo mejor (menos intercambios; uno en cada paso)
No es estable: intercambios a larga distancia
LuisHernndezYez

No se garantiza que se mantenga el mismo orden relativo original


Comportamiento no natural (trabaja siempre lo mismo)

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 715


LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 716


Algoritmo de ordenacin por el mtodo de la burbuja
Variacin del mtodo de seleccin directa
El elemento menor va ascendiendo hasta alcanzar su posicin

9 9 9 9 1
4 4 4 1 9
3 3 1 4 4
6 1 3 3 3
LuisHernndezYez

1 6 6 6 6

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 717

12 32 14 5 14 7
0 1 2 3 4 5

12 32 14 5 7 14
0 1 2 3 4 5

12 32 14 5 7 14
0 1 2 3 4 5

12 32 5 14 7 14
0 1 2 3 4 5

12 5 32 14 7 14
LuisHernndezYez

0 1 2 3 4 5

5 12 32 14 7 14
0 1 2 3 4 5

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 718


burbuja.cpp

Ordenacin de un array por el mtodo de la burbuja


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

lista[j 1]=tmp;
}
}
}

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 719

Algoritmo de ordenacin por el mtodo de la burbuja


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
La lista ya est ordenada
35121616
LuisHernndezYez

No hace falta seguir


12353535
50505050

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 720


burbuja2.cpp

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

i++;
}
} Esta variacin s tiene un comportamiento natural

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 721


LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 722


Gestin de listas ordenadas
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
LuisHernndezYez

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;

typedef tRegistro tArray[N];

typedef struct {
tArray registros;
int cont;
}tLista;
LuisHernndezYez

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);
voidguardar(tLista lista);
LuisHernndezYez

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;
}
booloperator<(tRegistro opIzq,tRegistro opDer){
return opIzq.nombre <opDer.nombre;
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 726


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

lista.registros[i]=registro;
lista.cont++;
}
}

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 727


LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 728


Bsqueda de un elemento en una secuencia
No ordenada: recorremos hasta encontrarlo o al final
Ordenada: recorremos hasta encontrarlo o mayor / al final

5 7 12 13 14 14 15 20 27 32
0 1 2 3 4 5 6 7 8 9

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
LuisHernndezYez

Se encuentra uno mayor


Mientras no al final y el valor sea menor que el buscado

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
LuisHernndezYez

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
Buscamos el 12 Elemento mitad
5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9

5 7 12 14 14 15 18 20 27 32
LuisHernndezYez

0 1 2 3 4 5 6 7 8 9

5 7 12
14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9

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

5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9

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
LuisHernndezYez

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

5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9

12 <lista[mitad] fin=mitad 1
ini mitad fin

5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9

12 >lista[mitad] ini=mitad+1
ini fin
LuisHernndezYez

5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9

mitad Encontrado!
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 734
Si el elemento no est, nos quedamos sin sublista: ini>fin
Para el 13: mitad
ini fin

5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9

13 >lista[mitad] ini=mitad+1
mitad
ini
fin

5 7 12 14 14 15 18 20 27 32
0 1 2 3 4 5 6 7 8 9
LuisHernndezYez

13 <lista[mitad] fin=mitad 1 2
ini>fin !!! No hay dnde seguir buscando No est

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 735

Implementacin constintN=10;
typedefinttLista[N];
int buscado; tLista lista;
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{
LuisHernndezYez

ini=mitad+1;
}
}//Sisehaencontrado,esten[mitad]

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 736


#include<iostream> binaria.cpp
usingnamespacestd;
#include<fstream>

constint N=100;
typedef int tArray[N];
typedef struct {
tArray elementos;
int cont;
}tLista;

int buscar(tLista lista,int buscado);

int main(){
tLista lista;
ifstream archivo;
LuisHernndezYez

int dato;
lista.cont =0;
archivo.open("ordenados.txt");//Existeyescorrecto
archivo>>dato;
...
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 {
LuisHernndezYez

cout<<"Noencontrado!"<<endl;
}
return 0;
}...

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 738


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

pos=mitad;
}
return pos;
}

Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 739

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
LuisHernndezYez

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

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

Ordenacinporintercambio 744
Mezcladedoslistasordenadas 747
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo)
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo) Pgina 744

Algoritmo de ordenacin por intercambio


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 7 12 32 20 14 27 5 13 15
0 1 2 3 4 5 6 7 8 9

7 14 12 32 20 14 27 5 13 15
0 1 2 3 4 5 6 7 8 9
LuisHernndezYez

5 14 12 32 20 14 27 7 13 15
0 1 2 3 4 5 6 7 8 9

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo) Pgina 745


intercambio.cpp

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

}
Igual nmero de comparaciones, muchos ms intercambios
No es estable
Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo) Pgina 746
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo) Pgina 747


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
Lo copiamos en la lista resultado y avanzamos su ndice una posicin
LuisHernndezYez

Copiamos en la lista resultado los que queden en la lista no acabada

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo) Pgina 748

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

}
...

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo) Pgina 749


mezcla1.cpp

//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++;
}
}
}
LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo) Pgina 750

Mezcla de dos listas ordenadas en archivos


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

while ((dato1!=1)&&(dato2!=1)){
//Mientrasquedealgoenambosarchivos
...

Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo) Pgina 751


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

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

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


Facultad de Informtica
Universidad Complutense

Programasmultiarchivoycompilacinseparada 757
Interfazfrenteaimplementacin 762
Usodemdulosdebiblioteca 768
Ejemplo:GestindeunalistaordenadaI 770
Compilacindeprogramasmultiarchivo 778
Elpreprocesador 780
Cadacosaensumdulo 782
Ejemplo:GestindeunalistaordenadaII 784
Elproblemadelasinclusionesmltiples 789
Compilacincondicional 794
Proteccinfrenteainclusionesmltiples 795
Ejemplo:GestindeunalistaordenadaIII 796
Implementacionesalternativas 804
Espaciosdenombres 808
Implementacionesalternativas 817
LuisHernndezYez

Calidadyreutilizacindelsoftware 827

Fundamentosdelaprogramacin:Programacinmodular
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, ...)
Lista Principal Clculos Archivos
constintN=10; intmain(){ doublemean(tArray lista); boolcargar(tArray &lista,
typedefdoubletArray[N]; tArray lista; stringnombre);
typedefstruct{ boolok; doublemin(tArray lists);
tArray elem; init(lista); boolguardar(tArray lista,
intcont; cargar(lista,"bd.txt"); doublemax(tArray lista); stringnombre);
}tArray; sort(lista);
doubledato; doubledesv(tArray lista); boolmezclar(stringarch1,
voidinit(tArray &lista); cout<<"Dato:"; stringarch2);
cin>>dato; intminIndex(tArray lista);
voidinsert(tArray &lista, insert(lista,dato,ok); intsize(stringnombre);
doubleelem,bool&ok); cout<<min(lista)<<endl; intmaxIndex(tArray lista);
cout<<max(lista)<<endl; boolexportar(stringnombre);
voidremove(tArray &lista, cout<<sum(lista)<<endl; doublesum(tArray lista);
intpos,bool&ok); guardar(lista,"bd.txt");
...
return0;
}
LuisHernndezYez

Ejecutable
Fundamentosdelaprogramacin:Programacinmodular Pgina 758
Compilacin separada
Cada mdulo se compila a cdigo objeto de forma independiente
Lista lista.obj
constintN=10; 00101110101011001010010010101
typedefdoubletArray[N]; 00101010010101011111010101000
typedefstruct{ 10100101010101010010101010101
tArray elem; 01100101010101010101010101001
intcont; 01010101010100000101010101101
}tArray; 01001010101010101000010101011
11001010101010111100110010101
voidinit(tArray &lista);

voidinsert(tArray &lista,
01101010101010010010101001111
00101010101001010100101010010
10100101010100101000010011110
Archivos archivos.obj
doubleelem,bool&ok); 10010101011001010101001010100
10101010101010010101001010101 11101010110010100100101010010
boolcargar(tArray &lista,
voidremove(tArray &lista, 01000010101011100101010010100 10100101010111110101010001010
stringnombre);
intpos,bool&ok); 01110101011101001101010100101 01010101010100101010101010110
... 01011111110101011001101010111 01010101010101010101010010101
boolguardar(tArray lista,
00001001010100101010101010110 01010101000001010101011010100
stringnombre);
10101010101010000101010111100
boolmezclar(stringarch1, 10101010101111001100101010110
stringarch2); 10101010100100101010011110010

Clculos calculos.obj intsize(stringnombre);


10101010010101001010100101010
01010101001010000100111101001
01010110010101010010101001010
boolexportar(stringnombre); 10101010100101010010101010100
doublemean(tArray lista); 01011001010010010101001010100 00101010111001010100101000111
10101011111010101000101001010 01010111010011010101001010101
doublemin(tArray lists); 10101010010101010101011001010 11111101010110011010101110000
10101010101010101001010101010 10010101001010101010101101111
doublemax(tArray lista); 10100000101010101101010010101
01010101000010101011110010101
LuisHernndezYez

doubledesv(tArray lista); 01010111100110010101011010101


01010010010101001111001010101
intminIndex(tArray lista); 01001010100101010010101001010
10100101000010011110100101010
intmaxIndex(tArray lista); 11001010101001010100101010101
01010010101001010101010000101
doublesum(tArray lista); 01011100101010010100011101010
11101001101010100101010111111
10101011001101010111000010010
10100101010101010110001111010

Fundamentosdelaprogramacin:Programacinmodular Pgina 759

Compilacin separada
Al compilar el programa principal, se adjuntan los mdulos compilados
Principal
Mdulos del programa intmain(){
tArray lista;
Bibliotecas del sistema
boolok;
init(lista);
cargar(lista,"bd.txt");
sort(lista);
lista.obj doubledato; iostream.obj
cout<<"Dato:";
cin>>dato;
insert(lista,dato,ok);
calculos.obj cout<<min(lista)<<endl;
cout<<max(lista)<<endl;
fstream.obj
cout<<sum(lista)<<endl;
guardar(lista,"bd.txt");

archivos.obj ... }
return0; math.obj ...
LuisHernndezYez

Ejecutable

Fundamentosdelaprogramacin:Programacinmodular Pgina 760


Compilacin separada
Slo los archivos fuente modificados necesitan ser recompilados!
Principal

lista.cpp main.cpp

COMPILACIN

lista.obj iostream.obj

calculos.obj
fstream.obj

archivos.obj
main.obj
math.obj
... ...
ENLACE
LuisHernndezYez

Ejecutable
Fundamentosdelaprogramacin:Programacinmodular Pgina 761
LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 762


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
LuisHernndezYez

Etctera
+ Implementacin de los subprogramas (cmo se hace)

Fundamentosdelaprogramacin:Programacinmodular Pgina 763

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
LuisHernndezYez

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 lista.cpp
constintN=10; #include"lista.h"
Mdulo
typedefdoubletArray[N];
typedefstruct{
tArray elem;
voidinit(tArray &lista){
lista.cont =0;
Unidad
intcont;
}tArray;
}

voidinsert(tArray &lista,
Biblioteca
voidinit(tArray &lista); doubleelem,bool&ok){
if(lista.cont ==N){
voidinsert(tArray &lista, okfalse;
doubleelem,bool&ok); }
else{
voidremove(tArray &lista, ...
intpos,bool&ok);
...

Si otro mdulo quiere usar algo de esa biblioteca:


Debe incluir el archivo de cabecera
LuisHernndezYez

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;

Interfaz
typedefdoubletArray[N];
typedefstruct{
tArray elem;
intcont;
}tArray;

Archivo de cabecera (.h): todo lo que necesita voidinit(tArray &lista);

voidinsert(tArray &lista,

conocer otro mdulo (o programa principal) doubleelem,bool&ok);

voidremove(tArray &lista,

que quiera utilizar sus servicios (subprogramas)


intpos,bool&ok);
...

La directiva #include aade las declaraciones del archivo


de cabecera en el cdigo del mdulo (preprocesamiento):
main.cpp main.cpp
Preprocesador
#include"lista.h" constintN=10;
typedefdoubletArray[N];
... typedefstruct{
tArray elem;
intcont;

Todo lo que se necesita saber para


}tArray;
LuisHernndezYez

voidinit(tArray &lista);

comprobar si el cdigo de main.cpp voidinsert(tArray &lista,doubleelem,


bool&ok);

hace un uso correcto de la lista voidremove(tArray &lista,intpos,


bool&ok);
(declaraciones y llamadas) ...

Fundamentosdelaprogramacin:Programacinmodular Pgina 766


Creacin de mdulos de biblioteca lista.cpp

Implementacin #include"lista.h"

voidinit(tArray &lista){
lista.cont =0;

Compilar el mdulo significa compilar


}

voidinsert(tArray &lista,
doubleelem,bool&ok){

su archivo de implementacin (.cpp)


if(lista.cont ==N){
okfalse;
}
else{
...

Tambin necesita conocer sus propias declaraciones:


lista.cpp
#include"lista.h" lista.obj
...
00101110101011001010010010101
00101010010101011111010101000

Al compilar el mdulo se genera el cdigo objeto


10100101010101010010101010101
01100101010101010101010101001
01010101010100000101010101101
01001010101010101000010101011
11001010101010111100110010101

Si no se modifica no hay necesidad de recompilar


01101010101010010010101001111
00101010101001010100101010010
10100101010100101000010011110
10010101011001010101001010100
10101010101010010101001010101

Cdigo que usa el mdulo:


LuisHernndezYez

01000010101011100101010010100
01110101011101001101010100101
01011111110101011001101010111
00001001010100101010101010110

Necesita slo el archivo de cabecera para compilar


Se adjunta el cdigo objeto del mdulo durante el enlace
Fundamentosdelaprogramacin:Programacinmodular Pgina 767
LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 768


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

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


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

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

Cada prototipo, con un comentario que explique su utilidad/uso


LuisHernndezYez

(Aqu se omiten por cuestin de espacio)

Fundamentosdelaprogramacin:Programacinmodular Pgina 771

Implementacin lista.cpp

Mdulo: Gestin de una lista ordenada I


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

cout<<"Introduceelsueldo:";
cin>>registro.sueldo;
return registro;
}...

Fundamentosdelaprogramacin:Programacinmodular Pgina772
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];
}
LuisHernndezYez

lista.registros[i]=registro;
lista.cont++;
}
}...

Fundamentosdelaprogramacin:Programacinmodular Pgina773

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

...

Fundamentosdelaprogramacin:Programacinmodular Pgina774
Programaprincipal bd.cpp

Mdulo: Gestin de una lista ordenada I


#include<iostream>
usingnamespacestd;
#include"lista.h"

intmenu();

int main(){
tLista lista;
bool ok;
int op,pos;
cargar(lista,ok);
if (!ok){
cout<<"Nosehapodidoabrirelarchivo!"<<endl;
}
LuisHernndezYez

else {
do {
mostrar(lista);
op =menu();...

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

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

cout<<"0 Salir" <<endl;


int op;
do {
...

Fundamentosdelaprogramacin:Programacinmodular Pgina777
LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 778


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
Archivos de cabecera e implementacin en grupos distintos:

A los archivos de cabecera


los llama de encabezado
LuisHernndezYez

Con Depurar>Generarsolucin
se compilan todos los .cpp

Fundamentosdelaprogramacin:Programacinmodular Pgina 779


LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 780


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"lista.h"
#include<string> #include<string>
usingnamespacestd; intmenu(); usingnamespacestd;

constintN=100; ... constintN=100;

typedefstruct{ typedefstruct{
intcodigo; intcodigo;
stringnombre; stringnombre;
doublesueldo; doublesueldo;
}tRegistro; }tRegistro;

typedeftRegistro typedeftRegistro
tArray[N]; tArray[N];
LuisHernndezYez

typedefstruct{ typedefstruct{
tArray registros; tArray registros;
intcont; intcont;
}tLista; }tLista;
... ...

intmenu();
...

Fundamentosdelaprogramacin:Programacinmodular Pgina 781


LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 782


Distribuir la funcionalidad del programa en mdulos
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; Lista de registros:
string nombre;
Estructura tRegistro
double sueldo;
}tRegistro; Estructura tLista
typedef tRegistro tArray[N]; (contiene tRegistro)
LuisHernndezYez

typedef struct {
Cada estructura, en su mdulo
tArray registros;
int cont;
}tLista;

Fundamentosdelaprogramacin:Programacinmodular Pgina 783

Cabecera registro.h

Gestin de una lista ordenada II


#include<string>
usingnamespacestd;

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

Fundamentosdelaprogramacin:Programacinmodular Pgina 784


Implementacin registro.cpp

Gestin de una lista ordenada II


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

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"

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

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


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

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

int main(){
tLista lista;
No intentes compilar este ejemplo!
bool ok; Tiene errores
int op,pos;

cargar(lista,ok);
if (!ok){
cout<<"Nosepudoabrirelarchivo!"<<endl;
}
LuisHernndezYez

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

...
registro.h #include"registro.h"
#include"lista2.h"
#include<string>
...
...

registro.cpp

...
#include"registro.h"
... lista2.h

...
#include"registro.h"
...

lista2.cpp
LuisHernndezYez

...
Incluye... #include"lista2.h"
...

Fundamentosdelaprogramacin:Programacinmodular Pgina 790


Gestin de una lista ordenada II
Preprocesamiento de #include: #include<string>
#include<iostream> usingnamespacestd;
usingnamespacestd;
typedef struct {
#include"registro.h" ...
}tRegistro;
#include"lista2.h" ...

intmenu(); #include<string>
#include<string> usingnamespacestd;
... usingnamespacestd;
#include "registro.h" typedef struct {
...
const int N=100; }tRegistro;
typedef tRegistro tArray[N]; ...
typedef struct {
LuisHernndezYez

tArray registros;
int cont;
}tLista;
...

Fundamentosdelaprogramacin:Programacinmodular Pgina 791

Gestin de una lista ordenada II


Preprocesamiento de #include:
Sustituido
#include<iostream>
usingnamespacestd;
#include<string>
#include<string> usingnamespacestd;
usingnamespacestd; #include<string>
usingnamespacestd;
typedef struct {
... typedef struct {
}tRegistro; ...
... }tRegistro;
...
#include"lista2.h"
const int N=100;
intmenu(); typedef tRegistro tArray[N];
typedef struct {
LuisHernndezYez

... 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];
#include<string> typedef struct {
usingnamespacestd; tArray registros;
int cont;
typedef struct { }tLista;
... ...
}tRegistro;
... intmenu();

#include<string> ...
usingnamespacestd;
#include<string>
usingnamespacestd;

typedef struct {
Identificador duplicado!
LuisHernndezYez

...
}tRegistro;
...

Fundamentosdelaprogramacin:Programacinmodular Pgina 793

Compilacin condicional
Directivas #ifdef, #ifndef, #else y #endif
Se usan en conjuncin con la directiva #define
#define X #define X
#ifdef X #ifndef X
...//Cdigoif ...//Cdigoif
[#else [#else
...//Cdigoelse ...//Cdigoelse
] ]
#endif #endif
La directiva #define define un smbolo (identificador)
Izquierda: se compilar el Cdigo if y no el Cdigo else
LuisHernndezYez

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:
#ifndef X
#define X El smbolo X debe ser nico
...//Mdulo para cada mdulo de la aplicacin
#endif
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
LuisHernndezYez

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;

typedef struct {
int codigo;
string nombre;
double sueldo;
}tRegistro;

tRegistro nuevo();
LuisHernndezYez

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


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

booloperator>(tRegistro opIzq,tRegistro opDer){


returnopIzq.nombre >opDer.nombre;
}...

Fundamentosdelaprogramacin:Programacinmodular Pgina 797

Cabecera listafin.h

Gestin de una lista ordenada III


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

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


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

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

int main(){
tLista lista;
bool ok; Ahora ya puedes compilarlo!
int op,pos;

cargar(lista,ok);
if (!ok){
cout<<"Nosepudo abrir elarchivo!" <<endl;
}
LuisHernndezYez

else {
do {
mostrar(lista);
op=menu();
...
Fundamentosdelaprogramacin:Programacinmodular Pgina 800
Gestin de una lista ordenada III
Preprocesamiento de #include en bdfin.cpp:
#include<iostream> #ifndef registrofin_h
usingnamespacestd;
#define registrofin_h
#include<string>
#include"registrofin.h" usingnamespacestd;

#include"listafin.h" typedef struct {


...
intmenu(); }tRegistro;
...
...

registrofin_h no se ha definido todava


LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 801

Gestin de una lista ordenada III


Preprocesamiento de #include en bdfin.cpp:
#include<iostream>
usingnamespacestd;
#ifndef listafin_h
#define listafin_h
#define registrofin_h #include<string>
#include<string> usingnamespacestd;
usingnamespacestd; #include "registrofin.h"

typedef struct { const int N=100;


... typedef tRegistro tArray[N];
typedef struct {
}tRegistro;
tArray registros;
... int cont;
}tLista;
#include"listafin.h" ...
LuisHernndezYez

intmenu();

... listafin_h no se ha definido todava

Fundamentosdelaprogramacin:Programacinmodular Pgina 802


Gestin de una lista ordenada III
Preprocesamiento de #include en bdfin.cpp:
#include<iostream>
usingnamespacestd;
#define registrofin_h
#include<string>
usingnamespacestd;

typedef struct { #ifndef registrofin_h


... #define registrofin_h
}tRegistro; #include<string>
... usingnamespacestd;

#define listafin_h typedef struct {


#include<string> ...
usingnamespacestd; }tRegistro;
LuisHernndezYez

#include "registrofin.h" ...

...
intmenu(); registrofin_h ya est definido!
...

Fundamentosdelaprogramacin:Programacinmodular Pgina 803


LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 804


Misma interfaz, implementacin alternativa
#include<string> lista.h
usingnamespacestd;
#include "registrofin.h"

const int N=100;


typedef tRegistro tArray[N];
typedef struct {
tArray registros;
Lista int cont; Lista
}tLista;
ordenada no ordenada
void insertar(tLista&lista,tRegistro registro,bool &ok);

void insertar(tLista&lista,tRegistro registro,bool &ok){


ok=true;
if (lista.cont ==N){ void insertar(tLista&lista,tRegistro registro,bool &ok){
ok=false;//Lista llena ok=true;
} if (lista.cont ==N){
else { ok=false;//Listallena
int i =0; }
else {
while((i<lista.cont)&&(lista.registros[i]<registro)){
LuisHernndezYez

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;
listaORD.cpp: Lista ordenada if (lista.cont ==N){
ok=false;//Listallena
...
}
#include "lista.h"
else {
lista.registros[lista.cont]=registro;
void insertar(tLista&lista,tRegistro registro,bool &ok){
ok=true; lista.cont++;
if (lista.cont ==N){ }
ok=false;//Lista llena }
} ...
else {
int i=0;
while((i<lista.cont)&&(lista.registros[i]<registro)){
i++;
}
//Insertamos enlaposicin i
LuisHernndezYez

for (intj=lista.cont;j>i;j){
//Desplazamos aladerecha
lista.registros[j]=lista.registros[j 1];
}
lista.registros[i]=registro;
...

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...
Incluye la implementacin de la lista sin ordenacin
LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 807


LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 808


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
}
Por ejemplo:
namespace miEspacio {
int i;
double d;
LuisHernndezYez

}
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
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 { namespace segundo {
int x=5; double x=3.1416;
LuisHernndezYez

} }
Ahora se distingue entre primero::x y segundo::x

Fundamentosdelaprogramacin:Programacinmodular Pgina 810


using
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;
double y=2.7183; 10
} 3.1416
int main(){
using primero::x;
using segundo::y;
cout<<x<<endl;//xesprimero::x
LuisHernndezYez

cout<<y<<endl;//yessegundo::y
cout<<primero::y<<endl;//espacioexplcito
cout<<segundo::x<<endl;//espacioexplcito
return 0;
}
Fundamentosdelaprogramacin:Programacinmodular Pgina 811

usingnamespace
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
namespace segundo{ slo tiene efecto 3.1416
double x=3.1416; en el bloque
double y=2.7183; en que se encuentra 2.7183
}
int main(){
usingnamespace primero;
cout<<x<<endl;//xesprimero::x
cout<<y<<endl;//yesprimero::y
LuisHernndezYez

cout<<segundo::x<<endl;//espacioexplcito
cout<<segundo::y<<endl;//espacioexplcito
return 0;
}

Fundamentosdelaprogramacin:Programacinmodular Pgina 812


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

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


//...
}

voidord::eliminar(tLista&lista,intpos,bool &ok){
//...
}

intord::buscar(tLista lista,stringnombre){
//...
LuisHernndezYez

...

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"

int menu();

int main(){
ord::tLista lista;
boolok;
ord::cargar(lista,ok);
if (!ok){
cout<<"Nosepudoabrirelarchivo!"<<endl;
}
LuisHernndezYez

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;

int menu();

int main(){
tLista lista;
bool ok;
cargar(lista,ok);
if (!ok){
cout<<"Nosepudoabrirelarchivo!"<<endl;
LuisHernndezYez

}
else {
mostrar(lista);
...

Fundamentosdelaprogramacin:Programacinmodular Pgina 816


Implementaciones alternativas
Distintos espacios de nombres para distintas implementaciones
Lista ordenada o lista desordenada?
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];
...
LuisHernndezYez

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;

typedef tRegistro tArray[N];


typedef struct {
tArray registros;
int cont;
}tLista;
LuisHernndezYez

void mostrar(consttLista&lista);
void eliminar(tLista&lista,int pos,bool &ok);//pos =1..N

...

Fundamentosdelaprogramacin:Programacinmodular Pgina 818


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
LuisHernndezYez

#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){//...
}

void mostrar(const tLista&lista){//...


}

//IMPLEMENTACINDELOSSUBPROGRAMASDELESPACIODENOMBRESord
void ord::insertar(tLista&lista,tRegistro registro,bool &ok){
ok=true;
if (lista.cont ==N){
ok=false;//Listallena
}
LuisHernndezYez

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

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

}
else {
ini=mitad+1;
}
}...

Fundamentosdelaprogramacin:Programacinmodular Pgina 821

if (encontrado){
mitad++;
}
else {
mitad=1;
}
return mitad;
}

void ord::cargar(tLista&lista,bool &ok){//...


}

void ord::guardar(tLista lista){//...


}
...
LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 822


//IMPLEMENTACINDELOSSUBPROGRAMASDELESPACIODENOMBRESdes

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

}
else {
pos++;
}
}...

Fundamentosdelaprogramacin:Programacinmodular Pgina 823

if (encontrado){
pos++;
}
else {
pos=1;
}
return pos;
}

void des::cargar(tLista&lista,bool &ok){//...


}

void des::guardar(tLista lista){//...


}
LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 824


bdEN.cpp

Programa principal
#include<iostream>
usingnamespacestd;
#include"registrofin.h"
#include"listaEN.h"
usingnamespaceord;

int menu();

int main(){
tLista lista;
bool ok;
...
tRegistro registro=nuevo();
insertar(lista,registro,ok);
if (!ok){
LuisHernndezYez

...

Fundamentosdelaprogramacin:Programacinmodular Pgina 825

bdEN.cpp

Programa principal
#include<iostream>
usingnamespacestd;
#include"registrofin.h"
#include"listaEN.h"
usingnamespacedes;

int menu();

int main(){
tLista lista;
bool ok;
...
tRegistro registro=nuevo();
insertar(lista,registro,ok);
if (!ok){
LuisHernndezYez

...

Fundamentosdelaprogramacin:Programacinmodular Pgina 826


LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 827

Software de calidad
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
LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular Pgina 828


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

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

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
LuisHernndezYez

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

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> string nombre;


#include<string> double precio;
usingnamespacestd; int unidades;
}tProducto;
const int NCLI=100;
const int NPROD=200; typedef struct {
const int NVENTAS=3000; tProducto productos[NPROD];
int cont;
typedef struct { }tListaProductos;
intid_cli;
string nif; typedef struct {
string nombre; int id;
string telefono; int id_prod;
}tCliente; int id_cli;
int unidades;
typedef struct { }tVenta;
tCliente clientes[NCLI];
int cont; typedef struct {
}tListaClientes; tVenta ventas[NVENTAS];
LuisHernndezYez

int cont;
typedef struct{ }tListaVentas;
int id_prod;
string codigo; ...

Fundamentosdelaprogramacin:Ejemplodemodularizacin Pgina 833


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

voidbuscar(const tListaProductos &lista,stringcodigo,tProducto &producto,


bool &ok);
voideliminar(tListaProductos &lista,stringcodigo,bool &ok);
...

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

intmenu();

intmain(){
...

Fundamentosdelaprogramacin:Ejemplodemodularizacin Pgina 835


#include<iostream> string nombre;
#include<string> double precio;
usingnamespacestd; int unidades;
}tProducto;
const int NCLI=100; Lista de productos
const int NPROD=200; typedef struct {
const int NVENTAS=3000; tProducto productos[NPROD];
int cont;
typedef struct { Cliente }tListaProductos;
intid_cli;
string nif; typedef struct { Venta
string nombre; int id;
string telefono; int id_prod;
}tCliente; int id_cli;
Lista de clientes int unidades;
typedef struct { }tVenta;
Lista de ventas
tCliente clientes[NCLI];
int cont; typedef struct {
}tListaClientes; tVenta ventas[NVENTAS];
LuisHernndezYez

int cont;
typedef struct{ Producto }tListaVentas;
int id_prod;
string codigo; ...

Fundamentosdelaprogramacin:Ejemplodemodularizacin Pgina 836

tCliente nuevoCliente(); Cliente


bool valida(tCliente cliente);//Funcininterna
bool operator<(tCliente opIzq,tCliente opDer);//PorNIF
voidmostrar(tCliente cliente); Lista de clientes
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
booloperator<(tProducto opIzq,tProducto opDer);//Porcdigo
LuisHernndezYez

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, Venta
const tListaProductos &productos);
...
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);
voidstock(const tListaVentas &ventas,consttListaClientes &clientes,
consttListaProductos &productos);
intmenu();
LuisHernndezYez

intmain(){
...

Fundamentosdelaprogramacin:Ejemplodemodularizacin Pgina 839


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

Implementacin de los subprogramas en el .cpp

Fundamentosdelaprogramacin:Ejemplodemodularizacin Pgina 840

Ventas
main.cpp

Cliente Lista de clientes Venta Lista de ventas


cliente.h listaclientes.h venta.h listaventas.h
cliente.cpp listaclientes.cpp venta.cpp listaventas.cpp

Producto Lista de productos


producto.h listaproductos.h
LuisHernndezYez

producto.cpp listaproductos.cpp

Fundamentosdelaprogramacin:Ejemplodemodularizacin Pgina 841


Inclusiones (adems de otras bibliotecas del sistema)
typedef struct {
intid_cli;
string nif;
string nombre; cliente.h string
string telefono;
}tCliente;

const int NCLI=100;

typedef struct { listaclientes.h cliente.h


tCliente clientes[NCLI];
int cont; string
}tListaClientes;
LuisHernndezYez

voidbuscar(const tListaClientes &lista,stringnif,tCliente


&cliente,bool &ok);

Fundamentosdelaprogramacin:Ejemplodemodularizacin Pgina 842

typedef struct{
int id_prod;
string codigo;
string nombre; producto.h string
double precio;
int unidades;
}tProducto;

const int NPROD=200;


listaproductos.h producto.h
typedef struct {
tProducto productos[NPROD]; string
int cont;
}tListaProductos;
LuisHernndezYez

voidbuscar(const tListaProductos &lista,stringcodigo,tProducto


&producto,bool &ok);

Fundamentosdelaprogramacin:Ejemplodemodularizacin Pgina 843


typedef struct {
int id;
int id_prod; venta.h listaclientes.h
int id_cli;
int unidades; listaproductos.h
}tVenta;

voidmostrar(tVenta venta,consttListaClientes &clientes,


const tListaProductos &productos);

const int NVENTAS =3000;


listaventas.h venta.h
typedef struct {
tVenta ventas[NVENTAS]; listaclientes.h
int cont;
}tListaVentas; listaproductos.h
LuisHernndezYez

doubletotalVentas(const tListaVentas &ventas,stringnif,


consttListaClientes &clientes,
consttListaProductos &productos);

Fundamentosdelaprogramacin:Ejemplodemodularizacin Pgina 844

#ifndef cliente_h
#definecliente_h

#include<string>
usingnamespacestd;

typedefstruct {
int id_cli;
string nif;
string nombre;
string telefono;
}tCliente;

tCliente nuevoCliente();
bool operator<(tCliente opIzq,tCliente opDer);//PorNIF
LuisHernndezYez

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

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


Facultad de Informtica
Universidad Complutense

Direccionesdememoriaypunteros 849
Operadoresdepunteros 854
Punterosydireccionesvlidas 864
Punterosnoinicializados 866
Unvalorseguro:NULL 867
Copiaycomparacindepunteros 868
Tipospuntero 873
Punterosaestructuras 875
Punterosaconstantesypunterosconstantes 877
Punterosypasodeparmetros 879
Punterosyarrays 883
Memoriaydatosdelprograma 886
Memoriadinmica 891
Punterosydatosdinmicos 895
Gestindelamemoria 907
LuisHernndezYez

Errorescomunes 911
Arraysdedatosdinmicos 916
Arraysdinmicos 928

Fundamentosdelaprogramacin:Punterosymemoriadinmica
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 849

Los datos en la memoria


Todo dato se almacena en memoria:
Varios bytes a partir de una direccin 0F03:1A37 ...
i 0F03:1A38 00000000
int i=5; 0F03:1A39 00000000
0F03:1A3A 00000000
Direccin base
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
LuisHernndezYez

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
...
Indireccin:
i 0F03:1A38 00
Acceso indirecto a un dato
0F03:1A39 00
0F03:1A3A 00 punt punt apunta a i
0F03:1A3B 05
... i 5
punt 0F07:0417 0F
0F07:0418 03
LuisHernndezYez

0F07:0419 1A De qu tipo es el dato apuntado?


0F07:041A 38 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
int*punt;//punt inicialmentecontieneunadireccin
//quenoesvlida(noapuntaanada)
LuisHernndezYez

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)
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)
Para qu sirven los punteros?
Para implementar el paso de parmetros por referencia
LuisHernndezYez

Para manejar datos dinmicos


(Datos que se crean y destruyen durante la ejecucin)
Para implementar los arrays
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 853
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 854


&
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; i
punt=&i;//puntcontieneladireccindei
Ahora punt ya contiene una direccin de memoria vlida
LuisHernndezYez

punt apunta a (contiene la direccin de) la variable i (int)

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 855

&
Obtener la direccin de memoria de ...
...

i 0F03:1A38
int i,j;
0F03:1A39
... 0F03:1A3A
int*punt; 0F03:1A3B

j 0F03:1A3C

0F03:1A3D

0F03:1A3E

0F03:1A3F

...

punt 0F07:0417
LuisHernndezYez

0F07:0418
0F07:0419
0F07:041A

...

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 856


&
Obtener la direccin de memoria de ...
...

i 0F03:1A38 00
int i,j;
0F03:1A39 00
... 0F03:1A3A 00
int*punt; 0F03:1A3B 05

... j 0F03:1A3C

0F03:1A3D
i=5;
0F03:1A3E

0F03:1A3F

...

punt 0F07:0417
LuisHernndezYez

0F07:0418
0F07:0419
i 5
0F07:041A

...

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 857

&
Obtener la direccin de memoria de ...
...

i 0F03:1A38 00
int i,j;
0F03:1A39 00
... 0F03:1A3A 00
int*punt; 0F03:1A3B 05

... j 0F03:1A3C

0F03:1A3D
i=5;
0F03:1A3E
punt=&i;
0F03:1A3F

...

punt punt 0F07:0417 0F


LuisHernndezYez

0F07:0418 03

i 0F07:0419 1A
5
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


*punt accede al contenido de esa variable i
Acceso indirecto al valor de i
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 859

*
Obtener lo que hay en la direccin ...
...

i 0F03:1A38 00
int i,j;
0F03:1A39 00
... 0F03:1A3A 00
int *punt; 0F03:1A3B 05

... j 0F03:1A3C

0F03:1A3D
i=5;
0F03:1A3E
punt=&i;
0F03:1A3F
j=*punt; ...

punt 0F07:0417 0F
LuisHernndezYez

0F07:0418 03
0F07:0419 1A
punt:
0F07:041A 38
...

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 860


*
Obtener lo que hay en la direccin ...
...

i 0F03:1A38 00
int i,j;
0F03:1A39 00
... 0F03:1A3A 00
Direccionamiento
int *punt; indirecto 0F03:1A3B 05

... (indireccin) j 0F03:1A3C


Seaccedealdatoi 0F03:1A3D
i=5;
deformaindirecta 0F03:1A3E
punt=&i;
0F03:1A3F
j=*punt; ...

punt 0F07:0417 0F
LuisHernndezYez

0F07:0418 03
0F07:0419 1A
*punt:
0F07:041A 38
...

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 861

*
Obtener lo que hay en la direccin ...
...

i 0F03:1A38 00
int i,j;
0F03:1A39 00
... 0F03:1A3A 00
int *punt; 0F03:1A3B 05

... j 0F03:1A3C 00
0F03:1A3D 00
i=5;
0F03:1A3E 00
punt=&i;
0F03:1A3F 05
j=*punt; ...

punt 0F07:0417 0F
LuisHernndezYez

0F07:0418 03
0F07:0419 1A
0F07:041A 38
...

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 862


punteros.cpp

Ejemplo de uso de punteros


#include <iostream>
usingnamespacestd;

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

cout<<k<<endl;//Mismo valorque j

return 0;
}

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 863


LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 864


Todo puntero ha de tener una direccin vlida
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
LuisHernndezYez

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

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 X
*punt=13;
punt ha sido inicializado a NULL: No apunta a nada!

Si no apunta a nada, qu significa *punt??? No tiene sentido

ERROR: Acceso a un dato a travs de un puntero nulo!

Error de ejecucin, lo que ciertamente no es bueno


LuisHernndezYez

Pero sabemos cul ha sido el problema, lo que es mucho


Sabemos dnde y qu buscar para depurar

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 867


LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 868


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 X punt2
LuisHernndezYez

x 5

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

punt1 punt2
LuisHernndezYez

x 5

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;

punt1 punt2

Al dato x ahora se puede


LuisHernndezYez

acceder de tres formas:


x 8
5
x*punt1*punt2

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 871

Apuntan al mismo dato?


Operadores relacionales == y !=:
int x=5;
int *punt1=NULL;
int *punt2=&x;
...
if (punt1==punt2){
cout<<"Apuntanalmismodato" <<endl;
}
else{
cout<<"Noapuntanalmismodato" <<endl;
}
LuisHernndezYez

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

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;

Operador flecha (>):


Acceso a los campos a travs de un puntero sin usar el operador *
LuisHernndezYez

puntero>codigo puntero>nombrepuntero>sueldo
puntero>... (*puntero)....

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 875

structPtr.cpp

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

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;
tIntCtePtr punt_a_cte =&entero1;

(*punt_a_cte)++;//ERROR: Datonomodificable!
LuisHernndezYez

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;
tIntPtrCte punt_cte =&entero1;

(*punt_cte)++;//OK:Elpunteronoapuntaacte.
LuisHernndezYez

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:
void incrementa(int *punt);

void incrementa(int *punt){


(*punt)++;
}
Paso por valor:
... El argumento (el puntero) no cambia
int entero=5;
Aquello a lo que apunta (el entero)
incrementa(&entero);
LuisHernndezYez

S puede cambiar
cout<<entero<<endl;
Mostrar 6 en la consola

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 880


Paso de parmetros por referencia o variable
int entero=5;
incrementa(&entero); entero 5

punt recibe la direccin de entero

void incrementa(int *punt){ punt


(*punt)++;
}
entero 6
LuisHernndezYez

cout<<entero<<endl; entero 6

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

void foo(int *param1,double *param2,char *param3){


//Alprimerargumentoseaccedecon*param1
//Alsegundoargumentoseaccedecon*param2
//Altercerargumentoseaccedecon*param3
}
Cmo se llamara?
LuisHernndezYez

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
Un nombre de array es un puntero constante!
Siempre apunta al primer elemento (no se puede modificar)
LuisHernndezYez

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:
constint N=...;
void cuadrado(int arr[N]);
void cuadrado(int arr[],int size);//Arraynodelimitado
void cuadrado(int *arr,int size);//Puntero
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:
LuisHernndezYez

intPtr inicializar();

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 885


LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 886


Regiones de la memoria
El sistema operativo distingue varias regiones en la memoria:

Pila(Stack) Datos locales

Montn(Heap) Datos dinmicos

Datos globales

Cdigodel
Memoria principal
programa
LuisHernndezYez

S.O.

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 887

Memoria principal Pila Datos locales

Datos globales del programa: Montn Datos dinmicos

Declarados fuera Datos globales


de los subprogramas Cdigodelprograma Memoria principal

S.O.
typedef struct {
...
}tRegistro;
const intN=1000;
typedef tRegistro tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;
LuisHernndezYez

intmain(){
...

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 888


La pila (stack) Pila Datos locales

Datos locales de subprogramas: Montn Datos dinmicos

Parmetros por valor Datos globales


y variables locales Cdigodelprograma Memoria principal

S.O.
voidfunc(tLista lista,double &total)
{
tLista aux;
int i;
...

Y los punteros temporales &resultado


que apuntan a los argumentos
de los parmetros por referencia
LuisHernndezYez

func(lista,resultado)

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 889

El montn (heap) Pila Datos locales

Datos dinmicos Montn Datos dinmicos

Datos que se crean y se destruyen Datos globales

durante la ejecucin del programa, Cdigodelprograma Memoria principal

a medida que se necesita 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
LuisHernndezYez

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
Montn
Datodinmico
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
LuisHernndezYez

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

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
LuisHernndezYez

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;

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
LuisHernndezYez

Los datos estticos tambin se pueden acceder a travs de punteros


int *p=&i;
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 894
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 895

Devuelve NULL si no queda memoria suficiente


El operador new
new tipo 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;
La variable dinmica se accede exclusivamente por punteros
No tiene identificador asociado
int i;//iesunavariableesttica
int *p1,*p2;
p1=&i;//Punteroquedaaccesoalavariable
LuisHernndezYez

//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
#include<iostream>
usingnamespacestd;
#include"registro.h"

int main(){
tRegistroreg;
reg =nuevo();
LuisHernndezYez

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

El puntero deja de contener una direccin vlida!


LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 898


dinamicas.cpp

#include<iostream>
usingnamespacestd;

int main(){
double a=1.5; p1 Identificadores:
double *p1,*p2,*p3;
p1=&a; 4
p2=new double; (a, p1, p2, p3)
*p2=*p1; a 1.5
p3=new double;
*p3=123.45;
cout<<*p1<<endl; p2 1.5 Variables:
cout<<*p2<<endl;
cout<<*p3<<endl; 6
delete p2; (+ *p2 y *p3)
LuisHernndezYez

delete p3; p3 123.45

return 0; Montn (heap)


}

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 899

#include<iostream>
usingnamespacestd; PILA
a 1.5
int main(){ p1 ?
double a=1.5;
p2 ?
double *p1,*p2,*p3;
p3 ?
LuisHernndezYez

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 900


#include<iostream>
usingnamespacestd; PILA
a 1.5
int main(){ p1
double a=1.5;
p2 ?
double *p1,*p2,*p3;
p1=&a; p3 ?
LuisHernndezYez

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 901

#include<iostream>
usingnamespacestd; PILA
a 1.5
int main(){ p1
double a=1.5;
p2
double *p1,*p2,*p3;
p1=&a; p3 ?
p2=new double;
LuisHernndezYez

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 902


#include<iostream>
usingnamespacestd; PILA
a 1.5
int main(){ p1
double a=1.5;
p2
double *p1,*p2,*p3;
p1=&a; p3 ?
p2=new double;
*p2=*p1;
LuisHernndezYez

1.5
MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 903

#include<iostream>
usingnamespacestd; PILA
a 1.5
int main(){ p1
double a=1.5;
p2
double *p1,*p2,*p3;
p1=&a; p3
p2=new double;
*p2=*p1;
p3=new double;
LuisHernndezYez

1.5
MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 904


#include<iostream>
usingnamespacestd; PILA
a 1.5
int main(){ p1
double a=1.5;
p2
double *p1,*p2,*p3;
p1=&a; p3
p2=new double;
*p2=*p1;
p3=new double;
*p3=123.45;

123.45
LuisHernndezYez

1.5
MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 905

#include<iostream>
usingnamespacestd; PILA
a 1.5
int main(){ p1
double a=1.5;
p2 ?
double *p1,*p2,*p3;
p1=&a; p3
p2=new double;
*p2=*p1;
p3=new double;
*p3=123.45;
cout<<*p1<<endl;
cout<<*p2<<endl;
cout<<*p3<<endl;
delete p2; 123.45
LuisHernndezYez

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 906


#include<iostream>
usingnamespacestd; PILA
a 1.5
int main(){ p1
double a=1.5;
p2 ?
double *p1,*p2,*p3;
p1=&a; p3 ?
p2=new double;
*p2=*p1;
p3=new double;
*p3=123.45;
cout<<*p1<<endl;
cout<<*p2<<endl;
cout<<*p3<<endl;
delete p2;
LuisHernndezYez

delete p3;

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 907


LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 908


La memoria se reparte entre la pila y el montn Pila

Crecen en direcciones opuestas


Al llamar a subprogramas la pila crece
Al crear datos dinmicos el montn crece
Montn

Colisin pilamontn
Los lmites de ambas regiones se encuentran
Se agota la memoria

Desbordamiento de la pila
LuisHernndezYez

La pila suele tener un tamao mximo establecido


Si se sobrepasa se agota la pila

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 909

Gestin del montn


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)


LuisHernndezYez

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

G++ no indicar ningn error y el programa parecer terminar


correctamente, pero dejar memoria desperdiciada
LuisHernndezYez

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
...
intmain(){ p1 tRegistro
tRegistro *p1=new tRegistro;
*p1=nuevo();
mostrar(*p1); p2
tRegistro *p2;
p2=p1;
mostrar(*p2);
delete p1;
delete p2;

return 0;
Slo se ha creado
LuisHernndezYez

}
una variable

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 913

Prdida de un dato dinmico


...
intmain(){
tRegistro *p1,*p2;
p1=new tRegistro(nuevo());
p2=new tRegistro(nuevo());
p2 tRegistro
mostrar(*p1);
p1=p2; p1 tRegistro
mostrar(*p1);

Perdido!
delete p1;
delete p2;
LuisHernndezYez

return 0; 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); p ha dejado de apuntar
al dato dinmico destruido
return 0; Acceso a memoria inexistente
}
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 915


LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 916


Arrays de punteros a datos dinmicos
typedef struct {
intcodigo;
string nombre; Los punteros ocupan
double valor; muy poco en memoria
}tRegistro; Los datos a los que apunten
typedef tRegistro *tRegPtr; estarn en el montn

const int N=1000;


//Arraydepunterosaregistros:
typedef tRegPtr tArray[N];
typedef struct {
tArray registros;
LuisHernndezYez

int cont;
}tLista; Se crean a medida que se insertan
Se destruyen a medida que se eliminan

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 917

tLista lista;
lista.cont =0;

lista.cont 0
0 1 2 3 4 5 6 998 999

lista.registros
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 918


tLista lista;
lista.cont =0;
lista.registros[lista.cont]=new tRegistro(nuevo());
lista.cont++;

lista.cont 1
0 1 2 3 4 5 6 998 999

lista.registros
LuisHernndezYez

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 1 2 3 4 5 6 998 999

lista.registros
LuisHernndezYez

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 1 2 3 4 5 6 998 999

lista.registros
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 921

Los registros se acceden a travs de los punteros (operador >):


cout<<lista.registros[0]>nombre;

lista.cont 3
0 1 2 3 4 5 6 998 999

lista.registros
LuisHernndezYez

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 1 2 3 4 5 6 998 999

lista.registros
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 923

lista.h

#ifndef lista_h
#definelista_h registro.h con el tipo puntero:
#include"registro.h"
typedef tRegistro *tRegPtr;
const int N=1000;
const string BD="bd.dat";
typedef tRegPtr tArray[N];
typedef struct {
tArray registros;
int cont;
}tLista;
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);
LuisHernndezYez

void guardar(const tLista &lista);


void destruir(tLista &lista);

#endif

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 924


lista.cpp

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

}
lista.cont;
}
}

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 925

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++){
LuisHernndezYez

delete lista.registros[i];
}
lista.cont =0;
}
...

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 926


listadinamica.cpp

#include<iostream>
usingnamespacestd;
#include"registro.h"
#include"lista.h"

int main(){
tLista lista;
bool ok;
cargar(lista,ok);
if(ok){
mostrar(lista);
destruir(lista);
}

return 0;
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 927


LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 928


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:


delete []p;
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 929

#include<iostream>
usingnamespacestd;
const int N=10;

int main(){
int*p=new int[N];
for (int i=0;i<N;i++){
p[i]=i;
}
for (int i=0;i<N;i++){
cout<<p[i]<<endl;
}
delete []p;
No olvides destruir el array dinmico!
LuisHernndezYez

return 0;
}

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

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;
lista.cont++; el array al cargar
}
}

void eliminar(tLista&lista,int code, bool &ok){


ok=true;
int ind =buscar(lista,code); No usamos delete
if (ind ==1){
ok=false; Se destruye todo
} el array al final
else {
for (int i=ind +1;i<lista.cont;i++){
LuisHernndezYez

lista.registros[i 1]=lista.registros[i];
}
lista.cont;
}
}...

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 932


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

lista.cont =0;
}
...

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 {
tRegistro registro; Se crean todos a la vez
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++;
LuisHernndezYez

archivo>>registro.codigo;
}
archivo.close();
}
}

Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 934


ejemploAD.cpp

Mismo programa principal que el del array de datos dinmicos


Pero incluyendo listaAD.h, en lugar de lista.h
LuisHernndezYez

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 dinmico:


Array de punteros Puntero a array
0 1 2 3 4 5 6 7

0 1 2 3 4 5 6 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.
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.
LuisHernndezYez

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

Aritmticadepunteros 940
Recorridodearraysconpunteros 953
Referencias 962
Listasenlazadas 964
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)
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++;
punt++ hace que punt pase a apuntar al siguiente elemento
cout<<*punt<<endl;//Muestra 28(segundo elemento)
LuisHernndezYez

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:1A38
0F03:1A39
typedef int*tIntPtr; 0F03:1A3A 31
tIntPtr punt=dias; 0F03:1A3B
dias[1] 0F03:1A3C
0F03:1A3D
0F03:1A3E 28
0F03:1A3F
dias[2] 0F03:1A40
0F03:1A41
0F03:1A42 31
0F03:1A43
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
LuisHernndezYez

punt 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:1A38
0F03:1A39
typedef int*tIntPtr; 0F03:1A3A 31
tIntPtr punt=dias; 0F03:1A3B
dias[1] 0F03:1A3C
punt++; 0F03:1A3D
0F03:1A3E 28
0F03:1A3F
dias[2] 0F03:1A40
0F03:1A41
0F03:1A42 31
0F03:1A43
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
LuisHernndezYez

punt 0F07:041B 0F
0F07:041C 03

punt hace que apunte al elemento anterior


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:1A38
0F03:1A39
typedef int*tIntPtr; 0F03:1A3A 31
tIntPtr punt=dias; 0F03:1A3B
dias[1] 0F03:1A3C
punt =punt+2; 0F03:1A3D
0F03:1A3E 28
0F03:1A3F
dias[2] 0F03:1A40
0F03:1A41
0F03:1A42 31
0F03:1A43
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
LuisHernndezYez

punt 0F07:041B 0F
0F07:041C 03
0F07:041D 1A
Restando pasamos a elementos anteriores 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:1A38
0F03:1A39
typedef int*tIntPtr; 0F03:1A3A 31
tIntPtr punt=dias; 0F03:1A3B
dias[1] 0F03:1A3C
punt=punt+2; 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
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
LuisHernndezYez

punt 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] 0F03:1A38
0F03:1A39 31
shortint dias[12]={31,28,31,30, dias[1] 0F03:1A3A
28
0F03:1A3B
31,30,31,31,30,31,30,31}; dias[2] 0F03:1A3C
0F03:1A3D 31
typedef shortint*tSIPtr; dias[3] 0F03:1A3E
tSIPtr punt=dias; 0F03:1A3F 30
dias[4] 0F03:1A40
0F03:1A41 31
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
punt 0F07:041B 0F
LuisHernndezYez

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] 0F03:1A38
typedef shortint*tSIPtr; 0F03:1A39 31
dias[1] 0F03:1A3A
tSIPtr punt=dias; 0F03:1A3B 28
punt++; dias[2] 0F03:1A3C
31
0F03:1A3D
dias[3] 0F03:1A3E
0F03:1A3F 30
dias[4] 0F03:1A40
0F03:1A41 31
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
punt 0F07:041B 0F
LuisHernndezYez

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] 0F03:1A38
typedef shortint*tSIPtr; 0F03:1A39 31
dias[1] 0F03:1A3A
tSIPtr punt=dias; 0F03:1A3B 28
punt++; dias[2] 0F03:1A3C
0F03:1A3D 31
punt=punt+3; dias[3] 0F03:1A3E
0F03:1A3F 30
dias[4] 0F03:1A40
0F03:1A41 31
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
punt 0F07:041B 0F
LuisHernndezYez

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] 0F03:1A38
typedef shortint*tSIPtr; 0F03:1A39 31
dias[1] 0F03:1A3A
tSIPtr punt=dias; 0F03:1A3B 28
punt++; dias[2] 0F03:1A3C
0F03:1A3D 31
punt=punt+3; dias[3] 0F03:1A3E

punt; 0F03:1A3F 30
dias[4] 0F03:1A40
0F03:1A41 31
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
punt 0F07:041B 0F
LuisHernndezYez

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] 0F03:1A38
typedef shortint*tSIPtr; 0F03:1A39 31
dias[1] 0F03:1A3A
tSIPtr punt=dias; 0F03:1A3B 28
punt++; dias[2] 0F03:1A3C
31
0F03:1A3D
punt=punt+3; dias[3] 0F03:1A3E

punt; 0F03:1A3F 30
dias[4] 0F03:1A40
tSIPtr punt2; 0F03:1A41 31
...
dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
punt 0F07:041B 0F
LuisHernndezYez

0F07:041C 03
0F07:041D 1A
0F07:041E 3E
punt2 0F07:041F ?

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 950

shortint dias[12]={31,28,31,30,
...
31,30,31,31,30,31,30,31};
dias[0] 0F03:1A38
typedef shortint*tSIPtr; 0F03:1A39 31
dias[1] 0F03:1A3A
siPtr punt=dias; 0F03:1A3B 28
punt++; dias[2] 0F03:1A3C
0F03:1A3D 31
punt=punt+3; dias[3] 0F03:1A3E

punt; 0F03:1A3F 30
dias[4] 0F03:1A40
tSIPtr punt2; 0F03:1A41 31
...
punt2=dias; dias 0F07:0417 0F
0F07:0418 03
0F07:0419 1A
0F07:041A 38
punt 0F07:041B 0F
LuisHernndezYez

0F07:041C 03
0F07:041D 1A
0F07:041E 3E
punt2 0F07:041F 0F

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 951


shortint dias[12]={31,28,31,30,
...
31,30,31,31,30,31,30,31};
dias[0] 0F03:1A38
typedef shortint*tSIPtr; 0F03:1A39 31
dias[1] 0F03:1A3A
siPtr punt=dias; 28
3 0F03:1A3B

punt++; dias[2] 0F03:1A3C


0F03:1A3D 31
punt=punt+3; dias[3] 0F03:1A3E

punt; 0F03:1A3F 30
dias[4] 0F03:1A40
tSIPtr punt2; 0F03:1A41 31
...
punt2=dias; dias 0F07:0417 0F

cout<<punt punt2;//3 0F07:0418 03


0F07:0419 1A
0F07:041A 38
punt 0F07:041B 0F
LuisHernndezYez

0F07:041C 03
0F07:041D 1A
0F07:041E 3E
punt2 0F07:041F 0F

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 952


LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 953


arraypunt.cpp

Punteros como iteradores para arrays


constint MAX=100;
typedefint tArray[MAX];
typedef struct{
tArray elementos;
int cont;
}tLista;
typedefint*tIntPtr;
tLista lista;

Usamos un puntero como iterador para recorrer el array:


tIntPtr punt=lista.elementos;
for(int i=0;i<lista.cont;i++){
cout<<*punt <<endl;
LuisHernndezYez

punt++;
}

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 954

...
intPtr punt=lista.elementos;

punt

0 1 2 3 4 5 6 7 8 ... 98 99

lista.elementos 4 13 3 47 53 19 7 48

lista.cont 8
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 955


...
for(int i=0;i<lista.cont;i++){
cout<<*punt <<endl;
punt++;
}

i 0 punt

0 1 2 3 4 5 6 7 8 ... 98 99

lista.elementos 4 13 3 47 53 19 7 48

lista.cont 8
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 956

...
for(int i=0;i<lista.cont;i++){ 4
cout<<*punt <<endl;
punt++;
}

i 1 punt

0 1 2 3 4 5 6 7 8 ... 98 99

lista.elementos 4 13 3 47 53 19 7 48

lista.cont 8
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 957


...
for(int i=0;i<lista.cont;i++){ 4
13
cout<<*punt <<endl;
punt++;
}

i 2 punt

0 1 2 3 4 5 6 7 8 ... 98 99

lista.elementos 4 13 3 47 53 19 7 48

lista.cont 8
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 958

...
for(int i=0;i<lista.cont;i++){ 4
13
cout<<*punt <<endl; 3
punt++;
}

i 3 punt

0 1 2 3 4 5 6 7 8 ... 98 99

lista.elementos 4 13 3 47 53 19 7 48

lista.cont 8
LuisHernndezYez

. . .

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 959


...
for(int i=0;i<lista.cont;i++){ 4
13
cout<<*punt <<endl; 3
punt++; 47
} 53
19
7

i 7 punt

0 1 2 3 4 5 6 7 8 ... 98 99

lista.elementos 4 13 3 47 53 19 7 48

lista.cont 8
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 960

...
for(int i=0;i<lista.cont;i++){ 4
13
cout<<*punt <<endl; 3
punt++; 47
} 53
19
7
48
i 8 punt

0 1 2 3 4 5 6 7 8 ... 98 99

lista.elementos 4 13 3 47 53 19 7 48

lista.cont 8
LuisHernndezYez

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;
Las referencias se usan en el paso de parmetros por referencia
LuisHernndezYez

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;
structtNodo { reg sig
tRegistro reg; tRegistro tLista
tLista sig;
};
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
LuisHernndezYez

Vaca
Lista Definicin recursiva!
Elemento seguido de una lista

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
tLista lista=NULL;//Listavaca
LuisHernndezYez

lista

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 966

structtNodo;
typedef tNodo *tLista;
structtNodo {
tRegistro reg;
tLista sig;
};
tLista lista=NULL;//Listavaca
lista=new tNodo;
lista>reg =nuevo();
lista>sig=NULL;
LuisHernndezYez

lista tem1

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 967


tLista lista=NULL;//Listavaca
lista=new tNodo;
lista>reg =nuevo();
lista>sig=NULL;
tLista p;
p=lista;

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

p
LuisHernndezYez

lista tem1 tem2

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 969


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

lista tRegistro tRegistro tRegistro

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 970

Usamos la memoria que necesitamos, ni ms ni menos

lista tRegistro tRegistro tRegistro

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

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 971


listaenlazada.h

structtNodo;
typedef tNodo *tLista;
struct tNodo {
tRegistro reg;
tLista sig;
};

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

void destruir(tLista &lista);//Liberarlamemoriadinmica

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 972

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){
p=p>sig; nuevo
LuisHernndezYez

} p
p>sig=nuevo;
}
lista
}
}...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 973


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 {
tLista ant=p; lista
p=p>sig;
bool encontrado=false;
while ((p!=NULL)&&!encontrado){
if (p>reg.codigo ==code){
ant p
encontrado=true;
}
LuisHernndezYez

else {
ant=p; lista
p=p>sig;
}
}...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 974

if (!encontrado){
ok=false;//Noexisteesecdigo
}
else {
ant>sig=p>sig;
delete p;
}
}
}
...
ant p

lista
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 975


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

while (p!=NULL){
mostrar(p>reg);
p=p>sig;
}
}...

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

...

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();
}
return ok;
}...
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 978

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

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

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


Facultad de Informtica
Universidad Complutense

Conceptoderecursin 983
Algoritmosrecursivos 986
Funcionesrecursivas 987
Diseodefuncionesrecursivas 989
Modelodeejecucin 990
Lapiladelsistema 992
Lapilaylasllamadasafuncin 994
Ejecucindelafuncinfactorial() 1005
Tiposderecursin 1018
Recursinsimple 1019
Recursinmltiple 1020
Recursinanidada 1022
Recursincruzada 1026
Cdigodelsubprogramarecursivo 1027
Parmetrosyrecursin 1032
Ejemplosdealgoritmosrecursivos 1034
LuisHernndezYez

Bsquedabinaria 1035
TorresdeHanoi 1038
Recursinfrenteaiteracin 1043
Estructurasdedatosrecursivas 1045

Fundamentosdelaprogramacin:Introduccinalarecursin
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


(http://farm1.static.flickr.com/83
/229219543_edf740535b.jpg)

(wikipedia.org)
La imagen del paquete
LuisHernndezYez

aparece dentro del propio


paquete,... hasta el infinito!
(wikipedia.org) Las matrioskas rusas

Fundamentosdelaprogramacin:Introduccinalarecursin 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:

N x Factorial(N1) si N > 0 Caso recursivo (induccin)


Factorial(N)
1 si N = 0 Caso base (o de parada)

El valor de N se va aproximando al valor del caso base (0)


LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 985


LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 986


Funciones recursivas
Una funcin puede implementar un algoritmo recursivo
La funcin se llamar a s misma si no se ha llegado al caso base
1 si N = 0
Factorial(N)
N x Factorial(N1) si N > 0
longlong int factorial(int n){
longlong intresultado;
if (n==0){//Caso base
resultado =1;
}
else {
LuisHernndezYez

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)
5 x 4 x 3 x factorial(2) 5 x 4 x 3 x 2 x factorial(1)
LuisHernndezYez

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
Factorial(N)
N x Factorial(N1) si N > 0
LuisHernndezYez

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


LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 990


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
LuisHernndezYez

mantener los datos locales y la direccin de vuelta

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 991

Regiones de memoria que distingue el sistema operativo:

Pila(Stack) Llamadas a subprogramas

Montn(Heap) Memoria dinmica (Tema 9)

Datos delprograma

Cdigodelprograma Memoria principal


LuisHernndezYez

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 Entra Entra Sale


4 7 2 2

2
7 7 7
LuisHernndezYez

4 4 4 4

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 993

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}
int funcA(int a){
intb;
...
<DIR2> b=funcB(a);
...
return b;
}
int main(){
LuisHernndezYez

... Pila
Llamada a funcin:
<DIR1> cout<<funcA(4);
Entra la direccin de vuelta
...

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 994


Datos locales y direcciones de vuelta
...
int funcB(int x){
...
return x;
}
int funcA(int a){
Entrada en la funcin:
intb; Se alojan los datos locales
...
<DIR2> b=funcB(a);
...
return b;
}
int main(){ <DIR1>
LuisHernndezYez

... Pila
<DIR1> cout<<funcA(4);
...

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 995

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}
int funcA(int a){
intb;
...
<DIR2> b=funcB(a); Llamada a funcin:
Entra la direccin de vuelta
...
return b; b
} a
int main(){ <DIR1>
LuisHernndezYez

... Pila
<DIR1> cout<<funcA(4);
...

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 996


Datos locales y direcciones de vuelta
...
int funcB(int x){ Entrada en la funcin:
... Se alojan los datos locales
return x;
}
int funcA(int a){
intb;
...
<DIR2> b=funcB(a);
... <DIR2>
return b; b
} a
int main(){ <DIR1>
LuisHernndezYez

... Pila
<DIR1> cout<<funcA(4);
...

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
}
int funcA(int a){
intb;
... x
<DIR2> b=funcB(a);
... <DIR2>
return b; b
} a
int main(){ <DIR1>
LuisHernndezYez

... Pila
<DIR1> cout<<funcA(4);
...

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 998


Datos locales y direcciones de vuelta
...
int funcB(int x){
...
return x; Vuelta de la funcin:
} Sale la direccin de vuelta

int funcA(int a){


intb;
...
<DIR2> b=funcB(a);
... <DIR2>
return b; b
} a
int main(){ <DIR1>
LuisHernndezYez

... Pila
<DIR1> cout<<funcA(4);
...

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 999

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}
int funcA(int a){
intb;
...
<DIR2> b=funcB(a); La ejecucin contina
en esa direccin
...
return b; b
} a
int main(){ <DIR1>
LuisHernndezYez

... Pila
<DIR1> cout<<funcA(4);
...

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1000


Datos locales y direcciones de vuelta
...
int funcB(int x){
...
return x;
}
int funcA(int a){
intb;
...
<DIR2> b=funcB(a);
...
return b; Vuelta de la funcin: b
Se eliminan los datos locales
} a
int main(){ <DIR1>
LuisHernndezYez

... Pila
<DIR1> cout<<funcA(4);
...

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1001

Datos locales y direcciones de vuelta


...
int funcB(int x){
...
return x;
}
int funcA(int a){
intb;
...
<DIR2> b=funcB(a);
...
return b; Vuelta de la funcin:
Sale la direccin de vuelta
}
int main(){ <DIR1>
LuisHernndezYez

... Pila
<DIR1> cout<<funcA(4);
...

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1002


Datos locales y direcciones de vuelta
...
int funcB(int x){
...
return x;
}
int funcA(int a){
intb;
...
<DIR2> b=funcB(a);
...
return b;
}
int main(){
LuisHernndezYez

... Pila
<DIR1> cout<<funcA(4); 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
...
int funcC(...){
...
}
int funcB(...){
...
LLAMADAS
V U E LTAS

...funcC(...)
}
int funcA(...){ funcC
...
...funcB(...) funcB
}
int main(){ funcA
LuisHernndezYez

...
cout<<funcA(...); Pila
...

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1004


longlong int factorial(int n){
longlong intresultado;
if (n==0){//Caso base
resultado =1;
}
else {
resultado =n*factorial(n 1);
}
return resultado;
}

cout<<factorial(5)<<endl;
LuisHernndezYez

Obviaremos las direcciones de vuelta en la pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1005

factorial(5)

resultado=?
LuisHernndezYez

n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1006


factorial(5)
factorial(4)

resultado =?
n=4
resultado=?
LuisHernndezYez

n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1007

factorial(5)
factorial(4)
factorial(3)

resultado=?
n=3
resultado =?
n=4
resultado=?
LuisHernndezYez

n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1008


factorial(5)
factorial(4)
factorial(3)
factorial(2)

resultado=?
n=2
resultado=?
n=3
resultado =?
n=4
resultado=?
LuisHernndezYez

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
resultado=?
LuisHernndezYez

n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1010


factorial(5)
factorial(4)
factorial(3)
factorial(2) resultado=1
factorial(1) n=0

factorial(0) resultado=?
n=1
resultado=?
n=2
resultado=?
n=3
resultado =?
n=4
resultado=?
LuisHernndezYez

n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1011

factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0) resultado=1
n=1
resultado=?
1
n=2
resultado=?
n=3
resultado =?
n=4
resultado=?
LuisHernndezYez

n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1012


factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)

resultado=2
1
n=2
1 resultado=?
n=3
resultado =?
n=4
resultado=?
LuisHernndezYez

n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1013

factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)

1
1 resultado=6
n=3
2
resultado =?
n=4
resultado=?
LuisHernndezYez

n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1014


factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)

1
1
2
resultado =24
6 n=4
resultado=?
LuisHernndezYez

n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1015

factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)

1
1
2
6
24 resultado=120
LuisHernndezYez

n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1016


factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
factorial(0)

1
1
2
6
24
LuisHernndezYez

120
Pila

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1017


LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1018


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;
}
Una sola llamada recursiva
LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1019

Varias llamadas recursivas


Ejemplo: Clculo de los nmeros de Fibonacci

0 si n = 0

Fib(n) 1 si n = 1
Fib(n1) + Fib(n2) si n > 1

Dos llamadas recursivas


LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1020


fibonacci.cpp

... 0 si n = 0
int main(){ Fib(n) 1 si n = 1
for(int i=0;i<20;i++){ Fib(n1) + Fib(n2) si n > 1
cout<<fibonacci(i)<<endl;
}
return 0;
}

int fibonacci(int n){


int resultado;
if (n==0){
resultado=0;
}
elseif (n==1){
resultado=1;
}
else {
LuisHernndezYez

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:

n + 1 si m = 0

Ack(m, n) Ack(m1, 1) si m > 0 y n = 0


Ack(m1, Ack(m, n1)) si m > 0 y n > 0

Argumento que es una llamada recursiva


LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1022


ackermann.cpp

n + 1 si m = 0
Nmeros de Ackermann Ack(m, n) 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;
LuisHernndezYez

}
Prubalo con nmeros muy bajos:
Se generan MUCHAS llamadas recursivas

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1023

n + 1 si m = 0
Nmeros de Ackermann Ack(m, n) Ack(m1, 1) si m > 0 y n = 0
Ack(m1, Ack(m, n1)) si m > 0 y n > 0
ackermann(1,1)
ackermann(0,ackermann(1,0))
2
3 ackermann(0,1)
ackermann(0,2)
LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1024


n + 1 si m = 0
Nmeros de Ackermann Ack(m, n) Ack(m1, 1) si m > 0 y n = 0
Ack(m1, Ack(m, n1)) si m > 0 y n > 0
ackermann(2,1)
ackermann(1, ackermann(2,0))
3
5 ackermann(1,1)
ackermann(0,ackermann(1,0))

2
ackermann(0,1)
3
ackermann(0,2)
ackermann(1,3)
ackermann(0,ackermann(1,2))
ackermann(0, ackermann(1,1))
4 ackermann(0,ackermann(1,0))
5
LuisHernndezYez

2
ackermann(0,1)
3
ackermann(0,2)
ackermann(0,3)
ackermann(0,4)

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1025


LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1026


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
Se ejecuta para las distintas entradas tras llegarse al caso base
El cdigo anterior se ejecuta en orden directo para las distintas
LuisHernndezYez

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

func(5);

El cdigo anterior se ejecuta


para los sucesivos valores de n (5, 4, 3, ...)
LuisHernndezYez

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

void mostrar(tLista lista,int pos){


if (pos<lista.cont){
LuisHernndezYez

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

void mostrar(tLista lista,int pos){


if (pos<lista.cont){
LuisHernndezYez

mostrar(lista,pos+1);
cout<<lista.elementos[pos]<<endl;
}
}

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1030


LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1031

Parmetros por valor y por referencia


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

}
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

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

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

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

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1035

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

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

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
LuisHernndezYez

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

A B C

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
LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1038


Resolucin del problema en base Mover 4 discos de A a C

a problemas ms pequeos
Mover N discos del pilar A al pilar C:
Mover N1 discos del pilar A al pilar B A B C

Mover el disco del pilar A al pilar C


Mover N1 discos del pilar B al pilar C
A B C

Para llevar N discos de un pilar origen a


otro destino se usa el tercero como auxiliar A B C
Mover N1 discos del origen al auxiliar
Mover el disco del origen al destino
LuisHernndezYez

Mover N1 discos del auxiliar al destino A B C

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1039

Mover N1 discos se hace igual, pero Mover 3 discos de A a B

usando ahora otros origen y destino


Mover N1 discos del pilar A al pilar B:
Mover N2 discos del pilar A al pilar C A B C

Mover el disco del pilar A al pilar B


Mover N2 discos del pilar C al pilar B
A B C
Naturaleza recursiva de la solucin

A B C
LuisHernndezYez

Simulacin para 4 discos (wikipedia.org)


A B C

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1040


hanoi.cpp

Caso base: no quedan discos que mover


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

int main(){
int n;
cout<<"Nmerodetorres:";
cin>>n;
hanoi(n,'A','C','B');
LuisHernndezYez

return 0;
}

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1041


LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1042


longlong int factorial(int n){ longlong int factorial(int n){
longlong intfact; longlong int fact=1;

assert(n>=0); assert(n>=0);

if (n==0){ for (int i=1;i<=n;i++){


fact=1; fact=fact*i;
} }
else {
fact=n*factorial(n 1); return fact;
} }

return fact;
}
LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1043

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

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1044


LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1045

Definicin recursiva de listas


Ya hemos definido de forma recursiva alguna estructura de datos:
elemento seguido de una secuencia
Secuencia
secuencia vaca (ningn elemento)
Las listas son secuencias:
elemento seguido de una lista
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,
LuisHernndezYez

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

resto(lista): sublista tras quitar el primer elemento


LuisHernndezYez

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

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

Flujos 1051
Archivosbinarios 1054
Tamaodelosdatos:Eloperadorsizeof() 1056
Aperturadearchivosbinarios 1059
Lecturadearchivosbinarios(accesosecuencial) 1061
Escrituraenarchivosbinarios(accesosecuencial) 1066
Accesodirectooaleatorio 1070
Ejemplosdeusodearchivosbinarios 1078
Ordenacindelosregistrosdelarchivo 1079
Bsquedabinaria 1085
Insercinenunarchivobinarioordenado 1088
Cargadelosregistrodeunarchivoenunatabla 1092
Almacenamientodeunatablaenunarchivo 1093
LuisHernndezYez

Fundamentosdelaprogramacin:Archivosbinarios
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
Dispositivos/archivos de salida
de entrada

Programa
LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios Pgina 1052


Flujos de texto y binarios
Flujo de texto: contiene una secuencia de caracteres
T o t a l : 1 2 3 . 4 A

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

Lo que signifiquen los cdigos depender del programa que use el archivo

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
LuisHernndezYez

Ya hemos usado flujos de texto para E/S por consola/archivos

Fundamentosdeprogramacin:Archivosbinarios Pgina 1053


LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios Pgina 1054


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 1 2 4 5 6 7 8 9 4

9 caracteres (se guarda el cdigo ASCII de cada uno)


Representacin binaria:
00000111011011001100000101010110Hex: 076CC156

Flujo binario 07 6C C1 56
LuisHernndezYez

4 caracteres interpretados como cdigos binarios

Fundamentosdeprogramacin:Archivosbinarios Pgina 1055

El operador sizeof()
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;
LuisHernndezYez

const int SIZE=sizeof(tRegistro);


En un archivo binario un dato del tipo tRegistro
ocupar exactamente SIZE caracteres

Fundamentosdeprogramacin:Archivosbinarios Pgina 1056


typedef struct {
MEMORIA
int cod;
...
double val;
reg 0F03:1A38 00
} tRegistro; 0F03:1A39 00
tRegistro reg; 0F03:1A3A 00
reg.cod
const int SIZE=sizeof(reg); (4)
0F03:1A3B 05

... 0F03:1A3C 0A
0F03:1A3D 37
Posiciones de memoria usadas SIZE
0F03:1A3E 1C
(12)
0F03:1A3F DF
reg.val
0F03:1A40 03
(8)
0F03:1A41 92

Se guardan los SIZE bytes: 0F03:1A42 99


0F03:1A43 0E
LuisHernndezYez

0F03:1A44 ...
Flujo binario
00 00 00 05 0A 37 1C DF 03 92 99 0E

Fundamentosdeprogramacin:Archivosbinarios 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:
typedef struct {
char c;
int i;
} tRegistro;
const int SIZE=sizeof(tRegistro);
LuisHernndezYez

char (1 byte) + int (4 bytes) SIZE toma el valor 8 (4 + 4), no 5


char + int + double 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

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
LuisHernndezYez

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
archivo.read((char *)&registro,sizeof(tRegistro));
LuisHernndezYez

Los caracteres ledos se interpretan como cdigos binarios

Fundamentosdeprogramacin:Archivosbinarios Pgina 1062


xito o fallo de la lectura
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
}
LuisHernndezYez

else {
//LecturaOK
...

Fundamentosdeprogramacin:Archivosbinarios Pgina 1063

leer.cpp

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

}
archivo.close(); No olvides cerrar el archivo!
return 0;
}

Fundamentosdeprogramacin:Archivosbinarios Pgina 1064


registro.h

El tipo tRegistro
constint Max=80;
typedefchar tCadena[Max];
typedef struct {
int codigo;
tCadena item;
double valor;
}tRegistro;
const int SIZE=sizeof(tRegistro);
Por qu usamos cadenas al estilo de C?
string: tamao variable en memoria
Requieren un proceso de serializacin
LuisHernndezYez

Las cadenas al estilo de C siempre ocupan lo mismo en memoria

Fundamentosdeprogramacin:Archivosbinarios Pgina 1065


LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios Pgina 1066


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
archivo.write((char *)&registro,sizeof(tRegistro));
LuisHernndezYez

Se escriben tantos caracteres como celdas de memoria ocupe


la variable registro

Fundamentosdeprogramacin:Archivosbinarios Pgina 1067

escribir.cpp

#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:";
LuisHernndezYez

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!)
return 0;
}
LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios Pgina 1069


LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios Pgina 1070


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
LuisHernndezYez

ios::end: final del archivo

Fundamentosdeprogramacin:Archivosbinarios Pgina 1071

ios::beg ios::end
0 SIZE 2*SIZE 3*SIZE 4*SIZE 5*SIZE 6*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?
archivo.seekg(0,ios::end);//0car.desdeelfinal>final
int pos=archivo.tellg();//Totaldecaracteresdelarchivo
LuisHernndezYez

int numReg =pos/SIZE;

Fundamentosdeprogramacin:Archivosbinarios Pgina 1072


ios::beg ios::end
0 SIZE 2*SIZE 3*SIZE 4*SIZE 5*SIZE 6*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:


archivo.seekg((num 1)*SIZE,ios::beg);
LuisHernndezYez

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);
Ahora podemos tanto leer como escribir
LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios Pgina 1074


actualizar.cpp

//Actualizacindeunregistro
#include<iostream>
usingnamespacestd;
#include<fstream>
#include"registro.h"

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

int num;
cout<<"Registronmero?";
cin>>num;
...

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

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

Fundamentosdeprogramacin:Archivosbinarios Pgina 1077


LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios Pgina 1078


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

void mostrar();

...
LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios Pgina 1079

void mostrar(){
fstream archivo;
tRegistro registro;
int cuantos;

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

...

Fundamentosdeprogramacin:Archivosbinarios Pgina 1080


int main(){

mostrar(); Orden inicial

fstream archivo;
archivo.open(BD,ios::in |ios::out |ios::binary);
archivo.seekg(0,ios::end);
LuisHernndezYez

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

menor
i j
LuisHernndezYez

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 regMenor

i
menor j

LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios 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";

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

elseif(buscado<registro.codigo){
fin=mitad 1;
}
...

Fundamentosdeprogramacin:Archivosbinarios Pgina 1086


else{
ini=mitad+1;
}
}
if (encontrado){
int pos=mitad+1;
cout<<"Encontradoenlaposicin" <<pos<<endl;
mostrar(registro);
}
else{
cout<<"Noencontrado!" <<endl;
}
archivo.close();

return 0;
LuisHernndezYez

...

Fundamentosdeprogramacin:Archivosbinarios Pgina 1087

insertar.cpp

Ordenado por el campo codigo


#include<iostream>
usingnamespacestd;
#include<fstream>
#include"registro.h"

const char BD[]="ord2.dat";

void mostrar();

int main(){
mostrar();
tRegistro nuevoRegistro =nuevo(),registro;
fstream archivo;
archivo.open(BD,ios::in|ios::out |ios::binary);
LuisHernndezYez

archivo.seekg(0,ios::end);
int pos=archivo.tellg();
int numReg =pos/SIZE;
...
Fundamentosdeprogramacin:Archivosbinarios Pgina 1088
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);
LuisHernndezYez

}
...

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

mostrar(); nuevoRegistro

return 0;
LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios Pgina 1090


Al principio

Por el medio
LuisHernndezYez

Al final

Fundamentosdeprogramacin:Archivosbinarios Pgina 1091

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

tabla.registros[tabla.cont]=registro;
tabla.cont++;
}
archivo.close();
}
}
Fundamentosdeprogramacin:Archivosbinarios Pgina 1092
tabla.cpp

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

Fundamentosdeprogramacin:Archivosbinarios Pgina 1093

bd.cpp

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

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

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

Fundamentosdeprogramacin:Archivosbinarios Pgina 1095

You might also like