Está en la página 1de 568

FacultaddeInformtica UniversidadComplutense

Apuntesdeclasedelaasignatura

Fundamentosdelaprogramacin

1curso GradoenIngenieraenInformtica GradoenIngenieradelSoftware GradoenIngenieradeComputadores

20132014
LuisHernndezYez

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

Estapublicacincontienelosapuntesdeclasedelaasignatura Fundamentosdelaprogramacin,asignaturade1cursodelosgrados queseimpartenenlaFacultaddeInformticadelaUCM. Durantelostresprimeroscursosenlosquesehaimpartidolaasignatura, estematerialhasidosometidoacontinuasrevisionesycontribuciones porpartedelosprofesoresquehanimpartidolosdistintosgrupos delaasignatura.Aunqueeltrabajohaquedadobastanteconsolidado, estoysegurodequetodavacontienemuchaserratas.Siencuentrasalguna, nodudes,porfavor,enhacrmelosaberyconseguiras quelasiguienteversinestmejordepurada. Quieroagradeceratodoslosprofesoresquehanimpartidolaasignatura sucontribucineneldesarrollodelmaterial,destacandoespecialmente lalabordePabloMorenoGeryCarlosCervignRckauer. LuisHernndezYez ProfesordelaFacultaddeInformticadelaUCM

Fundamentosdelaprogramacin

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

Facultad de Informtica Universidad Complutense

Tema1 Tema2

LuisHernndezYez

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

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

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

3 12 15 19 24 27 30 35 39 45

LuisHernndezYez

Fundamentosdelaprogramacin

LuisHernndezYez

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

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

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

177 180 183 186 190 199

Fundamentosdelaprogramacin

int float Notacincientfica double char bool string Literalesconespecificacindetipo

214 216 217 218 220 221 222 223

LuisHernndezYez

Fundamentosdelaprogramacin

LuisHernndezYez

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

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

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

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

Fundamentosdelaprogramacin

Eloperadorternario?

399

Recorridos Unaparcamiento Parntesisbienemparejados? Dossecuenciasiguales? NmerosprimosmenoresqueN Bsquedas Bsquedadeunnmeroenunarchivo Bsquedasensecuenciasordenadas


LuisHernndezYez

404 405 409 412 413 417 419 420

Fundamentosdelaprogramacin

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

427 434 441 446 451 467 473 475 477 480 490

LuisHernndezYez

Fundamentosdelaprogramacin

Archivoscomoparmetros Lafuncinmain() Argumentosimplcitos Sobrecargadesubprogramas

498 501 504 508

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

LuisHernndezYez

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

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

CadenasalestilodeC E/SconcadenasalestilodeC Labibliotecacstring Ejemplo

582 583 584 585

LuisHernndezYez

Fundamentosdelaprogramacin

LuisHernndezYez

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

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

Fundamentosdelaprogramacin

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

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

Fundamentosdelaprogramacin

Ordenacinporintercambio Mezcladedoslistasordenadas

744 747

LuisHernndezYez

Fundamentosdelaprogramacin

LuisHernndezYez

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

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

Fundamentosdelaprogramacin

Modularizacindeunprograma

833

LuisHernndezYez

Fundamentosdelaprogramacin

LuisHernndezYez

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

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

Fundamentosdelaprogramacin

Aritmticadepunteros Recorridodearraysconpunteros Referencias Listasenlazadas

940 953 962 964

LuisHernndezYez

Fundamentosdelaprogramacin

LuisHernndezYez

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

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

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

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

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. Programacin en C++ para ingenieros F. Xhafa et al. Thomson, 2006
Fundamentosdelaprogramacin

LuisHernndezYez

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)


LuisHernndezYez

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

Fundamentosdelaprogramacin

Programacin y resolucin de problemas con C++


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

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


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

Programacin en C++ para ingenieros


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 Lenguajemquinayensamblador Lenguajesdeprogramacindealtonivel Unpocodehistoria ProgramacineIngenieradelSoftware EllenguajedeprogramacinC++ Sintaxisdeloslenguajesdeprogramacin UnprimerprogramaenC++ Herramientasdedesarrollo C++:UnmejorC

3 12 15 19 24 27 30 35 39 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 mediante la ejecucin de programas informticos

LuisHernndezYez

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

ParqueJursico

LuisHernndezYez

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

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 8

Esquema general
Memoria temporal
UnidadCentraldeProceso CentralProcessorUnit

Dispositivos de entrada Teclado Ratn Escner Tctil

C.P.U.

Dispositivos de salida Monitor Impresora Altavoz

LuisHernndezYez

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
LuisHernndezYez

Memoria

Unidad de Control

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 10

La memoria
Memoria
01 02 03 04

Cada celda en una direccin Celdas de 8 / 16 / 32 / 64 bits Informacin voltil


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

Bus de datos

05 06 07 08 ...

LuisHernndezYez

Direccin

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
A02F 3E01 A030 3E02 1D B331 Lenguajedebajonivel Acceder a la celda de memoria 2F Dependientedelamquina Programacindifcil Copiarlo el registro 1 de la ALU Acceder a la celda de memoria 30 Copiarlo en el registro 2 de la ALU Sumar Guardar el resultado en la celda de memoria 31
Pgina 13

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Nemotcnicos para los cdigos hexadecimales: A0 READ3E REG1D ADD Mayor legibilidad: READ2F REG01 READ30 REG02 ADD WRITE31 Lenguaje de nivel medio
LuisHernndezYez

Cdigo fuente (lenguaje ensamblador) Programa ensamblador

Cdigo objeto (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
Compiladores:
Compilan y enlazan programas completos

Cdigo fuente

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

Compilador

Intrpretes:
Compilan, enlazan y ejecutan instruccin a instruccin
LuisHernndezYez

Cdigo objeto Enlazador

0100010100111010011100

Cdigo objeto de biblioteca


Paraunaarquitecturaconcreta yunsistemaoperativo

Programa ejecutable
Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 17

Genealoga de lenguajes
Prolog COBOL
1959

Versiones/Estndares
1970

PL/I
1964

C++
1983

Java
1995

FORTRAN
1954

CPL
1963

C
1971

C#
2000

Python ALGOL
1958

Pascal BASIC
1964 1970

Modula
1975

1991

Ada
1979

Eiffel
1986

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

Simula
1964

Smalltalk
1971

Ruby
1993

Haskell Lisp
1958

Scheme
1975

1987

Logo
1968 Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 18

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 19

La prehistoria
El baco

Siglo XIX
Mquina analtica de Charles Babbage

(Wikipedia)

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 1953 IBM 650: Primera computadora a gran escala 1966 ARPANET: Origen de Internet 1967 El disquete 1970 Sistema operativo UNIX 1972 Primer virus informtico (Creeper) Lenguaje de programacin C 1974 Protocolo TCP. Primera red local
Fundamentosdelaprogramacin:Computadorasyprogramacin

ENIAC(Wikipedia)

LuisHernndezYez

Pgina 21

1975 1976 1979 1981 1983 1984 1985 1990


LuisHernndezYez

1991

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

AppleII(Wikipedia)

Linux

IBMPC(Wikipedia)

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

LuisHernndezYez

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

LuisHernndezYez

Algoritmo: Secuencia de pasos y operaciones que debe realizar el programa para resolver el problema El programa implementa el algoritmo en un lenguaje concreto
Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 25

La programacin es slo una etapa del proceso de desarrollo Modelo de desarrollo en cascada:
Planificacin Anlisis Diseo Programacin
LuisHernndezYez

Recursos necesarios, presupuesto, plan, Qu? Cmo? Implementacin

Prueba y depuracin Mantenimiento


Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 26

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 27

Bjarne Stroustrup (1983)


HolaMundo!

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


LuisHernndezYez

return 0; }

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 28

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

Directiva

usingnamespacestd;

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


Comentario

LuisHernndezYez

Instruccin

return 0; }

Dato

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 |significa <nada>::=

LuisHernndezYez

+ 0..9

+23 159 1374 134 3.4 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 134 <numeroentero>::=<signoopcional><secuenciadedgitos> ::=<secuenciadedgitos>::=<dgito><secuenciadedgitos> ::=1<secuenciadedgitos>::=ERROR ( noes<dgito>)
Fundamentosdelaprogramacin:Computadorasyprogramacin

LuisHernndezYez

Pgina 33

+23

+ 0..9

+23 1374

1374

+ 0..9

134
LuisHernndezYez

+ 0..9

Pgina 34

Fundamentosdelaprogramacin:Computadorasyprogramacin

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 Instruccin

#include<iostream> usingnamespacestd;

Espaciodenombres Coloreado sintctico

Tipo Declaracin Bloquedecdigo

Palabrasreservadas Cabeceradelafuncin Cadenadecaracteres Constante

int main() {
Variable

Instruccin

cout<<"HolaMundo!" <<endl;
Operador Datosliterales Operador

LuisHernndezYez

Instruccin

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

LuisHernndezYez

El estilo importa!

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 38

LuisHernndezYez

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 39

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

LuisHernndezYez

Instalacin y uso: Seccin Herramientasdedesarrollo en el Campus Virtual

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 40

hola.cpp (cdigofuente)

Compilador

hola.obj (cdigoobjeto)

Cdigo objeto de la biblioteca iostream


HolaMundo!

Enlazador

Cargador
LuisHernndezYez

hola.exe (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

LuisHernndezYez

Instalacin y uso: Seccin Herramientasdedesarrollo en el Campus Virtual

Fundamentosdelaprogramacin:Computadorasyprogramacin

Pgina 43

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

Pantalla(cout) _ HolaMundo! _

LuisHernndezYez

cout<<"HolaMundo!" <<endl; Muestra HolaMundo! en la pantalla y salta de lnea return0; Devuelve 0 como cdigo 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 Distingue entre maysculas y minsculas Palabras reservadas (o clave): en minsculas
Fundamentosdelaprogramacin:Computadorasyprogramacin Pgina 46

LuisHernndezYez

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

LuisHernndezYez

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

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

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

177 180 183 186 190 199

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

Start; Go North3Blocks; Stop;


Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 51

Sintaxis del lenguaje de programacin


Start instruccin Stop avanzar avanzar Go North
LuisHernndezYez

= Literales ;

direccin

num 1 2 num 3 4 5

Blocks

direccin

East South West

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 52

El problema a resolver
Estando el coche en la posicin A, conseguir llegar al Cine Tvoli (B) Qu pasos hay que seguir? Arrancar Ir un bloque al Norte Ir dos bloques al Este Ir cinco bloques al Norte Ir dos bloques al Este Parar
B

A Bloque:

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 53

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

El programa
Instrucciones escritas en el lenguaje de programacin
B

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 55

El programa
Escribimos el cdigo del programa en un editor y lo guardamos en un archivo:

LuisHernndezYez

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

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

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 56

La compilacin
Introducimos la llave USB en el coche y pulsamos el botn de ejecutar el programa:
Stat; ^Unknown word. Go North1Blocks ^;missing. Go EastBlocks; ^Number missing. Go Noth 5Blocks; ^Unknown word. Go West2Blocks; Stop; There areerrors.Impossible to run the program.

Errores de sintaxis

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 57

Depuracin
Editamos el cdigo para corregir los errores sintcticos:

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


LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 58

La ejecucin
Se realiza lo que pide cada instruccin:
B

Start; Go North1Blocks; Go East3Blocks;

LuisHernndezYez

Error de ejecucin Una instruccin no se puede ejecutar!

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 59

Depuracin
Editamos el cdigo para arreglar el error de ejecucin:

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


LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 60

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; Go North1Blocks; Go East2Blocks; Go North5Blocks; Go West2Blocks; Stop;


LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 62

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!

_
LuisHernndezYez

endl end line

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 <<
Inserta textos en la pantalla de modo texto Representacin textual de los datos A partir de la posicin del cursor

cout<<...;

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

Lascomillasnosemuestran!

endl

Puntodecimal,NOcoma!

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 71

El programa principal
La funcin main(): donde comienza la ejecucin...
#include<iostream> usingnamespacestd; int main() { cout<<"HolaMundo!"<<endl; return 0; }
LuisHernndezYez

//main()esdondeempiezalaejecucin

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() { ... return 0; }
LuisHernndezYez

Es una funcin!

Cuerpo de la funcin (bloque de cdigo)

return 0;

Devuelve el resultado (0) de la funcin

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 73

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

Hasta el final de la lnea: De varias lneas:

// Comentariodeunalnea /* Comentariodevarias lneasseguidas*/


Pgina 74

Fundamentosdelaprogramacin:TiposeinstruccionesI

La infraestructura
Cdigo para reutilizar:
#include<iostream> usingnamespacestd; intmain()//main()esdondeempiezalaejecucin { cout<<"HolaMundo!"<<endl; return0; }
LuisHernndezYez

Una directiva: empieza por #

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

Es una instruccin: termina en ;

Siempre usaremos el espacio de nombres estndar (std) Muchas bibliotecas no tienen espacios de nombres
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 76

Compilacin y enlace
hola.cpp (cdigofuente) Compilador

Amenudoenunpaso hola.obj (cdigoobjeto)

Cdigo objeto de la biblioteca iostream


HolaMundo!
LuisHernndezYez

Enlazador

Cargador

hola.exe (ejecutable)

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 77

Elementos del programa


Biblioteca Directiva Instruccin

#include<iostream> usingnamespacestd;
Palabrasreservadas

Espaciodenombres Coloreadosintctico:
DirectivasTipos Palabrasreservadasgenerales DatosliteralesComentarios

Tipo Declaracin Bloquedecdigo

int main() {
Variable

Cabeceradelafuncin Cadenadecaracteres Constante

Instruccin

cout<<"HolaMundo!" <<endl;
Operador Operador Datosliterales

LuisHernndezYez

Instruccin

return0; }

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;

LuisHernndezYez

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

Cul se lee mejor?

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 operadoroperando_derecho Resultado 7 0.44 286 15.15
Pgina 87

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

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

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 500 /3 500.0 /3 500 /3.0 500.0 /3.0
LuisHernndezYez

Resultado 166 166.667 166.667 166.667

Comprueba siempre que el tipo de divisin sea el que quieres

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 91

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 92

Datos que se mantienen en memoria


Variable: dato que se accede por medio de un nombre Dato literal: un valor concreto Variable: puede cambiar de valor (variar) edad=19;//variableedadyliteral19 Las variables deben ser declaradas Qu tipo de dato queremos mantener? Valor numrico sin decimales (entero): tipo int Valor numrico con decimales (real): tipo double Declaracin: tipo nombre;

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 93

Declaracin de variables
int cantidad; double precio; Se reserva espacio suficiente

tipo nombre;
Memoria cantidad precio ? ? ...

LAS VARIABLES NO SE INICIALIZAN No se deben usar hasta que se les haya dado algn valor
LuisHernndezYez

Dnde colocamos las declaraciones? Siempre, antes del primer uso Habitualmente al principio de la funcin

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 94

Declaracin de variables
#include<iostream> usingnamespacestd; int main() { int cantidad; double precio,total; cantidad precio total

Memoria ? ? ? ...

LuisHernndezYez

return 0; }

Podemos declarar varias de un mismo tipo separando los nombres con comas

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 95

Capacidad de las variables


int 2.147.483.648 ... 2.147.483.647 2147483648 .. 2147483647 double 2,23 x10308 ... 1,79 x 10+308 y sus negativos [+|] 2.23e308 .. 1.79e+308
LuisHernndezYez

Notacin cientfica

Problemas de precisin

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 96

Asignacin de valores a las variables (operador =)


variable = expresin;
Instruccin: termina en ;

cantidad 12 cantidad=12; //int precio=39.95; //double total=cantidad*precio;//Asigna479.4 Concordancia de tipos:


LuisHernndezYez

cantidad=12.5;

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

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 97

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 98

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

Expresin
A igual prioridad se evalan de izquierda a derecha Parntesis para forzar ciertas operaciones total=cantidad1+cantidad2*precio; total=(cantidad1+cantidad2)*precio; Unos operadores se evalan antes que otros
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 99

LuisHernndezYez

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; return 0; }
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 101

LuisHernndezYez

Ejemplo de uso de variables


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

Memoria
? ? ?
...

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 102

Ejemplo de uso de variables


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

Memoria
12 ? ?
...

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 103

Ejemplo de uso de variables


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

Memoria
12 39.95 ?
...

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 104

Ejemplo de uso de variables


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

Memoria cantidad precio total


12 39.95 479.4
...

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 105

Ejemplo de uso de variables


#include<iostream> usingnamespacestd; cantidad precio

Memoria
12 39.95

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 106

Ejemplo de uso de variables


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

LuisHernndezYez

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 108

cin (iostream)

character input stream

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

cin>>cantidad;
Memoria

cin

>>cantidad;
12 _

cantidad

12 ? ...

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

39.95abc

39.95

Se asigna el valor 39,95 a la variable; el resto queda pendiente Recomendacin: Lee cada variable en una lnea 39.95
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 111

Qu pasa si el usuario se equivoca?


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

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

LuisHernndezYez

Lectura correcta!!!

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 114

Divisin de dos nmeros


Pedir al usuario dos nmeros y mostrarle el resultado de dividir el primero entre el segundo Algoritmo. 1. Pedir el numerador
Variablenumerador (double) Datos/clculos

2. Pedir el denominador

Variabledenominador (double)

3. Realizar la divisin, guardando el resultado


LuisHernndezYez

Variableresultado (double) resultado=numerador/denominador

4. Mostrar el resultado
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 115

EntradaProcesoSalida
Muchos programas se ajustan a un sencillo esquema:

Declaraciones

Entrada

Procesamiento

Salida

1. Leer numerador 2. Leer denominador


LuisHernndezYez

3. Calcular divisin en resultado 4. Mostrar resultado

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 116

Divisin de dos nmeros


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

Leer numerador
cin>>numerador;

Leer denominador
cin>>denominador;

Calcular divisin en resultado Mostrar resultado


resultado=numerador/denominador;

4.

cout<<resultado;
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 117

Divisin de dos nmeros


#include<iostream> usingnamespacestd;

divisin.cpp
Numerador:_ 129

_ Denominador: 2 _ _ Resultado: _ 64.5 64.5

LuisHernndezYez

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

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 cout cin 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
LuisHernndezYez

variable variable

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 121

Datos que maneja el programa: tipos


Objeto Pantalla "Introduzcalabasedeltringulo:" Basedeltringulo Teclado "Introduzcalaalturadeltringulo:" Alturadeltringulo readeltringulo
LuisHernndezYez

Tipo

Vara? Variable Constante

Nombre cout ninguno base cin ninguno altura area

double

Variable Variable Constante

double double

Variable Variable

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.

LuisHernndezYez

area =base*altura/2

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 123

Secuencia de acciones que ha de realizar el programa para conseguir resolver el problema


1. Mostrar en la pantalla el texto que pida la base del tringulo 2. Leer del teclado el valor para la base del tringulo 3. Mostrar en la pantalla el texto que pida la altura 4. Leer del teclado el valor para la altura del tringulo 5. Calcular el rea del tringulo 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 traducido a cdigo en C++


LuisHernndezYez

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

return 0; }

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 125

tringulo.cpp

El programa: implementacin
#include<iostream> usingnamespacestd; tringulo?

LuisHernndezYez

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

Recuerda: las instrucciones terminan en ;


Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 126

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 127

Variabilidad de los datos


"Introduzcalabasedeltringulo:" 3.141592653589

Literales Constantes Datos Variables


LuisHernndezYez

Con nombre Pi=3.141592653589

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
LuisHernndezYez

totalbasealturaarea

numerador

Al menos 32 caracteres significativos


Ni ees ni vocales acentuadas!
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 130

Palabras reservadas del lenguaje C++


asm autoboolbreakcasecatchcharclassconst continuedefaultdeletedodouble elseenumexplicitexternfalse ifinlineintlong const_cast dynamic_cast

floatforfriendgoto

mutablenamespacenewoperatorprivateprotected publicregisterreinterpret_cast signedsizeofstaticstatic_cast


LuisHernndezYez

returnshort structswitch

templatethisthrowtruetrytypedeftypeid typename unionunsignedusingvirtualvoid

volatilewhile
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 131

a..z,A..Z,_

Qu identificadores son vlidos?


balance

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

interesAnual

_base_imponible

__edad valor%100
EDAD12 100caracteres
LuisHernndezYez

aos

_12_meses

clculoNmina AlgunValor valor? ____valor


salario_1_mes
Pgina 132

Fundamentosdelaprogramacin:TiposeinstruccionesI

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 133

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

125 true 'a' 3.14159 "Hola"

El conjunto (intervalo) de valores vlidos El conjunto de operaciones que se pueden realizar

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

LuisHernndezYez

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

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

1 byte

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 136

Valores lgicos
Slo dos valores posibles: Verdadero (true) Falso (false) Literales: truefalse 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;

"

LuisHernndezYez

Las comillas tipogrficas (apertura/cierre) NO sirven 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; cout<<"Cadena:" <<cadena<<endl; return 0; }

LuisHernndezYez

Cuntos nmeros hay en total en el programa? Y caracteres? Y cadenas? Y booleanos?


Pgina 140

Fundamentosdelaprogramacin:TiposeinstruccionesI

signed / unsigned : con signo (por defecto) / sin signo short / long : menor / mayor intervalo de valores

Tipo int unsignedint shortint longint unsignedlongint


LuisHernndezYez

Intervalo 2147483648 .. 2147483647 0 .. 4294967295 32768 .. 32768 2147483648 .. 2147483647 0 .. 4294967295 +| 2.23e308 .. 1.79e+308 +| 3.37E4932 .. 1.18E+4932

unsignedshortint 0 .. 65535

double longdouble

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;

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 143

Se reserva memoria suficiente para cada tipo de dato int inicio; shortintunidades; double balance;
Memoria
inicio
01 02 03 04

unidades balance

05 06 07 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:

LuisHernndezYez

Identificador

Expresin

Expresin: valor compatible

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

Enparticular,unaexpresin 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;
LuisHernndezYez

Las variables han de haber sido previamente declaradas

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
LuisHernndezYez

5;

//ERROR:expresinnovlida(faltaoperador)

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 149

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


Memoria Memoria

i j

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

? 2

i
23 +2 *5

01 02 03 04

33 2
...

05 06 07 08 09 10

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 150

Necesitamos una variable auxiliar double a=3.45,b=127.5,aux;


a b aux 3.45 127.5 ? a 3.45 127.5 3.45 127.5 127.5 3.45 127.5 3.45 3.45

aux=a;

b aux a

a=b;

b aux

LuisHernndezYez

b=aux;

b aux

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: Asignacin (=) Operadores relacionales (menor, mayor, igual, ...)
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 153

LuisHernndezYez

Operadores para tipos de datos numricos


Operador Operandos Posicin + * / % ++
LuisHernndezYez

int

float / double
Cambiodesigno Suma Resta Producto

1(monario) Prefijo 2(binario) 2(binario) 2(binario) 2(binario) 2(binario) Infijo Infijo Infijo Infijo Infijo

Div.entera Mdulo

Divisinreal Noaplicable

1(monario) Prefijo/postfijo 1(monario) Prefijo/postfijo

Incremento Decremento

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 154

Operadores monarios y operadores binarios


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

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


++interes mesesj++ //1ms1menos

LuisHernndezYez

Operadores binarios Operando izquierdo operador operando derecho Operandos: literales, constantes, variables o expresiones
2 +3 a*RATIOa+b (a%b)*(c/d)
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 155

Divisin entera o divisin real?


Ambos operandos enteros: divisin entera int i=23,j=2; cout<<i/j;//Muestra11 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
LuisHernndezYez

5 24

3
123 %5

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 157

Operadores de incremento y decremento


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

++/

Incremento/decremento de la variable numrica en una unidad


int i=10,j; j=++i;//Incrementaantesdecopiar cout<<i<<" "<<j;//Muestra11 11 int i=10,j; j=i++;//Copiaydespusincrementa cout<<i<<" "<<j;//Muestra11 10 No mezcles ++ y con otros operadores
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 158

Postfijo: Despus de acceder


j=i; i=i+1;
LuisHernndezYez

#include<iostream> usingnamespacestd;

operadores.cpp

LuisHernndezYez

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

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 160

En qu orden se evalan los operadores?


3 +5 *2 /2 1
De izquierda a derecha? De derecha a izquierda? Unos antes que otros? 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
Mayor prioridad

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

Menor prioridad

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

LuisHernndezYez

Misma precedencia: Izquierda antes

Mayor precedencia

Misma precedencia: Izquierda antes

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 162

((3 + 5)*4 +12)/4 (3 * 2 1) (8 *4 +12)/4 * antes que + (32 +12)/4 44 /4 5 / antes que 11 5
LuisHernndezYez

Primero, los parntesis...

* antes que (6 1)

Pon espacio antes y despus de cada operador binario

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 a=a+12; a=a*3; a=a 5; a=a/37; a=a%b; Abreviatura a+=12; a*=3; a=5; a/=37; a%=b;

Igual precedencia que la asignacin De momento, mejor evitarlas

LuisHernndezYez

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 0 = positivo + 0 0 0 0 0 0 0 0 1 = negativo


1 0 0 0 0 0 0 0
LuisHernndezYez

1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 1

32767 + 1 32768

0 0 0 0 0 0 0 0

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 La constante no podr volver a aparecer a la izquierda de un =

constshortintMeses=12; constdouble Pi=3.141592, RATIO=2.179 *Pi;

LuisHernndezYez

Programacin con buen estilo: Pon en mayscula la primera letra de una constante o todo su nombre

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 168

Aumentan la legibilidad del cdigo


cambioPoblacion =(0.1758 0.1257)*poblacion;

vs.

cambioPoblacion =(RatioNacimientos RatioMuertes)*poblacion;

Facilitan la modificacin del cdigo


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

LuisHernndezYez

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; total=neto+porIVA; cout<<"Totalcompra:"<<total<<endl; return 0; }
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 170

LuisHernndezYez

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 171

#include<cmath>
Algunas ... abs(x) sqrt(x) ceil(x) floor(x) exp(x) log(x) log10(x) sin(x) cos(x)
LuisHernndezYez

Valor absoluto de x Raz cuadrada de x Menor entero que es mayor o igual que x Mayor entero que es menor o igual que x ex Ln x (logaritmo natural de x) Logaritmo en base 10 de x Seno de x Coseno de x Tangente de x Redondeo al entero ms prximo Prdida de la parte decimal (entero)
Pgina 172

pow(x,y) x elevado a y

tan(x) round(x) trunc(x)

Fundamentosdelaprogramacin:TiposeinstruccionesI

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; }
Pon un espacio detrs de cada coma en las listas de argumentos
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 173

LuisHernndezYez

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 174

char
Asignacin, ++/ y operadores relacionales

Funciones para caracteres (biblioteca cctype)


isalnum(c) isalpha(c) isdigit(c) islower(c) isupper(c) toupper(c) tolower(c) true si c es una letra o un dgito true si c es una letra true si c es un dgito true si c es una letra minscula true si c es una letra mayscula false en caso contrario
LuisHernndezYez

devuelve la mayscula de 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; cout<<"Alfabtico?"<<isalpha(caracter3)<<endl; cout<<"Dgito?"<<isdigit(caracter3)<<endl; return 0; 1 true / 0 false }
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 176

LuisHernndezYez

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)


< <= >
LuisHernndezYez

menor que menor o igual que mayor que mayor o igual que igual que distinto de

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


Pgina 178

>= == !=

Fundamentosdelaprogramacin:TiposeinstruccionesI

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
LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 179

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 180

Seleccin: bifurcacin condicional


true cdigoT Condicin false cdigoF

LuisHernndezYez

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

if (condicin) { cdigoT } else{ cdigoF }

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; } return0; }
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 182

LuisHernndezYez

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 183

Agrupacin de instrucciones
Grupo de instrucciones a ejecutar en una rama del if
{ instruccin } {
Tab 3 esp.

LuisHernndezYez

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

intruccin1 intruccin2 ... intruccinN

mbito local (declaraciones locales)

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 184

Posicin de las llaves: cuestin de estilo


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

No necesitamos las llaves si slo hay una instruccin


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

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

Usaremos siempre llaves por simplicidad... Evita poner el if y la instruccin objetivo en la misma lnea:
if (num>0)cout<<"Positivo";
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 185

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 186

Repeticin o iteracin condicional


while ( condicin ) cuerpo
Bloque de cdigo

true Cuerpo

Condicin

false

while (condicin) { 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 <<")=" <<suma<<endl; return0; }
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 188

LuisHernndezYez

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

5 6 2 3 4 5 1 15 10 1 3 6 0

i<=n

false

suma

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 189

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 190

Flujos de texto (streams)

#include<iostream> 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
7 3 5 . 3 5 1

cout
Programa 1
6 = l a t o T

Biblioteca iostream con espacio de nombres std


LuisHernndezYez

Extractor Insertor

Flujodeentrada Flujodesalida

>> <<

Variable Expresin
Pgina 191

Fundamentosdelaprogramacin:TiposeinstruccionesI

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 cout<<"Introducetuedad:"; cin>>edad;
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 192

LuisHernndezYez

#include<string> usingnamespacestd;

cin>>cadena cin.sync()

termina con el primer espacio en blanco descarta la entrada pendiente


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

string nombre,apellidos; cout<<"Nombre:"; cin>>nombre; cout<<"Apellidos:"; cin>>apellidos; cout<<"Nombrecompleto:" <<nombre<<"" <<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;
LuisHernndezYez

La biblioteca iostream define la constante endl como un salto de lnea

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

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 195

cout

<<

Expresin

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

Total: 123.45 Meses: 7

cout<<meses;

Fundamentosdelaprogramacin:TiposeinstruccionesI

Pgina 196

#include<iomanip> Constantes y funciones a enviar a cout para ajustar el formato de salida Biblioteca Constante/funcin
iostream showpoint/ noshowpoint fixed scientific boolalpha left/right iomanip setw(anchura)* setprecision(p)
LuisHernndezYez

Propsito
Mostrar o no el punto decimal para reales sin decimales (34.0) Notacin de punto fijo (reales) (123.5) Notacin cientfica (reales) (1.235E+2) Valores bool como true / false Ajustar a la izquierda/derecha (por defecto) N de caracteres (anchura) para el dato Precisin: N de dgitos (en total) Con fixed o scientific, n de decimales

*setw() slo afecta al siguiente dato que se escriba, mientras que los otros afectan a todos
Fundamentosdelaprogramacin:TiposeinstruccionesI Pgina 197

bool fin=false; cout<<fin<<">" <<boolalpha <<fin<<endl; double d=123.45; char c='x'; int i=62; cout<<d<<c<<i<<endl; cout<<"|" <<setw(8)<<d<<"|"<<endl; cout<<"|" <<left<<setw(8)<<d<<"|"<<endl; cout<<"|" <<setw(4)<<c<<"|"<<endl; cout<<"|" <<right<<setw(5)<<i<<"|"<<endl; double e=96;
LuisHernndezYez

0>false

123.45x62 |123.45| |123.45| |x| |62| 96 96.0000 1.234500e+002 123.45000000

cout<<e<<" "<<showpoint<<e<<endl; cout<<scientific<<d<<endl; cout<<fixed<<setprecision(8)<<d<<endl;

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 }

LuisHernndezYez

Tipo de dato que devuelve la funcin como resultado Parmetros para proporcionar datos a la funcin Declaraciones de variables separadas por comas Cuerpo: secuencia de declaraciones e instrucciones Un bloque de cdigo!

Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 200

Datos locales: declarados en el cuerpo de la funcin Datos auxiliares que utiliza la funcin (puede no haber) Parmetros: declarados en la cabecera de la funcin Datos de entrada de la funcin (puede no haber) Ambos son de uso exclusivo de la funcin y no se conocen fuera
double f(intx,int y){ //Declaracindedatoslocales: double resultado; //Instrucciones: resultado=2 *pow(x,5) +sqrt(pow(x,3) /pow(y,2)) /abs(x*y) cos(y); return resultado;//Devolucindelresultado }
Fundamentosdeprogramacin:TiposeinstruccionesI Pgina 201

LuisHernndezYez

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
LuisHernndezYez

Llamadas a la funcin: en expresiones de otras funciones


int valor=f(2,3);

Fundamentosdeprogramacin:TiposeinstruccionesI

Pgina 202

Se copian los argumentos en los parmetros


int funcion(int x,double a){ ... } int main(){ int i=124; double d=3; funcion(i,33 *d); ...
LuisHernndezYez

Memoria i d 124 3.0 ...

... x a 124 99.0 ...

return0;//main()devuelve0alS.O. } Los argumentos no se modifican


Pgina 203

Fundamentosdeprogramacin:TiposeinstruccionesI

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){ return x*x; x=x*x;
LuisHernndezYez

int main(){ cout<<2 *cuad(16); 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 ;
LuisHernndezYez

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

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

LuisHernndezYez

else{ cout<<"Impar"; } cout<<endl; if (numero>1){ cout<<"Sumatoriode1a" <<numero<<":" <<suma(numero)<<endl; } cout<<"Carcter:"; cin>>caracter; if(!letra(caracter)){ cout<<"no"; } cout<<"esunaletra" <<endl; cout<<"f(x,y)=" <<formula(x,y)<<endl; //Losargumentospuedenllamarseigualonoquelosparmetros
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++; } return sum; } ...
Fundamentosdeprogramacin:TiposeinstruccionesI Pgina 209

LuisHernndezYez

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 float Notacincientfica double char bool string Literalesconespecificacindetipo

214 216 217 218 220 221 222 223

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

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

01 02 03 04 05 06

+ 0..9 Notacin octal


LuisHernndezYez

07 08

0..9 0 x 0..7 0..9,A..F

09 ...

Notacin hexadecimal

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 AD = A x 161 + D x 160 = 10 x 16 + 13 = 160 + 13

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 215

Nmeros reales (con decimales)


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

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

Notacin cientfica: 1.4E2, 5.23e02


LuisHernndezYez

+ 0..9
Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

+ . 0..9 e,E
Pgina 216

0..9

Siempre un nmero (con o sin signo) con un solo dgito de parte entera, seguido del exponente (potencia de 10): 5.23e2 1.11e2 7.4523e04 5,23 x 102 1,11 x 102 7,4523 x 104 0,0523 111,0 0,00074523 3.333.300

3.3333e+06 3,3333 x 106

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 217

Nmeros reales (con decimales)


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

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

Notacin cientfica: 1.4E2, 5.23e02


LuisHernndezYez

+ 0..9
Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

+ . 0..9 e,E
Pgina 218

0..9

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

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

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

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 219

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 220

Valores lgicos
Slo dos valores posibles: Verdadero (true) Falso (false) Bytes de memoria: 1 (FC) Literales: true, false En realidad, cualquier nmero distinto de 0 es equivalente a true y el nmero 0 es equivalente a false
LuisHernndezYez

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

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

Ojo! Las comillas tipogrficas (apertura/cierre) te darn problemas al compilar. Asegrate de utilizar comillas rectas: ""

Fundamentosdelaprogramacin:TiposeinstruccionesI(Anexo)

Pgina 222

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

Abreviaturas para modificadores de tipos


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

LuisHernndezYez

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

LuisHernndezYez

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

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

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

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

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; int j=9; char c='a'; double x=1.5;
i j c a x 1.5 3 9

LuisHernndezYez

El significado de los bits depende del tipo de la variable: 00000000000000000000000001111000 Interpretado como int es el entero 120 Interpretado como char (slo 01111000) es el carcter 'x'

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 229

Simples

Estndar: int, float, double, char, bool Conjunto de valores predeterminado Definidos por el usuario: enumerados Conjunto de valores definido por el programador

Estructurados (Tema 5)

Colecciones homogneas: arrays Todos los elementos de la coleccin de un mismo tipo Colecciones heterogneas: estructuras Elementos de la coleccin de tipos distintos

LuisHernndezYez

Fundamentosdeprogramacin:TiposeinstruccionesII

Pgina 230

Con sus posibles modificadores: [unsigned][short] int longlong int float [long] double char bool Definicin de variables: tipo nombre [=expresin][,...]; Definicin de constantes con nombre: consttipo nombre =expresin;
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 231

longint int

LuisHernndezYez

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; int j=2; double a=1.5,b; b=a+i*j; b=a+3 *2;
LuisHernndezYez

long double

Promocin

double float long int int short int

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

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

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

long double double float long int

Conversin no segura: int De un tipo mayor a un tipo menor short int intentero=1234; char caracter; caracter =entero;//Conversinnosegura 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;

LuisHernndezYez

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;
moneda1 (Internamente se usan enteros)
Fundamentosdelaprogramacin:TiposeinstruccionesII

dos_centimos euro
Pgina 240

moneda2

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

Se ver un nmero entero 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; cout<<"12 Diciembre" <<endl; cout<<"Numerodemes:"; cin>>op; tMes mes=tMes(op 1);
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 242

LuisHernndezYez

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

LuisHernndezYez

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

Tambin podemos utilizar una instruccin switch


Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 243

Conjunto de valores ordenado (posicin en la enumeracin)


typedefenum{lunes,martes,miercoles,jueves, viernes,sabado,domingo}tDiaSemana; tDiaSemana dia; ... if(dia ==jueves)... bool noLaborable =(dia >=sabado);
lunes <martes <miercoles <jueves <viernes <sabado <domingo

No admiten operadores de incremento y decremento Emulacin con moldes:


LuisHernndezYez

int i=int(dia);//dia nohadevalerdomingo! i++; dia =tDiaSemana(i);


Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 244

#include<iostream> usingnamespacestd;

Si los tipos se usan en varias funciones, los declaramos antes de los prototipos

typedef enum{enero,febrero,marzo,abril,mayo, junio,julio,agosto,septiembre,octubre, noviembre,diciembre }tMes; typedef enum {lunes,martes,miercoles,jueves, viernes,sabado,domingo }tDiaSemana; string cadMes(tMes mes); string cadDia(tDiaSemana dia); int main(){ tDiaSemana hoy=lunes; int dia =21; tMes mes=octubre; int anio =2013; ...
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 245

LuisHernndezYez

//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; return 0; }
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 246

LuisHernndezYez

fechas.cpp string cadMes(tMes mes){ string cad; if (mes==enero){ cad ="enero"; } if (mes==febrero){ cad ="febrero"; } ... if (mes==diciembre){ cad ="diciembre"; }
LuisHernndezYez

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

return cad; }

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 247

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
LuisHernndezYez

(Ms adelante veremos el uso de archivos binarios)

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 ... Normalmente terminan con un dato especial (centinela) Por ejemplo, un NIF que sea X
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 251

LuisHernndezYez

#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


Para leer de un archivo de texto: 1 Declara una variable de tipo ifstream

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); ifstream archivo; archivo.open("abc.txt"); if(archivo.is_open())...

El archivo debe existir!


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

Cierre del archivo


flujo.close();
LuisHernndezYez

Desconecta la variable del archivo de texto del dispositivo


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 Hasta el siguiente salto de lnea (descartndolo) Con los archivos no tiene efecto la funcin sync()
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 256

LuisHernndezYez

Qu debo leer?
Un nmero Usa el extractor Un carcter (sea el que sea) Usa la funcin get() Una cadena sin espacios Usa el extractor archivo>>num; archivo.get(c); archivo>>cad;

LuisHernndezYez

Una cadena posiblemente con espacios Usa la funcin getline() getline(archivo,cad);

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 257

Dnde queda pendiente la entrada?


Nmero ledo con el extractor En el primer carcter no vlido (inc. espacios en blanco) Carcter ledo con get() En el siguiente carcter (inc. espacios en blanco) 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; 2 archivo.open("compras.txt");//Apertura 3 archivo>>nif >>unidades>>precio; getline(archivo,producto); 4 archivo.close();//Cierre
LuisHernndezYez 7 6 5 4 3 2 1

Flujo de entrada archivo

Programa

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
LuisHernndezYez

unidades 2 precio 123.95

producto

ReproductordeDVD

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
LuisHernndezYez

unidades 2 precio 123.95

producto ReproductordeDVD 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 Calcular y mostrar el total Leer el siguiente NIF
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 262

LuisHernndezYez

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

leer.cpp

LuisHernndezYez

Pgina 263

LuisHernndezYez

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

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

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 265

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 266

Flujos de texto de salida


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

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

1 ofstream archivo; 2 archivo.open("output.txt");//Apertura 3 archivo<<'X' <<"Hola!" <<123.45 <<endl<<valor<<"Bye!"; 4 archivo.close();//Cierre

2 1

! a l o H

Flujo de salida archivo

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

LuisHernndezYez

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

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

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 271

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 272

{ double oper1,oper2,prod; cout<<"Operando1:"; cin>>oper1; cout<<"Operando2:"; ... cout<<"Producto:" <<prod;


InstruccinN

Flujo de ejecucin

Instruccin1 Instruccin2 Instruccin3

LuisHernndezYez

return 0; }

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 273

Uno entre dos o ms caminos de ejecucin


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

true

Condicin

false

false true

InstruccinT

InstruccinF

false true false

if
LuisHernndezYez

ifelseif switch Diagramasdeflujo


Fundamentosdelaprogramacin:TiposeinstruccionesII

true false

Pgina 274

Repetir la ejecucin de una o ms instrucciones


Acumular, procesar colecciones, ...

Inicializacin

Iterar?

No

Cdigo
LuisHernndezYez

while
Fundamentosdelaprogramacin:TiposeinstruccionesII

for
Pgina 275

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 276

La instruccin if
if (condicin){ cdigoT } [else { cdigoF }]
true
BloqueT Condicin

false
BloqueF Opcional

LuisHernndezYez

condicin: expresin bool Clusula else opcional

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 277

signo.cpp

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

cout<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 278

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


num<0
cout<<"Positivo";
LuisHernndezYez

_29 1 129 _ Positivo _

cin>>num;

false
num 129 ?

cout<<endl;

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 279

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


num<0
num ? 5

5 Negativo

cin>>num;

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; cout<<"Resultado:" <<resultado<<endl; } return 0; }
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 281

LuisHernndezYez

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 282

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

! && ||

NO Y O

Monario Binario Binario

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

LuisHernndezYez

&& ||

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 283

! true false false true

&& true false

true true false

false false false

|| true false

true true true

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


LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 284

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

LuisHernndezYez

Encierra las condiciones simples entre parntesis!

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


Pgina 285

Fundamentosdelaprogramacin:TiposeinstruccionesII

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; } else{ dias =30; } }
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 287

LuisHernndezYez

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

LuisHernndezYez

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

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

LuisHernndezYez

La sangra ayuda a asociar los else con sus if


Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 289

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 290

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

Expresin lgica (true/false) Sin operadores lgicos

Compatibilidad con el lenguaje C: 0 es equivalente a false Cualquier valor distinto de 0 es equivalente a true

Condicin compuesta: Combinacin de condiciones simples y operadores lgicos


!isalpha(car) (num<0)|| (car=='a') (num<0)&& ((car=='a')||!isalpha(car)) No confundas el operador de igualdad (==) con el operador de asignacin (=).
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 291

LuisHernndezYez

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) Como la primera sera false: no se evala la segunda!

LuisHernndezYez

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)

true ==10 false true cout<<"MH"

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

>=9 false true >=7 false true >=5 false

cout<<"SB"

cout<<"NT"

cout<<"AP" cout<<"SS"

si no SS

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 296

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

LuisHernndezYez

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


Pgina 298

LuisHernndezYez

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

Simplificacin de las condiciones


0 SS 5 AP 7 NT

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


Siempre true: ramas else Si no es 10, es menor que 10 if (nota==10){cout<<"MH";} Si no es >= 9, es menor que 9 else if (nota>=9){cout<<"SB";} Si no es >= 7, es menor que 7 else if (nota>=7){cout<<"NT";}

9 SB 10 MH

LuisHernndezYez

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(){ Sinum==2 entoncesMedio int num; cout<<"Introduceelnivel:"; Sinum==1 entoncesBajo cin>>num; if (num==4){ cout<<"Muyalto" <<endl; } elseif (num==3){ cout<<"Alto" <<endl; } elseif (num==2){ cout<<"Medio" <<endl; } elseif (num==1){ cout<<"Bajo" <<endl; } else{ cout<<"Valornovlido" <<endl; } return 0; }
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 300

LuisHernndezYez

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

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 301

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 302

Seleccin entre valores posibles de una expresin


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

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 303

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

Si num==4 Muy alto Si num==3 Alto Si num==2 Medio Si num==1 Bajo

LuisHernndezYez

Pgina 304

Interrumpe el switch; contina en la instruccin que le siga


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

Num:3 Alto

LuisHernndezYez

Pgina 305

LuisHernndezYez

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

Num:3 Alto Medio Bajo Valornovlido

Pgina 306

true
num==4 Muyalto break; Sin break;

false true
num==3

Alto break; Sin break;

false true
num==2

Medio break; Sin break; Bajo Sin break;


Novlido

false true
num==1

break;

false
LuisHernndezYez

default

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 307

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

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

LuisHernndezYez

Pgina 308

LuisHernndezYez

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

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 310

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

case case {

7: 8:

LuisHernndezYez

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

Pgina 311

LuisHernndezYez

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

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 313

Inicializacin

S Cuerpo

Iterar?

No

LuisHernndezYez

Bucles while y for

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 314

Nmero de iteraciones condicionado (recorrido variable):

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

Nmero de iteraciones prefijado (recorrido fijo):

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 315

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


LuisHernndezYez

Muestra los nmeros del 1 al 100

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 317

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


i=1

true Cuerpo

Condicin

false

100 101 99 ? 3 2 1 4 true


i<=100

_ 1

false

2 3 99 100

cout<<i<<endl;
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; }
LuisHernndezYez

Si el usuario introduce un nmero entre 0 y 4: No se ejecuta el cuerpo del bucle

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 319

primero.cpp

Primer entero cuyo cuadrado es mayor que 1.000


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

Empezamosen1 Incrementamosen1

LuisHernndezYez

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

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


Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 320

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

LuisHernndezYez

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++)... for(int i=100;i>=1;i)...
LuisHernndezYez

1,2,3,4,5,...,100 100,99,98,97,...,1

Tantos ciclos como valores toma la variable contadora

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 323

for(inicializacin;condicin;paso)cuerpo

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


i=1

true

i<=100

false

cout<<i;
LuisHernndezYez

i++

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 324

for1.cpp

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


i
? 100 101 2 1 3

...
true

i=1
i<=100 false

1 2 3 99 100

cout<<i<<endl; i++
LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 325

La variable contadora
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

for2.cpp

Muy importante El cuerpo del bucle NUNCA debe alterar el valor del contador

Garanta de terminacin
LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 326

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

LuisHernndezYez

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... Cada vez ms lejos del valor final (100) Es un error de diseo/programacin
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 328

LuisHernndezYez

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

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

Bucle for equivalente? No sabemos cuntos nmeros introducir el usuario!


Pgina 330

Fundamentosdelaprogramacin:TiposeinstruccionesII

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++){ for(int j=1;j<=5;j++){ cuerpo } } Para cada valor de i el valor de j vara entre 1 y 5
LuisHernndezYez

j vara ms rpido que i

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

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

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 332

tablas.cpp

#include<iostream> usingnamespacestd; #include<iomanip> int main(){ for(int i=1;i<=10;i++){ for(int j=1;j<=10;j++){ cout<<setw(2)<<i<<"x" <<setw(2)<<j<<"=" <<setw(3)<<i*j<<endl; } }
LuisHernndezYez

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

return 0; }
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 333

tablas2.cpp

#include<iostream> usingnamespacestd; #include<iomanip> int main(){ for(int i=1;i<=10;i++){ cout<<"Tabladel"<<i<<endl; cout<<""<<endl; for(int j=1;j<=10;j++){ cout<<setw(2)<<i<<"x" <<setw(2)<<j<<"=" <<setw(3)<<i*j<<endl; } cout<<endl; } return 0; }
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 334

LuisHernndezYez

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<<"=" <<setw(3)<<i*j<<endl; } } } break;...
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 335

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 336

LuisHernndezYez

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

LuisHernndezYez

while (opcion!=0){ ... for(int i=1;i<=10;i++){ for(int j=1;j<=10;j++){ ... } } while (num<=0){ ... suma() } for(int i=1;i<=n;i++){ ... } while ((op <0)||(op >2)){ ... } menu() }
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 338

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 339

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

LuisHernndezYez

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

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 341

LuisHernndezYez

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

LuisHernndezYez

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

LuisHernndezYez

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

LuisHernndezYez

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

LuisHernndezYez

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

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

LuisHernndezYez

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

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 349

Sucesin de elementos de un mismo tipo que se acceden linealmente


elemento secuencia (Secuencia vaca) secuencia o 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 (sucesor), si es que existe Todos los elementos, de un mismo tipo
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 350

LuisHernndezYez

No tratamos secuencias infinitas: siempre hay un ltimo elemento Secuencias explcitas:

Sucesin de datos de un dispositivo (teclado, disco, sensor, ...) Frmula de recurrencia que determina el elemento siguiente

Secuencias calculadas:

Listas (ms adelante) Secuencias explcitas que manejaremos: Datos introducidos por el teclado o ledos de un archivo
LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 351

Secuencia explcita leda de archivo: Detectar la marca de final de archivo (Eof End of file) Detectar un valor centinela al final Secuencia explcita leda del teclado: Preguntar al usuario si quiere introducir un nuevo dato Preguntar al usuario primero cuntos datos va a introducir Detectar un valor centinela al final Valor centinela: Valor especial al final que no puede darse en la secuencia (Secuencia de nmeros positivos centinela: cualquier negativo)
12 4 37 23 8 19 83 63 2 35 17 76 15 1
Pgina 352

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

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

37 23

19 83 63 1 35 17 76 15 No se procesan

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 353

Tratamiento de los elementos uno a uno desde el primero

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

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

LuisHernndezYez

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

Al final?

true

false
Obtener elemento Procesar elemento

No sabemos cuntos elementos hay No podemos implementar con for

LuisHernndezYez

Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 357

Implementacin con while


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

Centinela?

true

false
Procesar elemento 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; } cout<<"Suma="<<suma<<endl; Finalizacin

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 359

Longitud de una secuencia de caracteres


Centinela: carcter punto (.)

longitud.cpp

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 360

Cuntas veces aparece un carcter en una cadena?


Centinela: asterisco (*)
cont.cpp

LuisHernndezYez

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

Suma de los nmeros de la secuencia


Centinela: 0

suma2.cpp

LuisHernndezYez

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

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 363

sumatorio.cpp

Recurrencia:

ei+1 = ei + 1

e1 = 1

12345678... Suma de los nmeros de la secuencia calculada:


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

LuisHernndezYez

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

sumatorio=0; int i=1;

n sumatorio i

5 ? 15 10 1 0 3 6

i<=n
2 5 4 1 3 6 24 1 3 4 5 13 2 3 12 2 11

false

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

LuisHernndezYez

Secuencia

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

LuisHernndezYez

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 } }
Demasiados comentarios? Para no oscurecer el cdigo, mejor una explicacin al principio
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 367

LuisHernndezYez

El bucle calcula adecuadamente la secuencia:


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

01 1 2 3 5 ...

5 2 3 1 ? 3 1 2 ? 2 1 0 ?

fibMenos1 fibMenos2

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 Variable lgica que indique si se ha encontrado

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 370

Localizacin del primer elemento con una propiedad


Inicializacin / encontrado=false; true

Al final o encontrado?

false

Obtener elemento Encontrado?


LuisHernndezYez

Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 371

Implementacin con while


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

Encontrado o centinela?

true

false
Obtener siguiente

LuisHernndezYez

Finalizacin

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 372

Primer nmero mayor que uno dado


Centinela: 1

busca.cpp

LuisHernndezYez

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

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

vMar 76.95

vMie 328.80

vJue 254.62

vVie 435.00

vSab 164.29

vDom 0.00

... declaramos una tabla de N valores:


ventas 125.40 ndices 0
76.95 1 328.80 254.62 435.00 164.29 2 3 4 5 0.00 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
0 76.95 1 328.80 254.62 435.00 164.29 2 3 4 5 0.00 6

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII

Declaracin de tipos de arrays


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

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 377

Declaracin de variables arrays


tipo nombre; Ejemplos:
tTemp tempMax; tDiasMes diasMes; tVocales vocales; tVentas ventasFeb;

typedef typedef typedef typedef

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

tempMax ? ? ? ? ? ? ?
0 1 2 3 4 5 6

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

vocales ? ? ? ? ?
0 1 2 3 ... 4

LuisHernndezYez

ventasFeb ? ? ? ? ? ? ? ? ? ? ? ? ?
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;
vocales 'a'
0

typedef char tVocales[5];

'e'
1

'i'
2

'o'
3

'u'
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]

LuisHernndezYez

Qu es ventas[100]? O ventas[1]? O ventas[132]? Memoria de alguna otra variable del programa!


Define los tamaos de los arrays con constantes
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 381

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 0

10.96 1

8.43 2

11.65 3

13.70 4

13.41 5

14.07 6

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


i=0

Memoria Dias temp[0] temp[1] temp[2] temp[3] temp[4] 7 12.40 10.96 8.43 11.65 13.70 13.41 14.07 ? 23.36 31.79 84.62 12.40 0.00 43.44 3 0 2 7 4 1

true i<Dias
total+=temp[i]

false

temp[5] temp[6]

...

media total i

LuisHernndezYez

i++

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

LuisHernndezYez

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


LuisHernndezYez

Las funciones no pueden devolver arrays

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 386

constint Cuantas=15; typedefenum {centimo,dos_centimos,cinco_centimos, diez_centimos,veinte_centimos,medio_euro,euro }tMoneda; typedef tMoneda tCalderilla[Cuantas]; 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; ... for(int moneda=0;moneda<Cuantas;moneda++) cout<<aCadena(bolsillo[moneda])<<endl;

LuisHernndezYez

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++; } } if (!encontrado){ ind =1; } returnind; }
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 389

LuisHernndezYez

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;

LuisHernndezYez

contador: indica cuntas posiciones del array se utilizan Slo accederemos a las posiciones entre 0 y contador1 Las dems posiciones no contienen informacin del programa

Fundamentosdelaprogramacin:TiposeinstruccionesII

Pgina 394

lista.cpp #include<iostream> usingnamespacestd; #include<fstream> const int Max=100; typedef double tArray[Max]; double media(const tArray lista,int cont); int main(){ tArray lista; int contador=0; double valor,med; ifstream archivo; archivo.open("lista.txt"); if (archivo.is_open()){ archivo>>valor; while ((valor!=1)&&(contador<Max)){ lista[contador]=valor; contador++; archivo>>valor; }...
Fundamentosdelaprogramacin:TiposeinstruccionesII Pgina 395

LuisHernndezYez

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]; } med =total/cont; Slo recorremos hasta cont1 return med; }

LuisHernndezYez

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 Exp1 y Exp2: Expresiones Si Condicin se evala a true, el resultado es Exp1; si Condicin se evala a false, el resultado es Exp2.
int a=5,b=3,c; c=(a+b==10)?2 :3;
LuisHernndezYez

Operadores(prioridad) ++ (postfijos) Llamadas a funciones Moldes ++ (prefijos) ! (cambio de signo) */% + < <=>>= ==!= && || ?: =+==*=/=%=

c=(8

==10)?2 :3; ?2 :3;

c=false 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 si no, si nota>=9 entonces SB si no, si nota>=7 entonces NT si no, si nota>=5 entonces AP si no SS
double nota; cin>>nota; if (nota==10){cout<<"MH";} else if (nota>=9){cout<<"SB";} else if (nota>=7){cout<<"NT";} else if (nota>=5){cout<<"AP";} else {cout<<"SS";}

true
==10 "MH"

false true
>=9 "SB"

false true
>=7 "NT"

false true
>=5 "AP"

LuisHernndezYez

false
"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 Unaparcamiento Parntesisbienemparejados? Dossecuenciasiguales? NmerosprimosmenoresqueN Bsquedas Bsquedadeunnmeroenunarchivo Bsquedasensecuenciasordenadas

404 405 409 412 413 417 419 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(); } return 0; }
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina406

LuisHernndezYez

LuisHernndezYez

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

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina407

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

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina408

Cada parntesis, con su pareja


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

Contador del nivel de anidamiento: Al encontrar '(' incrementamos Al encontrar ')' decrementamos Al terminar, el contador deber tener el valor 0 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; } if (!error){ cin>>c; } }
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 410

LuisHernndezYez

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 sec1.close(); y por secuencia4.txt para comprobar otros casos sec2.close(); return sonIguales; }
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 412

LuisHernndezYez

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++; } } } return 0; }
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 413

LuisHernndezYez

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){ if (n%i==0){ esPrimo =false;//Esdivisiblepori } }...
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 415

LuisHernndezYez

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> usingnamespacestd; #include<fstream>

buscaarch.cpp

int busca(int n); //Devuelvelalneaenlaqueseencuentrao1sinoest intmain(){ intnum,linea; cout<<"Valoralocalizar:"; cin>>num; linea =busca(num); if(linea !=1){ cout<<"Encontrado(lnea" <<linea <<")" <<endl; } else{ cout<<"Noencontrado" <<endl; } return 0; }
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII) Pgina 418

LuisHernndezYez

int busca(int n){ int i,linea =0; bool encontrado=false; ifstream archivo; archivo.open("enteros.txt"); if (!archivo.is_open()){ linea =1; } else { archivo>>i; while ((i!=0)&&!encontrado){ linea++; if (i==n){ encontrado=true; } archivo>>i; } if (!encontrado){ linea =1; } archivo.close(); } return linea; }
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Centinela

LuisHernndezYez

Pgina 419

LuisHernndezYez

Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

Pgina 420

Secuencia ordenada de menor a mayor: paramos al encontrar uno mayor o igual al buscado
cout<<"Valoralocalizar:"; cin>>num; archivo>>i; while ((i!=0)&&(i<num)){ cont++; archivo>>i; } if (i==num){ cout<<"Encontrado(pos.:" <<cont <<")"; } else { cout<<"Noencontrado"; } cout<<endl; archivo.close();
Fundamentosdelaprogramacin:TiposeinstruccionesII(AnexoII)

buscaord.cpp

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

LuisHernndezYez

Pgina 421

Si el elemento est: procesamiento similar a secuencias desordenadas

15

16

24

41

73

78

82

123

153

159

...

archivo>>i;

num

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

false

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 el resto de la secuencia

15

16

24

41

73

78

82

123

153

159

...

archivo>>i;

num

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

false

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 Subprogramas Subprogramasydatos Parmetros Argumentos Resultadodelafuncin Prototipos Ejemploscompletos Funcionesdeoperador Diseodescendente(unejemplo) Precondicionesypostcondiciones

427 434 441 446 451 467 473 475 477 480 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:
LuisHernndezYez

Dibujar Mostrar la cadena HOLA MAMA en letras gigantes

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 428

1. Dibujar 2. Dibujar 3. Dibujar 1. Dibujar 2. Dibujar 2.1. Dibujar REFINAMIENTO


LuisHernndezYez

Misma tarea

2.2. Dibujar 3. Dibujar

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 429

1. Dibujar 2. Dibujar 2.1. Dibujar


4tareas,perodosdeellassoniguales

2.2. Dibujar
LuisHernndezYez

Nosbastaconsabercmodibujar:

3. Dibujar

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 430

void dibujarCirculo() {...}

Dibujar

void dibujarSecantes() {...} void dibujarLinea() {...}

Dibujar

Dibujar

Dibujar

Dibujar

Dibujar

void dibujarTriangulo() { dibujarSecantes(); dibujarLinea(); } int main(){ dibujarCirculo(); dibujarTriangulo(); dibujarSecantes(); return 0; }

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 431

Mostrar la cadena HOLA MAMA en letras gigantes


MostrarHOLAMAMA

MostrarHOLA

Espacioenblanco

MostrarMAMA

A Tareas bsicas

LuisHernndezYez

Espacioenblanco

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 432

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

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

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

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

void mostrarL() {...} 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
Aumentan el nivel de abstraccin del programa Facilitan la prueba, la depuracin y el mantenimiento
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 435

LuisHernndezYez

Flujo de ejecucin
int main() { mostrarH(); mostrarO(); ... } void mostrarH() { ... }
LuisHernndezYez

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


Pgina 436

Fundamentosdelaprogramacin:Laabstraccinprocedimental

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; Se sustituye en la expresin por el valor que devuelve Ya venimos utilizando funciones desde el Tema 2!
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 438

LuisHernndezYez

Funciones
Subprogramas de tipo distinto de void
... int menu() { int op; cout<<"1 Editar"<<endl; cout<<"2 Combinar"<<endl; cout<<"3 Publicar"<<endl; cout<<"0 Cancelar"<<endl; cout<<"Elija:"; cin>>op; returnop; }
LuisHernndezYez

intmain() { ... int opcion; opcion =menu(); ...

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 439

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

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

LuisHernndezYez

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

LuisHernndezYez

mbito de los datos locales: resto del subprograma


No se conocen fuera del subprograma

Visibilidad de los datos


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

#include<iostream> usingnamespace std; const int MAX=100; double ingresos; ... void proc(){ int op; double ingresos; ... } int main(){ int op; ... return 0; } Datos globales op de proc() es distinta de op de main()

Datos locales a proc() Se conocen MAX (global), op (local) e ingresos (local que oculta la global)

LuisHernndezYez

Datos locales a main() Se conocen MAX (global), op (local) e ingresos (global)

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 444

Sobre el uso de datos globales en los subprogramas


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
LuisHernndezYez

Excepciones: Constantes globales (valores inalterables) 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 que dado un nmero muestra en la pantalla su cuadrado:
x 5 Subprograma cuadrado()

Datos de salida: Devueltos


Subprograma que dado un nmero devuelve su cuadrado:
x 5

Subprograma cuadrado() y (=x2)

Datos de entrada/salida: Aceptados y modificados


LuisHernndezYez

Subprograma x cuadrado() x

Subprograma que dada una variable numrica la eleva al cuadrado:

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 447

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

Lista de parmetros formales


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

De salida identificador ,

parmetros

tipo

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 448

Reciben copias de los argumentos usados en la llamada


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

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
LuisHernndezYez

Atencin! Los arrays se pasan por referencia sin utilizar &


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

El argumento de lista (variable tArray) quedar modificado


Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 450

LuisHernndezYez

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 451

nombre(argumentos)

Tantos argumentos como parmetros y en el mismo orden Concordancia de tipos argumentoparmetro Por valor: Expresiones vlidas (se pasa el resultado) Por referencia: Slo variables! Se copian los valores de las expresiones pasadas por valor en los correspondientes parmetros 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) {...} int main() { int i=124; double d=3; proc(i,33 *d); ...
LuisHernndezYez

Memoria i d 124 3.0 ...

... x a 124 99.0 ...

return0; }

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 454

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

Memoria x a i d 124 3.0 ...

return0; }

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 455

Dadas las siguientes declaraciones:


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

Qu pasos de argumentos son correctos? Por qu no?

LuisHernndezYez

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


proc(3,i,d);

N de argumentos N de para metros

Parmetro por referencia variable! Argumento double para parmetro int! Argumento double para parmetro int! N de argumentos N de para metros

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 456

... void divide(int op1,int op2,int&div,int&rem){ //Divideop1entreop2ydevuelveelcocienteyelresto div =op1/op2; rem=op1%op2; } int main(){ int cociente,resto; for (int j=1;j<=4;j++){ for (int i=1;i<=4;i++){ divide(i,j,cociente,resto); cout<<i<<"entre" <<j<<"dauncocientede" <<cociente<<"yunrestode" <<resto<<endl; } } return 0; }
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 457

LuisHernndezYez

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

resto i j ...

? 1 1

return 0; }

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 458

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

rem

resto i j ...

? 1 1

op1 op2 ...

1 1

return 0; }

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 459

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

rem

resto i j ...

0 1 1

op1 op2 ...

1 1

return 0; }

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 460

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

resto i j ...

0 1 1

return 0; }

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 461

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

LuisHernndezYez

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

... //Prototipo void cambio(double precio,double pago,int&euros,int&cent50, int&cent20, int&cent10,int&cent5,int&cent2,int&cent1); int main(){ double precio,pago; int euros,cent50,cent20,cent10,cent5,cent2,cent1; cout<<"Precio:"; cin>>precio; cout<<"Pago:"; cin>>pago; cambio(precio,pago,euros,cent50,cent20,cent10,cent5,cent2, cent1); cout<<"Cambio:" <<euros<<"euros," <<cent50<<"x50c.," <<cent20<<"x20c.," <<cent10<<"x10c.," <<cent5<<"x5c.," <<cent2<<"x2c.y" <<cent1<<"x1c." <<endl; return 0; }
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 463

LuisHernndezYez

LuisHernndezYez

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

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

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

LuisHernndezYez

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); if (error){ cout<<"Error:Elpagoesinferioralprecio" <<endl; } else { ...
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 466

LuisHernndezYez

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){ return x*x; x=x*x;
LuisHernndezYez

int main(){ cout<<2 *cuad(16); return 0; }


256

Esta instruccin 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++){ fact =fact *i; } } return fact; }
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 469

LuisHernndezYez

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

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

return resultado; }

Punto de salida nico

Pgina 471

Fundamentosdelaprogramacin:Laabstraccinprocedimental

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

void dibujarCirculo(); void mostrarM(); void proc(double&a); int cuad(int x); ...

main() es el nico subprograma que no hay que prototipar

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 474

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

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


Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 475

mates.cpp
#include<iostream> usingnamespace std; //Prototipos longlong int factorial(int n); int sumatorio(int n); int main(){ intnum; cout<<"Num:"; cin>>num; cout<<"Factorialde" <<num<<":" <<factorial(num) <<endl <<"Sumatoriode1a" <<num<<":" <<sumatorio(num) <<endl; return 0; } return sum; }
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 476

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

LuisHernndezYez

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 Grados Fahrenheit a centgrados Galones a litros
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 481

LuisHernndezYez

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

6 grandes tareas: 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

LuisHernndezYez

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

Fundamentosdelaprogramacin:Laabstraccinprocedimental

Pgina 484

Paso 3. Cada tarea, un subprograma Comunicacin entre los subprogramas:


Funcin menu() pulgACm() lbAGr() grFAGrC() galALtr() main()
LuisHernndezYez

Entrada double pulg double libras double grF double galones

Salida

Valordevuelto int double double double double int

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

LuisHernndezYez

LuisHernndezYez

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

. . .
Pgina 487

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

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

. . .
Pgina 488

conversiones.cpp
double lbAGr(double libras){ constdouble grPorLb =453.6; return libras*grPorLb; } double grFAGrC(double grF){ return ((grF 32)*5 /9); } 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
LuisHernndezYez

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

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; } else{ //Secumplelaprecondicin... ...
Fundamentosdelaprogramacin:Laabstraccinprocedimental Pgina 493

LuisHernndezYez

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

LuisHernndezYez

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 Lafuncinmain() Argumentosimplcitos Sobrecargadesubprogramas

498 501 504 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(); } return0; }
Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo) Pgina 499

LuisHernndezYez

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) argv: array con las cadenas proporcionadas como argumentos

LuisHernndezYez

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; No podemos dejar signo por defecto cout<<"X="; y concretar delta cin>>x; cout<<"Y="; cin>>y; cout<<"signoydeltapordefecto:" <<f(x,y)<<endl; cout<<"signo1ydeltapordefecto:" <<f(x,y,1)<<endl; cout<<"signoydeltaconcretos:" <<f(x,y,1,1.25)<<endl; 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) abs(3L)
LuisHernndezYez

//argumentoint>primerafuncin //argumentolongint>tercerafuncin

abs(2.3) //argumentodouble>segundafuncin

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

Fundamentosdelaprogramacin:Laabstraccinprocedimental(Anexo)

Pgina 509

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

LuisHernndezYez

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

LuisHernndezYez/PabloMorenoGer

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

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

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 514

Clasificacin de tipos
Simples

Estndar: int, float, double, char, bool Conjunto de valores predeterminado Definidos por el usuario: enumerados Conjunto de valores definido por el programador Colecciones homogneas: arrays Todos los elementos del mismo tipo Colecciones heterogneas: estructuras Los elementos pueden ser de tipos distintos

LuisHernndezYez/PabloMorenoGer

Estructurados

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

Elementos organizados por posicin: 0, 1, 2, 3, ... Acceso por ndice: 0, 1, 2, 3, ... Una o varias dimensiones

Estructuras (tuplas, registros)


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

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

76.95 1

328.80 254.62 435.00 164.29 2 3 4 5

0.00 6

[] 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
Pgina 518

Fundamentosdelaprogramacin:Tiposdedatosestructurados

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

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

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 520

12.40
0

10.96
1

8.43
2

11.65
3

13.70
4

13.41
5

14.07
6

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


i=0
LuisHernndezYez/PabloMorenoGer

Memoria Dias ventas[0] ventas[1] ventas[2] ventas[3] ventas[4] ventas[5] 7 12.40 10.96 8.43 11.65 13.70 13.41 14.07 ? 84.62 23.36 31.79 12.40 0.00 43.44 3 2 7 0 4 1

true

i<Dias

false

ventas[6]

total+=ventas[i]

...

media total i

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

5...10

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


tTabla i={0};//Ponetodosloselementosa0

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 523

LuisHernndezYez/PabloMorenoGer

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

Simulacin de paso de parmetro por referencia Sin poner & en la declaracin del parmetro Los subprogramas reciben la direccin en memoria del array
const intMax=10; typedef inttTabla[Max]; void inicializa(tTabla tabla);//Sinponer&
LuisHernndezYez/PabloMorenoGer

Las modificaciones del array quedan reflejadas en el argumento


inicializa(array);

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

Son el mismo array!


Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 525

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

LuisHernndezYez/PabloMorenoGer

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


LuisHernndezYez/PabloMorenoGer

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

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 528

Listas con un nmero fijo de elementos


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

Recorrido de la lista:
LuisHernndezYez/PabloMorenoGer

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

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

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 529

Listas con un nmero variable de elementos


Array con un mximo de elementos + Contador de elementos
constint MAX=100; typedefdoubletLista[MAX];//Hasta100elementos tLista lista; int contador=0;//Seincrementaalinsertar

Recorrido de la lista:
LuisHernndezYez/PabloMorenoGer

for(int i=0;i<contador;i++){ ...

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

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 531

Arrays de caracteres
Cadenas: secuencias de caracteres de longitud variable
"Hola""Adis""Supercalifragilstico""1234567"

LuisHernndezYez/PabloMorenoGer

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

o
1

l
2

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

d
1

i
2

s
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

Longitud: 5
S
0

u
1

p
2

e
3

r
4

c
5

a
6

l
7

i
8

f
9

r
10

a
11

g
12

i
13

l
14

15

s
16

t
17

i
18

c
19

o
20 21

LuisHernndezYez/PabloMorenoGer

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

d
1

i
2

s
4

\0
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' 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

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

Se pueden inicializar en la declaracin Se pueden copiar con el operador de asignacin Se pueden concatenar con el operador + Multitud de funciones de utilidad

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 536

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

LuisHernndezYez/PabloMorenoGer

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

Se pueden comparar con los operadores relacionales:


if(cad1<=cad2){...

LuisHernndezYez/PabloMorenoGer

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

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 538

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

Lectura incluyendo espacios en blanco:


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); cout<<"Nombrecompleto:" <<nombre<<"" <<apellidos<<endl; return 0; }

LuisHernndezYez/PabloMorenoGer

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


LuisHernndezYez/PabloMorenoGer

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

cadena.rfind(subcadena) Posicin de la ltima ocurrencia de subcadena en cadena


string cad ="Olala"; cout<<cad.rfind("la");//Muestra3
Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 541

cadena.erase(ini,num) Elimina num caracteres a partir de la posicin ini


string cad ="abcdefgh"; cad.erase(3,4);//cad ahoracontiene"abch"

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


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; int edad; string nif; }tPersona; tPersona persona;
persona

Memoria Luis Antonio

persona.nombre

persona.apellidos
LuisHernndezYez/PabloMorenoGer

nombre LuisAntonio apellidos HernndezYez edad 22


persona.edad persona.nif

Hernndez Yez 22 00223344F

nif 00223344F

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 547

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

LuisHernndezYez/PabloMorenoGer

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

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 548

typedefstruct { stringdni; char letra; } tNif; tPersona persona;

typedefstruct { ... tNif nif; }tPersona;


tPersona
nombre apellidos edad nif dni letra

Acceso al NIF completo:


persona.nif //Otraestructura
LuisHernndezYez/PabloMorenoGer

tNif

Acceso a la letra del NIF:


persona.nif.letra

Acceso al DNI:
persona.nif.dni

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 549

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

personal
nombre

apellidos edad nif nombre

apellidos edad nif nombre

apellidos edad nif

Nombre de la tercera persona:


personal[2].nombre
nombre

Edad de la duodcima persona:


personal[11].edad

DIM1

apellidos edad nif

NIF de la primera persona:


personal[0].nif
Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 550

LuisHernndezYez/PabloMorenoGer

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

elementos
0
nombre apellidos edad nif nombre apellidos edad nif nombre apellidos edad nif

contador

MAX1

nombre apellidos edad nif

Nombre de la tercera persona: lista.elementos[2].nombre Edad de la duodcima persona: lista.elementos[11].edad NIF de la primera persona: lista.elementos[0].nif
Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 551

LuisHernndezYez/Pablo Moreno Ger /Pablo Moreno Ger

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 552

Estructura que agrupe el array y el contador:


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

Elementos sin usar (datos basura)

12.0
0

2.2
1

5.4
2

0.0
3

36.2
4

35.0
5

X
6

X
7

X
8

X
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 nuevo 3 pos
LuisHernndezYez/PabloMorenoGer

12.0 2.2
0 1

5.4
2

0.0
3

36.2 35.0
4 5

X
6

X
7

X
8

X
9

Hay que asegurarse de que haya sitio (contador < mximo) Operacin en 3 pasos: 1. Abrir hueco para el nuevo elemento (desde la posicin) 2. Colocar el elemento nuevo en la posicin 3. Incrementar el contador
Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 554

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 nuevo 3 pos

12.0 2.2
0 1

5.4
2

42.0
3

0.0
4

36.2 35.0
5 6

X
7

X
8

X
9

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 555

Eliminar el elemento en una posicin


Posiciones vlidas: 0 a contador1
12.0 2.2 3 pos
0 1

5.4
2

0.0
3

36.2 35.0
4 5

X
6

X
7

X
8

X
9

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

5.4
2

0.0
3

36.2 35.0
4 5

X
6

X
7

X
8

X
9

12.0 2.2 3 pos


0 1

5.4
2

36.2 35.0 35.0


3 4 5

X
6

X
7

X
8

X
9

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: Aadir un nuevo alumno Eliminar un alumno existente Calificar a los estudiantes Listado de notas, identificando la mayor y la media

LuisHernndezYez/PabloMorenoGer

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; double nota; } tEstudiante; typedef tEstudiantetArray[MAX]; typedef struct{ tArray elementos; int contador; } tLista;
Fundamentosdelaprogramacin:Tiposdedatosestructurados

LuisHernndezYez/PabloMorenoGer

Declaraciones de constantes y tipos globales Tras las bibliotecas

Pgina 560

LuisHernndezYez/PabloMorenoGer

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

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 562

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

Condicin al final del bucle


condicin ) ;

LuisHernndezYez/PabloMorenoGer

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

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 563

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


i=1;

Cuerpo true

Condicin false

LuisHernndezYez/PabloMorenoGer

cout<<i<<endl; i++;
true i<=100 false

El cuerpo se ejecuta al menos una vez

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 564

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


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

LuisHernndezYez/PabloMorenoGer

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

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

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 565

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

LuisHernndezYez/PabloMorenoGer

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 566

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

LuisHernndezYez/PabloMorenoGer

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

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

Lee en una variable auxiliar de tipo tEstudiante


Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 568

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

LuisHernndezYez/PabloMorenoGer

Simplemente, un dato en cada lnea y en orden:


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

LuisHernndezYez/PabloMorenoGer

LuisHernndezYez/PabloMorenoGer

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

Fundamentosdelaprogramacin:Tiposdedatosestructurados

Pgina 571

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]; } lista.contador; } }

LuisHernndezYez/PabloMorenoGer

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; for(int i=0;i<lista.contador;i++){ if(lista.elementos[i].nota>max){ max =lista.elementos[i].nota; pos=i; } } return pos; }
Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 575

LuisHernndezYez/PabloMorenoGer

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

LuisHernndezYez/PabloMorenoGer

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

LuisHernndezYez/PabloMorenoGer

LuisHernndezYez/PabloMorenoGer

case2: { cout<<"Posicin:"; cin>>pos; eliminarEstudiante(lista,pos 1,exito); if(!exito){ cout<<"Elementoinexistente!" <<endl; } } break; case3: { calificar(lista); } break; case4: { listado(lista,mediaClase(lista),mayorNota(lista)); } } }while(op !=0); guardar(lista); } return 0; }
Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 578

Licencia CC (Creative Commons)


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

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

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


Fundamentosdelaprogramacin:Tiposdedatosestructurados Pgina 579

Fundamentosdelaprogramacin

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

Facultad de Informtica Universidad Complutense

CadenasalestilodeC E/SconcadenasalestilodeC Labibliotecacstring Ejemplo

582 583 584 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
LuisHernndezYez/PabloMorenoGer

A
0

d
1

i
2

s
4

\0
5 6 7 8 9 10 11 12 13 14

En el array caben MAX1 caracteres significativos Longitud mxima de la variable cadena: 14 No se pueden asignar cadenas literales: cadena="Hola"; Ni copiar cadenas directamente: cad2=cad1; Ni comparar con op. relacionales: if(cad1<cad2)...
Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo) Pgina 582

tCadena cadena; cin>>cadena;//Seaadeunnuloalfinal

Extractor: la lectura termina en el primer espacio en blanco No se comprueba si se leen ms caracteres de los que caben! setw(): mximo de caracteres a colocar (incluyendo el nulo)
cin>>setw(15)>>cadena;

LuisHernndezYez/PabloMorenoGer

cin.getline(cadena_estilo_C,mx): Para leer tambin los espacios en blanco y no ms de mx1


cin.getline(cadena,15);//Hasta14caracteres cout<<cadena<<endl;//Elnulonosemuestra
cin.getline(cad,mx) Cadenas al estilo de C getline(cin,cad) Cadenas de tipo string
Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo) Pgina 583

strlen(cadena): longitud actual de la cadena cout<<"Longitud:" <<strlen(cadena); strcpy(destino,origen): copia origen en destino strcpy(cad2,cad1); strcpy(cad,"MegustaC++"); strcat(destino,origen): aade origen al final de destino tCadena cad1="Hola",cad2="Adis"; strcat(cad1,cad2);//cad1contiene"HolaAdis"
LuisHernndezYez/PabloMorenoGer

strcmp(cad1,cad2): compara lexicogrficamente las cadenas 0 si son iguales, 1 si cad1 > cad2 1 si cad1 < cad2 tCadena cad1="Hola",cad2="Adis"; strcmp(cad1,cad2)//Devuelve1("Hola">"Adis") . . .
http://www.cplusplus.com/reference/clibrary/cstring/

Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo)

Pgina 584

cadenas.cpp #include<iostream> usingnamespacestd; #include<cstring> int main(){ const int MAX=20; typedef chartCad[MAX]; tCad cadena="MegustaC++"; cout<<cadena<<endl; cout<<"Cadena:"; cin>>cadena;//Leehastaelprimerespacioenblanco cout<<cadena<<endl; cin.sync();//Sincronizarlaentrada cout<<"Cadena:"; cin.getline(cadena,MAX); cout<<cadena<<endl; cout<<"Longitud:" <<strlen(cadena)<<endl; strcpy(cadena,"Hola"); ...
Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo) Pgina 585

LuisHernndezYez/PabloMorenoGer

LuisHernndezYez/PabloMorenoGer

tCad cadena2="amigo"; strcat(cadena,cadena2); cout<<cadena<<endl; if(strcmp(cadena,cadena2)==0){ cout<<"Iguales"; } elseif(strcmp(cadena,cadena2)>0){ cout<<cadena<<"esmayorque" <<cadena2; } else{ cout<<cadena<<"esmenorque" <<cadena2; } cout<<endl; return 0; }

Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo)

Pgina 586

Licencia CC (Creative Commons)


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

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

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


Fundamentosdelaprogramacin:CadenasalestilodeC(Anexo) Pgina 587

Fundamentosdelaprogramacin

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

Facultad de Informtica Universidad Complutense

LuisHernndezYez

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

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

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 590

Esquema de recorrido
Inicializacin Mientras no al final de la secuencia: Obtener el siguiente elemento Procesar el elemento Finalizacin
Al final? Inicializacin

true

false
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: Recorrer el array hasta el ndice contador 1

LuisHernndezYez

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

LuisHernndezYez

double elemento; for(int i=0;i<N;i++){ elemento=ventas[i]; //Procesarelelemento... }

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 593

Recorrido de arrays no completos con centinela


No todas las posiciones del array estn ocupadas
const intN=10; typedef doubletArray[N]; tArray datos;//Datospositivos:centinela=1 ...
datos 125.40 0
76.95 328.80 254.62 435.00 164.29 316.05 1.0

LuisHernndezYez

int i=0; double elemento=datos[i]; while(elemento!=1){ //Procesarelelemento... i++; elemento=datos[i]; }

int i=0; double elemento; do { elemento=datos[i]; if(elemento!=1){ //Procesarelelemento... i++; } }while(elemento!=1);


Pgina 594

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Recorrido de arrays no completos con contador


Array y contador ntimamente relacionados: estructura
const intN=10; typedefdoubletArray[N]; typedefstruct { tArray elementos; int contador; }tLista;
elementos
125.40 76.95 328.80 254.62 435.00 164.29 316.05

Listas de elementos de longitud variable

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

numeros numDig

123 0 0 0

2 1 0 1

46237 2 0 2

2345 3 0 3

236 4 0 4

11234 5 0 5

33 6

999 7

...

61 99

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
LuisHernndezYez

srand(time(NULL));//Inicialasecuencia ... numeros[0]=rand();//Entre0y32766

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 601

digitos.cpp

Cuenta de valores con k dgitos


#include<iostream> usingnamespacestd; #include<cstdlib>//srand()yrand() #include<ctime>//time() int digitos(int dato); int main(){ const intNUM=100; typedef inttNum[NUM];//Exactamente100nmeros const intDIG =5; typedef inttDig[DIG]; tNum numeros; tDig numDig ={0 };//Inicializatodoelarraya0 srand(time(NULL)); //Inicialasecuenciaaleatoria ...

LuisHernndezYez

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; } int digitos(int dato){ ...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 603

LuisHernndezYez

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 604

Esquema de bsqueda
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)
LuisHernndezYez

Inicializacin / encontrado=false;

Al final o encontrado?

true

false
Obtener elemento Encontrado?

Finalizacin

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 605

Todas las posiciones ocupadas

LuisHernndezYez

int buscado; bool encontrado=false; cout<<"Valorabuscar:"; cin>>buscado; int pos=0; while((pos<N)&&!encontrado){ //Mientrasnoselleguealfinalynoencontrado if(lista[pos]==buscado){ encontrado=true; } else{ pos++; } } if(encontrado)//...

const intN=100; typedef inttArray[N]; tArray lista;

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 606

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

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 607

Con contador

LuisHernndezYez

int buscado; cout<<"Valorabuscar:"; cin>>buscado; int pos=0; bool encontrado=false; while((pos<miLista.contador) &&!encontrado){ //Mientrasnoalfinalynoencontrado if(miLista.elementos[pos]==buscado){ encontrado=true; } else{ pos++; } } if(encontrado)//...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

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

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

Ventas del cuarto da del tercer mes en la primera sucursal:


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

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 609

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 610

#include<iostream> usingnamespacestd; #include<fstream> const intN=100; typedefdoubletArray[N]; typedefstruct { tArray elementos; int contador; }tLista; void cargar(tLista&lista,bool &ok);

umbral.cpp

int main(){ tLista lista; bool ok; cargar(lista,ok); if (!ok){ cout<<"Error:nohayarchivoodemasiadosdatos" <<endl; }
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 611

LuisHernndezYez

LuisHernndezYez

else { double umbral; cout<<"Valorumbral:";cin>>umbral; boolencontrado=false; int pos=0; while ((pos<lista.contador)&&!encontrado){ if (lista.elementos[pos]>umbral){ encontrado=true; } else { pos++; } } if (encontrado){ cout<<"Valorenpos."<<pos+1 <<"(" <<lista.elementos[pos]<<")" <<endl; } else { cout<<"Noencontrado!"<<endl; } } return0; }
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 612

void cargar(tLista&lista,bool &ok){ ifstreamarchivo; doubledato; boolabierto=true,overflow =false; lista.contador =0; archivo.open("datos.txt"); if(!archivo.is_open()){ abierto=false; } else { archivo>>dato; while((dato>=0)&&!overflow){ if(lista.contador ==N){ overflow =true;//Demasiados! } else { lista.elementos[lista.contador]=dato; lista.contador++; archivo>>dato; } } archivo.close(); } ok=abierto&&!overflow; }
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 613

LuisHernndezYez

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); inversa=car+inversa;//Insertacaralprincipio pos++; }//...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 615

LuisHernndezYez

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 { pos++; } } if(encontrado)//...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 616

LuisHernndezYez

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
LuisHernndezYez

Dado un vector, determina si alguno de los valores almacenados en el vector es igual a la suma del resto de los valores del mismo; devuelve el ndice del primero encontrado o 1 si no se encuentra Dado un vector, determina si alguno de los valores almacenados en el vector est repetido
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 618

vectores.cpp void desplazar(tVector v){ int aux=v[N 1]; for (int i=N 1;i>0;i){ v[i]=v[i 1]; } v[0]=aux; } int sumaPares(const tVector v){ int suma=0; for (int i=0;i<N;i=i+2){ suma=suma+v[i]; } return suma; }

LuisHernndezYez

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]); i++; } return !encontrado; }
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 620

LuisHernndezYez

LuisHernndezYez

int compruebaSuma(const tVector v){ //Algunoigualalasumadelresto? bool encontrado=false; int i=0; int suma; while ((i<N)&&!encontrado){ suma=0; for (int j=0;j<N;j++){ if (j!=i){ suma=suma+v[j]; } } encontrado=(suma==v[i]); i++; } if (!encontrado){ i=0; } return i 1; }
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 621

bool hayRepetidos(const tVector v){ bool encontrado=false; int i=0,j; while ((i<N)&&!encontrado){ j=i+1; while ((j<N)&&!encontrado){ encontrado=(v[i]==v[j]); j++; } i++; } return encontrado; }
LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 622

Dado un vector de N caracteres v1, en el que no hay elementos repetidos, y otro vector de M caracteres v2, donde N M, se quiere comprobar si todos los elementos del vector v1 estn tambin en el vector v2 Por ejemplo, si: v1= 'a' 'h' 'i' 'm' v2= 'h' 'a' 'x' 'x' 'm' 'i' 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; } else { cout<<"NO:v1noestaincluidoenv2" <<endl; } return 0; }
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 624

LuisHernndezYez

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++; encontrado=esta(v1[i],v2); } return encontrado; }
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 625

LuisHernndezYez

Un programa que lea dos cadenas del teclado y determine si una es un anagrama de la otra, es decir, si una cadena es una permutacin de los caracteres de la otra. Por ejemplo, "acre" es un anagrama de "cera" y de "arce". Ten en cuenta que puede haber letras repetidas ("carro", "llave").

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; } else { numCar=0;//Contadordecaracteresdelaprimeracadena while (sonAnagramas&&(numCar<cad1.length())){ posEnCad2=buscaCaracter(cad2,cad1.at(numCar));
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 627

LuisHernndezYez

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

return pos; }

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 629

LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 630

Arrays de varias dimensiones


Varios tamaos en la declaracin: cada uno con sus corchetes
typedef tipo_base nombre[tamao1][tamao2]...[tamaoN];

Varias dimensiones, tantas como tamaos se indiquen


typedefdouble tMatriz[50][100]; tMatriz matriz;

Tabla bidimensional de 50 filas por 100 columnas:


0 0 1
LuisHernndezYez

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

98

99

2 ... 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 0 1 2 ...
LuisHernndezYez

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

98

99

...

...

...

...

... ... ...

...

...

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; } else { archivo>>min>>max; //Elarchivoterminacon9999 ...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 635

LuisHernndezYez

LuisHernndezYez

while(!((min==99)&&(max ==99)) &&(dia <MaxDias)){ temp[dia][0]=min; temp[dia][1]=max; dia++; archivo>>min>>max; } archivo.close(); for(int i=0;i<dia;i++){ tMinMedia =tMinMedia +temp[i][0]; if(temp[i][0]<tMinAbs){ tMinAbs =temp[i][0]; } tMaxMedia =tMaxMedia +temp[i][1]; if(temp[i][1]>tMaxAbs){ tMaxAbs =temp[i][1]; } } ...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 636

tMinMedia =tMinMedia /dia; tMaxMedia =tMaxMedia /dia; cout<<"Temperaturasmnimas." <<endl; cout<<"Media=" <<fixed<<setprecision(1) <<tMinMedia <<"CMnimaabsoluta=" <<setprecision(1)<<tMinAbs <<"C" <<endl; cout<<"Temperaturasmximas." <<endl; cout<<"Media=" <<fixed<<setprecision(1) <<tMaxMedia <<"CMximaabsoluta=" <<setprecision(1)<<tMaxAbs <<"C" <<endl; } return 0; }
LuisHernndezYez

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 637

Podemos dar valores a los elementos de un array al declararlo Arrays bidimensionales:


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

Se asignan en el orden en el que los elementos estn en memoria La memoria es de una dimensin: secuencia de celdas En memoria varan ms rpidamente los ndices de la derecha:
cuads[0][0]cuads[0][1]cuads[1][0]cuads[1][1]cuads[2][0]...

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 cuads[0][0] cuads[0][1] cuads[1][0] cuads[1][1] cuads[2][0] cuads[2][1] cuads[3][0]
LuisHernndezYez

1 1 4 9 16 25

1 1 2 4 3 9 4 16 5 25

0 1 2 3 4

1 2 3 4 5

Si hay menos valores que elementos, el resto se inicializan a cero Inicializacin a cero de todo el array: int cuads[5][2]={0 };

cuads[3][1] cuads[4][0] cuads[4][1]

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

Pgina 639

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


matriz[0][0][0][0] matriz[0][0][0][1] matriz[0][0][0][2] matriz[0][0][1][0] matriz[0][0][1][1] matriz[0][0][1][2] matriz[0][1][0][0] matriz[0][1][0][1] matriz[0][1][0][2] matriz[0][1][1][0]
LuisHernndezYez

Memoria 1 2 3 4 5 6 7 8 9 10 11 12 0 0
Pgina 640

matriz[0][1][1][1] matriz[0][1][1][2] matriz[0][2][0][0] ...


Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

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 <<"delmes"<<mes+1 <<":"; cin>>ventas[mes][dia]; } }
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 642

LuisHernndezYez

Ventas de todos los meses de un ao


Das
0 0 1 2 3 4 5 6 7
LuisHernndezYez

1 125 231 417 845 652 438 543 541 327 583 427 666

2 234 675 327 654 555 824 353 164 432 333 585 512

3 112 325 333 212 222 547 777 563 249 100 218 400

4 156 111 324 562 777 175 437 327 777 334 843 259

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

28 234 444 354 428 321 765 538 528 743 777 438

29 543 367 548 999 356 678 159 529 468 555 637

30 667 437 666 555 235 531 879


Pgina 643

201 323 523 145 327 854 654 327 333 524 217 222

Meses

Celdas no utilizadas

8 9 10 11

Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

const const const const

intDIM1=10; intDIM2=5; intDIM3=25; 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] } } } }
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 644

LuisHernndezYez

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 { anual tVentaAnual tVentaMes ventas; anual[i] tMes int dias; anual[i].dias int }tMes;
LuisHernndezYez

const intMESES=12; typedeftMes tVentaAnual[MESES]; tVentaAnual anual;


Fundamentosdelaprogramacin:Recorridoybsquedaenarrays

anual[i].ventas tVentaMes anual[i].ventas[j][k] double

Pgina 645

Clculo de las ventas de todo el ao: Para cada mes... Para cada da del mes... Para cada sucursal... Acumular las ventas

const intDIAS =31; const intSUCURSALES=4; typedefdouble tVentaMes[DIAS][SUCURSALES]; typedefstruct { tVentaMes ventas; int dias; }tMes; const intMESES=12; typedeftMes tVentaAnual[MESES]; tVentaAnual anual;

LuisHernndezYez

double total=0; for (int mes=0;mes<MESES;mes++){ for (int dia =0;dia <anual[mes].dias;dia++){ for (int suc =0;suc <SUCURSALES;suc++){ total=total+anual[mes].ventas[dia][suc]; } } }
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 646

LuisHernndezYez

Primer valor > umbral boolencontrado=false; int mes=0,dia,suc; while ((mes<MESES)&&!encontrado){ dia =0; while ((dia <anual[mes].dias)&&!encontrado){ suc =0; while ((suc <SUCURSALES)&&!encontrado){ if (anual[mes].ventas[dia][suc]>umbral){ encontrado=true; } else { suc++; } } if (!encontrado){ dia++; } } if (!encontrado){ mes++; } } if (encontrado){...
Fundamentosdelaprogramacin:Recorridoybsquedaenarrays Pgina 647

Licencia CC (Creative Commons)


Este tipo de licencias ofrecen algunos derechos a terceras personas bajo ciertas condiciones. Este documento tiene establecidas las siguientes:
Reconocimiento (Attribution): En cualquier explotacin de la obra autorizada por la licencia har falta reconocer la autora. 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 Algoritmodeordenacinporinsercin Ordenacindearraysporinsercin Algoritmodeordenacinporinsercin conintercambios Clavesdeordenacin Estabilidaddelaordenacin Complejidadyeficiencia Ordenacionesnaturales Ordenacinporseleccindirecta Mtododelaburbuja Listasordenadas Bsquedasenlistasordenadas Bsquedabinaria
LuisHernndezYez

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

Fundamentosdelaprogramacin:Algoritmosdeordenacin

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 651

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

Algoritmo de ordenacin (de menor a mayor)


array
76.95 0 93.45 125.40 164.29 219.99 254.62 316.05 328.80 435.00 756.62 1 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 Hay otros algoritmos de ordenacin mejores

LuisHernndezYez

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

LuisHernndezYez

6 1 3 8 2 9 4 7 5

Baraja de nueve cartas numeradas del 1 al 9 Las cartas estn desordenadas Ordenaremos de menor a mayor (ascendente)

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 655

Algoritmo de ordenacin por insercin

6 1 3 8 2 9 4 7 5
LuisHernndezYez

Colocamos el primer elemento en la lista vaca

Lista ordenada:

5
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 656

Algoritmo de ordenacin por insercin

6 1 3 8 2 9 4 7
LuisHernndezYez

El 7 es mayor que todos los elementos de la lista Lo insertamos al final

Lista ordenada:

5 7
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 657

Algoritmo de ordenacin por insercin

6 1 3 8 2 9 4
LuisHernndezYez

Primer elemento (5) mayor que el nuevo (4): Desplazamos todos una posicin a la derecha Insertamos el nuevo en la primera posicin
Hemos insertado el elemento en su lugar Lista ordenada:

5 5 4 7 7
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 658

Algoritmo de ordenacin por insercin

6 1 3 8 2 9
LuisHernndezYez

9 es mayor que todos los elementos de la lista Lo insertamos al final

Lista ordenada:

4 5 7 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 659

Algoritmo de ordenacin por insercin

6 1 3 8 2
LuisHernndezYez

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

Lista ordenada:

4 4 2 5 5 7 7 9 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 660

Algoritmo de ordenacin por insercin

6 1 3 8

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

Lista ordenada:
LuisHernndezYez

2 4 5 7 8 4 9 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 661

Algoritmo de ordenacin por insercin

6 1 3

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

Lista ordenada:
LuisHernndezYez

2 3 4 4 4 5 5 7 7 8 8 9 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 662

Algoritmo de ordenacin por insercin

6 1

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

Lista ordenada:
LuisHernndezYez

2 2 1 3 3 4 4 5 5 7 7 8 8 9 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 663

Algoritmo de ordenacin por insercin

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

LISTA ORDENADA !!!


Lista ordenada:
LuisHernndezYez

1 2 3 4 5 6 7 7 8 8 9 9
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 664

Ordenacin de arrays por insercin


El array contiene inicialmente la lista desordenada:
20
0

7
1

14
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

A medida que insertamos: dos zonas en el array Parte ya ordenada y elementos por procesar
7
0

14
1

20
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

LuisHernndezYez

Parte ya ordenada

Elementos por insertar

Siguiente elemento a insertar en la parte ya ordenada

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 665

Ordenacin de arrays por insercin


Situacin inicial: Lista ordenada con un solo elemento (primero)
20
0

7
1

14
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

Desde el segundo elemento del array hasta el ltimo: Localizar el primer elemento mayor en lo ya ordenado

20
LuisHernndezYez

7
1

14
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

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
0

7
1

14
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

nuevo 7 7
0

LuisHernndezYez

20
1

14
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

nuevo 7
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 667

Implementacin

LuisHernndezYez

... int nuevo,pos; //Desdeelsegundoelementohastaelltimo... for(int i=1;i<N;i++){ nuevo=lista[i]; pos=0; while((pos<i)&&!(lista[pos]>nuevo)){ pos++; } //pos:ndicedelprimermayor;isinolohay for(int j=i;j>pos;j){ lista[j]=lista[j 1]; } lista[pos]=nuevo; }
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 668

constintN=15; typedefinttLista[N]; tLista lista;

20
0

7
1

14
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

i 1 20
0

pos 0 27
6

nuevo 7 13
8

7
1

14
2

32
3

5
4

14
5

12
7

15
9

20
0

20
1

14
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

LuisHernndezYez

7
0

20
1

14
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 669

7
0

14
1

20
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

i 4 7
0

pos 0 27
6

nuevo 5 13
8

14
1

20
2

32
3

5
4

14
5

12
7

15
9

7
0
LuisHernndezYez

7
1

14
2

20
3

32
4

14
5

27
6

12
7

13
8

15
9

5
0

7
1

14
2

20
3

32
4

14
5

27
6

12
7

13
8

15
9

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 670

5
0

7
1

14
2

20
3

32
4

14
5

27
6

12
7

13
8

15
9

i 5 5
0

pos 3 27
6

nuevo 14 12
7

7
1

14
2

20
3

32
4

14
5

13
8

15
9

5
0
LuisHernndezYez

7
1

14
2

20
3

20
4

32
5

27
6

12
7

13
8

15
9

5
0

7
1

14
2

14 20
3 4

32
5

27
6

12
7

13
8

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

7
1

14
2

20
3

32
4

14
5

27
6

12
7

13
8

15
9

5
0
LuisHernndezYez

7
1

14
2

20
3

14
4

32
5

27
6

12
7

13
8

15
9

5
0

7
1

14
2

14 20
3 4

32
5

27
6

12
7

13
8

15
9

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 673

7
0

14
1

20
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

7
0

14
1

20
2

5
3

32
4

14
5

27
6

12
7

13
8

15
9

7
0

14
1

5
2

20
3

32
4

14
5

27
6

12
7

13
8

15
9

7
0
LuisHernndezYez

5
1

14
2

20
3

32
4

14
5

27
6

12
7

13
8

15
9

5
0

7
1

14
2

20
3

32
4

14
5

27
6

12
7

13
8

15
9

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 674

LuisHernndezYez

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

constintN=15; typedefinttLista[N]; tLista lista;

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 675

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

insercion.cpp

const int N=100; typedef inttArray[N]; typedefstruct{ //Listadelongitudvariable tArray elementos; int contador; }tLista; int main(){ tLista lista; ifstream archivo; int dato,pos,tmp; lista.contador =0; ...
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 676

LuisHernndezYez

LuisHernndezYez

archivo.open("insercion.txt"); if (!archivo.is_open()){ cout<<"Errordeaperturadearchivo!" <<endl; } else { archivo>>dato; while ((lista.contador <N)&&(dato!=1)){ //Centinela1alfinal lista.elementos[lista.contador]=dato; lista.contador++; archivo>>dato; } archivo.close(); //SihaymsdeNignoramoselresto cout<<"Antesdeordenar:"<<endl; for (int i=0;i<lista.contador;i++){ cout<<lista.elementos[i]<<""; } cout<<endl;...
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 677

LuisHernndezYez

for (int i=1;i<lista.contador;i++){ pos=i; while ((pos>0) &&(lista.elementos[pos1]>lista.elementos[pos])) { tmp=lista.elementos[pos]; lista.elementos[pos]=lista.elementos[pos 1]; lista.elementos[pos 1]=tmp; pos; } } cout<<"Despusdeordenar:"<<endl; for (int i=0;i<lista.contador;i++){ cout<<lista.elementos[i]<<""; } cout<<endl; } return 0; }
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 678

Consideracin de implementacin
Operador relacional adecuado? lista[pos 1] > o >= ? lista[pos] Con >= se realizan intercambios intiles:
5
0

7
1

14
2

20
3

32
4

14
5

27
6

12
7

13
8

15
9

5
0

7
1

14
2

20
3

14
4

32
5

27
6

12
7

13
8

15
9

LuisHernndezYez

5
0

7
1

14
2

14
3

20
4

32
5

27
6

12
7

13
8

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

LuisHernndezYez

Clave de ordenacin: Campo en el que se basan las comparaciones

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 681

Claves de ordenacin
tDato tmp; while ((pos>0) &&(lista[pos 1].nombre>lista[pos].nombre)){ tmp=lista[pos]; lista[pos]=lista[pos 1]; lista[pos 1]=tmp; pos; }

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; int cont; }tLista; ...
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 684

LuisHernndezYez

void mostrar(tListalista); bool operator>(tDato opIzq,tDato opDer); int main(){ tListalista; ifstreamarchivo; lista.cont =0; archivo.open("datos.txt"); if(!archivo.is_open()){ cout<<"Errordeaperturadelarchivo!" <<endl; } else { tDato dato; archivo>>dato.codigo; while ((lista.cont <N)&&(dato.codigo !=1)){ archivo>>dato.nombre >>dato.sueldo; lista.datos[lista.cont]=dato; lista.cont++; archivo>>dato.codigo; } archivo.close();...
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 685

LuisHernndezYez

LuisHernndezYez

cout<<"Antesdeordenar:"<<endl; mostrar(lista); for (int i=1;i<lista.cont;i++){ //Desdeelsegundoelementohastaelltimo int pos=i; while ((pos>0) &&(lista.datos[pos1]>lista.datos[pos])){ tDatotmp; tmp=lista.datos[pos]; lista.datos[pos]=lista.datos[pos 1]; lista.datos[pos 1]=tmp; pos; } } cout<<"Despusdeordenar:"<<endl; mostrar(lista); } return 0; }
Fundamentosdelaprogramacin:Algoritmosdeordenacin

...
Pgina 686

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

bool operator>(tDato opIzq,tDato opDer){ return (opIzq.nombre >opDer.nombre); }

Cambia a codigo o sueldo para ordenar por otros campos


Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 687

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 21112Domnguez90000 Sueldo Lista ordenada por Nombre
LuisHernndezYez

11111Durn120000 22222Fernndez120000 12345Gmez100000 10000Hernndez150000 21112Jimnez100000 11111Prez90000 12345Snchez90000 10000Sergei100000 33333Tarazona120000 12345Turgano100000 11111Urpiano90000

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 689

Ordenamos ahora por el campo Codigo:


10000Sergei100000 10000Hernndez150000 11111Urpiano 90000 11111Bentez 100000 11111Prez 90000 11111Durn 120000 12345Snchez90000 12345lvarez120000 12345Turgano100000 12345Gmez100000 21112Domnguez90000 21112Jimnez100000 22222Fernndez120000 33333Tarazona120000
LuisHernndezYez

10000Hernndez150000 10000Sergei100000 11111Bentez 100000 11111Durn 120000 11111Prez 90000 11111Urpiano 90000 12345lvarez120000 12345Gmez100000 12345Snchez90000 12345Turgano100000 21112Domnguez90000 21112Jimnez100000 22222Fernndez120000 33333Tarazona120000

No estable: Los nombres no mantienen sus posiciones relativas

Estable: Los nombres mantienen 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 10000Sergei100000 11111Bentez100000 11111Durn120000 11111Prez90000 11111Urpiano90000 12345lvarez120000 12345Gmez100000 12345Snchez90000 12345Turgano100000 21112Domnguez90000 21112Jimnez100000 22222Fernndez120000 33333Tarazona120000 11111Prez90000 11111Urpiano90000 12345Snchez90000 21112Domnguez90000 10000 Sergei100000 11111 Bentez100000 12345 Gmez 100000 12345 Turgano 100000 21112 Jimnez100000 11111Durn120000 12345lvarez120000 22222Fernndez120000 33333Tarazona120000 10000Hernndez150000

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 691

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 692

Casos de estudio para los algoritmos de ordenacin


Lista inicialmente ordenada
5
0

7
1

12
2

13
3

14
4

14
5

15
6

20
7

27
8

32
9

Lista inicialmente ordenada al revs


32
0

27
1

20
2

15
3

14
4

14
5

13
6

12
7

7
8

5
9

Lista con disposicin inicial aleatoria


13
LuisHernndezYez

20
1

7
2

14
3

12
4

32
5

27
6

14
7

5
8

15
9

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

Operaciones que realiza el algoritmo de ordenacin: Comparaciones 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++){ N variable de ciclos int pos=i; while((pos>0)&&(lista[pos 1]>lista[pos])){ int tmp; tmp=lista[pos]; lista[pos]=lista[pos 1]; lista[pos 1]=tmp; pos; } }

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

LuisHernndezYez

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 128716384 256865536 ...
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 700

LuisHernndezYez

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

LuisHernndezYez

Lista ordenada:

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 1

LuisHernndezYez

Lista ordenada:

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

8 3

LuisHernndezYez

Lista ordenada:

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 1 2 3

LuisHernndezYez

Lista ordenada:

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 705

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

5 7

LuisHernndezYez

Lista ordenada:

1 2 3 4

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 706

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

LuisHernndezYez

Lista ordenada:

1 2 3 4 5

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 707

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

LuisHernndezYez

Lista ordenada:

1 2 3 4 5 6

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 708

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

LuisHernndezYez

Lista ordenada:

1 2 3 4 5 6 7

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 709

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

9 1 2 3 4 5 6 7 8

LuisHernndezYez

Lista ordenada:

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 710

Algoritmo de ordenacin por seleccin directa


Seleccionar el siguiente elemento menor de los que queden

Lista desordenada:

LISTA ORDENADA !!!


LuisHernndezYez

Lista ordenada:

1 2 3 4 5 6 7 8 9

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 711

Ordenacin de un array por seleccin directa


Desde el primer elemento (i = 0) hasta el penltimo (N2): Menor elemento (en m) entre i + 1 y el ltimo (N1) Intercambiar los elementos en i y m si no son el mismo
i 20
0

m 7
1

14
2

32
3

5
4

14
5

27
6

12
7

13
8

15
9

im
LuisHernndezYez

Slo intercambiamos si no es la misma posicin


14
2

5
0

7
1

32
3

20
4

14
5

27
6

12
7

13
8

15
9

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 712

Ordenacin de un array por seleccin directa


i 5
0

m 32
3

7
1

14
2

20
4

14
5

27
6

12
7

13
8

15
9

i 5
0

m 20
4

7
1

12
2

32
3

14
5

27
6

14
7

13
8

15
9

i
LuisHernndezYez

m 14
5

5
0

7
1

12
2

13
3

20
4

27
6

14
7

32
8

15
9

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 713

seleccion.cpp

Implementacin

constintN=15; typedefinttLista[N]; tLista lista;

LuisHernndezYez

//Desdeelprimerelementohastaelpenltimo... for(int i=0;i<N 1;i++){ int menor=i; //Desdei+1hastaelfinal... for(int j=i+1;j<N;j++){ if (lista[j]<lista[menor]){ menor=j; } } if (menor>i){ int tmp; tmp=lista[i]; lista[i]=lista[menor]; lista[menor]=tmp; } }
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 714

Complejidad de la ordenacin por seleccin directa


Cuntas comparaciones se realizan? Bucle externo: N 1 ciclos Tantas comparaciones como elementos queden en la lista: (N 1) + (N 2) + (N 3) + ... + 3 + 2 + 1 = N x (N 1) / 2 = (N2 N) / 2 O(N2) Mismo nmero de comparaciones en todos los casos Igual que el mtodo de insercin Complejidad: O(N2) Algo mejor (menos intercambios; uno en cada paso)
LuisHernndezYez

No es estable: intercambios a larga distancia No se garantiza que se mantenga el mismo orden relativo original Comportamiento no natural (trabaja siempre lo mismo)
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 715

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 4 3
LuisHernndezYez

9 4 3 1 6

9 4 1 3 6

9 1 4 3 6

1 9 4 3 6
Pgina 717

6 1

Fundamentosdelaprogramacin:Algoritmosdeordenacin

12
0

32
1

14
2

5
3

14
4

7
5

12
0

32
1

14
2

5
3

7
4

14
5

12
0

32
1

14
2

5
3

7
4

14
5

12
0

32
1

5
2

14
3

7
4

14
5

LuisHernndezYez

12
0

5
1

32
2

14
3

7
4

14
5

5
0

12
1

32
2

14
3

7
4

14
5 Pgina 718

Fundamentosdelaprogramacin:Algoritmosdeordenacin

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]; lista[j 1]=tmp; } } }
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 719

LuisHernndezYez

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 35121616 12353535 50505050
Fundamentosdelaprogramacin:Algoritmosdeordenacin

La lista ya est ordenada No hace falta seguir

LuisHernndezYez

Pgina 720

burbuja2.cpp

LuisHernndezYez

bool inter=true; int i=0; //Desdeel1hastaelpenltimosihayintercambios... while((i<N 1)&&inter){ inter=false; //Desdeelltimohastaelsiguienteai... for(int j=N 1;j>i;j){ if (lista[j]<lista[j 1]){ int tmp; tmp=lista[j]; lista[j]=lista[j 1]; lista[j 1]=tmp; inter=true; } } if (inter){ i++; } } Esta variacin s tiene un comportamiento natural
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 721

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

return opIzq.nombre <opDer.nombre; }

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 726

LuisHernndezYez

void insertar(tLista &lista,tRegistro registro,bool &ok){ ok=true; if (lista.cont ==N){ ok=false;//listallena } else { int i=0; while ((i<lista.cont)&&(lista.registros[i]<registro)){ i++; } //Insertamosenlaposicini(primermayoroigual) for (int j=lista.cont;j>i;j){ //Desplazamosunaposicinaladerecha lista.registros[j]=lista.registros[j 1]; } lista.registros[i]=registro; lista.cont++; } }
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
0

7
1

12
2

13
3

14
4

14
5

15
6

20
7

27
8

32
9

LuisHernndezYez

Buscamos el 36: al llegar al final sabemos que no est Buscamos el 17: al llegar al 20 ya sabemos que no est Condiciones de terminacin: Se llega al final Se encuentra el elemento buscado Se encuentra uno mayor Mientras no al final y el valor sea menor que el buscado
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 729

LuisHernndezYez

int buscado; constintN=10; cout<<"Valorabuscar:"; typedefinttLista[N]; cin>>buscado; tLista lista; int i=0; while((i<N)&&(lista[i]<buscado)){ i++; } //Ahora,oestamosalfinalolista[i]>=buscado if(i==N){//Alfinal:nosehaencontrado cout<<"Noencontrado!" <<endl; } elseif (lista[i]==buscado){//Encontrado! cout<<"Encontradoenposicin" <<i+1 <<endl; } else { //Hemosencontradounomayor cout<<"Noencontrado!" <<endl; } Complejidad: O(N)
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 730

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 731

Bsqueda mucho ms rpida que aprovecha la ordenacin Comparar con el valor que est en el medio de la lista: Si es el que se busca, terminar Si no, si es mayor, buscar en la primera mitad de la lista Si no, si es menor, buscar en la segunda mitad de la lista Repetir hasta encontrarlo o no quede sublista donde buscar
Buscamos el 12
5
0

Elemento mitad 14
3

7
1

12
2

14
4

15
5

18
6

20
7

27
8

32
9

5
LuisHernndezYez

7
1

12
2

14
3

14
4

15
5

18
6

20
7

27
8

32
9

5
0

7
1

12
2

14
3

14
4

15
5

18
6

20
7

27
8

32
9 Pgina 732

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Vamos buscando en sublistas cada vez ms pequeas (mitades) Delimitamos el segmento de la lista donde buscar Inicialmente tenemos toda la lista:
ini 5
0

mitad 7
1

fin 15
5

12
2

14
3

14
4

18
6

20
7

27
8

32
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 Buscado > elemento en la mitad: ini=mitad+1 Si ini > fin, no queda dnde buscar

LuisHernndezYez

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Pgina 733

Buscamos el 12
ini 5
0

mitad 7
1

fin 15
5

12
2

14
3

14
4

18
6

20
7

27
8

32
9

12 <lista[mitad] fin=mitad 1
ini mitad 5
0

fin 12
2

7
1

14
3

14
4

15
5

18
6

20
7

27
8

32
9

12 >lista[mitad] ini=mitad+1
ini
LuisHernndezYez

fin 14
3

5
0

7
1

12
2

14
4

15
5

18
6

20
7

27
8

32
9

mitad

Encontrado!
Pgina 734

Fundamentosdelaprogramacin:Algoritmosdeordenacin

Si el elemento no est, nos quedamos sin sublista: ini>fin


Para el 13:
5
0

mitad ini fin 12


2

7
1

14
3

14
4

15
5

18
6

20
7

27
8

32
9

13 >lista[mitad] ini=mitad+1
mitad ini fin 5
LuisHernndezYez

7
1

12
2

14
3

14
4

15
5

18
6

20
7

27
8

32
9

13 <lista[mitad] fin=mitad 1 2 ini>fin !!! No hay dnde seguir buscando No est


Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 735

Implementacin

LuisHernndezYez

int buscado; cout<<"Valorabuscar:"; cin>>buscado; int ini=0,fin=N 1,mitad; bool encontrado=false; while((ini<=fin)&&!encontrado){ mitad=(ini+fin)/2;//Divisinentera if(buscado==lista[mitad]){ encontrado=true; } elseif(buscado<lista[mitad]){ fin=mitad 1; } else{ ini=mitad+1; } }//Sisehaencontrado,esten[mitad]
Fundamentosdelaprogramacin:Algoritmosdeordenacin

constintN=10; typedefinttLista[N]; tLista lista;

Pgina 736

#include<iostream> usingnamespacestd; #include<fstream> constint N=100; typedef int tArray[N]; typedef struct { tArray elementos; int cont; }tLista; int buscar(tLista lista,int buscado);

binaria.cpp

int main(){ tLista lista; ifstream archivo; int dato; lista.cont =0; archivo.open("ordenados.txt");//Existeyescorrecto archivo>>dato; ...
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 737

LuisHernndezYez

LuisHernndezYez

while ((lista.cont <N)&&(dato!=1)){ lista.elementos[lista.cont]=dato; lista.cont++; archivo>>dato; } archivo.close(); for (int i=0;i<lista.cont;i++){ cout<<lista.elementos[i]<<""; } cout<<endl; int buscado,pos; cout<<"Valorabuscar:"; cin>>buscado; pos=buscar(lista,buscado); if (pos!=1){ cout<<"Encontradoenlaposicin"<<pos+1 <<endl; } else { cout<<"Noencontrado!"<<endl; } return 0; }...
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 738

LuisHernndezYez

int buscar(tListalista,int buscado){ int pos=1,ini=0,fin=lista.cont 1,mitad; bool encontrado=false; while ((ini<=fin)&&!encontrado){ mitad=(ini+fin)/2;//Divisinentera if (buscado==lista.elementos[mitad]){ encontrado=true; } elseif(buscado<lista.elementos[mitad]){ fin=mitad 1; } else { ini=mitad+1; } } if (encontrado){ pos=mitad; } return pos; }
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 739

Complejidad
Qu orden de complejidad tiene la bsqueda binaria? Caso peor: No est o se encuentra en una sublista de 1 elemento N de comparaciones = N de mitades que podemos hacer N / 2, N / 4, N / 8, N / 16, ..., 8, 4, 2, 1 1, 2, 4, 8, ..., N / 16, N / 8, N / 4, N / 2 Si hacemos que N sea igual a 2k: 20, 21, 22, 23, ..., 2k4, 2k3, 2k2, 2k1 N de elementos de esa serie: k N de comparaciones = k N = 2k k = log2 N Complejidad: O(log2 N) Mucho ms rpida que O(N)
Fundamentosdelaprogramacin:Algoritmosdeordenacin Pgina 740

LuisHernndezYez

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 Mezcladedoslistasordenadas

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

7
1

12
2

32
3

20
4

14
5

27
6

5
7

13
8

15
9

7
0

14
1

12
2

32
3

20
4

14
5

27
6

5
7

13
8

15
9

LuisHernndezYez

5
0

14
1

12
2

32
3

20
4

14
5

27
6

7
7

13
8

15
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; while ((dato1!=1)&&(dato2!=1)){ //Mientrasquedealgoenambosarchivos ...

LuisHernndezYez

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){ mezcla<<dato2<<endl; archivo2>>dato2; } } ...
Fundamentosdelaprogramacin:Algoritmosdeordenacin(Anexo) Pgina 752

LuisHernndezYez

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

LuisHernndezYez

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

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

Fundamentosdelaprogramacin: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
constintN=10; typedefdoubletArray[N]; typedefstruct{ tArray elem; intcont; }tArray; voidinit(tArray &lista); voidinsert(tArray &lista, doubleelem,bool&ok); voidremove(tArray &lista, intpos,bool&ok); ...

Principal
intmain(){ tArray lista; boolok; init(lista); cargar(lista,"bd.txt"); sort(lista); doubledato; cout<<"Dato:"; cin>>dato; insert(lista,dato,ok); cout<<min(lista)<<endl; cout<<max(lista)<<endl; cout<<sum(lista)<<endl; guardar(lista,"bd.txt"); return0; }

Clculos
doublemean(tArray lista); doublemin(tArray lists); doublemax(tArray lista); doubledesv(tArray lista); intminIndex(tArray lista);

Archivos
boolcargar(tArray &lista, stringnombre); boolguardar(tArray lista, stringnombre); boolmezclar(stringarch1, stringarch2); intsize(stringnombre);

intmaxIndex(tArray lista); boolexportar(stringnombre); doublesum(tArray lista);

LuisHernndezYez

Ejecutable
Fundamentosdelaprogramacin:Programacinmodular Pgina 758

Compilacin separada
Cada mdulo se compila a cdigo objeto de forma independiente
Lista
constintN=10; typedefdoubletArray[N]; typedefstruct{ tArray elem; intcont; }tArray; voidinit(tArray &lista); voidinsert(tArray &lista, doubleelem,bool&ok); voidremove(tArray &lista, intpos,bool&ok); ...

lista.obj
00101110101011001010010010101 00101010010101011111010101000 10100101010101010010101010101 01100101010101010101010101001 01010101010100000101010101101 01001010101010101000010101011 11001010101010111100110010101 01101010101010010010101001111 00101010101001010100101010010 10100101010100101000010011110 10010101011001010101001010100 10101010101010010101001010101 01000010101011100101010010100 01110101011101001101010100101 01011111110101011001101010111 00001001010100101010101010110

Archivos
boolcargar(tArray &lista, stringnombre); boolguardar(tArray lista, stringnombre); boolmezclar(stringarch1, stringarch2); intsize(stringnombre); boolexportar(stringnombre);

archivos.obj
11101010110010100100101010010 10100101010111110101010001010 01010101010100101010101010110 01010101010101010101010010101 01010101000001010101011010100 10101010101010000101010111100 10101010101111001100101010110 10101010100100101010011110010 10101010010101001010100101010 01010101001010000100111101001 01010110010101010010101001010 10101010100101010010101010100 00101010111001010100101000111 01010111010011010101001010101 11111101010110011010101110000 10010101001010101010101101111

Clculos
doublemean(tArray lista); doublemin(tArray lists); doublemax(tArray lista);

calculos.obj
01011001010010010101001010100 10101011111010101000101001010 10101010010101010101011001010 10101010101010101001010101010 10100000101010101101010010101 01010101000010101011110010101 01010111100110010101011010101 01010010010101001111001010101 01001010100101010010101001010 10100101000010011110100101010 11001010101001010100101010101 01010010101001010101010000101 01011100101010010100011101010 11101001101010100101010111111 10101011001101010111000010010 10100101010101010110001111010

LuisHernndezYez

doubledesv(tArray lista); intminIndex(tArray lista); intmaxIndex(tArray lista); doublesum(tArray lista);

Fundamentosdelaprogramacin:Programacinmodular

Pgina 759

Compilacin separada
Al compilar el programa principal, se adjuntan los mdulos compilados
Principal Mdulos del programa
lista.obj calculos.obj archivos.obj
intmain(){ tArray lista; boolok; init(lista); cargar(lista,"bd.txt"); sort(lista); doubledato; cout<<"Dato:"; cin>>dato; insert(lista,dato,ok); cout<<min(lista)<<endl; cout<<max(lista)<<endl; cout<<sum(lista)<<endl; guardar(lista,"bd.txt");

Bibliotecas del sistema


iostream.obj fstream.obj math.obj

...

return0; }

...

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

calculos.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 Etctera + Implementacin de los subprogramas (cmo se hace)
Fundamentosdelaprogramacin:Programacinmodular Pgina 763

LuisHernndezYez

Creacin de mdulos de biblioteca


Interfaz: Definiciones/declaraciones de datos y prototipos Todo lo que el usuario de la unidad funcional necesita saber! Implementacin: Cdigo de los subprogramas que hacen el trabajo No hay que conocerlo para usarlo: Seguro que es correcto! Interfaz e implementacin en dos archivos separados: Cabecera: Definiciones/declaraciones de datos y prototipos Implementacin: Implementacin de los subprogramas. Archivo de cabecera: extensin .h Mismo nombre Archivo de implementacin: extensin .cpp Repartimos el cdigo entre ambos archivos (lista.h/lista.cpp)

LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular

Pgina 764

Creacin de mdulos de biblioteca


Interfaz frente a implementacin
lista.h
constintN=10; typedefdoubletArray[N]; typedefstruct{ tArray elem; intcont; }tArray; voidinit(tArray &lista); voidinsert(tArray &lista, doubleelem,bool&ok); voidremove(tArray &lista, intpos,bool&ok); ...

lista.cpp
#include"lista.h" voidinit(tArray &lista){ lista.cont =0; } voidinsert(tArray &lista, doubleelem,bool&ok){ if(lista.cont ==N){ okfalse; } else{ ...

Mdulo Unidad Biblioteca

LuisHernndezYez

Si otro mdulo quiere usar algo de esa biblioteca: Debe incluir el archivo de cabecera
main.cpp
#include"lista.h" ...

Los nombres de archivos de cabecera propios (no del sistema) se encierran entre dobles comillas, no entre ngulos
Pgina 765

Fundamentosdelaprogramacin:Programacinmodular

Creacin de mdulos de biblioteca

lista.h
constintN=10; typedefdoubletArray[N]; typedefstruct{ tArray elem; intcont; }tArray; voidinit(tArray &lista); voidinsert(tArray &lista, doubleelem,bool&ok); voidremove(tArray &lista, intpos,bool&ok); ...

Interfaz Archivo de cabecera (.h): todo lo que necesita conocer otro mdulo (o programa principal) que quiera utilizar sus servicios (subprogramas) La directiva #include aade las declaraciones del archivo de cabecera en el cdigo del mdulo (preprocesamiento):
main.cpp
#include"lista.h" ...

Preprocesador

main.cpp
constintN=10; typedefdoubletArray[N]; typedefstruct{ tArray elem; intcont; }tArray; voidinit(tArray &lista); voidinsert(tArray &lista,doubleelem, bool&ok); voidremove(tArray &lista,intpos, bool&ok); ...

LuisHernndezYez

Todo lo que se necesita saber para comprobar si el cdigo de main.cpp hace un uso correcto de la lista (declaraciones y llamadas)
Fundamentosdelaprogramacin:Programacinmodular

Pgina 766

Creacin de mdulos de biblioteca


Implementacin Compilar el mdulo significa compilar su archivo de implementacin (.cpp) Tambin necesita conocer sus propias declaraciones:
lista.cpp
#include"lista.h" ...

lista.cpp
#include"lista.h" voidinit(tArray &lista){ lista.cont =0; } voidinsert(tArray &lista, doubleelem,bool&ok){ if(lista.cont ==N){ okfalse; } else{ ...

lista.obj
00101110101011001010010010101 00101010010101011111010101000 10100101010101010010101010101 01100101010101010101010101001 01010101010100000101010101101 01001010101010101000010101011 11001010101010111100110010101 01101010101010010010101001111 00101010101001010100101010010 10100101010100101000010011110 10010101011001010101001010100 10101010101010010101001010101 01000010101011100101010010100 01110101011101001101010100101 01011111110101011001101010111 00001001010100101010101010110

LuisHernndezYez

Al compilar el mdulo se genera el cdigo objeto Si no se modifica no hay necesidad de recompilar Cdigo que usa el mdulo: Necesita slo el archivo de cabecera para compilar Se adjunta el cdigo objeto del mdulo durante el enlace
Fundamentosdelaprogramacin:Programacinmodular Pgina 767

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" Archivos de cabecera de bibliotecas del sistema: entre ngulos Y no tienen necesariamente que llevar extensin .h
Fundamentosdelaprogramacin:Programacinmodular Pgina 769

LuisHernndezYez

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; }tLista; const string BD="bd.txt"; ... Documenta bien el cdigo!
Fundamentosdelaprogramacin:Programacinmodular Pgina 770

LuisHernndezYez

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

LuisHernndezYez

Cada prototipo, con un comentario que explique su utilidad/uso


(Aqu se omiten por cuestin de espacio)

Fundamentosdelaprogramacin:Programacinmodular

Pgina 771

Implementacin

lista.cpp

Mdulo: Gestin de una lista ordenada I


#include <iostream> #include <string> usingnamespacestd; #include <fstream> #include <iomanip> #include "lista.h" tRegistro nuevo(){ tRegistro registro; cout<<"Introduceelcdigo:"; cin>>registro.codigo; cout<<"Introduceelnombre:"; cin>>registro.nombre; cout<<"Introduceelsueldo:"; cin>>registro.sueldo; return registro; }...
Fundamentosdelaprogramacin:Programacinmodular Pgina772

LuisHernndezYez

LuisHernndezYez

void insertar(tLista&lista,tRegistro registro,bool &ok){ ok=true; if (lista.cont ==N){ ok=false;//Listallena } else { int i=0; while((i<lista.cont)&&(lista.registros[i]<registro)){ i++; } //Insertamosenlaposicini for (intj=lista.cont;j>i;j){ //Desplazamosaladerecha lista.registros[j]=lista.registros[j 1]; } lista.registros[i]=registro; lista.cont++; } }...
Fundamentosdelaprogramacin:Programacinmodular Pgina773

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; } else { do { mostrar(lista); op =menu();...
Fundamentosdelaprogramacin:Programacinmodular Pgina775

LuisHernndezYez

LuisHernndezYez

if (op ==1){ tRegistro registro=nuevo(); insertar(lista,registro,ok); if (!ok){ cout<<"Error:Listallena!"<<endl; } } elseif(op ==2){ cout<<"Posicin:"; cin>>pos; eliminar(lista,pos,ok); if (!ok){ cout<<"Error:Posicion inexistente!"<<endl; } } elseif(op ==3){ stringnombre; cin.sync(); cout<<"Nombre:"; cin>>nombre; intpos=buscar(lista,nombre); ...

Fundamentosdelaprogramacin:Programacinmodular

Pgina776

if (pos==1){ cout<<"Nosehaencontrado!" <<endl; } else { cout<<"Encontradoenlaposicin" <<pos<<endl; } } }while (op !=0); guardar(lista); } return 0; } int menu(){ cout<<endl; cout<<"1 Insertar"<<endl; cout<<"2 Eliminar" <<endl; cout<<"3 Buscar" <<endl; cout<<"0 Salir" <<endl; int op; do { ...

LuisHernndezYez

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 Con Depurar>Generarsolucin se compilan todos los .cpp
Fundamentosdelaprogramacin:Programacinmodular Pgina 779

LuisHernndezYez

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<string> usingnamespacestd; constintN=100; typedefstruct{ intcodigo; stringnombre; doublesueldo; }tRegistro; typedeftRegistro tArray[N];
#include"lista.h" intmenu(); ...

#include<string> usingnamespacestd; constintN=100; typedefstruct{ intcodigo; stringnombre; doublesueldo; }tRegistro; typedeftRegistro tArray[N]; typedefstruct{ tArray registros; intcont; }tLista; ... intmenu(); ...

LuisHernndezYez

typedefstruct{ tArray registros; intcont; }tLista; ...

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; string nombre; double sueldo; }tRegistro; typedef tRegistro tArray[N]; typedef struct { tArray registros; int cont; }tLista;
Fundamentosdelaprogramacin:Programacinmodular

Lista de registros: Estructura tRegistro Estructura tLista (contiene tRegistro) Cada estructura, en su mdulo

LuisHernndezYez

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; } booloperator>(tRegistro opIzq,tRegistro opDer){ returnopIzq.nombre >opDer.nombre; }...
Fundamentosdelaprogramacin:Programacinmodular Pgina 785

LuisHernndezYez

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); voidmostrar(const tLista&lista); voidcargar(tLista&lista,bool &ok); voidguardar(tLista lista);

LuisHernndezYez

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 for (intj=lista.cont;j>i;j){//Desplazar aladerecha lista.registros[j]=lista.registros[j 1]; } ...
Fundamentosdelaprogramacin:Programacinmodular Pgina 787

LuisHernndezYez

bd2.cpp

Gestin de una lista ordenada II


#include<iostream> usingnamespacestd; #include"registro.h" #include"lista2.h" intmenu(); int main(){ tLista lista; bool ok; int op,pos;

No intentes compilar este ejemplo! Tiene errores

cargar(lista,ok); if (!ok){ cout<<"Nosepudoabrirelarchivo!"<<endl; } else { do { mostrar(lista); op =menu(); ...


Fundamentosdelaprogramacin:Programacinmodular Pgina788

LuisHernndezYez

LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular

Pgina 789

Gestin de una lista ordenada II


2 mdulos y el programa principal:
registro.h
#include<string> ...

bd2.cpp
... #include"registro.h" #include"lista2.h" ...

registro.cpp
... #include"registro.h" ...

lista2.h
... #include"registro.h" ...

LuisHernndezYez

lista2.cpp

Incluye...

... #include"lista2.h" ...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 790

Gestin de una lista ordenada II


Preprocesamiento de #include:
#include<iostream> usingnamespacestd; #include"registro.h" #include"lista2.h" intmenu(); ... #include<string> usingnamespacestd; #include "registro.h" const int N=100; typedef tRegistro tArray[N]; typedef struct { tArray registros; int cont; }tLista; ... #include<string> usingnamespacestd; typedef struct { ... }tRegistro; ... #include<string> usingnamespacestd; typedef struct { ... }tRegistro; ...

LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular

Pgina 791

Gestin de una lista ordenada II


Preprocesamiento de #include:
#include<iostream> usingnamespacestd; #include<string> usingnamespacestd; typedef struct { ... }tRegistro; ... #include"lista2.h" intmenu();
LuisHernndezYez

Sustituido

#include<string> usingnamespacestd; #include<string> usingnamespacestd; typedef struct { ... }tRegistro; ... const int N=100; typedef tRegistro tArray[N]; typedef struct { tArray registros; int cont; }tLista; ...

...

Fundamentosdelaprogramacin:Programacinmodular

Pgina 792

Gestin de una lista ordenada II


#include<iostream> usingnamespacestd; #include<string> usingnamespacestd; typedef struct { ... }tRegistro; ... #include<string> usingnamespacestd; #include<string> usingnamespacestd;
LuisHernndezYez

const int N=100; typedef tRegistro tArray[N]; typedef struct { tArray registros; int cont; }tLista; ... intmenu(); ...

typedef struct { ... }tRegistro; ...

Identificador duplicado!

Fundamentosdelaprogramacin:Programacinmodular

Pgina 793

Compilacin condicional
Directivas #ifdef, #ifndef, #else y #endif Se usan en conjuncin con la directiva #define
#define X #ifdef X ...//Cdigoif [#else ...//Cdigoelse ] #endif
LuisHernndezYez

#define X #ifndef X ...//Cdigoif [#else ...//Cdigoelse ] #endif

La directiva #define define un smbolo (identificador) Izquierda: se compilar el Cdigo if y no el Cdigo else Derecha: al revs, o nada si no hay else Las clusulas else son opcionales
Fundamentosdelaprogramacin:Programacinmodular Pgina 794

Proteccin frente a inclusiones mltiples


lista2.cpp y bd2.cpp incluyen registro.h

Identificadores duplicados! Cada mdulo debe incluirse una y slo una vez Proteccin frente a inclusiones mltiples:
#ifndef X #define X ...//Mdulo #endif
LuisHernndezYez

El smbolo X debe ser nico para cada mdulo de la aplicacin

La primera vez no est definido el smbolo X: se incluye y define Las siguientes veces el smbolo X ya est definido: no se incluye Smbolo X: nombre del archivo con _ en lugar de . registro_h, lista2_h, ...
Fundamentosdelaprogramacin:Programacinmodular Pgina 795

Cabecera

registrofin.h

Gestin de una lista ordenada III


#ifndef registrofin_h #define registrofin_h #include<string> usingnamespacestd; typedef struct { int codigo; string nombre; double sueldo; }tRegistro; tRegistro nuevo(); booloperator>(tRegistro opIzq,tRegistro opDer); booloperator<(tRegistro opIzq,tRegistro opDer); void mostrar(int pos,tRegistro registro); #endif
Fundamentosdelaprogramacin:Programacinmodular Pgina 796

LuisHernndezYez

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; } booloperator>(tRegistro opIzq,tRegistro opDer){ returnopIzq.nombre >opDer.nombre; }...
Fundamentosdelaprogramacin:Programacinmodular Pgina 797

LuisHernndezYez

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 intbuscar(tLista lista,stringnombre); voidcargar(tLista&lista,bool&ok); voidguardar(tLista lista); #endif
Fundamentosdelaprogramacin:Programacinmodular Pgina 798

LuisHernndezYez

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 for (intj=lista.cont;j>i;j){ //Desplazamosaladerecha lista.registros[j]=lista.registros[j 1]; } ...
Fundamentosdelaprogramacin:Programacinmodular Pgina799

LuisHernndezYez

bdfin.cpp

Gestin de una lista ordenada III


#include<iostream> usingnamespacestd; #include"registrofin.h" #include"listafin.h" intmenu(); int main(){ tLista lista; bool ok; int op,pos;

Ahora ya puedes compilarlo!

cargar(lista,ok); if (!ok){ cout<<"Nosepudo abrir elarchivo!" <<endl; } else { do { mostrar(lista); op=menu(); ...
Fundamentosdelaprogramacin:Programacinmodular Pgina 800

LuisHernndezYez

Gestin de una lista ordenada III


Preprocesamiento de #include en bdfin.cpp:
#include<iostream> usingnamespacestd; #include"registrofin.h" #include"listafin.h" intmenu(); ...
#ifndef registrofin_h #define registrofin_h #include<string> usingnamespacestd; typedef struct { ... }tRegistro; ...

LuisHernndezYez

registrofin_h no se ha definido todava

Fundamentosdelaprogramacin:Programacinmodular

Pgina 801

Gestin de una lista ordenada III


Preprocesamiento de #include en bdfin.cpp:
#include<iostream> usingnamespacestd; #define registrofin_h #include<string> usingnamespacestd; typedef struct { ... }tRegistro; ...
LuisHernndezYez

#ifndef listafin_h #define listafin_h #include<string> usingnamespacestd; #include "registrofin.h" const int N=100; typedef tRegistro tArray[N]; typedef struct { tArray registros; int cont; }tLista; ...

#include"listafin.h" intmenu(); ...

listafin_h no se ha definido todava


Pgina 802

Fundamentosdelaprogramacin:Programacinmodular

Gestin de una lista ordenada III


Preprocesamiento de #include en bdfin.cpp:
#include<iostream> usingnamespacestd; #define registrofin_h #include<string> usingnamespacestd; typedef struct { ... }tRegistro; ... #define listafin_h #include<string> usingnamespacestd; #include "registrofin.h" ... intmenu();
...
Fundamentosdelaprogramacin:Programacinmodular Pgina 803

#ifndef registrofin_h #define registrofin_h #include<string> usingnamespacestd; typedef struct { ... }tRegistro; ...

LuisHernndezYez

registrofin_h ya est definido!

LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular

Pgina 804

Misma interfaz, implementacin alternativa


#include<string> usingnamespacestd; #include "registrofin.h" const int N=100; typedef tRegistro tArray[N]; typedef struct { tArray registros; int cont; }tLista; void insertar(tLista&lista,tRegistro registro,bool &ok);
void insertar(tLista&lista,tRegistro registro,bool &ok){ ok=true; void insertar(tLista&lista,tRegistro registro,bool &ok){ if (lista.cont ==N){ ok=true; ok=false;//Lista llena if (lista.cont ==N){ } ok=false;//Listallena else { } int i =0; else { while((i<lista.cont)&&(lista.registros[i] <registro)){ i++; lista.registros[lista.cont]=registro; } lista.cont++; //Insertamos enlaposicin i } for (intj=lista.cont;j>i;j){ } //Desplazamos aladerecha lista.registros[j]=lista.registros[j 1]; ...

lista.h

Lista ordenada

Lista no ordenada

LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular

Pgina 805

Misma interfaz, implementacin alternativa


listaDES.cpp: Lista no ordenada
... #include "lista.h"

LuisHernndezYez

void insertar(tLista&lista,tRegistro registro,bool &ok){ ok=true; if (lista.cont ==N){ ok=false;//Listallena ... } #include "lista.h" else { lista.registros[lista.cont] =registro; void insertar(tLista&lista,tRegistro registro,bool &ok) { lista.cont++; ok=true; } if (lista.cont ==N){ } ok=false;//Lista llena ... } else { int i=0; while((i<lista.cont)&&(lista.registros[i]<registro)){ i++; } //Insertamos enlaposicin i for (intj=lista.cont;j>i;j){ //Desplazamos aladerecha lista.registros[j]=lista.registros[j 1]; } lista.registros[i]=registro; ...

listaORD.cpp: Lista ordenada

Fundamentosdelaprogramacin:Programacinmodular

Pgina 806

Misma interfaz, implementacin alternativa


Al compilar, incluimos un archivo de implementacin u otro: Programa con lista ordenada o con lista desordenada?
g++oprograma.exeregistrofin.cpplistaORD.cpp...

Incluye la implementacin de la lista con ordenacin


g++oprograma.exeregistrofin.cpplistaDES.cpp...

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

namespace primero { int x=5; }

namespace segundo { double x=3.1416; }

Ahora se distingue entre primero::x y segundo::x


Fundamentosdelaprogramacin:Programacinmodular Pgina 810

using
Introduce un nombre de un espacio de nombres en el mbito actual:
#include <iostream> usingnamespacestd; namespace primero{ int x=5; int y=10; 5 } namespace segundo{ 2.7183 double x=3.1416; 10 double y=2.7183; } 3.1416 int main(){ using primero::x; using segundo::y; cout<<x<<endl;//xesprimero::x cout<<y<<endl;//yessegundo::y cout<<primero::y<<endl;//espacioexplcito cout<<segundo::x<<endl;//espacioexplcito return 0; }
Fundamentosdelaprogramacin:Programacinmodular Pgina 811

LuisHernndezYez

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 } slo tiene efecto namespace segundo{ 3.1416 double x=3.1416; en el bloque 2.7183 double y=2.7183; en que se encuentra } int main(){ usingnamespace primero; cout<<x<<endl;//xesprimero::x cout<<y<<endl;//yesprimero::y cout<<segundo::x<<endl;//espacioexplcito cout<<segundo::y<<endl;//espacioexplcito return 0; }
Fundamentosdelaprogramacin:Programacinmodular Pgina 812

LuisHernndezYez

#ifndef listaEN_h #definelistaEN_h #include"registrofin.h" namespace ord {//Listaordenada const int N=100; typedef tRegistro tArray[N]; typedef struct { tArray registros; int cont; }tLista; const stringBD="bd.txt"; voidmostrar(const tLista&lista); voidinsertar(tLista&lista,tRegistro registro,bool &ok); voideliminar(tLista&lista,intpos,bool &ok);//1..N intbuscar(tLista lista,stringnombre); voidcargar(tLista&lista,bool &ok); voidguardar(tLista lista); }//namespace #endif
Fundamentosdelaprogramacin:Programacinmodular Pgina 813

LuisHernndezYez

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; } else { ord::mostrar(lista); ...

LuisHernndezYez

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; } else { mostrar(lista); ...
Fundamentosdelaprogramacin:Programacinmodular Pgina 816

LuisHernndezYez

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]; ... void mostrar(const tLista&lista); void insertar(tLista&lista,tRegistro registro,bool &ok); ... }//namespace
Fundamentosdelaprogramacin:Programacinmodular Pgina 817

LuisHernndezYez

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 #endif cargar() y guardar() se distinguen porque usan su propia BD, pero se implementan exactamente igual
Pgina 819

LuisHernndezYez

Fundamentosdelaprogramacin:Programacinmodular

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 } else { int i=0; while ((i<lista.cont)&&(lista.registros[i]<registro)){ i++; }...
Fundamentosdelaprogramacin:Programacinmodular Pgina 820

LuisHernndezYez

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; } else { ini=mitad+1; } }...
Fundamentosdelaprogramacin:Programacinmodular Pgina 821

LuisHernndezYez

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; } else { pos++; } }...
Fundamentosdelaprogramacin:Programacinmodular Pgina 823

LuisHernndezYez

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... Se han de probar todas las opciones/situaciones del programa En las clases prcticas veremos cmo se depura el software
Fundamentosdelaprogramacin:Programacinmodular Pgina 829

LuisHernndezYez

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> #include<string> usingnamespacestd; const int NCLI=100; const int NPROD=200; const int NVENTAS=3000; typedef struct { intid_cli; string nif; string nombre; string telefono; }tCliente; typedef struct { tCliente clientes[NCLI]; int cont; }tListaClientes;
LuisHernndezYez

string nombre; double precio; int unidades; }tProducto; typedef struct { tProducto productos[NPROD]; int cont; }tListaProductos; typedef struct { int id; int id_prod; int id_cli; int unidades; }tVenta; typedef struct { tVenta ventas[NVENTAS]; int cont; }tListaVentas; ...

typedef struct{ int id_prod; string codigo;

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 833

LuisHernndezYez

tCliente nuevoCliente(); bool valida(tCliente cliente);//Funcininterna bool operator<(tCliente opIzq,tCliente opDer);//PorNIF voidmostrar(tCliente cliente); voidinicializar(tListaClientes &lista); voidcargar(tListaClientes &lista); voidinsertar(tListaClientes &lista,tCliente cliente,bool &ok); voidbuscar(const tListaClientes &lista,stringnif,tCliente &cliente,bool &ok); voideliminar(tListaClientes &lista,stringnif,bool &ok); voidmostrar(const tListaClientes &lista); tProducto nuevoProducto(); boolvalida(tProducto producto);//Funcininterna booloperator<(tProducto opIzq,tProducto opDer);//Porcdigo voidmostrar(tProducto producto); voidinicializar(tListaProductos &lista); voidcargar(tListaProductos &lista); voidinsertar(tListaProductos &lista,tProducto producto,bool &ok); voidbuscar(const tListaProductos &lista,stringcodigo,tProducto &producto, bool &ok); voideliminar(tListaProductos &lista,stringcodigo,bool &ok); ...
Fundamentosdelaprogramacin:Ejemplodemodularizacin Pgina 834

LuisHernndezYez

void mostrar(const tListaProductos &lista); tVenta nuevaVenta(int id_prod,int id_cli,intunidades); bool valida(tVenta venta);//Funcininterna voidmostrar(tVenta venta,consttListaClientes &clientes, const tListaProductos &productos); voidinicializar(tListaVentas &lista); voidcargar(tListaVentas &lista); void insertar(tListaVentas &lista,tVenta venta,bool &ok); voidbuscar(const tListaVentas &lista,intid,tVenta &venta,bool &ok); void eliminar(tListaVentas &lista,intid,bool &ok); voidventasPorClientes(const tListaVentas &lista); voidventasPorProductos(const tListaVentas &lista); doubletotalVentas(const tListaVentas &ventas,stringnif, consttListaClientes &clientes, consttListaProductos &productos); voidstock(const tListaVentas &ventas,consttListaClientes &clientes, consttListaProductos &productos); intmenu(); intmain(){ ...

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 835

#include<iostream> #include<string> usingnamespacestd; const int NCLI=100; const int NPROD=200; const int NVENTAS=3000; typedef struct { intid_cli; string nif; string nombre; string telefono; }tCliente;

string nombre; double precio; int unidades; }tProducto;

Lista de productos

Cliente

typedef struct { tProducto productos[NPROD]; int cont; }tListaProductos; typedef struct { int id; int id_prod; int id_cli; int unidades; }tVenta;

Venta

Lista de clientes

LuisHernndezYez

typedef struct { tCliente clientes[NCLI]; int cont; }tListaClientes; typedef struct{ int id_prod; string codigo;

Lista de ventas

Producto

typedef struct { tVenta ventas[NVENTAS]; int cont; }tListaVentas; ...

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 836

tCliente nuevoCliente(); bool valida(tCliente cliente);//Funcininterna bool operator<(tCliente opIzq,tCliente opDer);//PorNIF voidmostrar(tCliente cliente); voidinicializar(tListaClientes &lista); voidcargar(tListaClientes &lista);

Cliente

Lista de clientes

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
LuisHernndezYez

Producto

voidmostrar(tProducto producto); ...

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 837

Lista de productos
voidinicializar(tListaProductos &lista); voidcargar(tListaProductos &lista); voidinsertar(tListaProductos &lista,tProducto producto,bool &ok); voidbuscar(const tListaProductos &lista,stringcodigo,tProducto &producto, bool &ok); voideliminar(tListaProductos &lista,stringcodigo,bool &ok); void mostrar(const tListaProductos &lista); tVenta nuevaVenta(int id_prod,int id_cli,intunidades); bool valida(tVenta venta);//Funcininterna voidmostrar(tVenta venta,consttListaClientes &clientes, const tListaProductos &productos); ...
LuisHernndezYez

Venta

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

intmenu(); intmain(){ ...

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 839

LuisHernndezYez

Cliente: cliente.h y cliente.cpp Lista de clientes: listaclientes.h y listaclientes.cpp Producto: producto.h y producto.cpp Lista de productos: listaproductos.h y listaproductos.cpp Venta: venta.h y venta.cpp Lista de ventas: listaventas.h y listaventas.cpp Programa principal: main.cpp Distribucin del cdigo en los mdulos: Declaraciones de tipos y datos en el archivo de cabecera (.h) Prototipos en el archivo de cabecera (.h) (excepto los de los subprogramas privados internos, que irn en el .cpp) Implementacin de los subprogramas en el .cpp

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 840

Ventas
main.cpp

Cliente
cliente.h cliente.cpp

Lista de clientes
listaclientes.h listaclientes.cpp

Venta
venta.h venta.cpp

Lista de ventas
listaventas.h listaventas.cpp

Producto
LuisHernndezYez

Lista de productos
listaproductos.h listaproductos.cpp

producto.h producto.cpp

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 841

Inclusiones (adems de otras bibliotecas del sistema)


typedef struct { intid_cli; string nif; string nombre; string telefono; }tCliente;

cliente.h

string

const int NCLI=100; typedef struct { tCliente clientes[NCLI]; int cont; }tListaClientes;
LuisHernndezYez

listaclientes.h

cliente.h string

voidbuscar(const tListaClientes &lista,stringnif,tCliente &cliente,bool &ok);

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 842

typedef struct{ int id_prod; string codigo; string nombre; double precio; int unidades; }tProducto;

producto.h

string

const int NPROD=200; typedef struct { tProducto productos[NPROD]; int cont; }tListaProductos; listaproductos.h producto.h string

LuisHernndezYez

voidbuscar(const tListaProductos &lista,stringcodigo,tProducto &producto,bool &ok);

Fundamentosdelaprogramacin:Ejemplodemodularizacin

Pgina 843

typedef struct { int id; int id_prod; int id_cli; int unidades; }tVenta;

venta.h

listaclientes.h listaproductos.h

voidmostrar(tVenta venta,consttListaClientes &clientes, const tListaProductos &productos); const int NVENTAS =3000; listaventas.h typedef struct { tVenta ventas[NVENTAS]; int cont; }tListaVentas; venta.h listaclientes.h 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 void mostrar(tCliente cliente); #endif

LuisHernndezYez

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

LuisHernndezYez

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

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

Fundamentosdelaprogramacin:Punterosymemoriadinmica

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 849

Los datos en la memoria


Todo dato se almacena en memoria: Varios bytes a partir de una direccin
i
0F03:1A37 0F03:1A38 0F03:1A39

... 00000000 00000000 00000000 00000101 ...

int i=5;
Direccin base

0F03:1A3A 0F03:1A3B 0F03:1A3C

LuisHernndezYez

El dato (i) se accede a partir de su direccin base (0F03:1A38) Direccin de la primera celda de memoria utilizada por el dato El tipo del dato (int) indica cuntos bytes (4) requiere el dato: 00000000000000000000000000000101 5
(La codificacin de los datos puede ser diferente; y la de las direcciones tambin)
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 850

Los punteros contienen direcciones de memoria


Un puntero sirve para acceder a travs de l a otro dato El valor del puntero es la direccin de memoria base de otro dato
... i
0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B

00 00 00 05 ...

Indireccin: Acceso indirecto a un dato


punt i punt apunta a i 5

punt
LuisHernndezYez

0F07:0417 0F07:0418 0F07:0419 0F07:041A

0F 03 1A 38 ...

De qu tipo es el dato apuntado? Cuntas celdas ocupa? Cmo se interpretan los 0/1?
Pgina 851

Fundamentosdelaprogramacin:Punterosymemoriadinmica

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 Para manejar datos dinmicos (Datos que se crean y destruyen durante la ejecucin) Para implementar los arrays
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 853

LuisHernndezYez

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


int i; int*punt; punt=&i;//puntcontieneladireccindei
LuisHernndezYez

punt i

Ahora punt ya contiene una direccin de memoria vlida punt apunta a (contiene la direccin de) la variable i (int)

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 855

&
Obtener la direccin de memoria de ...
...

int i,j; ... int*punt;

0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B

0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F ...

punt
LuisHernndezYez

0F07:0417 0F07:0418 0F07:0419 0F07:041A ...

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 856

&
Obtener la direccin de memoria de ...
...

int i,j; ... int*punt; ... i=5;

0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B

00 00 00 05

0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F ...

punt
LuisHernndezYez

0F07:0417 0F07:0418

0F07:0419 0F07:041A ...

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 857

&
Obtener la direccin de memoria de ...
...

int i,j; ... int*punt; ... i=5; punt=&i;

0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B

00 00 00 05

0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F ...

punt
LuisHernndezYez

punt i

0F07:0417 0F07:0418

0F 03 1A 38

0F07:0419 0F07:041A ...

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
LuisHernndezYez

Acceso indirecto al valor de i

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 859

*
Obtener lo que hay en la direccin ...
...

int i,j; ... int *punt; ... i=5; punt=&i; j=*punt;

0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B

00 00 00 05

0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F ...

punt
LuisHernndezYez

0F07:0417 0F07:0418

0F 03 1A 38

punt:

0F07:0419 0F07:041A ...

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 860

*
Obtener lo que hay en la direccin ...
...

int i,j; ... int *punt; ... i=5; punt=&i; j=*punt;


Direccionamiento indirecto (indireccin) Seaccedealdatoi deformaindirecta

0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B

00 00 00 05

0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F ...

punt
LuisHernndezYez

0F07:0417 0F07:0418

0F 03 1A 38

*punt:

0F07:0419 0F07:041A ...

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 861

*
Obtener lo que hay en la direccin ...
...

int i,j; ... int *punt; ... i=5; punt=&i; j=*punt;

0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B

00 00 00 05 00 00 00 05

0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F ...

punt
LuisHernndezYez

0F07:0417 0F07:0418 0F07:0419 0F07:041A ...

0F 03 1A 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; cout<<k<<endl;//Mismo valorque j return 0; }
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 863

LuisHernndezYez

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 q=p;//ahoraqyatieneunadireccinvlida q=NULL;//otradireccinvlidaparaq
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 865

LuisHernndezYez

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

Direccin de la zona de cdigo del sistema operativo? Podemos modificar el cdigo del propio S.O.! Consecuencias imprevisibles (cuelgue) (Los S.O. modernos protegen bien la memoria)
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 866

Punteros que no apuntan a nada


Inicializando los punteros a NULL podemos detectar errores:
int *punt =NULL; ... *punt=13;
punt

punt ha sido inicializado a NULL: No apunta a nada! Si no apunta a nada, qu significa *punt??? No tiene sentido ERROR: Acceso a un dato a travs de un puntero nulo!
LuisHernndezYez

Error de ejecucin, lo que ciertamente no es bueno Pero sabemos cul ha sido el problema, lo que es mucho Sabemos dnde y qu buscar para depurar

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 867

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

punt2

LuisHernndezYez

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

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

LuisHernndezYez

Al dato x ahora se puede acceder de tres formas: x*punt1*punt2

8 5

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;

LuisHernndezYez

Operador flecha (>): Acceso a los campos a travs de un puntero sin usar el operador *
puntero>codigo puntero>nombrepuntero>sueldo puntero>... (*puntero)....

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 875

structPtr.cpp

Acceso a estructuras a travs de punteros


typedefstruct { int codigo; string nombre; double sueldo; }tRegistro; tRegistro registro; typedeftRegistro *tRegistroPtr; tRegistroPtr puntero=&registro; registro.codigo =12345; registro.nombre ="Javier"; registro.sueldo =95000; cout<<puntero>codigo <<""<<puntero>nombre <<""<<puntero>sueldo<<endl; puntero>codigo

LuisHernndezYez

(*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! punt_a_cte =&entero2;//OK:Elpunteronoescte.

LuisHernndezYez

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. punt_cte =&entero2;//ERROR: Punteroconstante!

LuisHernndezYez

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)++; } ... int entero=5; incrementa(&entero); cout<<entero<<endl; Mostrar 6 en la consola
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 880

Paso por valor: El argumento (el puntero) no cambia Aquello a lo que apunta (el entero) S puede cambiar

LuisHernndezYez

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

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

Cmo se llamara?
int entero;double real;char caracter; //... foo(&entero,&real,&caracter);
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 882

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 883

Una ntima relacin


Variable array Puntero al primer elemento del array As, si tenemos:
int dias[12]= {31,28,31,30,31,30,31,31,30,31,30,31};

Entonces:
cout<<*dias <<endl;

Muestra 31 en la consola, el primer elemento del array Un nombre de array es un puntero constante!
LuisHernndezYez

Siempre apunta al primer elemento (no se puede modificar) Acceso a los elementos del array: Por ndice o con aritmtica de punteros (Anexo)
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 884

Paso de arrays a subprogramas


Esto explica por qu no usamos & con los parmetros array! El nombre del array es un puntero: ya es un paso por referencia Prototipos equivalentes para parmetros array:
constint N=...; void cuadrado(int arr[N]); void cuadrado(int arr[],int size);//Arraynodelimitado void cuadrado(int *arr,int size);//Puntero

LuisHernndezYez

Arrays no delimitados y punteros: se necesita la dimensin Elementos: se acceden con ndice (arr[i]) o con puntero (*arr) Una funcin slo puede devolver un array en forma de puntero:
intPtr inicializar();

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 885

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 programa S.O. Memoria principal

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 887

Memoria principal
Datos globales del programa: Declarados fuera de los subprogramas
typedef struct { ... }tRegistro; const intN=1000; typedef tRegistro tArray[N]; typedef struct { tArray registros; int cont; }tLista; intmain(){ ...

Pila Montn Datos globales Cdigodelprograma S.O.

Datos locales

Datos dinmicos

Memoria principal

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 888

La pila (stack)
Datos locales de subprogramas: Parmetros por valor y variables locales
voidfunc(tLista lista,double &total) { tLista aux; int i; ...

Pila Montn Datos globales Cdigodelprograma S.O.

Datos locales

Datos dinmicos

Memoria principal

LuisHernndezYez

Y los punteros temporales que apuntan a los argumentos de los parmetros por referencia

&resultado

func(lista,resultado)

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 889

El montn (heap)
Datos dinmicos Datos que se crean y se destruyen durante la ejecucin del programa, a medida que se necesita

Pila Montn Datos globales Cdigodelprograma S.O.

Datos locales

Datos dinmicos

Memoria principal

LuisHernndezYez

Sistema de gestin de memoria dinmica (SGMD) Cuando se necesita memoria para una variable se solicita El SGMD reserva espacio y devuelve la direccin base Cuando ya no se necesita ms la variable, se destruye Se libera la memoria y el SGMD cuenta de nuevo con ella

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 890

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 891

Datos dinmicos
Se crean y se destruyen durante la ejecucin del programa Se les asigna memoria del montn
Creacin Datodinmico Destruccin Montn

LuisHernndezYez

Por qu utilizar memoria dinmica? Almacn de memoria muy grande: datos o listas de datos que no caben en memoria principal pueden caber en el montn El programa ajusta el uso de la memoria a las necesidades de cada momento: ni le falta ni la desperdicia
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 892

Cundo se asigna memoria a los datos?


Datos globales En memoria principal al comenzar la ejecucin del programa Existen durante toda la ejecucin del programa Datos locales de un subprograma En la pila al ejecutarse el subprograma Existen slo durante la ejecucin de su subprograma Datos dinmicos En el montn cuando el programa lo solicita Existen a voluntad del programa

LuisHernndezYez

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 Los datos estticos tambin se pueden acceder a travs de punteros int *p=&i;
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 894

LuisHernndezYez

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 895

El operador new
new tipo

Devuelve NULL si no queda memoria suficiente

Reserva memoria del montn para una variable del tipo y devuelve la primera direccin de memoria utilizada, que debe ser asignada a un puntero

int *p;//Todavasinunadireccinvlida p=new int;//Yatieneunadireccinvlida *p=12;

La variable dinmica se accede exclusivamente por punteros No tiene identificador asociado


LuisHernndezYez

int i;//iesunavariableesttica int *p1,*p2; p1=&i;//Punteroquedaaccesoalavariable //estticai(accesibleconiocon*p1) p2=new int;//Punteroquedaaccesoaunavariable //dinmica(accesiblesloatravsdep2)


Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 896

registros.cpp

Inicializacin con el operador new


El operador new admite un valor inicial para el dato creado:
int *p; p=new int(12);

Se crea la variable, de tipo int, y se inicializa con el valor 12


#include<iostream> usingnamespacestd; #include"registro.h" int main(){ tRegistroreg; reg =nuevo(); tRegistro *punt =new tRegistro(reg); mostrar(*punt); ...
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 897

LuisHernndezYez

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 double *p1,*p2,*p3; p1=&a; p2=new double; a *p2=*p1; p3=new double; *p3=123.45; cout<<*p1<<endl; p2 cout<<*p2<<endl; cout<<*p3<<endl; delete p2; delete p3; p3 return 0; }
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 899

Identificadores:

4
1.5 (a, p1, p2, p3) Variables:

1.5

6
123.45
Montn (heap)

LuisHernndezYez

(+ *p2 y *p3)

#include<iostream> usingnamespacestd;
a

PILA 1.5 ? ? ? p1 p2 p3

int main(){ double a=1.5; double *p1,*p2,*p3;

LuisHernndezYez

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 900

#include<iostream> usingnamespacestd;
a

PILA 1.5 ? ? p1 p2 p3

int main(){ double a=1.5; double *p1,*p2,*p3; p1=&a;

LuisHernndezYez

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 901

#include<iostream> usingnamespacestd;
a

PILA 1.5 p1 p2 p3 ?

int main(){ double a=1.5; double *p1,*p2,*p3; p1=&a; p2=new double;

LuisHernndezYez

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 902

#include<iostream> usingnamespacestd;
a

PILA 1.5 p1 p2 p3 ?

int main(){ double a=1.5; double *p1,*p2,*p3; p1=&a; p2=new double; *p2=*p1;

LuisHernndezYez

1.5 MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 903

#include<iostream> usingnamespacestd;
a

PILA 1.5 p1 p2 p3

int main(){ double a=1.5; double *p1,*p2,*p3; p1=&a; p2=new double; *p2=*p1; p3=new double;

LuisHernndezYez

1.5 MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 904

#include<iostream> usingnamespacestd;
a

PILA 1.5 p1 p2 p3

int main(){ double a=1.5; double *p1,*p2,*p3; p1=&a; p2=new double; *p2=*p1; p3=new double; *p3=123.45;

LuisHernndezYez

123.45 1.5 MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 905

#include<iostream> usingnamespacestd;
a

PILA 1.5 ? p1 p2 p3

LuisHernndezYez

int main(){ double a=1.5; double *p1,*p2,*p3; p1=&a; p2=new double; *p2=*p1; p3=new double; *p3=123.45; cout<<*p1<<endl; cout<<*p2<<endl; cout<<*p3<<endl; delete p2;

123.45 MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 906

#include<iostream> usingnamespacestd;
a

PILA 1.5 ? ? p1 p2 p3

LuisHernndezYez

int main(){ double a=1.5; double *p1,*p2,*p3; p1=&a; p2=new double; *p2=*p1; p3=new double; *p3=123.45; cout<<*p1<<endl; cout<<*p2<<endl; cout<<*p3<<endl; delete p2; delete p3;

MONTN

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 907

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 908

La memoria se reparte entre la pila y el montn Crecen en direcciones opuestas Al llamar a subprogramas la pila crece Al crear datos dinmicos el montn crece Colisin pilamontn Los lmites de ambas regiones se encuentran Se agota la memoria Desbordamiento de la pila La pila suele tener un tamao mximo establecido Si se sobrepasa se agota la pila
Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pila

Montn

LuisHernndezYez

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
LuisHernndezYez

Y todo dato dinmico debe tener algn acceso (puntero) Es un grave error perder un dato en el montn

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 910

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 911

Olvido de destruccin de un dato dinmico


... intmain(){ tRegistro *p; p=new tRegistro; *p=nuevo(); mostrar(*p); Falta delete p; return 0; }

LuisHernndezYez

G++ no indicar ningn error y el programa parecer terminar correctamente, pero dejar memoria desperdiciada Visual C++ s comprueba el uso de la memoria dinmica y nos avisa si dejamos memoria sin liberar
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 912

Intento de destruccin de un dato inexistente


... intmain(){ tRegistro *p1=new tRegistro; *p1=nuevo(); mostrar(*p1); tRegistro *p2; p2=p1; mostrar(*p2); delete p1; delete p2;
LuisHernndezYez

p1 p2

tRegistro

return 0; }

Slo se ha creado una variable

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 913

Prdida de un dato dinmico


... intmain(){ tRegistro *p1,*p2; p1=new tRegistro(nuevo()); p2=new tRegistro(nuevo()); mostrar(*p1); p1=p2; mostrar(*p1); delete p1; delete p2; return 0; }

p2

tRegistro

p1

tRegistro Perdido!

LuisHernndezYez

Se pierde un dato en el montn Se intenta eliminar un dato ya eliminado


Pgina 914

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Intento de acceso a un dato tras su eliminacin


... intmain(){ tRegistro *p; p=new tRegistro(nuevo()); mostrar(*p); delete p; ... mostrar(*p); return 0;
LuisHernndezYez

p ha dejado de apuntar al dato dinmico destruido Acceso a memoria inexistente

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 915

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 916

Arrays de punteros a datos dinmicos


typedef struct { intcodigo; string nombre; double valor; }tRegistro; typedef tRegistro *tRegPtr; Los punteros ocupan muy poco en memoria Los datos a los que apunten estarn en el montn

LuisHernndezYez

const int N=1000; //Arraydepunterosaregistros: typedef tRegPtr tArray[N]; typedef struct { tArray registros; int cont; Se crean a medida que se insertan }tLista; Se destruyen a medida que se eliminan
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 917

tLista lista; lista.cont =0;

lista.cont lista.registros
LuisHernndezYez

0
0 1 2 3 4 5 6 998 999

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 918

tLista lista; lista.cont =0; lista.registros[lista.cont]=new tRegistro(nuevo()); lista.cont++;

lista.cont lista.registros
LuisHernndezYez

1
0 1 2 3 4 5 6 998 999

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

2
0 1 2 3 4 5 6 998 999

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

3
0 1 2 3 4 5 6 998 999

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 921

Los registros se acceden a travs de los punteros (operador >):


cout<<lista.registros[0]>nombre;

lista.cont lista.registros
LuisHernndezYez

3
0 1 2 3 4 5 6 998 999

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

3
0 1 2 3 4 5 6 998 999

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 923

lista.h #ifndef lista_h #definelista_h #include"registro.h" const int N=1000; const string BD="bd.dat"; typedef tRegPtr tArray[N]; typedef struct { tArray registros; int cont; }tLista;

registro.h con el tipo puntero: typedef tRegistro *tRegPtr;

LuisHernndezYez

void mostrar(const tLista&lista); voidinsertar(tLista&lista,tRegistro registro,bool &ok); voideliminar(tLista&lista,intcode,bool &ok); intbuscar(const tLista &lista,int code); void cargar(tLista&lista,bool &ok); void guardar(const tLista &lista); void destruir(tLista &lista); #endif
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 924

lista.cpp
void insertar(tLista&lista,tRegistro registro,bool &ok){ ok=true; if (lista.cont ==N){ ok=false; } else { lista.registros[lista.cont]=new tRegistro(registro); lista.cont++; } } void eliminar(tLista&lista,int code,bool &ok){ ok=true; int ind =buscar(lista,code); if (ind ==1){ ok=false; } else { delete lista.registros[ind]; for (int i=ind +1;i<lista.cont;i++){ lista.registros[i 1]=lista.registros[i]; } lista.cont; } }
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 925

LuisHernndezYez

int buscar(const tLista &lista,intcode){ //Devuelveelndiceo1sinosehaencontrado int ind =0; bool encontrado=false; while ((ind <lista.cont)&&!encontrado){ if (lista.registros[ind]>codigo ==code){ encontrado=true; } else { ind++; } if (!encontrado){ ind =1; } return ind; } void destruir(tLista &lista){ for (inti=0;i<lista.cont;i++){ delete lista.registros[i]; } lista.cont =0; } ...
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 926

LuisHernndezYez

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

return 0; }

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

return 0; }

No olvides destruir el array dinmico!

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 930

listaAD.h

... #include"registro.h" const int N=1000; //Lista:arraydinmico(puntero)ycontador typedef struct { tRegPtr registros; int cont; }tLista; ...
LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 931

listaAD.cpp
void insertar(tLista&lista,tRegistro registro, bool &ok){ ok=true; if (lista.cont ==N){ ok=false; No usamos new } else { Se han creado todo lista.registros[lista.cont]=registro; el array al cargar lista.cont++; } } void eliminar(tLista&lista,int code, bool &ok){ ok=true; int ind =buscar(lista,code); No usamos delete if (ind ==1){ Se destruye todo ok=false; } el array al final else { for (int i=ind +1;i<lista.cont;i++){ lista.registros[i 1]=lista.registros[i]; } lista.cont; } }...
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 932

LuisHernndezYez

int buscar(tLista lista,int code){ int ind =0; bool encontrado=false; while ((ind <lista.cont)&&!encontrado){ if (lista.registros[ind].codigo ==code){ encontrado=true; } else { ind++; } } if (!encontrado){ ind =1; } return ind; } void destruir(tLista &lista){ delete []lista.registros; lista.cont =0; } ...

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica

Pgina 933

LuisHernndezYez

void cargar(tLista&lista,bool &ok){ ifstream archivo; char aux; ok=true; archivo.open(BD.c_str()); if (!archivo.is_open()){ ok=false; } else { Se crean todos a la vez tRegistro registro; lista.cont =0; lista.registros =new tRegistro[N]; archivo>>registro.codigo; while((registro.codigo !=1)&&(lista.cont <N)){ archivo>>registro.valor; archivo.get(aux);//Saltamoselespacio getline(archivo,registro.nombre); lista.registros[lista.cont]=registro; lista.cont++; archivo>>registro.codigo; } archivo.close(); } }
Fundamentosdelaprogramacin:Punterosymemoriadinmica Pgina 934

ejemploAD.cpp

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 de punteros
0 1 2 3 4 5 6 7

Array dinmico: Puntero a array

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 Recorridodearraysconpunteros Referencias Listasenlazadas

940 953 962 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


LuisHernndezYez

cout<<*punt<<endl;//Muestra 28(segundo elemento)

A la direccin de memoria actual se le suman tantas unidades como bytes (4) ocupe en memoria un dato de ese tipo (int)
Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 941

int dias[12]={31,28,31,30,31,30, 31,31,30,31,30,31}; typedef int*tIntPtr; tIntPtr punt=dias;


dias[1] dias[0]

... 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F

31 28 31
0F 03 1A 38 0F 03 1A 38

dias[2]

0F03:1A40 0F03:1A41 0F03:1A42 0F03:1A43 ...

dias

0F07:0417 0F07:0418 0F07:0419 0F07:041A

LuisHernndezYez

punt

0F07:041B 0F07:041C 0F07:041D 0F07:041E ...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 942

int dias[12]={31,28,31,30,31,30, 31,31,30,31,30,31}; typedef int*tIntPtr; tIntPtr punt=dias; punt++;


dias[1] dias[0]

... 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F

31 28 31
0F 03 1A 38 0F 03 1A 3C

dias[2]

0F03:1A40 0F03:1A41 0F03:1A42 0F03:1A43 ...

dias

0F07:0417 0F07:0418 0F07:0419 0F07:041A

LuisHernndezYez

punt

0F07:041B 0F07:041C 0F07:041D 0F07:041E ...

punt hace que apunte al elemento anterior


Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 943

int dias[12]={31,28,31,30,31,30, 31,31,30,31,30,31}; typedef int*tIntPtr; tIntPtr punt=dias; punt =punt+2;


dias[1] dias[0]

... 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F

31 28 31
0F 03 1A 38 0F 03 1A 40

dias[2]

0F03:1A40 0F03:1A41 0F03:1A42 0F03:1A43 ...

dias

0F07:0417 0F07:0418 0F07:0419 0F07:041A

LuisHernndezYez

punt

0F07:041B 0F07:041C 0F07:041D 0F07:041E ...

Restando pasamos a elementos anteriores


Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 944

int dias[12]={31,28,31,30,31,30, 31,31,30,31,30,31}; typedef int*tIntPtr; tIntPtr punt=dias; punt=punt+2; int num=punt dias;
dias[1] dias[0]

... 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F

31 28 31
0F 03 1A 38 0F 03 1A 3C

dias[2]

0F03:1A40 0F03:1A41 0F03:1A42 0F03:1A43 ...

N de elementos entre los punteros


dias

0F07:0417 0F07:0418 0F07:0419 0F07:041A

LuisHernndezYez

punt

0F07:041B 0F07:041C 0F07:041D 0F07:041E ...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 945

Otro tipo base


shortint (2 bytes)
shortint dias[12]={31,28,31,30, 31,30,31,31,30,31,30,31}; typedef shortint*tSIPtr; tSIPtr punt=dias;
dias[4] dias[0] dias[1] dias[2] dias[3]

... 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F 0F03:1A40 0F03:1A41 ... dias 0F07:0417 0F07:0418 0F07:0419 0F07:041A punt 0F07:041B 0F07:041C 0F07:041D 0F07:041E ... 0F 03 1A 38 0F 03 1A 38

31 28 31 30 31

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 946

shortint dias[12]={31,28,31,30, 31,30,31,31,30,31,30,31}; typedef shortint*tSIPtr; tSIPtr punt=dias; punt++;


dias[1] dias[2] dias[3] dias[4] ... dias[0] 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F 0F03:1A40 0F03:1A41 ... dias 0F07:0417 0F07:0418 0F07:0419 0F07:041A punt 0F07:041B 0F07:041C 0F07:041D 0F07:041E ... 0F 03 1A 38 0F 03 1A 3A

31 28 31 30 31

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 947

shortint dias[12]={31,28,31,30, 31,30,31,31,30,31,30,31}; typedef shortint*tSIPtr; tSIPtr punt=dias; punt++; punt=punt+3;


dias[1] dias[2] dias[3] dias[4] ... dias[0] 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F 0F03:1A40 0F03:1A41 ... dias 0F07:0417 0F07:0418 0F07:0419 0F07:041A punt 0F07:041B 0F07:041C 0F07:041D 0F07:041E ... 0F 03 1A 38 0F 03 1A 40

31 28 31 30 31

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 948

shortint dias[12]={31,28,31,30, 31,30,31,31,30,31,30,31}; typedef shortint*tSIPtr; tSIPtr punt=dias; punt++; punt=punt+3; punt;
dias[1] dias[2] dias[3] dias[4] ... dias[0] 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F 0F03:1A40 0F03:1A41 ... dias 0F07:0417 0F07:0418 0F07:0419 0F07:041A punt 0F07:041B 0F07:041C 0F07:041D 0F07:041E ... 0F 03 1A 38 0F 03 1A 3E

31 28 31 30 31

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 949

shortint dias[12]={31,28,31,30, 31,30,31,31,30,31,30,31}; typedef shortint*tSIPtr; tSIPtr punt=dias; punt++; punt=punt+3; punt; tSIPtr punt2;
dias dias[1] dias[2] dias[3] dias[4] ... dias[0] 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F 0F03:1A40 0F03:1A41 ... 0F07:0417 0F07:0418 0F07:0419 0F07:041A punt 0F07:041B 0F07:041C 0F07:041D 0F07:041E punt2 0F07:041F 0F 03 1A 38 0F 03 1A 3E ?

31 28 31 30 31

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 950

shortint dias[12]={31,28,31,30, 31,30,31,31,30,31,30,31}; typedef shortint*tSIPtr; siPtr punt=dias; punt++; punt=punt+3; punt; tSIPtr punt2; punt2=dias;
dias dias[1] dias[2] dias[3] dias[4] ... dias[0] 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B 0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F 0F03:1A40 0F03:1A41 ... 0F07:0417 0F07:0418 0F07:0419 0F07:041A punt 0F07:041B 0F07:041C 0F07:041D 0F07:041E punt2 0F07:041F 0F 03 1A 38 0F 03 1A 3E 0F

31 28 31 30 31

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 951

shortint dias[12]={31,28,31,30, 31,30,31,31,30,31,30,31}; typedef shortint*tSIPtr; siPtr punt=dias; punt++; punt=punt+3; punt; tSIPtr punt2; punt2=dias; cout<<punt punt2;//3
punt dias dias[1] ... dias[0] 0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B dias[2] dias[3] dias[4] 0F03:1A3C 0F03:1A3D 0F03:1A3E 0F03:1A3F 0F03:1A40 0F03:1A41 ... 0F07:0417 0F07:0418 0F07:0419 0F07:041A 0F07:041B 0F07:041C 0F07:041D 0F07:041E punt2 0F07:041F 0F 03 1A 38 0F 03 1A 3E 0F

31 28 31 30 31

LuisHernndezYez

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

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 954

... intPtr punt=lista.elementos;

punt

...

98

99

lista.elementos lista.cont
LuisHernndezYez

4 8

13

47

53

19

48

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 955

... for(int i=0;i<lista.cont;i++){ cout<<*punt <<endl; punt++; }


i
0

punt

...

98

99

lista.elementos lista.cont
LuisHernndezYez

4 8

13

47

53

19

48

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 956

... for(int i=0;i<lista.cont;i++){ cout<<*punt <<endl; punt++; }


i
1

punt

...

98

99

lista.elementos lista.cont
LuisHernndezYez

4 8

13

47

53

19

48

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 957

... for(int i=0;i<lista.cont;i++){ cout<<*punt <<endl; punt++; }


i
2

4 13

punt

...

98

99

lista.elementos lista.cont
LuisHernndezYez

4 8

13

47

53

19

48

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 958

... for(int i=0;i<lista.cont;i++){ cout<<*punt <<endl; punt++; }


i
3

4 13 3

punt

...

98

99

lista.elementos lista.cont
LuisHernndezYez

4 8

13

47

53

19

48

. . .
Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 959

... for(int i=0;i<lista.cont;i++){ cout<<*punt <<endl; punt++; }


i
7

4 13 3 47 53 19 7

punt

...

98

99

lista.elementos lista.cont
LuisHernndezYez

4 8

13

47

53

19

48

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 960

... for(int i=0;i<lista.cont;i++){ cout<<*punt <<endl; punt++; }


i
8

punt

4 13 3 47 53 19 7 48

...

98

99

lista.elementos lista.cont
LuisHernndezYez

4 8

13

47

53

19

48

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 961

LuisHernndezYez

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 962

Nombres alternativos para los datos


Una referencia es una nueva forma de llamar a una variable Nos permiten referirnos a una variable con otro identificador:
int x=10; int&z=x; x y z son ahora la misma variable (comparten memoria)

Cualquier cambio en x afecta a z y cualquier cambio en z afecta a x


z=30; cout<<x;

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; reg structtNodo { tRegistro reg; tRegistro tLista sig; };
sig

tLista

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

Lista

Vaca Elemento seguido de una lista

Definicin recursiva!

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 965

Cada elemento de la lista en su nodo Apuntar al siguiente elemento o a ninguno (NULL)


structtNodo;//Declaracinanticipada typedef tNodo *tLista; structtNodo { tRegistro reg; tLista sig; };

Adems, un puntero al primer elemento (nodo) de la lista


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

LuisHernndezYez

tLista lista=NULL;//Listavaca lista=new tNodo; lista>reg =nuevo(); lista>sig=NULL; tLista p; p=lista; p>sig=new tNodo; p>sig>reg =nuevo(); p>sig>sig =NULL; p=p>sig; p>sig=new tNodo; p>sig>reg =nuevo(); p>sig>sig =NULL; p ...
lista
tRegistro tRegistro 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); void destruir(tLista &lista);//Liberarlamemoriadinmica

LuisHernndezYez

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){ nuevo p=p>sig; } p p>sig=nuevo; } lista } }...
Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 973

LuisHernndezYez

LuisHernndezYez

void eliminar(tLista&lista,int code,bool &ok){ ok=true; tLista p=lista; if (p==NULL){ ok=false;//Listavaca } else if (p>reg.codigo ==code){//Elprimero lista=p>sig; delete p; p } else { lista tLista ant=p; p=p>sig; bool encontrado=false; while ((p!=NULL)&&!encontrado){ if (p>reg.codigo ==code){ ant encontrado=true; } else { lista ant=p; p=p>sig; } }...
Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 974

if (!encontrado){ ok=false;//Noexisteesecdigo } else { ant>sig=p>sig; delete p; } } } ...


ant 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; while (p!=NULL){ mostrar(p>reg); p=p>sig; } }...
Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 976

LuisHernndezYez

LuisHernndezYez

void cargar(tLista&lista,bool &ok){ ifstream archivo; char aux; ok=true; lista=NULL; archivo.open(BD.c_str()); if (!archivo.is_open()){ ok=false; } else { tRegistro registro; tListault =NULL; archivo>>registro.codigo; while (registro.codigo !=1){ archivo>>registro.valor; archivo.get(aux);//Saltamoselespacio getline(archivo,registro.nombre); ...

Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo)

Pgina 977

if (lista==NULL){ lista=new tNodo; ult =lista; } else { ult>sig=new tNodo; ult =ult>sig; } ult>reg =registro; ult>sig=NULL; archivo>>registro.codigo; } archivo.close(); } 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; lista=lista>sig; delete p; } }
Fundamentosdelaprogramacin:Punterosymemoriadinmica(Anexo) Pgina 979

LuisHernndezYez

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

LuisHernndezYez

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

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

LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 983

Recursin (recursividad, recurrencia)


Definicin recursiva: En la definicin aparece lo que se define
Factorial(N) = N x Factorial(N1) (N >= 0)
Cada tringulo est formado por otros tringulos ms pequeos

La cmara graba lo que graba


(http://farm1.static.flickr.com/83 /229219543_edf740535b.jpg)

LuisHernndezYez

La imagen del paquete aparece dentro del propio paquete,... hasta el infinito!
(wikipedia.org) Fundamentosdelaprogramacin:Introduccinalarecursin

(wikipedia.org)

Las matrioskas rusas


Pgina 984

Factorial(N) = N x Factorial(N1) El factorial se define en funcin de s mismo Los programas no pueden manejar la recursin infinita La definicin recursiva debe adjuntar uno o ms casos base Caso base: aquel en el que no se utiliza la definicin recursiva Proporcionan puntos finales de clculo:
Factorial(N) N x Factorial(N1) si N > 0 1
LuisHernndezYez

Caso recursivo (induccin) Caso base (o de parada)

si N = 0

El valor de N se va aproximando al valor del caso base (0)

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 985

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
Factorial(N) 1 N x Factorial(N1) si N = 0 si N > 0

LuisHernndezYez

longlong int factorial(int n){ longlong intresultado; if (n==0){//Caso base resultado =1; } else { resultado =n*factorial(n 1); } return resultado; }
Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 987

factorial.cpp

Funciones recursivas
longlong int factorial(int n){ longlong intresultado; if (n==0){//Caso base resultado =1; } else { resultado =n*factorial(n 1); } return resultado; }

factorial(5) 5 x factorial(4) 5 x 4 x factorial(3)


LuisHernndezYez

5 x 4 x 3 x factorial(2) 5 x 4 x 3 x 2 x factorial(1) 5 x 4 x 3 x 2 x 1 x factorial(0) 5 x 4 x 3 x 2 x 1 x 1 120


Caso base

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 988

Diseo de funciones recursivas


Una funcin recursiva debe satisfacer tres condiciones: Caso(s) base: Debe haber al menos un caso base de parada Induccin: Paso recursivo que provoca una llamada recursiva Debe ser correcto para distintos parmetros de entrada Convergencia: Cada paso recursivo debe acercar a un caso base Se describe el problema en trminos de problemas ms sencillos
Factorial(N)
LuisHernndezYez

1 N x Factorial(N1)

si N = 0 si N > 0

Funcin factorial(): tiene caso base (N = 0), siendo correcta para N es correcta para N+1 (induccin) y se acerca cada vez ms al caso base (N1 est ms cerca de 0 que N)
Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 989

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

LuisHernndezYez

Cada llamada recursiva fuerza una nueva ejecucin de la funcin Cada llamada utiliza sus propios parmetros por valor y variables locales (n y resultado en este caso) En las llamadas a la funcin se utiliza la pila del sistema para mantener los datos locales y la direccin de vuelta

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 991

Regiones de memoria que distingue el sistema operativo:


Pila(Stack)
Llamadas a subprogramas

Montn(Heap)

Memoria dinmica (Tema 9)

Datos delprograma Cdigodelprograma


LuisHernndezYez

Memoria principal

S.O.

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 992

Mantiene los datos locales de la funcin y la direccin de vuelta Estructura de tipo pila: lista LIFO (lastin firstout) El ltimo que entra es el primero que sale:

Entra 4

Entra 7

Entra 2

Sale 2

2
LuisHernndezYez

7 4 4

7 4

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

int main(){ ... cout<<funcA(4); <DIR1> ...

Llamada a funcin: Entra la direccin de vuelta

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 994

Datos locales y direcciones de vuelta


... int funcB(int x){ ... return x; } int funcA(int a){ intb; ... <DIR2> b=funcB(a); ... return b; }
LuisHernndezYez

Entrada en la funcin: Se alojan los datos locales

int main(){ ... cout<<funcA(4); <DIR1> ...

<DIR1> Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 995

Datos locales y direcciones de vuelta


... int funcB(int x){ ... return x; } int funcA(int a){ intb; ... <DIR2> b=funcB(a); ... return b; }
LuisHernndezYez

Llamada a funcin: Entra la direccin de vuelta b a <DIR1> Pila

int main(){ ... cout<<funcA(4); <DIR1> ...

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 996

Datos locales y direcciones de vuelta


... int funcB(int x){ ... return x; } int funcA(int a){ intb; ... <DIR2> b=funcB(a); ... return b; }
LuisHernndezYez

Entrada en la funcin: Se alojan los datos locales

<DIR2> b a <DIR1> Pila

int main(){ ... cout<<funcA(4); <DIR1> ...

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 997

Datos locales y direcciones de vuelta


... int funcB(int x){ ... return x; } int funcA(int a){ intb; ... <DIR2> b=funcB(a); ... return b; }
LuisHernndezYez

Vuelta de la funcin: Se eliminan los datos locales

x <DIR2> b a <DIR1> Pila

int main(){ ... cout<<funcA(4); <DIR1> ...

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 998

Datos locales y direcciones de vuelta


... int funcB(int x){ ... return x; } int funcA(int a){ intb; ... <DIR2> b=funcB(a); ... return b; }
LuisHernndezYez

Vuelta de la funcin: Sale la direccin de vuelta

<DIR2> b a <DIR1> Pila

int main(){ ... cout<<funcA(4); <DIR1> ...

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

La ejecucin contina en esa direccin b a <DIR1> Pila

int main(){ ... cout<<funcA(4); <DIR1> ...

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

Vuelta de la funcin: Se eliminan los datos locales

b a <DIR1> Pila

int main(){ ... cout<<funcA(4); <DIR1> ...

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

Vuelta de la funcin: Sale la direccin de vuelta <DIR1> Pila

int main(){ ... cout<<funcA(4); <DIR1> ...

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

int main(){ ... cout<<funcA(4); <DIR1> ...

La ejecucin contina en esa direccin

Pila

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 funcA(...){ ... ...funcB(...) } int main(){ ... cout<<funcA(...); ...

LLAMADAS

int funcB(...){ ... ...funcC(...) }

V U E LTAS

funcC funcB funcA Pila

LuisHernndezYez

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)

LuisHernndezYez

resultado=? n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1006

factorial(5) factorial(4)

resultado =? n=4
LuisHernndezYez

resultado=? n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1007

factorial(5) factorial(4) factorial(3)

resultado=? n=3 resultado =? n=4


LuisHernndezYez

resultado=? n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1008

factorial(5) factorial(4) factorial(3) factorial(2)

resultado=? n=2 resultado=? n=3 resultado =? n=4


LuisHernndezYez

resultado=? n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1009

factorial(5) factorial(4) factorial(3) factorial(2) factorial(1)


resultado=? n=1 resultado=? n=2 resultado=? n=3 resultado =? n=4
LuisHernndezYez

resultado=? n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1010

factorial(5) factorial(4) factorial(3) factorial(2) factorial(1) factorial(0)


resultado=1 n=0 resultado=? n=1 resultado=? n=2 resultado=? n=3 resultado =? n=4
LuisHernndezYez

resultado=? n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1011

factorial(5) factorial(4) factorial(3) factorial(2) factorial(1) factorial(0) 1


resultado=1 n=1 resultado=? n=2 resultado=? n=3 resultado =? n=4
LuisHernndezYez

resultado=? n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1012

factorial(5) factorial(4) factorial(3) factorial(2) factorial(1) factorial(0) 1 1


resultado=2 n=2 resultado=? n=3 resultado =? n=4
LuisHernndezYez

resultado=? n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1013

factorial(5) factorial(4) factorial(3) factorial(2) factorial(1) factorial(0) 1 1 2


resultado=6 n=3 resultado =? n=4
LuisHernndezYez

resultado=? n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1014

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


LuisHernndezYez

resultado =24 n=4 resultado=? n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1015

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


LuisHernndezYez

24

resultado=120 n=5

Pila

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1016

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


LuisHernndezYez

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

Una sola llamada recursiva

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1019

Varias llamadas recursivas Ejemplo: Clculo de los nmeros de Fibonacci


0 Fib(n) 1 Fib(n1) + Fib(n2) si n = 0 si n = 1 si n > 1

Dos llamadas recursivas


LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1020

fibonacci.cpp
... int main(){ for(int i=0;i<20;i++){ cout<<fibonacci(i)<<endl; } return 0; }
0 Fib(n) 1 Fib(n1) + Fib(n2) si n = 0 si n = 1 si n > 1

LuisHernndezYez

int fibonacci(int n){ int resultado; if (n==0){ resultado=0; } elseif (n==1){ resultado=1; } else { resultado=fibonacci(n 1)+fibonacci(n 2); } returnresultado; }
Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1021

En una llamada recursiva alguno de los argumentos es otra llamada Ejemplo: Clculo de los nmeros de Ackermann:

n + 1 Ack(m, n) Ack(m1, 1) Ack(m1, Ack(m, n1))

si m = 0 si m > 0 y n = 0 si m > 0 y n > 0

Argumento que es una llamada recursiva

LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1022

ackermann.cpp

Nmeros de Ackermann

n + 1 Ack(m, n) Ack(m1, 1)

si m = 0 si m > 0 y n = 0

LuisHernndezYez

Ack(m1, Ack(m, n1)) si m > 0 y n > 0 ... int ackermann(int m,int n){ intresultado; if (m==0){ resultado =n+1; } elseif(n==0){ resultado =ackermann(m 1,1); } else{ resultado =ackermann(m 1,ackermann(m,n 1)); } return resultado; } Prubalo con nmeros muy bajos:

Se generan MUCHAS llamadas recursivas


Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1023

Nmeros de Ackermann
ackermann(1,1)

n + 1 Ack(m, n) Ack(m1, 1) Ack(m1, Ack(m, n1))

si m = 0 si m > 0 y n = 0 si m > 0 y n > 0

ackermann(0,ackermann(1,0))

2 3
ackermann(0,1) ackermann(0,2)

LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1024

Nmeros de Ackermann
ackermann(2,1)

n + 1 Ack(m, n) Ack(m1, 1) Ack(m1, Ack(m, n1))

si m = 0 si m > 0 y n = 0 si m > 0 y n > 0

ackermann(1, ackermann(2,0))

3 5
ackermann(1,1)
ackermann(0,ackermann(1,0)) ackermann(0,1) ackermann(0,2)

3
ackermann(1,3)

ackermann(0,ackermann(1,2))

LuisHernndezYez

ackermann(0, ackermann(1,1))
ackermann(0,ackermann(1,0)) ackermann(0,1) ackermann(0,2)

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

El cdigo anterior se ejecuta en orden directo para las distintas entradas, mientras que el cdigo posterior lo hace en orden inverso Si no hay cdigo anterior: recursin por delante Si no hay cdigo posterior: recursin por detrs
Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1027

Cdigo anterior y posterior a la llamada recursiva


void func(int n){ if (n>0){//Casobase:n==0 cout<<"Entrando(" <<n<<")" <<endl;//Cdigoanterior func(n 1);//Llamadarecursiva cout<<"Saliendo(" <<n<<")" <<endl;//Cdigoposterior } }

func(5); El cdigo anterior se ejecuta para los sucesivos valores de n (5, 4, 3, ...) El cdigo posterior al revs (1, 2, 3, ...)

LuisHernndezYez

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){ cout<<lista.elementos[pos]<<endl; mostrar(lista,pos+1); } }
Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1029

LuisHernndezYez

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){ mostrar(lista,pos+1); cout<<lista.elementos[pos]<<endl; } }
Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1030

LuisHernndezYez

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... Repetir con la segunda mitad de la lista La repeticin se consigue con las llamadas recursivas
Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1034

LuisHernndezYez

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

LuisHernndezYez

Repasa en el Tema 7 cmo funciona y cmo se implement iterativamente la bsqueda binaria (comprala con esta)

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)

LuisHernndezYez

Cada monje, en su turno, deba mover un nico disco de un pilar a otro, para con el tiempo conseguir entre todos llevar la torre del pilar inicial a uno de los otros dos; respetando una nica regla: nunca poner un disco sobre otro de menor tamao Cuando lo hayan conseguido, se acabar el mundo!
[Se requieren al menos 2641 movimientos; si se hiciera uno por segundo, se terminara en ms de 500 mil millones de aos]
Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1037

Queremos resolver el juego en el menor nmero de pasos posible Qu disco hay que mover en cada paso y a dnde? Identifiquemos los elementos (torre de cuatro discos):

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 a problemas ms pequeos Mover N discos del pilar A al pilar C: Mover N1 discos del pilar A al pilar B Mover el disco del pilar A al pilar C Mover N1 discos del pilar B al pilar C Para llevar N discos de un pilar origen a otro destino se usa el tercero como auxiliar Mover N1 discos del origen al auxiliar Mover el disco del origen al destino Mover N1 discos del auxiliar al destino

Mover 4 discos de A a C

LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1039

Mover N1 discos se hace igual, pero usando ahora otros origen y destino Mover N1 discos del pilar A al pilar B: Mover N2 discos del pilar A al pilar C Mover el disco del pilar A al pilar B Mover N2 discos del pilar C al pilar B Naturaleza recursiva de la solucin

Mover 3 discos de A a B

A
LuisHernndezYez

Simulacin para 4 discos (wikipedia.org)

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'); return 0; }
Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1041

LuisHernndezYez

LuisHernndezYez

Fundamentosdelaprogramacin:Introduccinalarecursin

Pgina 1042

longlong int factorial(int n){ longlong intfact; assert(n>=0); if (n==0){ fact=1; } else { fact=n*factorial(n 1); } return fact; }

longlong int factorial(int n){ longlong int fact=1; assert(n>=0); for (int i=1;i<=n;i++){ fact=fact*i; } 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:
Secuencia elemento seguido de una secuencia secuencia vaca (ningn elemento)

Las listas son secuencias:


elemento seguido de una lista Lista lista vaca (ningn elemento) (Caso base)

LuisHernndezYez

La lista 1, 2, 3 consiste en el elemento 1 seguido de la lista 2, 3, que, a su vez, consiste en el elemento 2 seguido de la lista 3, que, a su vez, consiste en el elemento 3 seguido de la lista vaca (caso base) Hay otras estructuras con naturaleza recursiva (p.e., los rboles) que estudiars en posteriores cursos
Fundamentosdelaprogramacin:Introduccinalarecursin Pgina 1046

Procesamiento de estructuras de datos recursivas


Naturaleza recursiva de las estructuras: procesamiento recursivo Procesar (lista): Si lista no vaca (caso base): Procesar el primer elemento de la lista // Cdigo anterior Procesar (resto(lista)) Procesar el primer elemento de la lista // Cdigo posterior 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 Archivosbinarios Tamaodelosdatos:Eloperadorsizeof() Aperturadearchivosbinarios Lecturadearchivosbinarios(accesosecuencial) Escrituraenarchivosbinarios(accesosecuencial) Accesodirectooaleatorio Ejemplosdeusodearchivosbinarios Ordenacindelosregistrosdelarchivo Bsquedabinaria Insercinenunarchivobinarioordenado Cargadelosregistrodeunarchivoenunatabla Almacenamientodeunatablaenunarchivo
LuisHernndezYez

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

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 de entrada Dispositivos/archivos de salida

LuisHernndezYez

Programa

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

LuisHernndezYez

En ambos casos se trata de una secuencia de caracteres En el segundo caso se interpretan como cdigos binarios Sin contemplar caracteres especiales como \n o \t Ya hemos usado flujos de texto para E/S por consola/archivos

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1053

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
LuisHernndezYez

Flujo binario

07

6C

C1

56

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; const int SIZE=sizeof(tRegistro);

LuisHernndezYez

En un archivo binario un dato del tipo tRegistro ocupar exactamente SIZE caracteres
Fundamentosdeprogramacin:Archivosbinarios Pgina 1056

typedef struct { int cod; double val; } tRegistro; tRegistro reg; const int SIZE=sizeof(reg); ...

MEMORIA ...

reg

0F03:1A38 0F03:1A39 0F03:1A3A 0F03:1A3B 0F03:1A3C

00 00 00 05 0A 37 1C DF 03 92 99 0E ...

reg.cod (4)

Posiciones de memoria usadas

SIZE (12)

0F03:1A3D 0F03:1A3E 0F03:1A3F 0F03:1A40 0F03:1A41

reg.val (8)

Se guardan los SIZE bytes:


LuisHernndezYez

0F03:1A42 0F03:1A43

Flujo binario
00 00 00 05 0A 37 1C DF 03 92

0F03:1A44

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) char + int + double


Fundamentosdeprogramacin:Archivosbinarios

SIZE toma el valor 8 (4 + 4), no 5 24 bytes (8 + 8 + 8)


Pgina 1058

NOTA: El tamao de palabra y los tamaos de los tipos dependen del sistema concreto

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 ios::app ios::binary ios::in ios::out ios::trunc
LuisHernndezYez

Significado Aadir: permite seguir escribiendo a partir del final Binario: tratar el archivo como archivo binario Entrada: archivo para leer de l Salida: archivo para escribir en l Truncar: borrar todo lo que haya y empezar de nuevo

Concatenacin de modos: operador | (O binaria: suma bit a bit)


archivo.open("entrada.dat",ios::in|ios::binary);
Fundamentosdeprogramacin:Archivosbinarios Pgina 1060

LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1061

archivo.read(puntero_al_bfer,nmero)
bfer: variable destino de los caracteres ledos Pasado como puntero a secuencia de caracteres Referencia (&) a la variable destino Molde de puntero a carcter (char *) nmero: cantidad de caracteres a extraer del archivo Operador sizeof() Archivo abierto con los modos ios::in e ios::binary
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 } else { //LecturaOK ...
Fundamentosdeprogramacin:Archivosbinarios Pgina 1063

LuisHernndezYez

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(); } archivo.close(); No olvides cerrar el archivo! return 0; }
Fundamentosdeprogramacin:Archivosbinarios Pgina 1064

LuisHernndezYez

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

LuisHernndezYez

Por qu usamos cadenas al estilo de C? string: tamao variable en memoria Requieren un proceso de serializacin Las cadenas al estilo de C siempre ocupan lo mismo en memoria

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1065

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:"; cin.sync(); cin.getline(registro.item,Max);//Mx:80 ...

LuisHernndezYez

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

No olvides cerrar el archivo! (prdida de datos!)

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1069

LuisHernndezYez

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1070

LuisHernndezYez

Acceso secuencial: empezando en el primero pasando a siguiente Acceso directo (tambin llamado aleatorio): Para localizar registros individuales necesitamos otras rutinas: tellg(): lugar donde se encuentra el puntero del archivo Siguiente posicin donde se realizar una lectura o escritura seekg(desplazamiento,origen): Lleva el puntero del archivo a una posicin concreta: desplazamiento caracteres desde el origen indicado Origen: ios::beg: principio del archivo ios::cur: posicin actual ios::end: final del archivo

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1071

ios::beg
0 SIZE 2*SIZE 3*SIZE 4*SIZE 5*SIZE

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

int pos=archivo.tellg();//Totaldecaracteresdelarchivo int numReg =pos/SIZE;

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1072

ios::beg
0 SIZE 2*SIZE 3*SIZE 4*SIZE 5*SIZE

ios::end
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; int num; cout<<"Registronmero?"; cin>>num; ...
Fundamentosdeprogramacin:Archivosbinarios Pgina 1075

LuisHernndezYez

if ((num>0)&&(num<=numReg)){ archivo.seekg((num 1)*SIZE,ios::beg); archivo.read((char *)&registro,SIZE); mostrar(registro); cout<<endl<<"Cambiarnombre[S/N]?"; char c; cin.sync(); cin>>c; if ((c=='s')||(c=='S')){ cout<<"Nombre:"; cin.sync(); cin.getline(registro.item,80); } cout<<endl<<"Cambiarprecio[S/N]?"; cin.sync(); cin>>c; if ((c=='s')||(c=='S')){ cout<<"Precio:"; cin>>registro.valor; } ...
Fundamentosdeprogramacin:Archivosbinarios Pgina 1076

LuisHernndezYez

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

LuisHernndezYez

fstream archivo; archivo.open(BD,ios::in |ios::out |ios::binary); archivo.seekg(0,ios::end); int pos=archivo.tellg(); int numReg =pos/SIZE; ...

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1081

//Ordenamosconelmtododeseleccindirecta tRegistro regMenor,reg; for (int i=0;i<numReg 1;i++){ int menor=i; for (int j=i+1;j<numReg;j++){ archivo.seekg(menor*SIZE,ios::beg); archivo.read((char *)&regMenor,SIZE); archivo.seekg(j*SIZE,ios::beg); archivo.read((char *)&reg,SIZE); if(strcmp(reg.item,regMenor.item)<0){ menor=j; } } regMenor reg ...
menor i
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
LuisHernndezYez

menor

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

LuisHernndezYez

archivo.open(BD,ios::in|ios::binary); archivo.seekg(0,ios::end); int pos=archivo.tellg(); int numReg =pos/SIZE; int buscado; cout<<"Cdigoabuscar:"; cin>>buscado; int ini=0,fin=numReg 1,mitad; bool encontrado=false; while((ini<=fin)&&!encontrado){ mitad=(ini+fin)/2; archivo.seekg(mitad*SIZE,ios::beg); archivo.read((char *)&registro,SIZE); if (buscado==registro.codigo){ encontrado=true; } elseif(buscado<registro.codigo){ fin=mitad 1; } ...
Fundamentosdeprogramacin:Archivosbinarios Pgina 1086

else{ ini=mitad+1; } } if (encontrado){ int pos=mitad+1; cout<<"Encontradoenlaposicin" <<pos<<endl; mostrar(registro); } else{ cout<<"Noencontrado!" <<endl; } archivo.close();
LuisHernndezYez

return 0; } ...

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1087

insertar.cpp

Ordenado por el campo codigo


#include<iostream> usingnamespacestd; #include<fstream> #include"registro.h" const char BD[]="ord2.dat"; void mostrar(); int main(){ mostrar(); tRegistro nuevoRegistro =nuevo(),registro; fstream archivo; archivo.open(BD,ios::in|ios::out |ios::binary); archivo.seekg(0,ios::end); int pos=archivo.tellg(); int numReg =pos/SIZE; ...
Fundamentosdeprogramacin:Archivosbinarios Pgina 1088

LuisHernndezYez

LuisHernndezYez

pos=0; bool encontrado=false; archivo.seekg(0,ios::beg); while ((pos<numReg)&&!encontrado){ archivo.read((char *)&registro,SIZE); if (registro.codigo >nuevoRegistro.codigo){ encontrado=true; } else { pos++; } } if (pos==numReg){//Debeiralfinal archivo.seekg(0,ios::end); archivo.write((char *)&nuevoRegistro,SIZE); } ...

Fundamentosdeprogramacin:Archivosbinarios

Pgina 1089

else {//Hayquehacerhueco for (int i=numReg 1;i>=pos;i){ archivo.seekg(i*SIZE,ios::beg); archivo.read((char *)&registro,SIZE); archivo.seekg((i+1)*SIZE,ios::beg); archivo.write((char *)&registro,SIZE); } archivo.seekg(pos*SIZE,ios::beg); archivo.write((char *)&nuevoRegistro,SIZE); } archivo.close(); mostrar();
LuisHernndezYez

nuevoRegistro

return 0; }

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); tabla.registros[tabla.cont]=registro; tabla.cont++; } archivo.close(); } }
Fundamentosdeprogramacin:Archivosbinarios

LuisHernndezYez

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); guardar(tabla); } return 0; }
Fundamentosdeprogramacin:Archivosbinarios Pgina 1094

LuisHernndezYez

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

También podría gustarte