Programación en C++
Un enfoque práctico
Serie Shaum
Programación en C++
Un enfoque práctico
Serie Schaum
LUIS JOYANES AGUILAR
LUCAS SÁNCHEZ GARCÍA
DepartamentodeLenguajesySistemasInformáticoseIngenieríadelSoftw are
FacultaddeInformática, EscuelaUniversitariadeInformática
UniversidadPontificiadeSalamancacampus Madrid
MADRID • BOGOTÁ • BUENOS AIRES • CARACAS • GUATEMALA • LISBOA • MÉXICO
NUEVA YORK • PANAMÁ • SAN JUAN • SANTIAGO • S ÃO PAULO
AUCKLAND • HAMBURGO • LONDRES • MILÁN • MONTREAL • NUEVA DELHI • PARÍS
SAN FRANCISCO • SIDNEY • SINGAPUR • ST. LOUIS • TOKIO • TORONTO
Lainformacióncontenidaenestelibroprocededeunaobraoriginalentregadaporlosautores.Noobstante, McGraw-Hill/InteramericanadeEspañanogarantizalae xactitudoperfeccióndelainformaciónpublicada. Tampocoasumeningúntipodegarantíasobr e
loscontenidosylasopinionesv ertidasendichostextos.
Estetrabajosepublicaconelreconocimientoe xpresodequeseestáproporcionandounainformación, peronotratandodeprestar
ningúntipodeservicioprofesionalotécnico.Losprocedimientosylainformaciónquesepresentanenestelibrotienensólol aintencióndeservircomoguíageneral.
McGraw-Hillhasolicitadolospermisosoportunosparalarealizaciónyeldesarrollodeestaobra.
Programación en C++. Un enfoque práctico. Serie Schaum
Noestápermitidalareproduccióntotaloparcialdeestelibro, nisutratamientoinformático, nilatransmisióndeningunaform ao
porcualquier medio, yaseaelectrónico, mecánico, porfotocopia, porregistrouotrosmétodos, sinelpermisoprevioyporescritode
lostitularesdelCopyright.
McGraw-Hill/Interamericana
de de España, S. A. U.
DERECHOSRESERVADOS© 2006, respectoalaprimeraediciónenespañol, por
McGRAW-HILL/INTERAMERICANADEESPAÑA, S.A.U.
EdificioValrealty, 1.ªplanta
Basauri, 17
28023Aravaca(Madrid)
www.mcgraw-hill.es
[email protected]
ISBN: 84-481-4643-3
Depósitolegal: M.
Editor: CarmeloSánchezGonzález
CompuestoenPuntographic, S.L.
Impresoen
IMPRESOENESPAÑA-PRINTEDINSPAIN
Contenido
Prólogo ..............................................................................................................................................................................
XIII
Capítulo 1. Programación orientada a objetos versus programación estructurada: C++ y algoritmos................
Introducción ............................................................................................................................................................
1.1. Conceptodealgoritmo ....................................................................................................................................
1.2. Programaciónestructurada..............................................................................................................................
1.3. Elparadigmadeorientaciónaobjetos ............................................................................................................
1.3.1. Propiedadesfundamentalesdelaorientaciónaobjetos .......................................................................
1.3.2. Abstracción...........................................................................................................................................
1.3.3. Encapsulaciónyocultacióndedatos ....................................................................................................
1.3.4. GeneralizaciónyEspecialización.........................................................................................................
1.3.5. Polimorfismo ........................................................................................................................................
1.4. C++Comolenguajedeprogramaciónorientadaaobjetos ............................................................................
Ejercicios.................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
1
1
1
3
4
5
5
6
6
7
7
8
8
14
Capítulo 2. Conceptos básicos de los programas en C++ ...........................................................................................
Introducción ............................................................................................................................................................
2.1. EstructurageneraldeunprogramaenC++ ....................................................................................................
2.1.1. Directivasdelpreprocesador ................................................................................................................
2.1.2. Declaracionesglobales .........................................................................................................................
2.1.3. Funciónmain() ....................................................................................................................................
2.1.4. Funcionesdefinidasporelusuario .......................................................................................................
2.1.5. Comentarios..........................................................................................................................................
2.2. LoselementosdeunprogramaenC++ ..........................................................................................................
2.2.1. Identificador..........................................................................................................................................
2.2.2. Palabrasreservadas...............................................................................................................................
2.2.3. Comentarios..........................................................................................................................................
2.2.4. Signosdepuntuaciónyseparadores ....................................................................................................
2.2.5. Archivosdecabecera ............................................................................................................................
2.3. TiposdedatosenC++ ....................................................................................................................................
2.3.1. Enteros(int) ........................................................................................................................................
2.3.2. Tiposencomaflotante( float/double) .............................................................................................
2.3.3. Caracteres(char)..................................................................................................................................
2.3.4. Eltipodedato bool .............................................................................................................................
2.4. Constantes .......................................................................................................................................................
2.4.1. Constantesliterales ...............................................................................................................................
2.5. Variables ..........................................................................................................................................................
2.6. Duracióndeunavariable ................................................................................................................................
2.6.1. Variableslocales ...................................................................................................................................
2.6.2. Variablesglobales .................................................................................................................................
2.6.4. Variablesdinámicasydeobjetos .........................................................................................................
15
15
15
16
16
17
18
18
19
19
19
19
20
20
20
20
21
21
23
23
23
25
25
25
26
26
V
VI
CONTENIDO
2.7. Entradasysalidas ............................................................................................................................................
2.7.1. Salida(cout) ........................................................................................................................................
2.7.2. Entrada(cin) ........................................................................................................................................
2.8. Espaciosdenombres( namespaces) ...............................................................................................................
Ejercicios.................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
26
27
27
28
29
31
34
Capítulo 3. Operadores y expresiones ..........................................................................................................................
Introducción ............................................................................................................................................................
3.1. Operadoresyexpresiones.............................................................................................................................
3.2. Operadordeasignación ................................................................................................................................
3.3. Operadoresaritméticos .................................................................................................................................
3.4. Operadoresdeincrementaciónydecrementación ........................................................................................
3.5. Operadoresrelacionales................................................................................................................................
3.6. Operadoreslógicos .......................................................................................................................................
3.7. Operadoresdemanipulacióndebits ............................................................................................................
3.7.1. Operadoresdedesplazamientodebits( >>, <<).................................................................................
3.7.2. Operadoresdeasignaciónadicionales ...............................................................................................
3.7.3. Operadoresdedirecciones .................................................................................................................
3.8. Operadorcondicional ? ................................................................................................................................
3.9. Operadorcoma , ..........................................................................................................................................
3.10. Operadoresespeciales ( ), [ ] y:: ...........................................................................................................
3.11. Eloperador sizeof ......................................................................................................................................
3.12. Conversionesdetipos ...................................................................................................................................
3.13. Prioridadyasociatividad ..............................................................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
35
35
35
35
36
39
39
40
41
41
42
42
42
43
44
44
45
45
46
47
48
49
55
Capítulo 4. Estructuras de control selectivas (if, if-else, switch) .........................................................................
Introducción ............................................................................................................................................................
4.1. Estructurasdecontrol......................................................................................................................................
4.2. Lasentencia if................................................................................................................................................
4.3. Sentenciaif dedosalternativas: if-else .....................................................................................................
4.4. Sentenciasif-else anidadas..........................................................................................................................
4.5. Sentenciadecontrol switch ...........................................................................................................................
4.6. Expresionescondicionales: eloperador ?: .....................................................................................................
4.7. Evaluaciónencortocircuitodeexpresioneslógicas .......................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
Problemaspropuestos..............................................................................................................................................
57
57
57
57
59
61
62
63
64
65
66
67
69
75
76
Capítulo 5. Estructuras de control repetitivas (while, for, do-while) .....................................................................
Introducción ............................................................................................................................................................
5.1. Lasentencia while..........................................................................................................................................
5.2. Repetición: elbuclefor ..................................................................................................................................
5.4. Repetición: elbucledo...while ....................................................................................................................
5.5. Comparacióndebucleswhile, for ydo–while ............................................................................................
77
77
77
81
83
84
CONTENIDO
VII
5.6. Buclesanidados...............................................................................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
Problemaspropuestos..............................................................................................................................................
86
86
88
89
91
100
101
Capítulo 6. Funciones y módulos...................................................................................................................................
Introducción ............................................................................................................................................................
6.1. Conceptodefunción.....................................................................................................................................
6.2. Estructuradeunafunción .............................................................................................................................
6.3. Prototiposdelasfunciones ...........................................................................................................................
6.4. Parámetrosdeunafunción ...........................................................................................................................
6.5. Funcionesenlínea( inline) ........................................................................................................................
6.6. Ámbito(alcance) ..........................................................................................................................................
6.7. Clasesdealmacenamiento............................................................................................................................
6.8. Conceptoyusodefuncionesdebiblioteca ..................................................................................................
6.9. Misceláneadefunciones ..............................................................................................................................
6.10. Sobrecargadefunciones(polimorfismo) .....................................................................................................
6.11. Plantillasdefunciones ..................................................................................................................................
Problemas ................................................................................................................................................................
Ejercicios.................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Problemaspropuestos..............................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
103
103
103
104
106
108
112
114
116
119
119
121
123
124
124
126
127
133
133
Capítulo 7. Arrays (arreglos, listas o tablas)................................................................................................................
Introducción ............................................................................................................................................................
7.1. Arrays(arreglos) .............................................................................................................................................
7.2. Inicializacióndearrays ...................................................................................................................................
7.3. Arraysmultidimensionales..............................................................................................................................
7.4. Utilizacióndearrayscomoparámetros ..........................................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
Problemaspropuestos..............................................................................................................................................
135
135
135
136
138
141
147
148
149
151
157
158
Capítulo 8. Registros (estructuras y uniones) ..............................................................................................................
Introducción ............................................................................................................................................................
8.1. Estructuras.......................................................................................................................................................
8.2. Uniones............................................................................................................................................................
8.3. Enumeraciones ................................................................................................................................................
8.4. Sinónimodeuntipodedatotypedef ..............................................................................................................
8.5. Camposdebit..................................................................................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Problemaspropuestos..............................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
161
161
161
168
170
172
172
174
175
176
178
181
181
VIII
CONTENIDO
Capítulo 9. Cadenas........................................................................................................................................................
Introducción ............................................................................................................................................................
9.1. Conceptodecadena ........................................................................................................................................
9.2. Lecturadecadenas ..........................................................................................................................................
9.3. Labibliotecastring.h.......................................................................................................................................
9.4. Conversióndecadenasanúmeros ..................................................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
Problemaspropuestos..............................................................................................................................................
183
183
183
185
189
191
193
194
195
198
201
202
Capítulo 10. Punteros (apuntadores) ............................................................................................................................
Introducción ............................................................................................................................................................
10.1. Conceptodepuntero(apuntador) .................................................................................................................
10.2. PunterosNULL yvoid ...................................................................................................................................
10.3. Punterosyarrays ..........................................................................................................................................
10.4. Punterosdecadenas......................................................................................................................................
10.5. Aritméticadepunteros .................................................................................................................................
10.6. Punteroscomoargumentosdefunciones .....................................................................................................
10.7. Punterosafunciones.....................................................................................................................................
10.8. Punterosaestructuras ...................................................................................................................................
Ejercicios.................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
Problemaspropuestos..............................................................................................................................................
203
203
203
206
206
208
208
212
213
216
217
219
219
222
225
226
Capítulo 11. Gestión dinámica de la memoria .............................................................................................................
Introducción ............................................................................................................................................................
11.1. Gestióndinámicadelamemoria ..................................................................................................................
11.2. Eloperador new ............................................................................................................................................
11.3. Eloperador delete ......................................................................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
Problemaspropuestos..............................................................................................................................................
227
227
227
228
233
235
236
237
239
242
243
Capítulo 12. Ordenación y búsqueda............................................................................................................................
Introducción ............................................................................................................................................................
12.1. Búsqueda ......................................................................................................................................................
12.1.1. Búsquedasecuencial .......................................................................................................................
12.1.2. Búsquedabinaria .............................................................................................................................
12.2. Ordenación....................................................................................................................................................
12.3. Ordenaciónporburbuja ................................................................................................................................
12.4. Ordenaciónporselección .............................................................................................................................
12.5. Ordenaciónporinserción .............................................................................................................................
12.6. OrdenaciónShell ..........................................................................................................................................
Problemas ................................................................................................................................................................
245
245
245
245
247
248
248
250
251
253
254
CONTENIDO
IX
Ejercicios.................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
Problemaspropuestos..............................................................................................................................................
254
255
256
257
258
Capítulo 13. Clases y objetos .........................................................................................................................................
Introducción ............................................................................................................................................................
13.1. Clasesyobjetos ............................................................................................................................................
13.2. Definicióndeunaclase ................................................................................................................................
13.3. Objetos..........................................................................................................................................................
13.4. Constructores ................................................................................................................................................
13.5. Destructrores.................................................................................................................................................
13.6. Clasecompuesta ...........................................................................................................................................
13.7. Erroresdeprogramación ..............................................................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
Problemaspropuestos..............................................................................................................................................
259
259
259
259
261
264
265
268
269
270
271
272
273
274
275
Capítulo 14. Herencia y polimorfismo ..........................................................................................................................
Introducción ............................................................................................................................................................
14.1. Herencia........................................................................................................................................................
14.1.1. Tiposdeherencia ............................................................................................................................
14.1.2. Clasesabstractas..............................................................................................................................
14.2. Ligadura........................................................................................................................................................
14.3. Funcionesvirtuales .......................................................................................................................................
14.4. Polimorfismo ................................................................................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Problemaspropuestos..............................................................................................................................................
277
277
277
280
286
287
287
287
288
289
290
290
292
Capítulo 15. Plantillas, excepciones y sobrecarga de operadores ..............................................................................
Introducción ............................................................................................................................................................
15.1. Generecidad ..................................................................................................................................................
15.2. Excepciones ..................................................................................................................................................
15.2.1. Lanzamientodeexcepciones ..........................................................................................................
15.2.2. Manejadoresdeexcepciones...........................................................................................................
15.2.3. Diseñodeexcepciones ....................................................................................................................
15.3. Sobrecarga ....................................................................................................................................................
15.3.1. Sobrecargadeoperadoresunitarios ................................................................................................
15.3.2. Conversióndedatosyoperadoresdecon versiónforzadadetipos ................................................
15.3.3. Sobrecargadeoperadoresbinarios .................................................................................................
Problemas ................................................................................................................................................................
Ejercicios.................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Problemaspropuestos..............................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
293
293
293
296
296
297
297
299
300
301
303
306
306
307
308
310
310
X
CONTENIDO
Capítulo 16. Flujos y archivos .......................................................................................................................................
Introducción ............................................................................................................................................................
16.1. Flujos(streams) ............................................................................................................................................
16.2. Lasclases istream yostream ....................................................................................................................
16.3. Lasclases ifstream yofstream ................................................................................................................
16.3.1. Aperturadeunarchivo....................................................................................................................
16.3.2. Funcionesdelecturayescrituraenf icheros...................................................................................
Solucióndelosejercicios........................................................................................................................................
Problemas ................................................................................................................................................................
Ejercicios.................................................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Problemaspropuestos..............................................................................................................................................
311
311
311
312
316
316
317
320
320
320
321
322
Capítulo 17. Listas enlazadas.........................................................................................................................................
Introducción ............................................................................................................................................................
17.1. Fundamentosteóricos ...................................................................................................................................
17.2. Clasificacióndelaslistasenlazadas .............................................................................................................
17.3. Operacionesenlistasenlazadas ...................................................................................................................
17.3.1. Declaracióndelostiposnodoypunteroanodoyclasenodo .......................................................
17.3.2. Declaracióndeclaselista, inicializaciónocreación ......................................................................
17.3.3. Insertarelementosenunalista ........................................................................................................
17.3.4. Buscarelementosdeunalista .........................................................................................................
17.3.5. Eliminarelementosdeunalista ......................................................................................................
17.4. Listadoblementeenlazada ...........................................................................................................................
17.4.1. Insercióndeunelementoenunalistadoblementeenlazada ..........................................................
17.4.2. Elininacióndeunelementoenunalistadoblementeenlazada ......................................................
17.5. Listascirculares ............................................................................................................................................
Problemas ................................................................................................................................................................
Ejercicios.................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
Problemaspropuestos..............................................................................................................................................
323
323
323
324
325
325
327
328
330
331
332
334
335
336
338
338
339
342
344
345
Capítulo 18. Pilas y colas................................................................................................................................................
Introducción ............................................................................................................................................................
18.1. Conceptodepila ...........................................................................................................................................
18.2. Conceptodecola ..........................................................................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Problemaspropuestos..............................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
347
347
347
353
359
360
361
362
364
364
Capítulo 19. Recursividad..............................................................................................................................................
Introducción ............................................................................................................................................................
19.1. Lanaturalezadelarecursividad...................................................................................................................
19.2. Funcionesrecursivas.....................................................................................................................................
19.3. Recursiónversusiteración............................................................................................................................
19.4. Recursióninfinita .........................................................................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
367
367
367
368
370
370
371
372
373
CONTENIDO
XI
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
Problemaspropuestos..............................................................................................................................................
374
377
377
Capítulo 20. Árboles .......................................................................................................................................................
Introducción ............................................................................................................................................................
20.1. Árbolesgenerales .........................................................................................................................................
20.2. Árbolesbinarios............................................................................................................................................
20.3. Estructurayrepresentacióndeunárbolbinario ..........................................................................................
20.5. Recorridosdeunárbol .................................................................................................................................
20.6. Árbolbinariodebúsqueda ...........................................................................................................................
20.7. Operacionesenárbolesbinariosdebúsqueda ..............................................................................................
Ejercicios.................................................................................................................................................................
Problemas ................................................................................................................................................................
Solucióndelosejercicios........................................................................................................................................
Solucióndelosproblemas ......................................................................................................................................
Ejerciciospropuestos ..............................................................................................................................................
Problemaspropuestos..............................................................................................................................................
379
379
379
380
381
383
384
385
388
389
390
392
394
395
Índice.................................................................................................................................................................................
396
Prólogo
C++esherederodirectodellenguajeCqueasuv ezsederivadellenguajeB.EllenguajedeprogramaciónCfuedesarrolladopor Dennis Ritche deAT&TBellLaboratoriesyseutilizóparaescribirymantenerelsistemaoperati voUNIX.Cesun
lenguajedepropósitogeneralquesepuedeutilizarparaescribircualquiertipodeprograma, perosuéxitoypopularidadestá
especialmenterelacionadoconelsistemaoperati voUNIX.Lossistemasoperati vossonlosprogramasquegestionan(administran)losrecursosdelacomputadora.EjemplosbienconocidosdesistemasoperativosademásdeUNIXsonMS/DOS, OS
Mac, OS/2, MVS, Linux, Windows95/98, NT, 2000, XP2000, oelrecientementepresentado Vista deMicrosoftquevendrá
asustituiralactualWindowsXP.
LaespecificaciónformaldellenguajeCesundocumentoescritoporRitchie, tituladoTheCReferenceManual.En1997,
Ritchie yBrian Kernighan, ampliaronesedocumentoypublicaronunlibroreferenciadellenguajeTheCProgrammingLanguage (tambiénconocidoporelK&R).AunqueCesunlenguajemuypotenteysiguesiendomuyutilizadoenelmundouniversitarioytambiénenelprofesional, elhechodehabersidodiseñadoalprincipiodelossetentayquelanaturalezadelaprogramaciónhacambiadoradicalmenteenladécadadelosochentaydelosnoventa, exigíaunaactualizaciónparasubsanarsus
“deficiencias”.
BjarneStroustrupdeAT&TBellLaboratoriesdesarrollóC++alprincipiodeladécadadelosochenta.Stroustrupdiseñó
C++comounmejorC.Engeneral, CestándaresunsubconjuntodeC++ylamayoríadelosprogramasCsontambiénprogramasC++(laaf irmacióninversanoesv erdadera).C++ademásdeañadirpropiedadesaC, presentacaracterísticasypropiedadesdeprogramaciónorientadaaobjetos, queesunatécnicadeprogramaciónmuypotenteyquesev eráenlasegunda
partedeestelibro.
SehanpresentadovariasversionesdeC++ysuevoluciónhaincorporadonuevasypotentespropiedades: herencia, genericidad, plantillas, funcionesvirtuales, excepciones, etc.C++haidoe volucionandoañoaañoycomosuautorhae xplicado:
«evolucionósiemprepararesolverproblemasencontradosporlosusuariosycomoconsecuenciadecon versacionesentreel
autor, susamigosysuscolegas»1.
C++comenzósupro yectodeestandarizaciónanteelcomité ANSIysuprimerareferenciaes TheAnnotatedC++ReferenceManual [Ellis 89] 2.Endiciembre1989sereunióelcomitéX3J16delANSIporiniciativadeHewlettPackard.Enjunio
de1991, laestandarizaciónde ANSIpasóaformarpartedeunesfuerzodeestandarizaciónISO.En1995sepublicóunborradordeestándarparasuexamenyen1998seaprobóelestándarC++internacionalporlasor ganizacionesANSIeISO, conocidocomoISO/IEC 14882 osimplementeC++ Estándar oANSI C++.Stroustruppublicóen1997laterceraediciónde
sulibroTheC++ProgrammingLanguagey, en1998, unaactualizaciónquesepublicócomo ediciónespecial 3.Ellibroque
tieneensusmanos, sigueelestándarANSI/ISOC++.
C++ en el aprendizaje de algoritmos y programación
orientada a objetos
TodaslascarrerasuniversitariasdeCienciaseIngeniería, asícomolosestudiosdeFormaciónProfesional (sobretodoenEspañalosciclossuperiores)requierenuncursobásicode algoritmosydeprogramación conunlenguajepotenteyprofesional
peroqueseasimpleyfácildeutilizar , asícomouncursode programaciónorientadaaobjetos.
1
2
3
[Stroustrup98], p.12
ExisteversiónespañoladeAddison-Wesley/DíazdeSantosytraducidaporlosprofesoresManuelKatribyLuisJo yanes.
Estaobrafuetraducidaporunequipodeprofesoresuni versitariosquedirigióycoordinóelprofesorLuisJo yanes, coautordeestaobra.
XIII
PRÓLOGO
XIV
Losdoceprimeroscapítulosconstituyenuncursoinicialdealgoritmosyprogramaciónypuedeserutilizadoenasignaturastalescomo Introducción a la programación , Fundamentos de programación oMetodología de la programación ocon
otrosnombrestalescomoAlgoritmos, Programación I, etc.Losrestantescapítulos(12al20)puedenserutilizadosparacursosdeintroducciónaestructurasdedatosyaprogramaciónorientadaaobjetos,ypuedeserutilizadoenasignaturastalescomo
EstructurasdedatosI , Introducciónalaprogramaciónorientadaaobjetos osimilares.C++esunodeloslenguajesuni versalesmásutilizadoyrecomendadoenplanesdeestudiodeuni versidadesycentrosdeformacióndetodoelmundo.Or ganizacionescomoACM, IEEE, colegiosprofesionales, siguenrecomendandolanecesidaddelconocimientoenprofundidadde
técnicasydelenguajesdeprogramaciónestructuradaconelobjeti vode“acomodar” laformacióndelestudiantealaconcepción, diseñoyconstruccióndealgoritmosydeestructurasdedatos.Elconocimientoprofundodealgoritmosunidoatécnicas
fiables, rigurosasyeficientesdeprogramaciónpreparanalestudianteoalautodidactaparaunaltorendimientoenprogramaciónylapreparaciónparaasumirlosretosdelaprogramaciónorientadaaobjetosenunaprimeraf aseylastécnicasymétodosinherentesaingenieríadesoftw areenotrafasemásavanzada.
Lamejormaneraparaaprenderaprogramarunacomputadoraespensarydiseñarelalgoritmoqueresuelv eelproblema,
codificarenunlenguajedeprogramación(C++ennuestrocaso)ydepurarelprogramaunayotrav ezhastaentenderlagramáticaysusre glasdesintaxis, asícomolalógicadelprograma.Nuncamejordicho: aprenderpracticando.EllenguajeC++
seprestaaescribir , compilar, ejecutaryv erificarerrores.Porestarazónhemosincluidoenlaestructuradellibrolasintroduccionesteóricasimprescindiblesconelapo yodenumerososejemplos, luegohemosincorporadonumerososejerciciosy
problemasdeprogramaciónconunanálisisdelproblemaysuscódigosfuente, yennumerosasocasionessepresentalasalidaoejecucióndelosrespectivosprogramas.
La estructura del libro en la colección Schaum
Estaediciónhasidoescritadentrodelaprestigiosacolección Schaum deMcGraw-Hill, comounmanualprácticoparalaenseñanzadelaprogramacióndecomputadorasestudiandoconellenguajedeprogramaciónC++.Debidoalosobjeti vosque
tieneestaantiguacolección, elenfoqueeseminentementeprácticoconelnecesarioestudioteóricoquepermitaa vanzarde
modorápidoyeficazalestudianteensuaprendizajedelaprogramaciónenC++.Pensandoenlacolecciónlosdosautoreshemosescritoestelibroconunplanteamientoeminentementeteórico-prácticocomosontodoslospertenecientesaestacolecciónconelobjetivodeayudaraloslectoresasuperarsuse xámenesypruebasprácticasensusestudiosdeformaciónprofesionalouni versitarios, ymejorarsuaprendizajedemodosimultáneoperoconunosplanteamientosprácticos:
analizarlos
problemas, escribirloscódigosfuentedelosprogramasydepurarestosprogramashastaconse guirelfuncionamientocorrectoyadecuado.
Hemosañadidouncomplementoprácticodeayudaallector .Enlapáginaof icialdellibro, encontraráellectortodoslos
códigosfuenteincluidosynoincluidosenlaobrayquepodrádescar gardeInternet.Pretendemosnosóloe vitarsuescritura
desdeeltecladoparaquesecentreenelestudiodelalógicadelprogramaysuposteriordepuración(edición, compilación,
ejecución, verificaciónypruebas)sinotambiénparaquepuedacontrastarela vanceadecuadodesuaprendizaje. Tambiénen
lapáginawebencontraráotrosrecursoseducati vosqueconfiamosleayudaránaprogresardeunmodoef icazyrápido.
¿Qué necesita para utilizar este libro?
ProgramaciónenC++. Unenfoquepráctico , estápensadoydiseñadoparaenseñarmétodosdeescrituradeprogramasen
C++, tantoestructuradoscomoorientadosaobjetos, útilesyeficientesycomoindicaelsubtítulodelaobra, deunmodototalmentepráctico.SepretendetambiénenseñartantolasintaxiscomoelfuncionamientodellenguajedeprogramaciónC++
juntoconlastécnicasdeprogramaciónylosfundamentosdeconstruccióndealgoritmosbásicos, juntoeldiseñoyconstruccióndeclasesyrestantespropiedadesfundamentalesdelaprogramaciónorientadaaobjetos.ElcontenidosehaescritopensandoenunlectorquetieneconocimientosbásicosdealgoritmosydeprogramaciónenC/C++, yquedeseaaprenderaconocerdemodoprácticotécnicasdeprogramación,
tantoestructuradascomoorientadasaobjetos.Lagranprofusiónde
ejemplosresueltospermitiráallectorsinconocimientosdeprogramaciónbásicaydellenguajeC/C++se guirelcursoincluidoenellibro, aunqueenestecasolerecomendamosnoafrontelaresolucióndelosejerciciosyproblemashastatantonohaya
estudiadoyasimiladobienlosconceptosteóricosyprácticosdecadacapítulo.
Ellibroeseminentementeprácticoconlaformaciónteóricanecesariaparaobtenerelmayorrendimientoensuaprendizaje.PretendequeellectorutiliceellibroparaaprenderdeunmodoprácticolastécnicasdeprogramaciónenC++, necesariasparaconvertirleenunbuenprogramadordeestelenguaje.
PRÓLOGO
XV
Parautilizarestelibroyobtenerelmáximorendimiento, esconvenienteutilizarenparaleloconelaprendizajeunacomputadoraquetengainstaladosuncompiladordeC++yuneditordete xtoparaprepararsusarchi vosdecódigofuente.Normalmente, hoydía, lamayoríadeloscompiladoresvienenconunEntornoIntegradodeDesarrollo(EID)quecontieneuncompilador, uneditoryundepuradordepuestaapuntodesusprogramas.ExistennumerososcompiladoresdeC++enelmercado
ytambiénnumerosasversionesshareware(libresdecostes)disponiblesenInternet.Idealmente, sedebeelegiruncompilador
queseacompatibleconlav ersiónestándardeC++del AmericanNationalStandardsInstitute(ANSI), ANSI C++, queesla
versiónempleadaenlaescrituradeestelibro.LamayoríadelosactualescompiladoresdisponiblesdeC++, comercialesode
dominiopúblico, soportanelestándarcitado.Losautoreshemosutilizadoelcompilador Dev C++ porconsiderarqueesuno
delosmásutilizadosho ydía, tantoporalumnosautodidactascomoporalumnosdecarrerasdecienciasydeingeniería, en
susprácticasregladasoensushogares, alseruncompiladorgratuito, delibredisposición, quefuncionaenentornosWindows
ytotalmentecompatibleconANSIC++.
Aunqueellibroestáconcebidocomounlibrodeproblemas, sehaincluidolateoríanecesariaparaqueellibropuedaser
consideradotambiénunlibrodeteoríaconlosconocimientosmínimosnecesariosparaconse guiralcanzarunnivelmediode
programación.NoobstantesinecesitaodeseaadquirirunnivelmásprofundodeteoríadeprogramaciónenC++, tantodealgoritmos, comodeprogramaciónestructuradauorientadaaobjetos, leproponemosunlibrocomplementariodeéste, ydeuno
desuscoautores(LuisJo yanes)ProgramaciónenC++: Algoritmos, estructuradedatosyobjetos , 1.ªedición, publicadoen
elaño2000.Enlaactualidadelautortrabajaenla2.ªediciónqueesperaestarpublicadaenelprimersemestrede2006.Esta
nuevaedicióntendrá, ademásdelasactualizacionescorrespondientes, elenunciadodetodoslosejerciciosyproblemas, resueltosypropuestosenestaobradela ColecciónSchaum demodoqueamboslibrosseconf igurancomounconjuntocomplementarioteórico-prácticoparaelaprendizajedeprogramaciónenC++.
Encualquierformasiustedsigueuncursoreglado, elmejormétodoparaestudiarestelibroesseguirlosconsejosdesu
maestroyprofesortantoparasuformaciónteóricacomoparasuformaciónpráctica.Siustedesunautodidactaoestudiade
modoautónomo, larecomendaciónentoncesseráqueamedidaquev ayaleyendoellibro, compile, ejecuteydepuredeerroressusprogramas, tantolosresueltosypropuestoscomolosqueusteddiseñe, tratandodeentenderlalógicadelalgoritmoy
lasintaxisdellenguajeencadaejercicioquerealice.
Compiladores y compilación de programas en C++
ExistennumerososcompiladoresdeC++enelmercado.Desdeedicionesgratuitasy descargablesatravésdeInternethasta
profesionales, concostesdiferentes, comercializadospordiferentesfabricantes.Esdifícildarunarecomendaciónallectorporquecasitodosellossonb uenoscompiladores, muchosdeellosconEntornosInte gradosdeDesarrollo (EID).Siustedesestudiante, talvezlamejordecisiónseautilizarelcompiladorquelehayapropuestosuprofesoryqueutiliceensuUniversidad,
InstitutoTecnológicoocualquierotroCentrodeFormación, dondeestudie.Siustedesunlectorautodidactayestáaprendiendo
porsucuenta, existenvariasversionesgratuitasquepuededescargardesdeInternet.Algunosdelosmásreconocidosson:DevC++ deBloodshed quecumplefielmenteelestándarANSI/ISOC++(utilizadoporlosautoresdellibroparaeditarycompilartodoslosprogramasincluidosenelmismo)yquecorrebajoentornos Windows;GCC deGNUquecorrebajolosentornosLinuxyUnix.Existenmuchosotroscompiladoresgratuitosporloquetienedondeelegir.Talvezunconsejomás: procure
queseacompatibleconelestándarANSI/ISOC++.
BjarneStroustrup(creadorein ventordeC++)ensupáginaof icial4 hapublicadoel9defebrerode2006, “unalistaincompletadecompilador esdeC++”, quelerecomiendoleayvisite.Porsuinterésincluimos, acontinuación, unbreveextractodesulistarecomendada:
Compiladoresgratuitos
AppleC++
BorlandC++
Dev-C++deBloodshed
GNUIntelC++paraLinux
MicrosoftVisualC++Toolkit2003
SunStudio...
4
http://public.research.att.com/˜bs/compilers.html.Elartículo“AnincompletelistofC++compilers” losuelemodificarStroustrupyenlacabeceraindica
lafechademodificación.Ennuestrocaso, consultamosdichapáginamientrasescribíamoselprólogoenlaprimeraquincenadema rzo, ylafechaincluidaesla
de9defebrerode2006.
PRÓLOGO
XVI
Compiladorescomerciales
BorlandC++
CompaqC++
HPC++
IBMC++
IntelC++paraWindows, Linuxyalgunossistemasempotrados
MicrosoftC++
StroustruprecomiendaunsitiodecompiladoresgratuitosdeCyC++( Compilers.net).
NOTA PRÁCTICA DE COMPATIBILIDAD C++ ESTÁNDAR
EnelartículoantescitadodeStroustrup,recomiendaquecompileconsucompiladorelsiguientesimpleprogramafuenteC++.Siustedcompilabienesteprograma, notendráproblemasconC++estándar.Encasocontrario, aconsejabuscarotrocompiladorqueseacompatible.
#include<iostream>
#include<string>
using namespace std;
int main( )
{
string s;
cout << ''Por favor introduzca su nombre seguido por ''Intro''\n'';
return 0; // esta sentencia return no es necesaria
}
¿Cómo está organizado el libro?
Todosloscapítulossiguenunaestructurasimilar:Breveintroducciónalcapítulo;fundamentosteóricosbásicos necesariospara
elaprendizajeconnumerososejemplos;enunciadosdeEjercicios yProblemas, yacontinuación, laSolucióndelosejercicios
ylaSolucióndelosproblemas, dondeseincluyenelanálisisdelproblemaylacodificaciónenC++;porúltimo, todosloscapítuloscontienenunacoleccióndeejerciciosyproblemaspropuestos, cuyoobjetivoesf acilitarallectorlamedicióndesu
aprendizaje.
Conelobjeti vodef acilitarlaedición, ejecuciónypuestaapuntodelosprogramasallector , estaediciónincluyeuna
novedad: todosloscódigosfuentedellibro, tantodelosnumerososejemploscomodeejerciciosyproblemassehanincluido enlapáginawebof icialdellibro( www.mhe.es/joyanes).Porestarazón, numerososlistadosdecódigosfuentedelos
ejerciciosyproblemasresueltosdediferentescapítulos, sólosehanincluidoenlapáginaWeb, ynosehaneditadoenellibro.
Sepretendeconestaestructuradoscosas: primera, queellibronoresultarav oluminosoennúmerodepáginas;se gunda,
que el lectorpudieracomprobarcuandoconsideraraoportunolasoluciónpropuesta, sinmásquebajardichocódigodelapáginaweb.
Capítulo 1. Programación orientada a objetos v ersus programación estructurada: C++ y algoritmos. Explicaydescribelosconceptosfundamentalesdealgoritmos, deprogramaciónestructuradaydeprogramaciónorientadaaobjetos, juntocon
laspropiedadesmássignificativasdeC++.
Capítulo 2. Conceptos básicos de los programas en C++. SeintroduceallectorenlaestructurageneralyelementosbásicosdeunprogramaenC++.Sedescribenlostiposdedatos, constantes, variablesylaentrada/salida;asícomoelnuevoconceptodeespaciodenombres (namespaces).
PRÓLOGO
XVII
Capítulo 3. Operadores y expresiones. Seaprendeelusodelosoperadoresaritméticos, relacionalesylógicosparalamanipulacióndeoperacionesye xpresionesenC.Seestudiantambiénoperadoresespecialesycon versionesdetipos, juntocon
reglasdeprioridady asociatividad delosoperadoresenlase xpresionesyoperacionesmatemáticas.
Capítulo 4. Estructuras de control selectivas (if, if-else, switch). Introducealassentenciasdeselecciónfundamentalesencualquierprograma.See xaminaelusodesentenciascompuestasobloquesasícomoelusodeoperadorescondicionalesyevaluacióndeexpresioneslógicas.
Capítulo 5. Estructuras de control repetitivas (while, for, do-while). Seaprendeelconceptodebucleolazoyelmodo
decontrolarlaejecucióndeunprogramamediantelassentencias for, while ydo-while.Tambiénseexplicaelconceptode
anidamientodebuclesybuclesvacíos;seproporcionanejemplosútilesparaeldiseñoef icientedebucles.
Capítulo 6. Funciones y módulos. ExaminalasfuncionesenC++, unaparteimportantedelaprogramaciónyenseñala
programaciónestructurada—unmétododediseñodeprogramasqueenfatizaenelenfoquedescendenteparalaresoluciónde
problemasmedianteladescomposicióndelproblemagrandeenproblemasdemenorni velqueseimplementanasuv ezcon
funciones.Seintroduceallectorenelconceptodefuncionesdebiblioteca, juntoconlapropiedaddesobrecar gayplantillas
defunciones.
Capítulo 7. Arrays o arreglos (listas y tablas). Seexplicaunmétodosencilloperopotentedealmacenamientodedatos.
Seaprendecómoagrupardatossimilaresen arrays o“arreglos” (listasytablas)numéricas.
Capítulo 8. Registros (estructuras y uniones). Sedescribenconceptosbásicosdeestructuras, unionesyenumeraciones:
declaración, definición, iniciación, usoytamaño.Elconceptodetipodedatodef inidoporelusuario( typedef)ydecampos
debit, seexplicantambiénenestecapítulo.
Capítulo 9. Cadenas. Sedescribeelconceptodecadena(string)asícomolasrelacionesentrepunteros, arrays ycadenas
enC++.Seintroducenconceptosbásicosdemanipulacióndecadenasjuntoconoperacionesbásicastalescomolongitud,concatenación, comparación, conversiónybúsquedadecaracteresycadenas.Sedescribenlasfuncionesmásnotablesdelabibliotecastring.h.
Capítulo 10. Punteros (apuntadores). Presentaunadelascaracterísticasmáspotentesyef icientesdellenguajeC++, los
punteros.Sedescribeelconcepto, lospunterosNULLyv oidylosdiferentespunterosdecadena, comoargumentosdefunciones, punterosafuncionesypunterosaestructuras, juntoconlaaritméticadepunteros.
Capítulo 11. Gestión dinámica de la memoria. Sedescribelagestióndinámicadelamemoriaylosoperadoresasociados aestatarea: new y delete. Seproporcionanre glasdefuncionamientodeestosoperadoresyre glasparaasignaciónde
memoria.
Capítulo 12. Ordenación y búsqueda. Sedescribenenelcapítulométodosbásicosdebúsquedadeinformación(secuencialybinaria)ydeordenacióndelistasyv ectores(burbuja, selección, inserciónyshell).
Capítulo 13. Clases y objetos. Losconceptosfundamentalesdelaprogramaciónorientadaaobjetosseestudianeneste
capítulo: clases, objetos, constructores, destructoresyclasescompuestas.
Capítulo 14. Herencia y polimorfismo. Laspropiedadesdeherenciaypolimorf ismoconstituyen, juntoconlasclases, la
espinadorsaldelaprogramaciónorientadaaobjetos.
Capítulo 15. Plantillas, excepciones y sobrecarga de operadores. Lapropiedaddegenericidadseimplementamediante
plantillas(templates). Lasexcepcionessonunmecanismomuypotenteparaprogramacióna vanzadaenC++yenotroslenguajes.Porúltimosedescribelapropiedadyaestudiadadesobrecar ga;enestecaso, lasobrecargadeoperadores.
Capítulo 16. Flujos y archivos. Lasestructurasdedatosbásicasdealmacenamientoendispositi vosexternos, flujosyarchivos, sonobjetodeestudioenestecapítulo.Lasclases istream, ostream, ifstream y ofstream, seanalizanydescriben
prácticamente.
Capítulo 17. Listas enlazadas. Unalistaenlazadaesunaestructuradedatosquemantieneunacoleccióndeelementos,
peroelnúmerodeellosnoseconoceporanticipadoov aríaenunrangoamplio.Lalistaenlazadasecomponedeelementos
quecontienenunvaloryunpuntero.Elcapítulodescribelosfundamentosteóricos, tiposdelistasyoperacionesquesepuedenrealizarenlalistaenlazada.
Capítulo 18. Pilas y colas. Lasestructurasdedatosmásutilizadasdesdeelpuntodevistadeabstraccióneimplementaciónsonlaspilasycolas.Suestructura, diseñoymanipulacióndelosalgoritmosbásicossee xplicanenelcapítulo.
Capítulo 19. Recursividad. Lanaturalezadelarecursividadysucomparaciónconlaiteraciónsemuestranenelcapítulo.
Estapropiedadesunadelasmáspotentese xistentesenprogramación.Sucomprensiónyb uenusoesmuyimportantepara
cualquierprogramador.
Capítulo 20 Árboles. Lasestructurasdedatosnolinealesydinámicassonmuyutilizadasenprogramación.Losárboles
sonunadelasestructurasmásconocidasenalgoritmiayenprogramaciónyaquesonlabaseparalastécnicasdeprogramaciónavanzada.
PRÓLOGO
XVIII
APÉNDICES EN LA WEB
Enelsitioof icialdellibro, www.mhe.es/joyanes, podráencontrarlossiguientesapéndicesquepodrádescar garlibremente:
A.
B.
C.
D.
E.
F.
G.
H.
I.
J.
C++frentea(versus)C
GuíadesintaxisdeANSI/ISOC++
Operadoresyexpresiones(prioridad)
CódigodecaracteresASCII
PalabrasreservadasANSI/ISOC++
BibliotecaestándardefuncionesANSI/ISOC++
BibliotecaestándardeclasesANSI/ISOC++
Glosario
Recursos(Libros/Revistas/Tutoriales)deprogramaciónenlaWeb
Bibliografía
AGRADECIMIENTOS
AnuestroeditorCarmeloSánchezqueconsussabiosconsejostécnicosyeditorialessiemprecontribuyealamejorediciónde
nuestroslibros.Nuestroagradecimientoeterno, amigoyeditor.TambiénycomosiempreatodosnuestroscompañerosdelDepartamentodeLenguajesySistemasInformáticoseIngenieríadeSoftwaredelaFacultaddeInformáticaydelaEscuelaUniversitariadeInformáticadelaUniversidadPontificiadeSalamancaenelcampusdeMadridqueenestaocasiónycomosiemprenosaniman, aconsejanyasesoranenladistrib ucióndelostemasynosdansusopinionesparamejoradenuestrasobras.
Graciascolegasyamigos.
Naturalmenteanuestroslectores, razóndeserdenuestrolibro.Conf iamosnodefraudarlaconf ianzadepositadaenesta
obrayaspiramosaquesuprogresiónenelaprendizajedelaprogramaciónenC++seatodolorápidayef icientequedeseamos.Asímismodeseamosdestacardemodomuyespecial, atodosnuestroslectores, profesores, maestrosyalumnosdeLatinoamérica, queutilizannuestroslibrosynosayudanconsuscomentarioscontinuosparamejorarcadaunadenuestrasobras
yediciones.Porúltimo, unagradecimientoespecialatodoslosprofesoresymaestrosquehanutilizadonuestraobra ProgramaciónenC++;muchosnoshabéisanimadoaescribirestenuevolibrodemodocomplementarioyquesirvieratantodemodo
independientecomounidoallibrocitadoentalleresyprácticasdeprogramación.Nuestroagradecimientomássinceroatodosynuestradisponibilidadtotal, siasíloconsideranoportuno.
EnCarchelejo(Jaén)yenMadrid, marzode2006.
LOS AUTORES
CAPÍTULO 1
Programación orientada
a objetos versus programación
estructurada: C++ y algoritmos
Introducción
Elaprendizajedelaprogramaciónrequiereelconocimientodetécnicasymetodologíasde programaciónestructurada.Aunqueafinalesdelsiglo XX y, sobretodoenestesiglo XXI, laprogramaciónorientadaaobjetos sehaconvertidoenlatecnologíadesoftwaremásutilizada;elconocimientoprofundodealgoritmosyestructurasdedatos, enmuchoscasosconelenfoqueestructurado, facultaráallectoryfuturoprogramadorlosfundamentostécnicosnecesariosparaconvertirseenunbrillante
programadordeC++, engeneral, yprogramadororientadoaobjetos, enparticular.
1.1. Concepto de algoritmo
Unalgoritmo esunasecuenciafinitadeinstrucciones, reglasopasosquedescribendemodoprecisolasoperacionesqueuna
computadoradeberealizarparaejecutarunatareadeterminadaenuntiempof inito[Knuth68] 1.Enlapráctica, unalgoritmo
esunmétodopararesolverproblemasmediantelospasosoetapassiguientes:
1. Diseñodelalgoritmo quedescribelasecuenciaordenadadepasos—sinambigüedades—conduncentesalasolución
deunproblemadado( Análisisdelproblemaydesarrollodelalgoritmo).
2. Expresarelalgoritmocomoun programa enunlenguajedeprogramaciónadecuado.( Fasedecodificación).
3. Ejecuciónyvalidación delprogramaporlacomputadora.
Parallegaralarealizacióndeunprogramaesnecesarioeldiseñopreviodeunalgoritmoindicandocómohaceelalgoritmolatareasolicitada, yesosetraduceenlaconstruccióndeunalgoritmo.Elresultadof inaldeldiseñoesunasoluciónque
debeserfácildetraduciraestructurasdedatosyestructurasdecontroldeunlenguajedeprogramaciónespecíf ico.
Lasdosherramientasmáscomúnmenteutilizadasparadiseñaralgoritmosson: diagramasdeflujo ypseudocódigos.
• Diagrama de flujo (flowchart). Representacióngráficadeunalgoritmo.
• Pseudocódigo. Lenguajedeespecificacióndealgoritmos, mediantepalabrassimilaresalinglésoespañol.
1
DonaldE.Knuth(1968): TheartofComputerProgramming, vol.1, 1.ªed., 1968;2.ªed.1997, AddisonWesley.Knuth, esconsideradounode
lospadresdelaalgoritmiaydelaprogramación.Sutrilogíasobre“Programacióndecomputadoras” esreferenciaobligadaentod oelmundodocente
einvestigadordeInformáticayComputación.
1
2
CAPÍTULO 1 Programación orientada a objetos versus programación...
Elalgoritmo eslaespecificaciónconcisadelmétodopararesolverunproblemaconindicacióndelasaccionesarealizar.
Unalgoritmo esunconjuntof initodere glasquedanunasecuenciadeoperacionespararesolv erundeterminadoproblema.
Es, portanto, unmétodopararesolverunproblemaquetieneengeneralunaentradayunasalida.Lascaracterísticasfundamentalesquedebecumplirtodoalgoritmoson:
• Unalgoritmodebeser preciso eindicarelordenderealizacióndecadapaso.
• Unalgoritmodebeestarbiendefinido.Sisesigueunalgoritmodosveces, sedebeobtenerelmismoresultadocadavez.
• Unalgoritmodebeser finito.Sisesigueunalgoritmo, sedebeterminarenalgúnmomento;osea, debetenerunnúmerofinitodepasos.
Ladefinicióndeunalgoritmodebedescribirtrespartes: Entrada, Proceso ySalida.
EJEMPLO 1.1. Sedeseadiseñarunalgoritmopar aconocersiunnúmeroesprimoono.
Unnúmeroesprimosisólopuededi vidirseporsímismoyporlaunidad(esdecir , notienemásdivisoresqueélmismoylaunidad).Porejemplo: 9, 8, 6, 4, 12, 16, 20, etc., nosonprimos, yaquesondivisiblespornúmerosdistintosa
ellosmismosyalaunidad. Así, 9esdivisiblepor3, 8loespor2, etc.Elalgoritmoderesolucióndelproblemapasa
pordividirsucesivamenteelnúmeropor2, 3, 4..., etc.
Entrada: dato n entero positivo
Salida: es o no primo.
Preceso:
1. Inicio.
2. Poner x igual a 2 (x = 2, x variable que representa a los divisores del número que se
busca n).
3. Dividir n por x (n/x).
4. Si el resultado de n/x es entero, entonces n es un número primo y bifurcar al punto 7; en
caso contrario, continuar el proceso.
5. Suma 1 a x (x ← x + 1).
6. Si x es igual a n, entonces n es un número primo; en caso contrario, bifurcar al punto 3.
7. Fin.
Elalgoritmoanteriorescritoenpseudocódigoes:
algoritmo primo
1. inicio
variables
entero: n, x:
lógico: primo;
2. leer(n);
x←2;
primo←verdadero;
3. mientras primo y (x < n) hacer
4.
si n mod x != 0 entonces
5.
x← x+1
sino
primo ←faslso
fin si
fin mientras
si (primo) entonces
escribe('es primo')
sino
escribe('no es primo')
fin si
7. fin
CAPÍTULO 1 Programación orientada a objetos versus programación...
3
1.2. Programación estructurada
Laprogramaciónestructuradaconsisteenescribirunprogramadeacuerdoconunasre glasyunconjuntodetécnicas.Lasreglasson: elprogramatieneundiseñomodular , losmódulossondiseñadosdescendentemente, cadamódulodeprogramase
codificausandotresestructurasdecontrol( secuencia, selección eiteración);eselconjuntodetécnicasquehandeincorporar: recursosabstractos;diseñodescendenteyestructurasbásicasdecontrol.
Descomponerunprogramaentérminosde recursosabstractos consisteendescomponeraccionescomplejasentérminos
deaccionesmássimplescapacesdeserejecutadasenunacomputadora.
Eldiseñodescendente seencargaderesolverunproblemarealizandounadescomposiciónenotrosmássencillosmediante
módulosjerárquicos. Elresultadodeestajerarquíademódulosesquecadamóduloserefinaporlosdenivelmásbajoqueresuelvenproblemasmáspequeñosycontienenmásdetallessobrelosmismos.
Lasestructurasbásicasdecontr ol sirvenparaespecificarelordenenqueseejecutaránlasdistintasinstruccionesdeun
algoritmo.Esteordendeejecucióndeterminael flujodecontrol delprograma.
Laprogramaciónestructuradasignifica:
• Elprogramacompletotieneundiseñomodular.
• Losmódulossediseñanconmetodologíadescendente(puedehacersetambiénascendente).
• Cadamódulosecodif icautilizandolastresestructurasdecontrolbásicas: secuenciales, selectivasyrepetiti vas
(ausenciatotaldesentencias ir → a (goto)).
• Estructuraciónymodularidad sonconceptoscomplementarios(sesolapan).
EJEMPLO 1.2. Calcularlamediadeunaseriedenúmerospositivos, suponiendoquelosdatosseleendesdeunterminal.Unvalordecero—comoentrada—indicaráquesehaalcanzadoelf inaldelaseriedenúmerospositivos.
Elprimerpasoadareneldesarrollodelalgoritmoesdescomponerelproblemaenunaseriedepasossecuenciales.
Paracalcularunamediasenecesitasumarycontarlosvalores.Porconsiguiente, elalgoritmoenformadescriptivasería:
inicio
1. Inicializar contador de números C y variable suma S a cero (S←0, C←1).
2. Leer un número en la variable N (leer(N))
3. Si el número leído es cero: (si (N =0) entonces)
3.1. Si se ha leído algún número (Si C>0)
• calcular la media; (media← S/C)
• imprimir la media; (Escribe(media)
3.2. si no se ha leído ningún número (Si C=0))
•
escribir no hay datos.
3.3. fin del proceso.
4. Si el numero leído no es cero : (Si (N <> 0) entonces
• calcular la suma; (S← S+N)
• incrementar en uno el contador de números; (C←C+1)
• ir al paso 2.
Fin
algoritmoescritoenpseudocódigo:
algoritmo media
inicio
variables
entero: n, c, s;
real: media;
C←0;
S←0;
CAPÍTULO 1 Programación orientada a objetos versus programación...
4
repetir
leer(N)
Si N <> 0 Entonces
S←S+N;
C←C+1;
fin si
hasta N=0
si C>0 entonces
media ← S/C
escribe(media)
sino
escribe('no datos')
fin si
fin
Unprogramaenunlenguajeprocedimentalesunconjuntodeinstruccionesosentencias.Lenguajesdeprogramación
comoC, Pascal, FORTRAN, yotrossimilares, seconocencomo lenguajesprocedimentales(porprocedimientos).Esdecir ,
cadasentenciaoinstrucciónindicaalcompiladorquerealicealgunatarea:obtenerunaentrada, producirunasalida, sumartres
números, dividirporcinco, etc.Enelcasodepequeñosprogramas, estosprincipiosdeor ganización(denominadosparadigma)sedemuestraneficientes.Elprogramadorsólohadecrearestalistadeinstruccionesenunlenguajedeprogramación,compilarenlacomputadorayésta, asuvez, ejecutalasinstrucciones.
Cuandolosprogramassevuelv enmásgrandes, lalistadeinstruccionesaumentaconsiderablemente, demodotalqueel
programadortienemuchasdificultadesparacontrolaresegrannúmerodeinstrucciones.P araresolveresteproblemalosprogramassedescomponenenunidadesmáspequeñasqueadoptanelnombredefunciones(procedimientos, subprogramasosubrutinasenotroslenguajesdeprogramación).Deestemodounprogramaorientadoaprocedimientossedi videenfunciones,
cadaunadelascualestieneunpropósitobiendef inidoyresuelveunatareaconcreta, ysediseñaunainterf azclaramentedefinida(elprototipoocabeceradelafunción)parasucomunicaciónconotrasfunciones.
Conelpasodelosaños, laideaderomperunprogramaenfuncionesfueevolucionandoysellegóalagrupamientodelas
funcionesenotrasunidadesmásgrandesllamadasmódulos (normalmente, enelcasodeC++, denominadasarchivos oficheros);sinembargo, elprincipioseguíasiendoelmismo: agruparcomponentesqueejecutanlistasdeinstrucciones(sentencias).
Existenvariasrazonesdeladebilidaddelosprogramasestructuradospararesolv erproblemascomplejos. Talvezlasdosrazonesmásevidentessonéstas.Primera, lasfuncionestienenaccesoilimitadoalosdatosglobales;se gundo, lasfuncionesinconexasydatos, fundamentosdelparadigmaprocedimentalproporcionanunmodelopobredelmundoreal.Laprogramación
orientada a objetos sedesarrollóparatratardepaliardiversaslimitacionesqueseencontrabanenanterioresenfoquesdeprogramación.
1.3. El paradigma de orientación a objetos
Laprogramaciónorientadaaobjetosaportaunnue voenfoquealosretosqueseplanteanenlaprogramaciónestructurada
cuandolosproblemasaresolv ersoncomplejos.Alcontrarioquelaprogramaciónprocedimentalqueenf atizaenlosalgoritmos, laPOOenfatizaenlosdatos.Enlugardeintentarajustarunproblemaalenfoqueprocedimentaldeunlenguaje, POOintentaajustarellenguajealproblema.Laideaesdiseñarformatosdedatosquesecorrespondanconlascaracterísticasesencialesdeunproblema.Loslenguajesorientadoscombinanenunaúnicaunidadomódulo, tantolosdatoscomolasfunciones
queoperansobreesosdatos. Talunidadsellama objeto.Sisedeseamodificarlosdatosdeunobjeto, hayquerealizarlomediantelasfuncionesmiembrodelobjeto.Ningunaotrafunciónpuedeaccederalosdatos.Estosimplificalaescritura, depuraciónymantenimientodelprograma.
Enelparadigmaorientadoaobjetos, elprogramaseor ganizacomounconjuntof initodeobjetosquecontienen
datosyoperaciones(funcionesmiembroenC++)quellamanaesosdatosyquesecomunicanentresímediante mensajes.
CAPÍTULO 1 Programación orientada a objetos versus programación...
5
Objeto
Datos
Interior
Interfaz
Funciones
Exterior
Figura 1.1. Diagrama de un objeto
Cuandosetrataderesolverunproblemaconorientaciónaobjetos, dichoproblemanosedescomponeenfuncionescomo
enprogramaciónestructuradatradicional, casodeC, sinoenobjetos.Elpensarentérminosdeobjetostieneunagranv entaja:
seasocianlosobjetosdelproblemaalosobjetosdelmundoreal.
1.3.1. PROPIEDADES FUNDAMENTALES DE LA ORIENTACIÓN A OBJETOS
Existendiversascaracterísticasligadasalaorientaciónaobjetos. Todaslaspropiedadesquesesuelenconsiderar , nosonexclusivasdeesteparadigma, yaquepuedene xistirenotrosparadigmas, peroensuconjuntodef inenclaramenteloslenguajes
orientadosaobjetos.Estaspropiedadesson:
•
•
•
•
•
Abstracción (tipos abstractos de datos y clases).
Encapsulado de datos.
Ocultación de datos.
Herencia.
Polimorfismo.
C++soportatodaslascaracterísticasanterioresquedef inenlaorientaciónaobjetos.
1.3.2. ABSTRACCIÓN
Laabstracción eslapropiedaddelosobjetosqueconsisteentenerencuentasólolosaspectosmásimportantesdesdeunpuntodevistadeterminadoynotenerencuentalosrestantesaspectos.Duranteelprocesodeabstracciónescuandosedecidequé
característicasycomportamientodebetenerelmodelo.Unmediodereducirlacomplejidadeslaabstracción.Lascaracterísticasylosprocesossereducenalaspropiedadesesenciales, sonresumidasocombinadasentresí.Deestemodo, lascaracterísticascomplejassehacenmásmanejables.
Enestructurasoregistros, laspropiedadesindividualesdelosobjetossepuedenalmacenarenlosmiembros.P aralosobjetosesdeinterésnosólo cómoestánorganizadossinotambiénquésepuedehacerconellos;esdecir , lasoperacionesdeun
objetosontambiénimportantes.Elprimerconceptoenelmundodelaorientaciónaobjetosnacióconlostiposabstractosde
datos(TAD).Un tipo abstracto de datos describenosólolosatrib utosdeunobjeto, sinotambiénsucomportamiento(las
operaciones).Estopuedeincluirtambiénunadescripcióndelosestadosquepuedealcanzarunobjeto.
EJEMPLO 1.3. Diferentesmodelosdeabstraccióndeltérminocoche(carro).
• Uncoche (carro) eslacombinación(ocomposición)dediferentespartes,talescomomotor, carrocería, cuatroruedas, cincopuertas, etc.
• Un coche (carro) esunconceptocomúnparadiferentestiposdecoches.Puedenclasif icarse, porelnombredel
fabricante(Audi, BMW, SEAT, Toyota, Chrisler...), porsucategoría(turismo, deportivo, todoterreno...), porelcarburantequeutilizan(gasolina, gasoil, gas, híbrido...).
Laabstracción coche seutilizarásiemprequelamarca, lacategoríaoelcarb urantenoseansignif icativos.Así, uncarro
(coche)seutilizaráparatransportarpersonasoirdeCarchelejoaCazorla, odeParadinasaMazarambroz.
CAPÍTULO 1 Programación orientada a objetos versus programación...
6
1.3.3. ENCAPSULACIÓN Y OCULTACIÓN DE DATOS
Elencapsulado oencapsulacióndedatos eselprocesodeagrupardatosyoperacionesrelacionadasbajolamismaunidadde
programación.Enelcasodequelosobjetosposeanlasmismascaracterísticasycomportamientoseagrupanenclases(unidadesomódulosdeprogramaciónqueencapsulandatosyoperaciones).
Laocultacióndedatospermitesepararelaspectodeuncomponente, definidoporsu interfazconelexterior, desusdetalles
internosdeimplementación.Lostérminosocultacióndelainformación(informationhiding) yencapsulacióndedatos(dataencapsulation) sesuelenutilizarcomosinónimos, peronosiempreesasíymuyalcontrariosontérminossimilaresperodistintos.
EnC++noeslomismo, yaquelosdatosinternosestánprotegidosdelexteriorynosepuedenaccederaellosmásquedesdesu
propiointeriory, portanto, noestánocultos.Elaccesoalobjetoestárestringidosóloatra vésdeunainterfazbiendefinida.
1.3.4. GENERALIZACIÓN Y ESPECIALIZACIÓN
Lageneralización eslapropiedadquepermitecompartirinformaciónentredosentidadesevitandolaredundancia.Enelcomportamientodeobjetose xistenconfrecuenciapropiedadesquesoncomunesendiferentesobjetosyestapropiedadsedenominageneralización.
Porejemplo, máquinaslavadoras, frigoríficos, hornosdemicroondas, tostadoras, lavavajillas, etc., sontodoselectrodomésticos(aparatosdelhogar).Enelmundodelaorientaciónaobjetos, cadaunodeestosaparatosesuna subclase delaclase Electrodoméstico yasuv ez Electrodoméstico esuna superclase detodaslasotrasclases (máquinas lavadoras,
frigoríficos, hornos de microondas, tostadoras, lavavajillas...).Elprocesoinversodelageneralizaciónpor
elcualsedefinennuevasclasesapartirdeotrasyae xistentessedenominaespecialización.
Enorientaciónaobjetos, elmecanismoqueimplementalapropiedaddegeneralizaciónsedenomina herencia. Laherenciapermitedefinirnuevasclasesapartirdeotrasclasesyaexistentes, demodoquepresentanlasmismascaracterísticasycomportamientodeéstas, asícomootrasadicionales.
Clase base
Característica A
Característica B
Característica A
Característica A
Característica A
Característica B
Característica B
Característica B
Característica X
Característica Y
Característica W
Característica Z
Clase derivada
Figura 1.2. Jerarquía de clases.
Unaclasehereda suscaracterísticas(datosyfunciones)deotraclase.
1.3.5. POLIMORFISMO
Lapropiedadde polimorfismo esaquellaenqueunaoperacióntieneelmismonombreendiferentesclases, peroseejecuta
dediferentesformasencadaclase. Así, porejemplo, laoperación abrir sepuededarendiferentesclases: abrirunapuerta,
abrirunaventana, abrirunperiódico, abrirunarchivo, abrirunacuentacorrienteenunbanco, abrirunlibro, etc.Encadacaso
seejecutaunaoperacióndiferenteaunquetieneelmismonombreentodosellos “abrir”.Elpolimorfismoeslapropiedadde
unaoperacióndeserinterpretadasóloporelobjetoalquepertenece.
CAPÍTULO 1 Programación orientada a objetos versus programación...
7
1.4. C++ Como lenguaje de programación orientada a objetos
C++esunae xtensión(ampliación)deCconcaracterísticasmáspotentes.EstrictamentehablandoesunsuperconjuntodeC.
LoselementosmásimportantesañadidosaCporC++son: clases, objetosyprogramaciónorientadaaobjetos(C++fuellamadooriginalmente“Cconclases”).
EnC++, unobjeto esunelementoindi vidualconsupropiaidentidad;porejemplo, unlibro, unautomóvil...Una clase
puededescribirlaspropiedadesgenéricasdeunejecuti vodeunaempresa(nombre, título, salario, cargo...)mientrasqueun
objetorepresentaráaunejecutivoespecífico(LuisMackoy, LucasSoblechero).
Engeneral, unaclasedefinequédatosseutilizanpararepresentarunobjetoylasoperacionesquesepuedenejecutarsobreesosdatos.Enelsentidoestrictodeprogramación, unaclaseesuntipodedatos.Diferentesv ariablessepuedencrearde
estetipo.Enprogramaciónorientadaaobjetos, estasvariablessellaman instancias.Lasinstanciasson, porconsiguiente, la
realizacióndelosobjetosdescritosenunaclase.Estasinstanciasconstandedatosoatrib utosdescritosenlaclaseysepue denmanipularconlasoperacionesdef inidasdentrodeellas.
Unaclase esunadescripcióngeneraldeunconjuntodeobjetossimilares.Pordef inicióntodoslosobjetosdeunaclase
compartenlosmismosatrib utos(datos)ylasmismasoperaciones( métodos).Unaclaseencapsulalasabstraccionesdedatos
yoperacionesnecesariasparadescribirunaentidaduobjetodelmundoreal.
Eldiseñodeclasesf iablesyútilespuedeserunatareadifícil. Afortunadamenteloslenguajesdeprogramaciónorientada
aobjetosfacilitanlatareayaqueincorporanclasesexistentesensupropiaprogramación.UnodelosbeneficiosrealesdeC++
esquepermitelareutilizaciónyadaptacióndecódigose xistentesyyabienprobadosydepurados.
Eneldiseñodeprogramasorientadosaobjetosserealizaenprimerlugareldiseñodelasclasesquerepresentanconprecisiónaquellascosasquetrataelprograma;porejemplo, unprogramadedibujo, puededefinirclasesquerepresentanrectángulos, líneas, pinceles, colores, etc.Lasdefinicionesdeclases, incluyenunadescripcióndeoperacionespermisiblesparacada
clase, talescomodesplazamientodeuncírculoorotacióndeunalínea. Acontinuaciónseprosigueeldiseñodeunprograma
utilizandoobjetosdelasclases.
Lostérminos objetoeinstanciaseutilizanfrecuentementecomosinónimos(especialmenteenC++).Siunav ariablede
tipo Carro sedeclara, secreaunobjeto Carro (unainstanciadelaclase Carro).Lasoperacionesdefinidasenlosobjetosse
llamanmétodos.Cadaoperaciónllamadaporunobjetoseinterpretacomoun mensaje alobjeto, queutilizaunmétodoespecíficoparaprocesarlaoperación
Desdeelpuntodevistadeimplementaciónunobjeto esunaentidadqueposeeunconjuntodedatos yunconjuntodeoperaciones(funciones ométodos).Elestado deunobjetovienedeterminadoporlosv aloresquetomansusdatos, cuyosvalores
puedentenerlasrestriccionesimpuestasenladefinicióndelproblema.Losdatos sedenominantambiénatributos ycomponen
laestructuradelobjetoylas operaciones —tambiénllamadasmétodos—representanlosserviciosqueproporcionaelobjeto.
Nuestroobjetivoesayudarleaescribirprogramasorientadoaobjetostanprontocomoseaposible.Sinembar go, comoya
sehaobservado, muchascaracterísticasdeC++sehanheredadodeC,demodoque, aunquelaestructuraglobaldeunprograma
puedaserorientadoobjetos, consideramosqueustednecesitaconocimientosprofundosdel“viejoestilo procedimental”.Por
ello, loscapítulosdelaprimerapartedellibrolev anintroduciendolentaypausadamenteenlaspotentespropiedadesorientadasaobjetosdelasúltimaspartes, alobjetodeconseguiralaterminacióndellibroeldominiodelaprogramaciónenC++.
NOTA: Compiladores y compilación de programas en C++
ExistennumerososcompiladoresdeC++enelmercado.Desdeedicionesgratuitasy descargablesatravésdeInternethasta
profesionales, concostesdiferentes, comercializadospordiferentesfabricantes.Esdifícildarunarecomendaciónallectorporquecasitodosellossonb uenoscompiladores, muchosdeellosconEntornosInte gradosdeDesarrollo (EID).Siustedesestudiante, talvezlamejordecisiónseautilizarelcompiladorquelehayapropuestosuprofesoryqueutiliceensuUniversidad,
InstitutoTecnológicoocualquierotroCentrodeFormación, dondeestudie.Siustedesunlectorautodidactayestáaprendiendo
porsucuentaexistenvariasversionesgratuitasquepuededescargardesdeInternet.Algunosdelosmásreconocidosson: DevC++ deBloodshed quecumplefielmenteelestándarANSI/ISOC++(utilizadoporlosautoresdellibroparaeditarycompilartodoslosprogramasincluidosenelmismo)yquecorrebajoentornos Windows;GCC deGNUquecorrebajolosentornosLinuxyUnix.Existenmuchosotroscompiladoresgratuitosporloquetienedondeelegir.Talvezunconsejomás: procure
queseacompatibleconelestándarANSI/ISOC++.
BjarneStroustrup(creadorein ventordeC++)ensupáginaof icial 2 hapublicadoel9defebrerode2006, “unalistain2
http://public.research.att.com/˜bs/compilers.html.Elartículo“AnincompletelistofC++compilers” losuelemodificarStroustrupyenlacabeceraindicalafechademodif icación.Ennuestrocaso, consultamosdichapáginamientrasescribíamoselprólogoenlaprimera quincenadeMarzo, ylafecha
incluidaeslade9defebrerode2006.
CAPÍTULO 1 Programación orientada a objetos versus programación...
8
completadecompilador esdeC++”, quelerecomiendoleayvisite.Porsuinterésincluimos, acontinuación, unbreveextractodesulistarecomendada:
Compiladoresgratuitos
Compiladorescomerciales
AppleC++
BorlandC++
Dev-C++deBloodshed
GNUIntelC++paraLinux
MicrosoftVisualC++Toolkit2003
SunStudio...
BorlandC++
CompaqC++
HPC++
IBMC++
IntelC++paraWindows, Linuxyalgunossistemasempotrados
MicrosoftC++
StroustruprecomiendaunsitiodecompiladoresgratuitosdeCyC++( Compilers.net).
EJERCICIOS
1.1.
1.2.
1.3.
1.4.
1.5.
Escribirunalgoritmoqueleatresnúmerosysielprimeroespositivocalculeelproductodelostresnúmeros, yenotrocaso
calculelasuma.
Escribirunalgoritmoqueleaelr adiodeuncírculo, ycalculesuperímetroysuárea.
Escribirunalgoritmoqueleacuatronúmerosenterosdeltecladoycalculesusuma.
Escribirunalgoritmoqueleaunnúmer oenteropositivon, ysumelosnprimerosnúmeronaturales.
Escribirunalgoritmoqueleaunnúmer on>0deltecladoysumelaseriesiguiente:
n
ai
Σ
i=1
1.6.
si
ai =
i*i
52
si
si
iesimpar
y
iespar
n=5
Definirunajerarquíadeclasespara: animal, insecto, mamíferos, pájaros, personahombreymujer.Realizarundefinición
enpseudocódigodelasclases.
SOLUCIÓN DE LOS EJERCICIOS
1.1.
SeusantresvariablesenterasNumero1, Numero2, Numero3, enlasqueseleenlosdatos, yotrasdosvariables ProducySuma enlasquesecalculaobienelpr oductoobienlasuma.
to
Entrada Numero1,Numero2 y Numero 3
Salida la suma o el producto
incio
1 leer los tres número Numero1, Numero2, Numero3
2 si el Numero1 es positivo
calcular el producto de los tres numeros
escribir el producto
3 si el Numero1 es no positivo
calcular la suma de los tres número
escribir la suma
fin
Elalgoritmoenpseudocódigoes:
algoritmo
variables
Producto_Suma
CAPÍTULO 1 Programación orientada a objetos versus programación...
9
entero: Numero1, Numero2, Numero3, Producto, Suma
inicio
leer(Numero1, Numero2, Numero3)
si (Numero1 > 0) entonces
Producto ← Numero1* Numero2 * Numero3
Escribe('El producto de los números es', Producto)
sino
Suma ← Numero1+ Numero2 + Numero3
Escribe('La suma de los números es', Suma)
fin si
fin
1.2.
Sedeclar anlasvariablesr ealesr ,
longitudyárea, asícomolaconstantepi
constantespi = 3.14
variables
realr, longitud, área
Diagramadeflujo
inicio
Leer(r)
No
Sí
r>0
Longitud ← 2*pi*r
Area ← pi*r*r
Escribe(’error’)
Escribe(’perimetro=’, longitud, ‘área=’,area)
fin
1.3.
Unbucleesunsegmentodeprogramacuyas
instruccionesser epitenunnúmer odeterminadodeveceshastaquesecumpleunadeterminadacondición. Tienelassiguientes
partes: entrada, salida, cuerpodelb ucley
decisiónqueformapartedelcuerpodelb ucleobiendelaentr adasalida.Elalgoritmo
sediseñaconunbucle, uncontadorenteroC,
unacumuladorenter o Suma yunavariable
numero paraleerlosdatos.
variables
entero Suma, C, numero
inicio
Bucle
Suma ← 0
C←0
Entrada de bucle
Decisión
C<4
No
Sí
Cuerpo de bucle
Leer(numero)
Salida de bucle
Suma ← Suma + numero
C←C+1
Escribe(suma)
fin
CAPÍTULO 1 Programación orientada a objetos versus programación...
10
algoritmo suma_4
inicio
variables
entero: Suma, C, numero;
C← 0;
suma← 0;
mientras C< 4 hacer
leer(Numero)
Suma← Suma + numero;
C←C+1;
fin mientras
escribe(suma)
fin
1.4.
Inicialmenteseaseguralalecturadelnúmeronatural n positivo.Medianteuncontador C secuentanlosnúmerosnaturalesquesesuman, yenelacumulador Suma sevanobteniendolassumasparciales.Ademásdeldiagramadeflujoserealizaunseguimientoparaelcasodelaentr adan= 5
variables Entero: n, Suma, C
inicio
Leer(r)
No
n>0
C es un contador; Suma es acumulador
Sí
Suma ← 0
C←0
Inicializaciones del contador y acumulador
Entrada de bucle
Decisión
No
C<n
Seguimiento
Salida de bucle
Cuerpo de bucle
C se incrementa
Sí
C←C+1
Suma ← Suma + C
Suma se modifica no constante
Escribe(suma)
fin
paso
n
C
Suma
0
5
0
0
1
5
1
1
2
5
2
3
3
5
3
6
4
5
4
10
5
5
5
15
CAPÍTULO 1 Programación orientada a objetos versus programación...
11
algoritmo suma_n_naturales
inicio
variables
entero: Suma, C, n;
repetir
Leer(n)
hasta n>0
C ← 0;
suma← 0;
mientras C< n Hacer
C←C + 1;
suma ← Suma + C;
fin mientras
escribe(Suma)
fin
1.5.
Laestructuradelalgoritmoesmuypar ecidaaladelejer cicioanterior, salvoqueahor aenlugardesumarelvalorde
unaconstantesesumaelvalordeunavariable .Seusauninterruptor sw quepuedetomarlosvalor esverdaderoofalso
yqueseencar gadedecidirsilasumaeselvalorde i*i oelvalorde 2.Observarqueenesteejer cicioelcontador i se
inicializaa 1 porloqueelincr ementode i serealizaalfinaldelcuerpodelb ucle, ylasalidadelb ucleserealizacuando i>n.
Pseudocódigo
algoritmo suma_serie
inicio
variables
entero: Suma, i, n;
logico sw;
repetir
Leer(n);
hasta n>0
i ← 1;
suma← 0;
Sw←falso
mientras i <= n Hacer
si (sw) Entonces
Suma ← Suma + 2;
sino
Suma ← Suma + i*i
fin si
i←i+1
sw ← no sw
fin mientras
escribe(Suma)
fin
Seguimiento n=5
paso
n
sw
i
suma
0
5
F
1
0
1
5
V
2
1
2
5
F
3
3
3
5
V
4
13
4
5
F
5
15
5
5
V
6
40
CAPÍTULO 1 Programación orientada a objetos versus programación...
12
Diagramadeflujo
inicio
Leer(r)
No
n>0
i es un contador; Suma es acumulador; sw interruptor
Sí
Suma ← 0
i←1
sw ← F
Inicializaciones de contador acumulador interruptor
Entrada de bucle
Decisión
No
i <= n
No
Sí
sw
Suma se incrementa
Suma ← Suma + 2
Suma ← Suma + i * i
i se incrementa
sw cambia v--f
Salida de bucle
i ← i + 1; sw ← no sw
Escribe(suma)
fin
1.6.
Lasclasesdeobjetomamífero, pájaroeinsectosedefinencomosubclasesdeanimal;laclasedeobjetopersona, comouna
subclasedemamífero, yunhombreyunamujersonsubclasesdeper sona.
Animal
Incesto
Mamíferos
Pájaros
Persona
Hombre
Mujer
Lasdefinicionesdeclasesparaestajerarquíapuedetomarlasiguienteestructur a:
CAPÍTULO 1 Programación orientada a objetos versus programación...
13
clase criatura
atributos (propiedades)
string: tipo;
real: peso;
(...algun tipo de habitat...):habitat;
operaciones
crear()→ criatura;
predadores(criatura)→ fijar(criatura);
esperanza_vida(criatura) → entero;
...
fin criatura.
clase mamifero hereda criatura;
atributos (propiedades)
real: periodo_gestacion;
operaciones
...
fin mamifero.
clase persona hereda mamifero;
atributos (propiedades)
string: apellidos, nombre;
date: fecha_nacimiento;
pais: origen;
fin persona.
clase hombre hereda persona;
atributos (propiedades)
mujer: esposa;
...
operaciones
...
fin hombre.
clase mujer hereda persona;
propiedades
esposo: hombre;
string: nombre;
...
fin mujer.
EJERCICIOS PROPUESTOS
1.1.
1.2.
Diseñarunalgoritmoqueleaeimprimaunaseriedenúmerosdistintosdecero.Elalgoritmodebeterminarcon
unvalorceroquenosedebeimprimir.Visualizarelnúmerodevaloresleídos.
Diseñarunalgoritmoqueimprimaysumelaseriede
números4, 8, 12, 16,..., 400.
1.3.
Escribirunalgoritmoqueleacuatronúmerosyacontinuaciónimprimaelmayordeloscuatro.
1.4.
Diseñarunalgoritmoparacalcularlavelocidad(enm/s)
deloscorredoresdelacarrerade1.500metros.Laentrada(tiempodelcorredor)consistiráenparejasdenúmeros(minutos, segundos);porcadacorredor , elalgo-
CAPÍTULO 1 Programación orientada a objetos versus programación...
14
ritmodebeimprimireltiempoenminutosyse gundos
asícomolavelocidadmedia.Ejemplodeentradadedatos: (3,53)(3,40)(3,46)(3,52)(4,0)(0,0);elúltimopar
dedatosseutilizarácomof indeentradadedatos.
1.7.
Dibujarundiagramajerárquicodeobjetosquerepresentelaestructuradeuncoche(carro).
1.8.
Dibujardiagramasdeobjetosquerepresentenlajerarquíadeobjetosdelmodelo Figura geométrica.
1.5.
Escribirunalgoritmoqueencuentreelsalariosemanal
deuntrabajador , dadalatarif ahorariayelnúmerode
horastrabajadasdiariamente.
1.9.
Escribirunalgoritmoparadeterminarelmáximocomún
divisordedosnúmerosenteros(MCD)porelalgoritmo
deEuclides:
1.6.
Escribirunalgoritmoquecuenteelnúmerodeocurrenciasdecadaletraenunapalabraleídacomoentrada.Por
ejemplo, “Mortimer” contienedos“ m”, una“ o”, dos
“r”, una“y”, una“t” yuna“ e”.
• Dividirelmayordelosdosenterosporelmáspequeño.
• Acontinuación, dividireldivisorporelresto.
• Continuarelprocesodedividirelúltimodivisorporel
últimorestohastaqueladivisiónseaexacta.
• ElúltimodivisoreselMCD.
NOTA PRÁCTICA SOBRE COMPILACIÓN DE PROGRAMAS FUENTE CON EL COMPILADOR DEV C++
Y OTROS COMPILADORES COMPATIBLES ANSI/ISO C++
Todoslosprogramasdellibrohansidocompiladosyejecutadosenelcompiladorde
freeware (delibredistrib ución)
versión4.9.9.2.DevC++esuneditordemúltiplesv entanasintegradoconuncompiladordefáciluso
quepermitelacompilación, enlaceyejecucióndeprogramasCoC++.
Lassentencias system(“PAUSE”);y return EXIT_SUCCES;seincluyenpordefectoporelentorno Dev entodoslosprogramasescritosenC++.Ellibroincluyeambassentenciasenprácticamentetodosloscódigosdeprograma.Porcomodidad
paraellectorquecompilelosprogramassehandejadoestassentencias.Sinembar
go, siustednoutilizaelcompilador
Dev C++onodeseaqueensuslistadosaparezcanestassentencias, puedesustituirlasbienporotrasequi valentesobienquitarlasdosysustituirlaspor return 0, comorecomiendaStroustrupparaterminarsusprogramas.
system(“PAUSE”);detienelaejecucióndelprogramahastaquesepulsaunatecla.LasdossentenciassiguientesdeC++
producenelmismoefecto:
BloodShed DEV-C++ 3,
cout << “Presione ENTER para terminar”;
cint.get();
return EXIT_SUCCES;devuelveelestadodeterminacióncorrectadelprogramaalsistemaoperati vo.LasiguientesentenciadeC++estándar, produceelmismoefecto:
return 0;
Tabla 1.1. Dev C++ versus otros compiladores de C++ (en compilación)
Sustitución de sentencias
DEV C++
3
Otros compiladores de C++
system("PAUSE");
cout << "Presione ENTER para terminar";
cint.get();
return EXIT_SUCCES;
return 0;
http://www.bloodshed.net/
CAPÍTULO 2
Conceptos básicos
de los programas en C++
Introducción
Estecapítulocomienzaconunrepasodelosconceptosteóricosyprácticosrelati vosalaestructuradeunprogramaenC++
dadasugranimportanciaeneldesarrollodeaplicaciones;sedescribentambiénloselementosbásicosquecomponenunprograma;tiposdedatosenC++ycómosedeclaran;conceptodeconstantesysudeclaración;conceptoydeclaracióndev ariables;tiempodevidaoduracióndev ariables;operacionesbásicasdeentrada/salidayespaciosdenombres.
2.1. Estructura general de un programa en C++
UnprogramaenC++secomponedeunaomásfunciones, delascualesunadebeserobligatoriamente main( ).Unafunción
enC++esungrupodeinstruccionesquerealizanunaomásacciones.Unprogramacontieneunaseriededirectivas #include
quepermitenincluirenelmismo, archivosdecabeceraqueasuv ezcontienenfuncionesydatospredef inidosenellos.
EJEMPLO 2.1. EstructuradeunprogramaC++.
#include <iostream.h>
archivodecabeceraiostream.h(osimplemente, <iostrean>)
int main( )
{
...
}
int func1 ( )
{
...
}
int func2 ( )
{
...
}
cabeceradefunción
nombredelafunción
sentenciasdelafunción
UnprogramaC++puedeincluir: directivasdepreprocesador;declaracionesglobales;lafunción main( );funcionesdefinidasporelusuario;comentariosdelprograma.
15
CAPÍTULO 2 Conceptos básicos de los programas en C++
16
EJEMPLO 2.2. PrimerprogramaenC++.
#include <iostream>
using namespace std;
// Este programa visualiza Bienvenido a la programacion en C++
// Pronto se van a escribir programas en C++
int main()
{
cout << "Bienvenido a la programacion en C++\n";
cout << "Pronto se van a escribir programas en C++\n";
system("PAUSE");
//si no compila con Dev C++ sustituya esta línea
return EXIT_SUCCESS; //y la siguiente por la sentencia
}
//count << "Presione ENTER (INTRO) para terminar"; cin.get(); return 0
Ladirectiva#include <iostream> serefierealainclusióndelarchi voexternodenominado iostream.h enelquesedeclaranlasfuncionesydatosquecontieneiostream, entreotros, lainformaciónrelativaalobjeto cout. using namespace std
sirveparausarlasdeclaracionesestándardelespacionombrado(consola).Lasdoblesbarrasinclinadas (//) sirvenparaindicarcomentariosquesonignoradosporelcompilador .Lasentencia main( ) esobligatoriaencadaprogramaC++, eindicael
comienzodelprograma.Lasllaves{ ...} encierranelcuerpodelafunciónmain( ) ysonnecesariasentodoslosprogramasC++.
cout << "Bienvenido a la programacion en C++\n";
cout << "Pronto se van a escribir programas en C++\n";
Lassentenciasanterioresen víanlosmensajesalasalidaestándarmedianteelobjeto cout.Elsímbolo << sedenomina
operadordesalida uoperadordeinserción.Insertaelmensajeenelflujodesalida.Elsímbolo ‘\n’ eselsímbolode nueva
línea.Lasentencia system("PAUSE") obligaaquesevisualiceelresultadodelaejecuciónhastaquesepulseunatecla.La
sentenciareturn EXIT_SUCCESS, retornaelcontrolalsistemaoperativo, unavezterminadalaejecución.
2.1.1. DIRECTIVAS DEL PREPROCESADOR
Elpreprocesador enunprogramaC++constade directivas quesoninstruccionesalcompilador.Todaslasdirectivasdelpreprocesadorcomienzanconelsignode libro o“almohadilla” (#)ynoterminanenpuntoycoma, yaquenosoninstrucciones
dellenguajeC++.
Ladirectiva#include indicaalcompiladorqueleaelarchivofuente(archivocabeceraodeinclusión)quevieneacontinuacióndeellaysucontenidoloinserteenlaposicióndondeseencuentradichadirecti va.Estosarchivossedenominan archivosdecabecera oarchivosdeinclusión.Estasinstruccionessondelaforma #include<nombrearch.h> obien #include
"nombrearch.h".Elarchivodecabeceramásfrecuentees iostream.h, yaqueproporcionaalcompiladorC++lainformaciónnecesariasobrelasfuncionesdebiblioteca cin y cout, asícomootrasrutinasdebibliotecaquerealizanoperacionesde
entradaysalida.
Ladirectiva #define indicaalpreprocesadorquedef inaun item dedatosuoperaciónparaelprogramaC++.Porejemplo, ladirectiva#define TAM 10 sustituiráelvalor10 cadavezque TAM aparezcaenelprograma.
2.1.2. DECLARACIONES GLOBALES
Lasdeclaracionesglobales indicanalusuarioquelasconstantesovariablesasídeclaradassoncomunesatodaslasfunciones
desuprograma.Sesitúanantesdelafunción main( ).Lazonadedeclaracionesglobalespuedeincluirdeclaracionesdev ariablesademásdedeclaracionesdeprototiposdefunción.Unprototipoesunadeclaracióndeunafunciónyconsisteenuna
definicióndelafunciónsincuerpoyterminadoconunpuntoycoma.
EJEMPLO 2.3. Unaestructuramodeloqueincluyedeclaracionesglobalesyprototiposdefunciones.
#include <iostream.h>
//Definir macros
#define pi 3.14 15
//Declaraciones globales
CAPÍTULO 2 Conceptos básicos de los programas en C++
float
17
radio, altura;
//prototipo de función
float area_circulo( float radio);
float volumen_cilindor( float radio, float altura);
int main()
{
// ...
}
2.1.3. FUNCIÓN main( )
CadaprogramaC++tieneunafunción main( ) queeselpuntoinicialdeentradaalprograma.Suestructuraes:
int main( )
{
... bloque de sentencias
}
Ademásdelafunción main(), unprogramaC++constadeunacolecciónde subprogramas (enC++siempresonfunciones).TodaslassentenciasdeC++situadasenelcuerpodelafunciónmain( ), odecualquierotrafunción, debenterminaren
puntoycoma.
EJEMPLO 2.4. Programaquevisualizaelnombreyladirección.
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
cout << "Lucas Sánchez García\n";
cout << "Calle Marquillos de Mazarambroz, \n";
cout << "Mazarambroz, TOLEDO \n";
cout << "Castilla la Mancha, ESPAÑA\n";
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 2.5. Unejemplodealgoritmoqueincluyeunpr ototipodeunafunción, sucodificaciónyunallamada.
#include <cstdlib>
#include <iostream>
using namespace std;
//cstdl:b contiene funciones de entrada y salida
void prueba( );
int main(int argc, char *argv[])
{
prueba( );
system("PAUSE");
return EXIT_SUCCESS;
}
void prueba( )
{
cout << "Mis primeros pasos
}
en C++ \n";
CAPÍTULO 2 Conceptos básicos de los programas en C++
18
Laejecucióndelprogramaanteriores:
2.1.4. FUNCIONES DEFINIDAS POR EL USUARIO
C++proporcionafuncionespredefinidasquesedenominan funcionesdebiblioteca yotras definidasporelusuario. Lasfuncionesdebiblioteca requierenqueseincluyaelarchi vodondeestásudeclaracióntalescomo matht.h o stdio.h. Las funcionesdefinidasporelusuario seinvocanporsunombreylosparámetrosactualesopcionalesquetengan.Estosparámetros
actualesdebencoincidirennúmeroordenytipoconlosparámetrosformalesdeladeclaración.Despuésdequelafunciónsea
llamada, elcódigoasociadoconlafunciónseejecutay , acontinuación, seretornaalafunciónllamadora.EnC++, lasfuncionesdefinidasporelusuariorequierenuna declaración oprototipo enelprograma, queindicaalcompiladoreltipodela
función, elnombreporelqueseráinvocada, asícomoelnúmeroytipodesusargumentos.TodoslosprogramasC++constan
deunconjuntodefuncionesqueestáncontroladasporlafunción main( ).
EJEMPLO 2.6. Elalgoritmosiguienteincluyeunprototipodeunafunciónsuma, unprogramamain yconsentencias
yunallamadaalafunción, asícomolacodificacióndelafunción suma.
#include <cstdlib>
#include <iostream>
using namespace std;
float suma(float a, float b);
int main(int argc, char *argv[])
{
float numero, numero1, sumadenumeros;
numero = 2;
numero1 = 3;
sumadenumeros = suma(numero, numero1);
cout << " la suma de " << numero << " y " << numero1 << endl;
cout << " es : " << sumadenumeros << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
float suma(float a, float b)
{
return a + b;
}
Elresultadodeejecucióndelprogramaanteriores:
2.1.5. COMENTARIOS
Un comentario escualquierinformaciónañadidaasuarchi vofuenteeignoradaporelcompilador .EnCestándarloscomentarioscomienzanpor /* yterminanconlasecuencia */.EnC++sedef ineunalíneadecomentariocomenzandocon
una doblebarrainclinada( //).Todoloquevienedespuésdeladoblebarrainclinadaesuncomentarioyelcompiladorlo
ignora.
LosarchivosdecabeceraenC++tienennormalmenteunae xtensión.h ylosarchivosfuente, laextensión.cpp.
CAPÍTULO 2 Conceptos básicos de los programas en C++
19
EJEMPLO 2.7. ProgramaconcomentariosenCyC++.
#include <iostream.h>
using namespace std;
// archivo cabecera donde se encuentra cout
// usa la consola como dispositivo estándar
int main(int argc, char *argv[])
// número de argumentos y cuales
{
// este programa sólo muestra en pantalla el mensaje
//hola mundo cruel
cout << " Hola mundo cruel";
// visualiza el mensaje
system("PAUSE");
// archivo de ejecución retenido hasta pulsar tecla
return EXIT_SUCCESS;
// retorna el control al sistema operativo.
}
2.2. Los elementos de un programa en C++
LoselementosbásicosdeunprogramaC++son: identificadores;palabras reservadas;comentarios;signos de puntuación;
separadores yarchivos cabecera.
2.2.1. IDENTIFICADOR
Unidentificador esunasecuenciadecaracteres, letras, dígitosysubrayados(_)quecomienzasiempreporuncarácter .Las
letrasmayúsculasyminúsculassondiferentes.Puedentenercualquierlongitud, peroelcompiladorignoraapartirdel32.No
puedenserpalabrasreservadas.Sonejemplosdeidentificadoreslossiguientes:
nombre_Alumno
Fecha_Compra
Letra_indice
alfa
Dia
Habitacion24
Mayor
i
menor
j
2.2.2. PALABRAS RESERVADAS
C++comolamayoríadeloslenguajestienereserv adosalgunosidentificadoresconunsignificadoespecial, quesólopueden
serusadosconesecometido.Una palabrareservada, talcomo void (ausenciadetipo, otipogenérico), esunacaracterística
dellenguajeC++.Unapalabrareserv adanosepuedeutilizarcomonombredeidentif icador, objetoofunción.Sonpalabras
reservadasdeC++lassiguientes:
asm
auto
bool
break
case
catch
char
class
const
continue
default
delete
do
double
else
enum
explicit
extern
float
for
friend
goto
if
inline
int
longmutable
namespace
new
operator
private
protected
public
register
return
short
signed
sizeof
static
struct
switch
template
this
throw
try
typedef
union
unsigned
virtual
void
volatile
wchar_t
while
2.2.3. COMENTARIOS
Uncomentario, estiloC++comienzacon // yterminaalfinaldelalíneaenqueseencuentraelsímbolo.Uncomentario, estiloCysoportadostambiénporC++, encerradosentre /* y*/ puedeextendersealolargodevariaslíneas.
CAPÍTULO 2 Conceptos básicos de los programas en C++
20
2.2.4. SIGNOS DE PUNTUACIÓN Y SEPARADORES
TodaslassentenciasdeC++debenterminarconunpuntoycoma (;).Losseparadoressonespaciosenblanco, tabulaciones,
retornosdecarroyavancesdelínea.Otrossignosdepuntuaciónson:
!
[
%
]
^
\
&
;
*
´
(
:
)
<
>
+
?
=
,
{
.
}
/
~
2.2.5. ARCHIVOS DE CABECERA
Unarchivodecabecera esunarchivoespecialquecontienelasdeclaracionesdeobjetosyfuncionesdelabibliotecaqueson
añadidosenellugardondeseinsertan.Unarchi vodecabeceraseinsertaconladirecti va #include.ElnuevoANSIC++ha
cambiadoelconvenio(notación)originaldelosarchi vosdecabecera.Esposibleutilizarsólolosnombresdelasbibliotecas
sinelsufijo .h;esdecir, sepuedeusar iostream, cmath, cassert y cstlib enlugarde iostream.h, math.h, assert.h y
stdlib.h respectivamente.
2.3. Tipos de datos en C++
C++nosoportaungrannúmerodetiposdedatospredef inidos, perotienelacapacidadparacrearsuspropiostiposdedatos.
LostiposdedatossimplesobásicosdeC++son: enteros;númerosdecomaflotante (reales)ycaracteres, ysemuestranen
laTabla2.2. ExistentrestiposadicionalesenC++quesetrataránmásadelante:
enum
bool
void
constantedeenumeración;
constantefalso-verdadero;
tipoespecialqueindicaausenciadetipo;
Tabla 2.1. Tipos de datos simples de C++
Tipo básico
Carácter
Entero
Real
Tipo
char
short
int
unsigned int
long
float
double
long double
Ejemplo
Tamaño en bytes
Rango. Mínimo..Máximo
‘C’
–15
1024
42325
262144
10.5
0.00045
1e-8
1
2
2
2
4
4
8
8
0..255
–128..127
–32768..32767
0..65535
–2147483648..2147483637
3.4*(10–38)..3.4*(1038)
2.7*(10–308)..2.7*(10308)
igualque double
2.3.1. ENTEROS (INT)
Lostiposenterossealmacenaninternamenteen2bytesdememoria.La Tabla2.2resumelostrestiposenterosbásicos, junto
conelrangodevaloresyeltamañoenbytesusual(dependedecadacompiladorC++).
Tabla 2.2. Tipos de datos enteros en C++
Tipo C++
int
unsigned int
short int
long
unsigned long
Rango de valores
Uso recomendado
–32.768 .. +32.767
0 .. 65.535
–32.768 .. +32.767
–2147483648..2147483647
0 .. +4294967295
Aritméticadeenteros, buclesfor, conteo.
Conteo, buclesfor, índices.
Aritméticadeenteros, buclesfor, conteo.
Enterolargo.Númerosgrandes.
Enterolargopositivo.Númerosgrandes.
CAPÍTULO 2 Conceptos básicos de los programas en C++
21
A tener en cuenta: eltipo char sóloadmitelosmodificadoresunsigned ysigned;eltipo float ydouble noadmitenelmodificador unsigned;losenterosyenteroslar gosadmitenelmodificador unsined y signed;eltipo bool no
admitemodificadores.
Declaración de variables
Laformamássimpledeunadeclaracióndev ariableenC++esponerprimeroeltipodedatoy , acontinuación, elnombreo
losnombresdelasv ariablesseparadosporcomas.Sisedeseadarunv alorinicialalav ariable, ésteseponeacontinuación
delidentificadordelavariableprecedidodelsignoigual:
<tipodedato><nombredevariable>=<valorinicial>
Sepuedentambiéndeclararmúltiplesvariablesenlamismalínea:
<tipo_de_dato><nom_var1>, <nom_var2>...<nom-varn>
EJEMPLO 2.8. Declaracióneinicializacióndevariablesenter asenC++.
int valor, valor1, valor2 = 100, valor3 = 25, x, y;
short int Numero_asociado = 345, numer, libre;
long numero_grande1, numero_grade2 = 345678;
C++permiteescribirconstantesenterasenoctal (base8)ohexadecimal (base16).Unaconstanteoctalescualquiernúmeroquecomienzaconun0ycontienedígitosenelrangode 1 a7.Unaconstantehexadecimalcomienzacon 0x yvaseguidadelosdígitos 0 a 9 olasletras A a F (obien a a f).LaTabla2.3muestraejemplosdeconstantesenterasrepresentadasen
susnotaciones decimal, hexadecimal yoctal.
Tabla 2.3. Constantes enteras en tres bases diferentes
Base 10 decimal
Base 16 hexadecimal (Hex)
Base 8 octal
8
10
16
65536
24
0x08
0x0A
0x10
0x10000
0x18
010
012
020
0200000
030
2.3.2. TIPOS EN COMA FLOTANTE (float/double)
Lostiposdedatos“coma( punto)flotante” representannúmerosrealesquecontienenunacoma(unpunto)decimal, talcomo
onúmerosmuygrandes, talescomo 2.43 e +18 = 2,43*1018.Ladeclaracióndelasv ariablesdecomaflotantees
igualqueladevariablesenteras.C++soportatresformatosdecomaflotante.Eltipofloat requiere4 bytesdememoria, double requiere 8 bytesy long doublerequiere 10 bytes.LaTabla2.4muestralostiposdedatosencomaflotante.
2.123,
Tabla 2.4. Tipos de datos en coma flotante
Tipo C
float
double
long double
Rango de valores
-38
Precisión
38
3.4 x 10
... 3.4 x 10
2.7 x 10-308 ... 2.7 x 10308
3.4 x 10-4932 ... 2.1 x 104932
7dígitos
15dígitos
19dígitos
2.3.3. CARACTERES (char)
Uncarácter escualquierelementodeunconjuntodecaracterespredef inidosoalfabeto.Lamayoríadelascomputadorasutilizanelconjuntodecaracteres ASCII.C++procesadatoscarácterutilizandoeltipodedato char.Internamente, loscaracteressealmacenancomonúmerosenterosenelrango -128 a +127 yseasocianconelcódigo ASCII;portantosepuedenrea-
CAPÍTULO 2 Conceptos básicos de los programas en C++
22
lizaroperacionesaritméticascondatostipo char.EllenguajeC++proporcionaeltipo unsigned char pararepresentarvaloresde 0 a 255 yasírepresentartodosloscaracteres ASCII.Sepuedenrealizaroperacionesaritméticascondatostipo char.
EJEMPLO 2.9. Defineeinicializaunavariabledetipo char, acontinuaciónsepasaamayúscula.
char car = 'c', car1 = 'D';
car = car – 32;
car1 = car1 + 32;
Elejemploconvierte'c' (códigoASCII99)a'C' (códigoASCII67), y 'D' (códigoASCII68)a'd' (códigoASCII100).
EJEMPLO 2.10. Diferenciaentrecharyunsignedchar.
Elprogramausadosvariables, dato, ydato1 detipo char yunisgned char respectivamene.Asignaacadavariable
unnúmeronaturalcomprendidoentre115 y129, visualizandoambasvariablescomoenterasycomocarácter.Cuando
noestáactivadoelbitdesigno, aparecennúmerosnegativosquenosecorrespondenconlosnúmerosASCIIasociados.
include <cstdlib>
#include <iostream>
using namespace std;
char dato;
unsigned char dato1;
// carácter
//declaración de tipo carácter sin signo
int main(int argc, char *argv[])
{
cout << "
char
unsigned char " << endl;
cout << " ASCII CAR ASCII
CAR " << endl;
for (int i = 115; i < 130; i++)
{
dato = i; dato1 = i;
cout << (int) dato << "
" << dato << "
";
cout << (int) dato1 << "
" << dato1<< endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadodeejecución:
CAPÍTULO 2 Conceptos básicos de los programas en C++
23
2.3.4. EL TIPO DE DATO bool
LamayoríadeloscompiladoresdeC++incorporaneltipodedato bool cuyosvaloresposiblesson: “verdadero” (true) y
falso” (false).Eltipobool proporcionalacapacidaddedeclararvariableslógicas, quepuedenalmacenarlosvaloresverdaderoyfalso.SienelcompiladordeC++noestádisponibleeltipo bool, deberáutilizareltipodedato int pararepresentar
eltipodedato bool.C++utilizaelv alorentero 0 pararepresentarf alsoycualquierv alorenterodistintodecero(normalmente 1)pararepresentarverdadero.Deestaforma, sepuedenutilizarenterosparaescribire xpresioneslógicasdeigualformaqueseutilizaeltipo bool.
EJEMPLO 2.11. Usodeltipobool.
#include <iostream.h>
void main()
{
bool b1, b2 = false,
int i1 = b3, i4 = 10;
b3 = true;
cout << " b2:" << b2 << endl;
...
// muestra el valor de b2 que es 0
}
2.4. Constantes
Unaconstanteesunobjetocuyovalornopuedecambiaralolargodelaejecucióndeunprograma.EnC++e xistencuatrotiposdeconstantes: constantesliterales, constantesdefinidas, constantesenumeradas, constantesdeclaradas.
2.4.1. CONSTANTES LITERALES
Lasconstantesliterales oconstantes, engeneral, seclasificanencuatrogrupos, cadaunodeloscualespuedeserdecualquieradelostipossiguientes: enteras, reales, decaracteres, decadena, enumeradas, definidasydeclaradas.
Constantes enteras. Sonunasucesióndedígitosprecedidosonoporelsigno+o–dentrodeunrangodeterminado.
EJEMPLO 2.12. Constantesnuméricas.
234, -456
12334L, 43567L
0777, 0123
0XFF3A, 0x2AB345
3456UL
constantesenteras.
constantesenteraslargas;tienenelsufijoL
constantesenoctal;comienzapor 0 ydígitosentre 0 y7
constanteshexadecimal;comienzanpor 0X
constantesinsignoylarga;sufijoU sinsigno
Constantes reales. Sonunasucesióndedígitosconunpuntodelante, alfinaloenmedioyseguidosopcionalmentedeunexponente: Porejemplo, 82.347, .63, 83., 47e-4, .25E7 y62.e+4.
Constantes carácter. Unaconstantecarácter(char)esuncarácterdelcódigoASCIIencerradoentreapóstrofes.Porejemplo,
'A', 'a', 'b', 'c'.Ademásdeloscaracteres ASCIIestándar, unaconstantecaráctersoportacaracteresespecialesquenose
puedenrepresentarutilizandosuteclado, comoporejemploloscódigosASCIIaltosylassecuenciasdeescape.
Tabla 2.5. Caracteres secuencias (códigos) de escape
Código de Escape
'\n'
'\r'
'\t'
'\v'
Significado
nuevalínea
retornodecarro
tabulación
tabulaciónvertical
Dec
13
13
9
11
Códigos ASCII
10
OD
OD
09
OB
Hex
OA
CAPÍTULO 2 Conceptos básicos de los programas en C++
24
Tabla 2.5. Caracteres secuencias (códigos) de escape (continuación)
Código de Escape
Significado
Dec
Códigos ASCII
Hex
'\a'
'\b'
'\f'
'\\'
'\''
alerta(pitidosonoro)
retrocesodeespacio
avancedepágina
barrainclinadainversa
comillasimple
7
8
12
92
39
07
08
OC
5C
27
'\"'
'\?'
'\000'
'\xhh'
doblecomilla
signodeinterrogación
númerooctal
númerohexadecimal
34
34
22
22
todos
todos
todos
todos
Constantes cadena. Unaconstantecadena (tambiénllamadaliteralcadena osimplementecadena)esunasecuenciadecaracteresencerradosentredoblescomillas.Porejemplo, "123", "14 de Julio de 2005", "esto es un ejemplo de cadena".Enmemoria, lascadenasserepresentanporunaseriedecaracteres ASCIImásun 0 onulo '\0' queesdef inidoen
C++mediantelaconstante NULL endiversosarchivosdecabecera(normalmente STDEF.H, STDIO.H, STDLIB.H y STRING.H).
Constantes definidas (simbólicas). Lasconstantespuedenrecibirnombressimbólicosmedianteladirecti va#define.Estas
constantessonsustituidasporsuvalorporelpreprocesador(antesdecomenzarlacompilacióndelprograma).
EJEMPLO 2.13. Seponennombressimbólicosaconstantesdeinterés.
#define
#define
#define
#define
NUEVALINEA '\n'
e 2.81
pi 3.1415929
// valor de la constante Pi
cabecera “esto es un ejemplo de cabecera de programa”
C++sustituye '\n', 2.81, 3.1415929, “esto es un ejemplo de cabecera de programa”, cuandoseencuentra
lasconstantessimbólicas NUEVALINEA, e, pi, cabecera.
Constantes enumeradas. Lasconstantesenumeradaspermitencrearlistasdeelementosaf ines.Cuandoseprocesaestasentenciaelcompiladorenumera losidentificadorescomenzandopor 0.Despuésdedeclararuntipodedatoenumerado, sepuedencrearvariablesdeesetipo, comoconcualquierotrotipodedatos.Enelejemplo2.13 Miercoles tomaelvalor2.
EJEMPLO 2.14. Declaracióndetiposenumeradoseinicializacióndevariablesdetipoenumer ado.
enum laborable { Lunes, Martes, Miercoles, Jueves, Viernes}
enum festivo {Sabado, Domingo};
laborable diaL =lunes;
festivo diaF = Domingo;
Constantes declaradas; const y volatile. Elcualificador const permitedarnombressimbólicosaconstantes.Suvalorno
puedesermodificadoporelprograma.Suformatoes:
const tipo nombre = valor;
Lapalabrareserv ada volatile, modificaeltipodeaccesodeunav ariable, permitiendocambiarelv alordelav ariable
pormediosnoexplícitamenteespecificadosporelprograma.Porejemploladireccióndeunav ariableglobalqueapuntaaun
puertoexterno.Elvalordeunavariable volatile puedesermodificadonosóloporelpropioprograma, sinotambiénporel
hardware oporelsoftware delsistema.Suformatodedeclaraciónes:
volatile tipo nombre = valor;
CAPÍTULO 2 Conceptos básicos de los programas en C++
25
Siseusa const y volatile juntos, seaseguraqueunavariablenopuedecambiarporprograma, perosípormediose xternosalprogamaC++.
Ejemplo: const volatile unsigned char *puerto=0x30;.
2.5. Variables
EnC++unavariable esunaposicióndememoriaaqueseleasociaunnombre(identif icador)enelquesealmacenaunvalor
deltipodedatodelquesehadef inido.Elvalordeunavariablepuedecambiaralolar godelaejecucióndelprograma, siendomanipuladaporlosoperadoresaplicablesaltipodelquehasidodef inidalavariable.
Delaración. Unadeclaración deunavariableesunasentenciaqueproporcionainformacióndelavariablealcompiladorC++.
Esprecisodeclarar lasvariablesantesdeutilizarlas.Lasintaxisdedeclaraciónes:
tipo lista de variables;
Siendo tipo elnombredeuntipodedatoconocidoporC++y lista de variables unasucesióndenombresseparadasporcomas, ycadanombredelalistaunidentif icadordeC++.
Inicialización. Lasvariables, puedenserinicializadasaltiempoquesedeclaran.Elformatogeneraldeunadeclaraciónde
inicializaciónes:
tipo lista de inicialización;
Siendo lista de inicialización unasucesión nombre_variable = expresión.Además expresión escualquierexpresiónválidacuyovaloresdelmismotipoque tipo.
Hayquetenerencuentaquelosdosformatosdedeclaraciónpuedencombinarseentresí.
EJEMPLO 2.15. Declaracióndevariableseinicializacióndealgunadeellas.
int x, z, t = 4;
float xx = 2.0, yy = 8, zz;
char Si = 'S', No = 'N', ch;
Lasvariablesx, z yt sonenteras.Lavariablet seinicializaa4.
Lasvariablesxx, yy, yzz sonreales.Seinicializan xx yzz a2.0, y8 respectivamente.
LasvariablesSi, No ych soncaracteres.Seinicializanlasdosprimerasaloscaracteres 'S' y'N' respectivamente.
2.6. Duración de una variable
Dependiendodellugardedef inición, lasvariablesdeC++, puedenserutilizadasenlatotalidaddelprograma, dentrodeuna
funciónosólodentrodeunbloquedeunafunción.Lazonadeunprogramaenlaqueunav ariableestáactivasedenomina,
normalmente, ámbito oalcance (“scope”).
2.6.1. VARIABLES LOCALES
Lasvariableslocalessonaquellasquesedef inendentrodeunafunción.Lasre glasporlasqueserigenlasv ariableslocales son:
1. Lasvariableslocalesnopuedenmodificarsefueradelafunción.
2. Losnombresdelasvariableslocalesnosonconocidasfueradedondesedeclaran.
3. Lasvariableslocalesnoexistenenmemoriahastaqueseejecutalafunción.
CAPÍTULO 2 Conceptos básicos de los programas en C++
26
2.6.2. VARIABLES GLOBALES
Lasvariablesglobales sonvariablesquesedeclaranfueradelasfuncionesypordefecto(omisión)sonvisiblesacualquier
funciónincluyendo main( ).Unavariableglobalpuedeseraccedidaomodif icadadesdecualquierfuncióndef inidodelarchivofuente.
EJEMPLO 2.16. Ámbitodeprograma, defunciónydebloquedevariables. Variableslocalesyglobales.
#include <iostream>
using namespace std;
int suma=0;//puede usarse en todas las funciones. Ámbito de programa.
// suma es una variable global.
int f( )
{
// puede usar suma por ser global, pero no i ni j por ser locales.
suma= suma + 30; // efecto lateral sobre suma. Debe evitarse.
}
int main(int argc, char *argv)
{
int j = 3 ;
// solo puede usarse en la función main
// variable local de main
for (int i = 1; i <= ;i++)
suma = suma + i;
//la variable i solo puede usarse dentro del bucle for.
// i tiene ámbito de bloque
//i es variable local del bucle for
suma = suma + j;//puede usar suma por ser global y j por ser local
f( );
cout << suma ;
system("PAUSE");
return EXIT_SUCCESS;
}
2.6.4. VARIABLES DINÁMICAS Y DE OBJETOS
Lasvariablesdinámicas similarestantoavariableslocalescomoaglobales. Aligualqueunav ariablelocal, unavariabledinámicasecreayliberadurantelaejecucióndeunafunción.La diferenciaentreunavariablelocalyunavariabledinámica
esquelavariabledinámicasecreatrassupetición(env ezdeautomáticamente, comolasvariableslocales), yseliberacuandoyanosenecesita.Aligualqueunavariableglobal, sepuedencrearvariablesdinámicasquesonaccesiblesdesdemúltiples
funciones.LasvariablesdinámicasseexaminanendetalleenelCapítulo10( Punteros).
Losobjetossontiposagre gadosdedatoquepuedencontenermúltiplesfuncionesyv ariablesjuntasenelmismotipo
de dato.EnelCapítulo12seintroducenlosobjetos, tipodedatocla veenC++ysobretodoenprogramaciónorientadaa
objetos.
2.7. Entradas y salidas
EnC++laentradaysalidaseleeyescribeenflujos(streams).Cuandoiostream.h seincluyeenunprograma, diferentesflujosestándarsondef inidosautomáticamente.Elflujo cin seutilizaparaentrada, quenormalmenteseleedeteclado.Elflujo
cout seutilizaparasaliday, normalmente, seenvíaalapantalladelusuario.
CAPÍTULO 2 Conceptos básicos de los programas en C++
27
2.7.1. SALIDA (cout)
Eloperadordeinserción, <<, insertadatosenelflujo cout quelosvisualizaenlapantalladesuequipo.Esposibleutilizar
unaseriedeoperadores << encascada
cout << "Esto es una cadena";
cout << 500 << 600 << 700;
cout << 500 << "," << 600;
//visualiza: Esto es una cadena
//visualiza 500 600 700
//visualiza 500, 600
C++utilizasecuenciasdeescape paravisualizarcaracteresquenoestánrepresentadosporsímbolostradicionales.Entre
lasmásusadasestán: línea.nuevalínea (\n), tabulación (\t) yalarma (\a).Unalistadelassecuenciascompletadeescape
serecogeenlaTabla2.6.
Ejemplo:
cout << "\n Error \n Pulsar una tecla para continuar \n";
Lainstrucciónanteriorsaltadelínea, escribeenotralínea Error, saltadelíneaescribe Pulsar una tecla para conysaltadelínea.Esdecirproducelasiguientesalida:
tinuar
Error
Pulsar una tecla para continuar
Tabla 2.6. Caracteres secuencias de escape
Secuencia de escape
Significado
\a
\b
\f
\n
\r
\t
\v
\\
\?
\"
\OOO
\xhh
\0
Alarma
Retrocesodeespacio
Avancedepágina
Retornodecarroyavancedelínea
Retornodecarro
Tabulación
Tabulaciónvertical
Barrainclinada
Signodeinterrogación
Doblescomillas
Númerooctal
Númerohexadecimal
Cero, nulo(ASCII0)
2.7.2. ENTRADA (cin)
Elarchivodecabecera iostream.h delabibliotecaC++proporcionaunflujodeentradaestándar cin yunoperadordeextracción, >>, paraextraervaloresdelflujoyalmacenarlosenvariables.Sinoseredirigeexplícitamente cin, laentradaprocededelteclado.
int numero;
cin >> numero;
double real;
cin >> real;
Lasórdenes cin leendosdatosdeltecladoylosalmacenanenlasv ariablesnumero yreal.
EJEMPLO 2.17. Programaqueleelasinicialesdelnombr eyprimerapellidoylasescribeenpantallase guidasde
unpunto.
#include <cstdlib>
#include <iostream>
using namespace std;
CAPÍTULO 2 Conceptos básicos de los programas en C++
28
int main()
{
char Nombre, Apellido;
cout << "Introduzca la inicial de su nombre y primer apellido: ";
cin >> Nombre >> Apellido;
cout << "Hola," << Nombre << "." << Apellido << ".\n";
system("PAUSE");
return EXIT_SUCCESS;
}
2.8. Espacios de nombres (NAMESPACES)
Unespaciodenombresesunmecanismoparaagruparlógicamenteunconjuntodeidentif icadores(nombresdetipos, funciones, etc.).Existeunespaciodenombresglobalysobreélsedefineelrestodelosespaciosdenombres.Aunidentificadorque
seencuentraenunespaciodenombressepuedeaccederdedistintasformas.
EJEMPLO 2.18. Espaciodenombreestándar.
Enelprogramaestándar, lacláusula using cargaespaciodenombresestándar( std)enelespaciodenombresactual,
queesglobalpermitiendoasíelempleodeidentificadorescomoendl (declaradoen<iostream> sinnecesidaddecualificarconeloperadordealcance).
// Programa inicial
#include <iostream>
..................
using namespace std;
int main ( )
{
cout << "¡Hola mundo cruel!" << endl;
}
Unespaciodenombres namespace esunaregióndeclarativaconnombreopcional.Elnombredeunespaciodenombres
sepuedeutilizarparaaccederaentidadesdeclaradaseneseespaciodenombre;esdecirlosmiembrosdelespaciodenombres.
Enesencia, unconjuntodevariables, defunciones, declasesydesubespaciosdenombres, miembrosquesiguenunasreglas
devisibilidad.ElespaciodenombresesunacaracterísticadeC++introducidaenlasúltimasv ersiones, diseñadaparasimplificarlaescrituradeprogramas.
Definición de un espacio de nombr es:
namespace identificador{cuerpo_del_espacio_de_nombres }
cuerpo_del_espacio_de_nombres
sección_de_declaraciones.
← Nohaypuntoycoma
//miembrosdelespaciodenombre
Paraaccederalespaciodenombressedebein vocaralnombredelmismocuandoseref ieraaellos.Existendosprocedimientosparahaceresto.
Método 1. Precederacadanombredelelementoenelnombredelespaciodenombreyeloperadorderesolucióndelámbitodealcance( ::).
Método 2. Utilizarladirectivausing, loquepermitepoderutilizarelespaciodenombresapartirdedondesedeclare.
CAPÍTULO 2 Conceptos básicos de los programas en C++
EJEMPLO 2.19. Espaciodenombresgeo.
#include <iostream>
namespace geo
{
const double PI = 3.141592;
double longcircun (double radio)
{
return 2*PI*radio;
}
}
using namespace std;
using namespace geo;
int main(int argc, char *argv[])
{
cout << "¡Hola mundo cruel!" << endl;
cout << longcircun (16);//no funciona al omitir using namespace geo;
cout << geo::longcircun(20);
}
EJERCICIOS
2.1.
¿Cuáleslasalidadelsiguientepr ograma?
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
// cout << "Hola mundo!\n";
system("PAUSE");
return EXIT_SUCCESS;
}
2.2.
¿Cuáleslasalidadelsiguientepr ograma?
#include <cstdlib>
#include <iostream>
using namespace std;
#define prueba "esto es una prueba"
int main()
{
char cadena[21]="sale la cadena.";
cout <<prueba << endl;
cout <<"Escribimos de nuevo.\n";
cout << cadena << endl;
cout << &cadena[8] << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
29
CAPÍTULO 2 Conceptos básicos de los programas en C++
30
2.3.
EscribirunprogramaquevisualicelaletraBconasteriscos.
*****
*
*
*
*
*
*
******
*
*
*
*
*
*
*****
2.4.
CodificarunprogramaenC++queescribaendoslíneasdistintaslasfr ases: Bienvenido al C++; Pronto comenzaremos a programar en C.
2.5.
DiseñarunprogramaenCquecopieenunarr aydecaractereslafrase“esunnuevoejemploenC++” yloescribaenla
pantalla.
2.6.
¿Cuáleslasalidadelsiguientepr ograma?
#include <cstdlib>
#include <iostream>
#define Constante "de declaracion de constante."
using namespace std;
int main( )
{
char Salida[21]="Esto es un ejemplo";
cout << Salida << endl;
cout << Constante << endl;
cout << "Salta dos lineas\n \n";
cout << "y tambien un\n";
cout << &Salida[11];
cout << " cadenas\n";
system("PAUSE");
return EXIT_SUCCESS;
}
2.7.
¿Cuáleslasalidadelsiguientepr ograma?
#include <cstdlib>
#include <iostream>
using namespace std;
int main( )
{
char pax[] = "Juan Sin Miedo";
cout << pax << "----> " <<&pax[4] << endl;
cout << pax << endl;
cout << &pax[9] << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 2 Conceptos básicos de los programas en C++
2.8.
Escribirunprogramaqueleaunavariableenter aydosrealesylovisualice.
2.9.
Escribirunprogramaqueleaellargoyelanchodeunrectángulo.
31
2.10. ¿Cuáldelossiguientesidentificadoressonválidos?
N
MiProblema
Mi Juego
MiJuego
write
m&m
registro
* 143Edad
85 Nombre
AAAAAAAAAA
Nombre_Apellidos
Saldo_Actual
92
Universidad Pontificia
Set 15
SOLUCIÓN DE LOS EJERCICIOS
2.1.
Elpr ogramapr oduceenlasalidaelmensaje , pulseunateclapar acontinuarcorr espondientealasentencia system
yaquelasentencia cout estácomocomentario, yportantonoseejecuta.Siseeliminar aelcomentarioapareceríaademáselmensaje: Hola Mundo!
("PAUSE"),
2.2.
Unprogramaqueresuelveelejercicioes:
#include <cstdlib>
#include <iostream>
using namespace std;
int main( )
{
cout << "*******\n";
...cout << "*
*\n";
...cout << "*
*\n";
...cout << "*
*\n";
...cout << "*******\n";
...cout << "*
*\n";
...cout << "*
*\n";
...cout << "*
*\n";
...cout << "*******\n";
...system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 2 Conceptos básicos de los programas en C++
32
2.3.
Lasalidasereflejaenelresultadodeejecuciónquesemuestr aacontinuación.
2.4.
Unacodificaciónes:
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
cout << " Bienvenido al C++ \n";
cout << " Pronto comenzaremos a programar en C++ \n";
system("PAUSE");
return EXIT_SUCCESS;
}
2.5.
Unprogramaqueresuelveelproblemaplanteadoes:
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
char ejemplo[50];
strcpy (ejemplo, " Es un nuevo ejemplo de programa en C\n");
cout << ejemplo << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
2.6.
Elresultadodeejecucióndelprogramaes:
2.7.
Alejecutarelprogramaseobtiene:
2.8.
Lacodificaciónpedidaes:
#include <cstdlib>
#include <iostream>
CAPÍTULO 2 Conceptos básicos de los programas en C++
using namespace std;
int main()
{
int v1 ;
float v2,precio;
cout << "Introduzca v1 ";
cin >> v1 ;
//lectura valor de v1
cout << "valor leidos: " << v1 << "\n";
cout << "introduzca dos valores\n";
cin >> v2 >> precio;
// lectura de v2, precio
cout << v2 << " " << precio << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
2.9.
Unacodificacióneslasiguiente:
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
float largo, ancho;
cout << "Introduzca largo: ";
cin >> largo;
cout << " introduzca ancho: " ;
cout << "introduzca dos valores\n";
cin >> ancho;
cout << " largo = "<< largo << "\n" ;
cout << " ancho = " << ancho << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
2.10. N
MiProblema
Mi Juego
MiJuego
write
m&m
registro
AB
85 Nombre
AAAAAAAAAA
Nombre_Apellidos
Saldo_Actual
92
Universidad Pontificia
Set 15
*143Edad
Correcto
Correcto
Incorrecto(llevaespacioenblanco)
Correcto(llevaespacioenblanco)
Correcto
Incorrecto
Correcto
Correcto
Incorrecto(comienzapornúmero)
Correcto
Correcto
Correcto
Incorrecto(número)
Incorrecto(llevaespacioenblanco)
Incorrecto(llevaespacioenblanco)
Incorrecto(nopuedecomenzarpor*)
33
CAPÍTULO 2 Conceptos básicos de los programas en C++
34
EJERCICIOS PROPUESTOS
2.1.
Depuraryescribirunprogramaquevisualicelaletra A
medianteasteriscos.
2.8.
Escribirunprogramaqueleatresnúmerosreales, ylos
visualice.
2.2.
Escribirunprogramaqueleaunte xtodecincolíneasy
lopresenteenpantalla.
2.9.
¿Cuáleslasalidadelsiguienteprograma?
2.3.
Escribirunprogramaquelea5númeroenterosytres
númerosrealesylosvisualice.
#include <cstdlib>
2.4.
Escribiryejecutarunprogramaqueleasunombreydirecciónyvisualicelamisma.
int main()
2.5.
#include <iostream>
using namespace std;
{
char p[] = "Esto es una prueba";
Escribirunprogramaquelealabaseylaalturadeun
trapecio.
2.6.
Escribiryejecutarunprogramaqueimprimaunapáginadetextoconnomásde40caracteresporlínea.
2.7.
Escribirunprogramaqueleaelradiodeunacircunferenciaycalculesulongitud.
cout << p << " " <<
&p[2] << endl;
cout << p << "\n";
cout << &p[2] << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 3
Operadores y expresiones
Introducción
EstecapítulomuestracómoC++haceusodelosoperadoresyexpresionesparalaresolucióndeoperaciones.Losoperadores
fundamentalesqueseanalizanenelcapítuloson: aritméticos, lógicos yrelacionales;demanipulacióndebits;condicionales
yespeciales.Además, seanalizanlascon versionesdetiposdedatosylasre glasquesigueelcompiladorcuandoconcurran
enunamismae xpresióndiferentestiposdeoperadores.Estasre glasseconocencomore glasde prioridad yasociatividad.
3.1. Operadores y expresiones
LosprogramasC++constandedatos, sentenciasdeprogramasye xpresiones.Unaexpresión es, unasucesióndeoperadores
yoperandosdebidamenterelacionadosqueespecificanuncálculo.C++soportaunconjuntopotentedeoperadoresunitarios,
binariosydeotrostipos.
3.2. Operador de asignación
Eloperadordeasignaciónesunoperadorcuyasintaxiseslasiguiente:
variable = expresión;
donde variable esunidentificadorválidodeC++declaradocomo variable.Eloperador = asignaelvalordelaexpresión
derechaalavariablesituadaasuizquierda.Esteoperadoresasociativoporladerecha, esopermiterealizarasignacionesmúltiples.Así, A = B = C = D = 12;equivalea A = (B =(C = (D = 12))) queasignaalasvariablesA, B, C yD elvalor12.
Estapropiedadpermiteinicializarvariasvariablesconunasolasentencia.Ademásdeloperadordeasignación = C++proporcionacincooperadoresdeasignaciónadicionalesdadosenla Tabla3.1.
EJEMPLO 3.1. Programaquedeclaravariablesyhaceusodeoper adoresdeasignación.
#include <cstdlib>
#include <iostream>
using namespace std;
35
CAPÍTULO 3 Operadores y expresiones
36
int main(int argc, char *argv[])
{
int codigo, CoordX, CoordY;
float fahrenheit, valor;
codigo = 3467;
valor = 10;
valor *= 3;
CoordX = 525;
CoordY = 725;
CoordY -= 10;
fahrenheit = 123.456;
system("PAUSE");
return EXIT_SUCCESS;
}
Tabla 3.1. Operadores y equivalencias de asignación de C++
Símbolo
=
*=
/=
%=
+=
-=
Uso
a
a
a
a
a
a
=
*=
/=
%=
+=
-=
b
b
b
b
b
b
Sentencia
abreviada
Descripción
Asignaelvalordeb aa.
Multiplicaa porb yasignaelresultadoalav ariablea.
Dividea entreb yasignaelresultadoalav ariablea.
Fijaa alrestodea/b.
Sumab ya yloasignaalavariablea.
Restab dea yasignaelresultadoalav ariablea.
m =
m *=
m /=
m %=
m +=
m -=
n
n;
n;
n;
n;
n;
Sentencia
no abreviada
m
m
m
m
m
m
=
=
=
=
=
=
m
m
m
m
m
n
*
/
%
+
-
n;
n;
n;
n;
n;
3.3. Operadores aritméticos
LosoperadoresaritméticosdeC++sirv enpararealizaroperacionesaritméticasbásicas.Siguenlasre glasalgebraicastípicas,
dejerarquíaoprioridad, clásicasdematemáticas.Estosoperadoresvienenrecogidosenla Tabla3.2.
Tabla 3.2. Operadores aritméticos
Operador
+
*
/
%
Tipos enteros
Tipos reales
Suma
Resta
Producto
Divisiónentera: cociente
Divisiónentera: resto
Suma
Resta
Producto
Divisiónencomaflotante
Ejemplo
x
b
x
b
b
+
–
*
/
%
y
c
y
5
5
Losparéntesissepuedenutilizarparacambiarelordenusualdee valuacióndeunae xpresióndeterminadaporsu prioridad yasociatividad.Laprioridaddelosoperadoresysuasociati vidadserecogenenla Tabla3.3.
Tabla 3.3. Prioridad y asociatividad
Prioridad (mayor a menor)
Asociatividad
+, - (unitarios)
*, /, %
+, -
izquierda-derecha(→)
izquierda-derecha(→)
izquierda-derecha(→)
CAPÍTULO 3 Operadores y expresiones
37
EJEMPLO 3.2. Evaluacióndeexpresiones.
a) ¿Cuáleselresultadodeevaluacióndelaexpresión: 50 – 4 * 3 + 2?
50 – 4 * 3 + 2
50 – 12 + 2
38 + 2
32
b) ¿Cuáleselresultadodeevaluacióndelaexpresión: 5 * ( 10 – 2 * 4 + 2 ) – 2?
5 * ( 10 – 2 * 4 + 2 ) – 2
5 * ( 10 – 8 + 2 ) – 2
5 * ( 2 + 2 ) - 2
5 * 4 – 2
20 – 2
18
c) ¿Cuáleselresultadodelae xpresión: 7 * 5 – 6 % 4 * 4 + 9?
7 * 5 – 6 % 4 * 4 + 9
35 – 6 % 4 * 4 + 9
35 – 2 * 4 + 9
35 – 8 + 9
27 + 9
36
d) ¿Cuáleselresultadodelae xpresión: 15 * 14 – 3 * 7?
15 * 14 – 3 * 7
210 – 3 * 7
210 – 21
189
e) ¿Cuáleselresultadodelae xpresión: 3 + 4 * (8 * (4 – (9 + 3) / 6)))?
3 +
3 +
3 +
3 +
3 +
3 +
99
4 * (8 * (4 – (9 + 2) / 6)))
4 *(8 * (4 – 11 / 6))
4 *(8 * (4 – 1))
4 *(8 * 3)
4 * 24
96
EJEMPLO 3.3. Programaqueleeelradio, calculayvisualizalalongituddelacircunferenciadeeseradio, yelárea
delcírculodelmismoradio.
#include <cstdlib>
#include <iostream>
#define pi 3.141592
using namespace std;
int main(int argc, char *argv[])
{
float radio, longitud, area;
CAPÍTULO 3 Operadores y expresiones
38
cin >> radio;
//lectura del radio
longitud = 2 * pi * radio;
area = pi * radio * radio;
cout << " radio = " << radio << endl;
cout << " longitud = " << longitud << endl;
cout << " area = " << area << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 3.4. Desglosarciertacantidaddese gundosintroducidaportecladoensuequivalenteensemanas, días,
horas, minutosysegundos.
Elprogramaleeelnúmerodesegundosyrealizalasconversiones, teniendoencuentaqueunasemanatiene7días, un
díatiene24horas, unahora60minutos, yunminuto60segundos.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int semanas, dias, horas, minutos, segundos, acu;
cout << "Introduzca segundos ";
cin >> acu;
segundos = acu % 60;
acu = acu / 60;
minutos = acu % 60;
acu = acu / 60;
horas = acu % 24;
acu = acu / 24;
dias = acu % 7;
semanas = acu / 7;
cout << "segundos en semanas dias horas minutos y segundos " << endl;
cout << " numero de semanas " << semanas << endl;
cout << " numero de dias " << dias << endl;
cout << " numero de horas " << horas << endl;
cout << " numero de minutos " << minutos << endl;
cout << " numero de segundos " << segundos << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Enresultadodeejecucióneselsiguiente:
CAPÍTULO 3 Operadores y expresiones
39
3.4. Operadores de incrementación y decrementación
DelascaracterísticasqueincorporaC++unadelasmásútilessonlosoperadoresde incremento ++ ydecremento --.Estos
operadoresunitariossumanorestan 1 respectivamentealavariableytienenlapropiedaddequepuedenutilizarsecomosuf ijooprefijo.Elresultadodelae xpresiónpuedeserdistinto, dependiendodelcontexto.Enla Tabla3.4serecogenlosoperadoresdeincrementaciónydecrementación.
Tabla 3.4. Operadores de incrementación ( ++) y decrementación ( --)
Incrementación
Decrementación
++n, n++
n += 1
n = n + 1
--n , n-n -= 1
n = n – 1
Silosoperadores++ y-- estándeprefijos, laoperacióndeincrementoseefectúaantesquelaoperacióndeasignación;
silosoperadores ++ y -- estándesufijos, laasignaciónseefectúaenprimerlugarylaincrementaciónodecrementaciónacontinuación.
EJEMPLO 3.5. Diferenciasentreoperadoresdepreincrementaciónypostincrementación.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int m = 10, n;
n = ++m;
// primero
cout << " m = " << m << " n = "
n = m++;
// primero
cout << " m = " << m << " n = "
cout << " m = " << m++ << endl;
cout << " m = " << ++m << endl;
n = 5;
m = ++n * ––n;
//++n pone
cout << " n = " << n << " m = "
system("PAUSE");
return EXIT_SUCCESS;
se
<<
se
<<
incrementa m y luego se asigna a n
n <<endl ;
asigna a n y luego se incrementa m
n <<endl ;
n a 6, luego –-n pone n a 5, luego m =25
<< m << endl;
}
Resultadodeejecución:
3.5. Operadores relacionales
C++soportaeltipobool quetienedosliteralesfalse ytrue.Unaexpresiónbooleana es, porconsiguiente, unasecuenciade
operandosyoperadoresquesecombinanparaproducirunodelosv alores true y false.C++utilizaeltipo int pararepresentarlosvaloresverdadero(true) yfalso(false).Elvalorentero0representaaf alsoycualquiervalordistintodeceroav er-
CAPÍTULO 3 Operadores y expresiones
40
dadero.Operadorestalescomo >= y= = quecompruebanunarelaciónentredosoperandossellaman operadoresrelacionales
yseutilizanenexpresionesdelaforma:
expresión1 operador_relacional expresión2
expresionescompatiblesC++
unoperadordelaTabla3.5
expresión1 y expresión2
operador_relacional
LaTabla3.5muestralosoperadoresrelacionalesquesepuedenaplicaraoperandosdecualquiertipodedatoestándar:
etc.
char, int, float, double,
Tabla 3.5. Operadores relacionales de C
Operador
Significado
forma
==
!=
>
<
>=
<=
Iguala
Noiguala
Mayorque
Menorque
Mayoroigualque
Menoroigualque
a == b
a != b
a > b
a < b
a >= b
a <= b
Ejemplo
´A´= = C´
2 != 4
5 > 6
´a´<´c´
´B´>=´b´
2 <= 1
falso
verdadero
falso
verdadero
falso
falso
3.6. Operadores lógicos
Losoperadoreslógicos seutilizancone xpresionesparadevolverunvalorverdadero (cualquierenterodistintodecero)oun
valorfalso (0).LosoperadoreslógicosdeCson: not (!), and (&&) y or(||).Eloperadorunitariológico !(not, no) producefalso (cero)sisuoperandoes verdaderos (distintodecero)yvice versa.Eloperadorbinariológico && (and, y) produce
verdadero sólo siambosoperandossonverdaderos (nocero);sicualquieradelosoperandoses falso producefalso.Eloperadorbinariológico || (or, o) produceverdadero sicualquieradelosoperandosesverdadero (distintodecero)yproducefalso sólosiambosoperandosson falsos.
Laprecedenciadelosoperadoreses: losoperadoresmatemáticostienenprecedenciasobrelosoperadoresrelacionales, y
losoperadoresrelacionalestienenprecedenciasobrelosoperadoreslógicos.
Eloperador ! tieneprioridadmásaltaque &&, queasuv eztienemayorprioridadque ||.Laasociati vidadesdeizquierdaaderecha.
Evaluación en cortocircuito. EnC++losoperandosdelaizquierdade && y|| seevalúansiempreenprimerlugar;sielv alordeloperandodelaizquierdadeterminadeformainequív ocaelv alordelae xpresión, eloperandoderechonosee valúa.
Estosignificaquesieloperandodelaizquierdade && esfalsooelde || esverdadero, eloperandodeladerechanosee valúa.Estapropiedadsedenomina evaluaciónencortocircuito.
Lassentenciasdeasignaciónsepuedenescribirdemodoquesepuededarunv alordetipo bool ounavariablebool.
EJEMPLO 3.6. Sentenciasdeasignaciónalostiposdevariablesbool.
int n;
float x ;
char car;
bool r, esletra, espositiva;
r = (n > -100) && (n < 100);
// true si n están entre –110 y 100
esletra = (( ´A´<= car) && (car <= ´Z´))
((´a´<= car) && (car <= ´Z´));
//si car es una letra la variable es letra true, y toma false en otro caso
espositivo = x >= 0;
CAPÍTULO 3 Operadores y expresiones
41
3.7. Operadores de manipulación de bits
Losoperadoresdemanipulaciónotratamientodebits( bitwise)ejecutanoperacioneslógicassobrecadaunodelosbitsdelos
operandos.Estasoperacionessoncomparableseneficienciayenvelocidadasusequivalentesenlenguajeensamblador.Cada
operadordemanipulacióndebitsrealizaunaoperaciónlógicabitabitsobredatosinternos.Losoperadoresdemanipulación
debitsseaplicansóloav ariablesyconstantes char, int ylong, ynoadatosencomaflotante.La Tabla3.6recogelosoperadoreslógicosbitabit.
Tabla 3.6. Operadores lógicos bit a bit
Operador
&
|
^
~
<<
>>
Operación
y (and) lógicabitabit.
o (or) lógica(inclusiva)bitabit.
o (xor) lógica(exclusiva)bitabit(ore
xclusive, xor).
Complementoauno(inversióndetodoslosbits).
Desplazamientodebitsaizquierda.
Desplazamientodebitsaderecha.
3.7.1. OPERADORES DE DESPLAZAMIENTO DE BITS (>>, <<)
Efectúaundesplazamientoaladerecha( >>)oalaizquierda( <<)de numero_de_bits posicionesdelosbitsdeloperando,
siendonumero_de_bits unnúmeroentero.Losformatosdelosoperadoresdedesplazamientoson:
1. valor << numero_de_bits;
2. valor >> numero_de_bits;
EJEMPLO 3.7. Sentenciasdemanipulacióndebits.
variable
X
Y
x & y
x | y
x ^ y
x << 2
y >> 2
V.entero
9
10
8
11
3
36
2
Vbinario
00001001
00001010
00001000
00001011
00000011
01000100
00000010
1001
1010
1001&1010 and bitabit
1001|1010 or bitabit
1001^1010 xor bitabit
1000100 aparecendoscerosaladerecha
10
Elsiguienteprogramacompruebalosv aloresindicadosenlatablaanterior.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{ int x = 9, y = 10, x_y_y, x_or_y, x_Xor_y;
x_y_y = x & y;
x_or_y = x | y;
x_Xor_y = x ^ y;
cout << "x = " << x << " \n";
cout << "y = " << y << " \n";
cout << "x_y_y = " << x_y_y << " \n";
CAPÍTULO 3 Operadores y expresiones
42
cout << "x_or_y = " << x_or_y << " \n";
cout << "x_Xor_y = " << x_Xor_y << " \n";
x = x << 2;
y = y >> 2;
cout << "x << 2 = " << x << " \n";
cout << "y >> 2 = " << y << " \n";
system("PAUSE");
return EXIT_SUCCESS;
}
Elresultadodeejecucióndelprogramaanteriores:
3.7.2. OPERADORES DE ASIGNACIÓN ADICIONALES
Losoperadoresdeasignaciónabre viadosestándisponiblestambiénparaoperadoresdemanipulacióndebits.Estosoperadoressemuestranenla Tabla3.7.
Tabla 3.7. Operadores de asignación adicionales
Símbolo
<<=
>>=
&=
^=
||=
Uso
a
a
a
a
a
<<=
>>=
&=
^=
||=
Descripción
Desplazaaalaizquierda b bitsyasignaelresultadoa a.
Desplazaaaladerecha b bitsyasignaelresultadoa a.
Asignaa a elvalora & b.
Establecea aa ^ b.
Establecea aa | b.
b
b
b
b
b
3.7.3. OPERADORES DE DIRECCIONES
Sonoperadoresquepermitenmanipularlasdireccionesdelosobjetos.Serecogenenla Tabla3.8.
Tabla 3.8. Operadores de direcciones
Operador
Acción
*
Leeomodificaelvalorapuntadoporlaexpresión.Secorrespondeconunpunteroyelresultadoesdel
tipoapuntado.
Devuelveunpunteroalobjetoutilizadocomooperando, quedebeserunlvalue (variabledotadadeuna
direccióndememoria).Elresultadoesunpunterodetipoidénticoaldeloperando.
Permiteaccederaunmiembrodeunobjetoagre gado(unión, estructura).
Accedeaunmiembrodeunobjetoagre gado( unión, estructura)apuntadoporeloperandodelaizquierda.
&
.
->
3.8. Operador condicional ?
Eloperador condicional ?, esunoperadorternarioquede vuelveunresultadocuyov alordependedelacondicióncomprobada.Elformatodeloperadorcondicionales:
expresion_L ? expresion_v : expresion_f;
CAPÍTULO 3 Operadores y expresiones
43
Seevalúalaexpresiónlógica expresion_L ysuvalordeterminacuáleslaexpresiónaejecutar;silacondiciónes verdadera seejecuta expresion_v ysiesfalsaseejecuta expresion_f. Laprecedenciade? esmenorqueladecualquierotrooperandotratadohastaesemomento.Suasociati vidadesaderecha.
EJEMPLO 3.8. Usodeloperadorcondicional ?.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int x = 10, y =12, mayor, menor;
bool z;
z = x >= y ? true: false ;
// z toma el valor de false.
mayor = x >= y ? x : y;
// calcula y almacena el mayor
menor = x >= y ? y : x;
// calcula y almacena el mayor
cout << "x = " << x << " \n";
cout << "y = " << y << " \n";
cout << "el mayor es = " << mayor << " \n";
cout << "el menor es = " << menor << " \n";
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadosdeejecución:
3.9. Operador coma ,
Eloperadorcoma permitecombinardosomáse xpresionesseparadasporcomasenunasolalínea.See valúaprimerolae xpresióndelaizquierdaylue golasrestantese xpresionesdeizquierdaaderecha.Lae xpresiónmásaladerechadeterminael
resultadoglobaldelaexpresión.Elusodeloperadorcomaes:
expresión1, expresión2, expresión3, ..., expresión
Cadaexpresiónseevalúacomenzandodesdelaizquierdaycontinuandohacialaderecha.
EJEMPLO 3.9. Usodeloperadorcondicional ,.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i, j, r, k;
CAPÍTULO 3 Operadores y expresiones
44
r = j = 10, i = j, k = (i++, i+1) ;
cout <<" i= "<< << " j= " << j << " r= " << r <<" k= " << k <<"\n";
system("PAUSE");
return EXIT_SUCCESS;
}
Elresultadodeejecuciónes:
tomaelvalorde 10, r tomaelvalorde j quees 10, i tomaelvalorde 10.Posteriormente i tomaelvalor 11;seejecutala
expresióni+1 quees 12 yseasignaa k.
j
3.10. Operadores especiales ( ),
[ ]
y ::
C++admitealgunosoperadoresespecialesquesirv enparapropósitosdiferentes.Cabedestacar: (), [] y::.
Eloperador () eseloperadordellamadaafunciones.Sirv eparaencerrarlosar gumentosdeunafunción, efectuarconversionesexplícitasdetipo, indicarenelsenodeunadeclaraciónqueunidentif icadorcorrespondeaunafunciónyresolv er
losconflictosdeprioridadentreoperadores.
Eloperador [] sirveparadesignarunelementodeunarray .Tambiénsepuedeutilizarenuniónconeloperador delete;
enestecaso, indicaeltamañodelarrayadestruirysusintaxises: delete [tamaño_array] puntero_array;
Eloperador :: esespecíficodeC++ysedenomina operadordeámbitoderesolución, ypermiteespecificarelalcanceo
ámbitodeunobjeto.Susintaxises:
class::miembro
obien
::miembro
3.11. El operador sizeof
C++proporcionaeloperadorsizeof, quetomaunargumento, bienuntipodedatoobienelnombredeunavariable(escalar,
array, registro, etc.), yobtienecomoresultadoelnúmerodebytesqueocupa.Elformatodeloperadores:
sizeof(nombre_variable)
sizeof(tipo_dato)
sizeof expresión
EJEMPLO 3.10. Elsiguienteprogramaescribeeltamañodelostiposdedatosensuor denador.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
cout << " el tamaño de variables de esta computadora son:\n";
cout << " entero: " << sizeof(int) << '\n';
cout << " entero largo: " << sizeof(long int) << '\n';
cout << " rael: " << sizeof(float) << '\n';
cout << " doble: " << sizeof(double) << '\n';
cout << " long doble: " << sizeof(long double) << '\n';
cout << " long doble: " << sizeof 20 << '\n';
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 3 Operadores y expresiones
45
3.12. Conversiones de tipos
Lasconversionesdetipospuedenser implícitas (ejecutadasautomáticamente)oexplícitas (solicitadasespecíficamenteporel
programador).C++hacemuchascon versionesdetiposautomáticamente: conviertevalorescuandoseasignaunv alordeun
tipoaunavariabledeotrotipo;conviertevalorescuandosecombinantiposmixtosene xpresiones;conviertevalorescuando
sepasanargumentosafunciones.
Conversión implícita. Lostiposfundamentales(básicos)puedensermezcladoslibrementeenasignacionesyexpresiones.Las
conversionesseejecutanautomáticamente: losoperandosdetipomásbajosecon viertenalosdetipomásaltodeacuerdocon
lassiguientesreglas: sicualquieroperandoesdetipo char, short oenumeradoseconvierteentipo int;silosoperandostienendiferentestipos, lasiguienteslistadeterminaaquéoperacióncon vertirá.Estaoperaciónsellamapromocióninte gral.
int,
unsigned int,
long, unsigned long, float, double
Eltipoquevieneprimero, enestalista, seconvierteenelquevienese gundo, etc.
Conversiones explícitas. C++fuerzalaconversiónexplícitadetiposmedianteeloperadordemolde (cast).Eloperadormolde tieneelformato (tiponombre)valor.Conviertevalor a tiponombre.
Porejemplodadaladeclaración: float x;
x = 3/2
x = (float)3/2
asignaa x elvalorde 1,
asignaa x elvalorde 1.5
EJEMPLO 3.10. Elsiguienteprogramamuestraconversionesimplícitasyexplícitasdeenterosycaracteres.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char c = 'Z' +1 ;
// asigna a c el siguiente carácter de 'Z'
cout <<'A' <<" " << (int)'A' << endl;
//carácter y número ASCII
cout <<'0' <<" " << (int)'0' << endl;
//carácter y número ASCII
cout <<'a' <<" " << (int)'a' << endl;
//carácter y número ASCII
cout << c << " " << (int) c << endl;
//carácter y número ASCII
cout <<'Z'+1<<" "<<(char)('Z'+1 ) << endl; //número ASCII y carácter
system("PAUSE");
return EXIT_SUCCESS;
}
Laejecucióndelprogramaanteriores:
3.13. Prioridad y asociatividad
Laprioridad oprecedencia deoperadoresdeterminaelordenenelqueseaplicanlosoperadoresaunvalor.Alahoradeevaluarunaexpresiónhayquetenerencuentalassiguientesre glasylaTabla3.9.
• Losoperadoresdelgrupo1tienenmayorprioridadquelosdelgrupo2, yasísucesivamente.
CAPÍTULO 3 Operadores y expresiones
46
• Sidosoperadoresseaplicanalmismooperando, eloperadorconmayorprioridadseaplicaprimero.
• Todoslosoperadoresdelmismogrupotienenigualprioridadyasociati vidad.
• Laasociatividadizquierda-derecha significaaplicareloperadormásalaizquierdaprimero, yenlaasociatividadderecha-izquierda seaplicaprimeroeloperadormásaladerecha.
• Losparéntesistienenlamáximaprioridad.
Tabla 3.9. Prioridad y asociatividad de los oper adores
Prioridad
Operadores
Asociatividad
:: x -> [] ()
++ –– ~ ! - + & * sizeof
.* ->*
* / %
+ << >>
I–D
D–I
I–D
I–D
I–D
I–D
7
8
9
10
11
12
13
< <= > >=
= = !=
&
^
|
&&
||
I–D
I–D
I–D
I–D
I–D
I–D
I–D
14
15
16
?: (expresióncondicional)
= *= /= %= += -= <<= >>= &= ||= ^=
, (operadorcoma)
D–I
D–I
I
1
2
3
4
5
6
I-D: Izquierda–Derecha
D-I: Derecha–Izquierda.
EJERCICIOS
3.1.
Determinarelvalordelassiguientese xpresionesaritméticas:
15/12
24/12
123/100
3.2.
15%12
24%12
200%100
¿Cuáleselvalordecadaunadelassiguientese xpresiones?
a) 10*14–3*2
b) –4+5*2
c) 13–(24+2*5)/4%3
3.3.
d) (4–40/5)%3
e) 4*(3+5)–8*4%2–5
f) –3*10+4*(8+4*7–10*3)/6
Escribirlassiguientese xpresionesaritméticascomoe xpresionesdecomputadora: Lapotenciapuedehacer seconlafunciónpow(), porejemplo(x+y) 2==pow(x+y,2).
a)
b)
x
+
y
x +y
x –y
y
c) x +
z
1
d)
b
g)
c +d
e) (a +b)
c
d
f) [(a +b)2]2
h)
xy
1–4x
xy
mn
i) (x +y)2 .(a –b)
CAPÍTULO 3 Operadores y expresiones
47
3.4.
Escribirlassentenciasdeasignaciónquepermitanintercambiarloscontenidos(valores)dedosvariablesx, eydeunciertotipodedatos.
3.5.
Escribirunprogramaqueleadosenterosenlasvariablesxey, y, acontinuación, obtengalosvaloresde: a)x/y;b);x % y.
Ejecuteelprogramavariasvecescondiferentesparesdeenteroscomoentrada.
3.6.
UnatemperaturadadaengradosCelsius(centígrados)puedeserconvertidaaunatemperaturaequivalenteFahrenheitde
9
acuerdoalasiguientefórmula: f = c +32.Escribirunprogramaquelealatemperaturaengradoscentígradosylacon5
viertaagradosFahrenheit.
PROBLEMAS
3.1.
Larelaciónentreloslados(a,b)deuntriánguloylahipotenusa(h)vienedadaporlafórmula:
programaquelealalongituddelosladosycalculelahipotenusa .
3.2.
Escribirunprogramaqueleaunenteroy, acontinuación, visualicesudobleysutriple .
3.3.
Escribaunprogramaquelealoscoef icientesa, b, c, d, e, fdeunsistemalinealdedosecuacionescondosincógnitasy
muestrelasolución.
a2 +b2 =h2. Escribirun
ax +by =c
5 cx +dy =f
3.4.
Lafuerzadeatracciónentredosmasas, m1 ym2 separadasporunadistanciad, estádadaporlafórmula:
F =
G ∗ m1∗ m2
d2
dondeGeslaconstantedegr avitaciónuniversal, G =6.673.x10 –8 cm3/g.seg2
Escribaunprogramaquelealamasadedoscuerposyladistanciaentr eellosy, acontinuación, obtengalafuerzagravitacionalentreella.Lasalidadebeserendinas;undinaesigualagr .cm/seg2
3.5.
LafamosaecuacióndeEinsteinpar aconversióndeunamasamenener gíavienedadaporlafórmula: E =cm3, dondec
eslavelocidaddelaluzysuvalores: c =2.997925× 1010m/sg.Escribirunprogramaqueleaunamasaengr amosyobtengalacantidaddeenergíaproducidacuandolamasaseconvierteenenergía.Nota: Silamasasedaengramos, lafórmulaproduceleenergíaenergios.
3.6.
Escribirunprogramaparaconvertirunamedidadadaenpiesasusequivalentesen: a)yardas;b)pulgadas;dondec)centímetros, yd)metros(1pie=12pulgadas, 1yarda=3pies, 1pulgada=2,54cm, 1m=100cm).Leerelnúmerodepiese
imprimirelnúmerodeyardas, pies, pulgadas, centímetrosymetros.
3.7.
Escribirunprogramaenelqueseintroduzcacomodatosdeentradalalongituddelperímetrodeunterreno, expresadacon
tresnúmerosenterosquerepresentenhectómetros, decámetrosymetrosrespectivamente, yvisualiceelperímetroendecímetros.
3.8.
Escribirunprogramaquesolicitealusuariounacantidaddeeur osytransformelacantidadeneur osenbilletesymonedasdecursolegal(cambioóptimo).
CAPÍTULO 3 Operadores y expresiones
48
SOLUCIÓN DE LOS EJERCICIOS
3.1.
Hayquetenerencuentaque / enelcasodenúmerosenteroscalculaelcocientedeladivisiónenter a, y% calculaelresto
deladivisiónentera.Portantolosresultadosson:
15 / 12 =
24 / 12 =
123 / 100
200 / 100
3.2.
1
2
= 1
= 2
15 % 12 =
24 % 12 =
123 % 100
200 % 100
Lasoluciónporpasosdecadaunodeellosporpasoses:
a) 10 * 14 – 3 * 2
d) (4 – 40 / 5) % 3
140 – 3 * 2
140 – 6
134
(4 – 8) %3
–4 % 3
–1
b) 4 + 5 * 2
e) 4 * (3 + 5) – 8 * 4 % 2 – 5
4 + 10
14
4 * 8 – 8 * 4 % 2 – 5
32 – 8 * 4 % 2 – 5
32 – 32 % 2 – 5
32 – 0 – 5
32 – 5
27
c) 13 – (24 + 2 * 5) / 4 %3
13
13
13
13
11
3.3.
3.4.
–
–
–
–
f) –3 * 10 + 4 * (8 + 4 * 7 – 10 * 3) / 6
(24 + 10) / 4 %3
34 / 4 %3
8 %3
2
–30
–30
–30
–30
–30
–30
–30
–26
+
+
+
+
+
+
+
4 * (8 + 4 * 7 – 10 * 3) / 6
4 * (8 + 28 – 10 * 3) / 6
4 * (8 + 28 – 30) / 6
4 * (36 – 30) / 6
4 * 6 / 6
24 / 6
4
Lapotenciapuedehacerseconlafunción pow( ), porejemplo (x + y)2 = = pow(x+y,2)
a) x / y + 1
d) b / (c + d)
g) x * y /(1 – 4 * x)
b) (x + y) / (x – y)
e) (a + b) * (c / d)
h) x * y / (m * n)
c) x + y / z
f ) pow(pow(x + y, 2),2)
i) pow(x + y,2)*(a – b)
SiAux esunavariabledelmismotipoque x ey lassentenciaspedidasson:
Aux = x;
x = y;
y = Aux;
3.5.
3
0
= 23
= 0
Unacodificacióndelprogramasolicitadoes:
#include <cstdlib>
#include <iostream>
using namespace std;
CAPÍTULO 3 Operadores y expresiones
49
int main(int argc, char *argv[])
{
int x , y ;
cin >> x >> y ;
cout << x / y <<" "<< x % y<<
system("PAUSE");
return EXIT_SUCCESS;
endl;
}
Alejecutarvariasveceselprogramaseobservaque / obtieneelcocienteentero, y% obtieneelrestodeladivisiónentera.
3.6.
Unacodificacióndelprogramasolicitadoes:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float c, f;
cout << "Introduce grados ";
cin >> c;
f = c * 9 / 5 + 32;
cout << " grados fahrenheit = " << f << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
SOLUCIÓN DE LOS PROBLEMAS
3.1.
Elcódigosolicitaloslados, yvisualizalosladosylahipotenusa:
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
int main(int argc, char *argv[])
{
float a, b, h;
cout << "Introduce los lados ";
cin >> a >> b;
h = sqrt( a * a + b * b);
cout << " lado 1 = " << a << endl;
cout << " lado 2 = " << b << endl;
cout << " hipotenusa = " << h << endl;
CAPÍTULO 3 Operadores y expresiones
50
system("PAUSE");
return EXIT_SUCCESS;
}
Unresultadodeejecuciónes:
3.2.
Lacodificaciónpedidaes:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int x;
cout << " dame un numero entero ";
cin >> x;
x = 2 * x;
cout << "su doble es " << x << " su triple es " << 3 * x << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Unresultadodeejecuciónes:
3.3.
ax +by =c
5 cx +dy =f
Unsistemalinealdedosecuacionescondosincógnitas
tienesoluciónúnicasiysolamentesia * e – b * d
esdistintodecero, yademáslasoluciónvienedadaporlase xpresionessiguientes:
ce –bf
x =e
ae –bd
y =
af –cd
ae –bd
Elprogramacodificadosolicitaalusuariolosvaloresa, b, c, d, e, f, yencasodequee xistasoluciónlamuestra.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float a, b, c, d, e, f, denominador, x, y;
cout << " Introduzca el valor de a de b y de c ";
cin >> a >> b >> c;
CAPÍTULO 3 Operadores y expresiones
51
cout << " Introduzca el valor de d de e y de f " ;
cin >> d >> e >> f;
denominador = a * e – b * d;
if (denominador == 0)
cout << " no solucion\n";
else
{
x = (c * e - b * f) / denominador;
y = (a * f - c * d) / denominador;
cout << " la solucion del sistema es\n";
cout << " x = " << x << " y = " << y << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Unresultadodeejecucióndelprogramaanteriores:
3.4.
SedeclaralaconstantedegravitaciónuniversalG = 6.673e-8, asícomolasvariables masa1, masa2, distancia, fuerparaposteriormenteaplicarlafórmulaypr esentarelresultado:
za
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
const float G = 6.673e-8;
float masa1, masa2, distancia, fuerza;
cout << " Introduzca la masa de los dos cuerpos en gramos:\n ";
cin >> masa1 >> masa2;
cout<<" Introduzca la distancia entre ellos en centimetros:\n ";
cin >> distancia;
if (( masa1 <= 0 ) || ( masa2 <= 0) || ( distancia <= 0 ))
cout << " no solucion\n";
else
{
fuerza = G * masa1 * masa2 / (distancia * distancia);
cout << " la solucion es: \n";
cout << " Fuerza en dinas = "<< fuerza << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 3 Operadores y expresiones
52
Unaejecucióneslasiguiente:
3.5.
Unacodificacióneslasiguiente:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float m, energia;
const float c = 2.997925e+10;
cout << " introduzca masa\n ";
cin >> m;
energia = c * m * m * m;
cout << " energia en ergios : " << energia;
system("PAUSE");
return EXIT_SUCCESS;
}
3.6.
Elprogramaleeelnúmerodepiesyrealizalastransformacionescorrespondientesdeacuerdoconloindicado.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float pies, pulgadas, yardas, metros, centimetros;
cout << " Introduzca pies: \n ";
cin >> pies;
pulgadas = pies * 12;
yardas = pies / 3;
centimetros = pulgadas * 2.54;
metros = centimetros / 100;
cout << " pies " << pies << endl;
cout << " pulgadas " << pulgadas << endl;
cout << " yardas " << yardas << endl;
cout << " centimetros " << centimetros << endl;
cout << " metros " << metros << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 3 Operadores y expresiones
3.7.
53
Elprogramaquesecodificaleeloshectómetros, decámetrosymetrosyrealizalasconversionescorrespondientes.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int hectometros, decametros, metros, decimetros;
cout << " Introduzca hectometros, decametros y metros ";
cin >> hectometros >> decametros >> metros;
decimetros = ((hectometros * 10 + decametros) * 10 + metros) * 10;
cout << " numero de decimetros es "<< decimetros << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Unresultadodeejecucióndelprogramaanteriores:
3.8.
Paraobtenerelmenornúmer odebilletesymonedasdeeur obastaconcomenzarporelbilleteomonedademásaltovalor.Paraobtenerelnúmeroocantidadquehayquetomardeesamonedaobillete, secalculaelcocientedelacantidaddivididoporelvalor.Elrestodeladivisiónenter adelacantidaddivididoporelvaloreslanue vacantidadconlaquehay
quevolverahacerlomismo, peroconelsiguientebilleteomonedaenvalor.Siseconsideraelsistemamonetariodeleuro,
losbilletesymonedasson: billetes(quinientos, doscientos, cien, cincuenta, veinte, diezycincoeuros);monedas(dosyun
euro;cincuenta, veinte, diez, cinco, dosyuncéntimodeeur o).Elprogramaleelacantidadeneur osenunavariabler eal
CantidadOriginal.Latransformaacéntimosdeeur osyserealizanloscálculos.Posteriormentesevisualizanlosr esultados.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int quinientos, doscientos, cien, cincuenta, veinte, diez;
int cinco, dos, uno, cincuentac, veintec, diezc, cincoc, dosc, unc;
float CantidadOriginal;
long int cantidad;
cout << "Introduzca cantidad en euros ";
cin >> CantidadOriginal;
CantidadOriginal*=100; // se pasa de euros con decimales a centimos
cantidad = (int) CantidadOriginal;
// se trunca a centimos de euro
quinientos = cantidad / 50000; cantidad = cantidad % 50000;
doscientos = cantidad / 20000; cantidad = cantidad % 20000;
cien = cantidad / 10000; cantidad = cantidad % 10000;
cincuenta = cantidad / 5000; cantidad = cantidad % 5000;
veinte = cantidad / 2000; cantidad = cantidad % 2000;
CAPÍTULO 3 Operadores y expresiones
54
diez = cantidad / 1000; cantidad = cantidad % 1000;
cinco = cantidad / 500; cantidad = cantidad % 500;
dos = cantidad / 200; cantidad = cantidad % 200;
uno = cantidad / 100; cantidad =cantidad % 100;
cincuentac = cantidad / 50; cantidad = cantidad % 50;
veintec = cantidad / 20; cantidad = cantidad % 20;
diezc = cantidad / 10; cantidad = cantidad % 10;
cincoc = cantidad / 5; cantidad = cantidad % 5;
dosc = cantidad / 2; cantidad = cantidad % 2;
unc = cantidad;
cout << " cambio en moneda con el menor numero " << endl;
cout << " cantidad original en centimos: "<< CantidadOriginal << endl;
cout << " billetes de quinientos euros: " << quinientos << endl;
cout << " billetes de doscientos euros: "<< doscientos << endl;
cout << " billetes de cien euros : " << cien << endl;
cout << " billetes de cincuenta euros: " << cincuenta << endl;
cout << " billetes de veinte euros: "<< veinte << endl;
cout << " billetes de diez euros : " << diez << endl;
cout << " billetes de cinco euros: " << cinco << endl;
cout << " monedad de dos euros: "<< dos << endl;
cout << " monedad de un euro: " << uno << endl;
cout << " monedas de cincuenta centimos de euros: "<<cincuentac<<endl;
cout << " monedad de veinte centimos de eruro: "<< veintec << endl;
cout << " monedad de diez centimos de euro: " << diezc << endl;
cout << " monedas de cinco centimos de euros: " << cincoc << endl;
cout << " monedad de dos centimos de eruro: "<< dosc << endl;
cout << " monedad de un centimo de euro: " << unc << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Unaejecucióndelprogramaanteriores:
CAPÍTULO 3 Operadores y expresiones
55
EJERCICIOS PROPUESTOS
3.1.
Escribirunprogramaqueacepteunañoescritoencifras
arábigasyvisualiceelañoescritoennúmerosromanos,
dentrodelrango1000a2100.
Nota: Recuerdeque V=5, X=10, L=50, C=100,
D =500yM=1.000.
IV=4
MCM=1900
MCMXL=1940
3.2.
XL=40
CM=900
MCML=1950
MCMLX=196
MCMLXXXIX=1989
Escribirunprogramaquelealahoradeundíadenotaciónde24horasylarespuestaennotaciónde12horas.
Porejemplo, silaentradaes13:45, lasalidaserá:
1: 45PM
Elprogramapediráalusuarioqueintroduzcae xactamentecincocaracteres.Porejemplo, lasnueveenpuntoseintroducecomo
09:00
3.3.
Escribirunprogramaquedeterminesiunañoesbisiesto.Unañoesbisiestosiesmúltiplode4(porejemplo
1984).Sinembargo, losañosmúltiplosde100sóloson
bisiestoscuandoalav ezsonmúltiplesde400(por
ejemplo, 1800noesbisiesto, mientrasque2000si
lo es).
3.4.
Construirunprogramaqueindiquesiunnúmerointroducidoportecladoespositi vo, igualacero, onegativo,
utilizarparahacerlaseleccióneloperador?.
3.5.
Escribirunprogramaqueleadosenterosycalculeeimprimasuproducto, cocienteyelrestocuandoelprimerosedivideporelsegundo.
3.6.
Escribirunprogramaqueleatresnúmerosynosescribaelmayoryelmenor.
3.7.
Escribirunprogramaquesolicitealusuariolalongitud
yanchuradeunahabitacióny, acontinuación, visualice
susuperficieyperímetro.
3.8.
Escribirunprogramaqueleacuatronúmerosycalcule
lamediaaritmética.
3.9.
Escribirunprogramaqueleaelradiodeuncírculoy
calculesuárea, asícomolalongituddelacircunferenciadeeseradio.
3.10. Escribirunprogramaqueleaelradioylaalturadeun
conoycalculesuvolumenyáreatotal.
3.11. Escribirunprogramaqueleatresenterosdetresdígitos
ycalculeyvisualicesusumaysuproducto.Lasalida
serájustificadaaderecha.
3.12. Escribirunprogramaqueleatresnúmerosysielterceroespositi vocalculeyescribalasumadelostresnúmeros, ysiesne gativocalculeyescribasuproducto.
3.13. Sedeseacalcularelsalarionetosemanaldelostrabajadoresdeunaempresadeacuerdoalassiguientes
normas:
HorasSemanalestrabajadas<38aunatasadada.
Horasextras(38omás)aunatasa50por100superior
alaordinaria.
Impuestos0por100, sielsalariobrutoesmenoroigual
a600euros.
Impuestos10por100, sielsalariobrutoesmayorde
600euros.
CAPÍTULO 4
Estructuras de control
selectivas
(if, if-else, switch)
Introducción
Losprogramasdefinidoshastaestepuntoseejecutandemodosecuencial.Laejecucióncomienzaconlaprimerasentenciade
lafunciónyprosiguehastalaúltimasentencia, cadaunadelascualesseejecutaunasolav ez.Paralaresolucióndeproblemasdetipogeneralsenecesitalacapacidaddecontrolarcuálessonlassentenciasqueseejecutanyenquémomentos.Las
estructuras oconstruccionesdecontrol controlanlasecuenciaoflujodeejecucióndelassentencias.Lasestructurasdecontrolsedividenentresgrandescategoríasenfuncióndelflujodeejecución: secuencia, selección yrepetición.
Estecapítuloconsideralas estructurasselectivas ocondicionales —sentencias if y switch—quecontrolansiunasentenciaolistadesentenciasseejecutanenfuncióndelcumplimientoonodeunacondición.P arasoportarestasconstrucciones, C++tieneeltipológico bool.
4.1. Estructuras de control
Lasestructuras de control controlanelflujodeejecucióndeunprogramaofunción.Lasinstruccionesosentenciasseorganizanentrestiposdeestructurasdecontrolquesirv enparacontrolarelflujodelaejecución: secuencia, selección (decisión)yrepetición.Unasentencia compuesta esunconjuntodesentenciasencerradasentrella ves({y})queseutilizapara
especificarunflujosecuencial.
4.2. La sentencia if
EnC++, laestructuradecontrolprincipaldeselecciónesunasentencia if.Lasentencia if tienedosalternativasoformatos
posibles.Elformatomássencillotienelasintaxissiguiente:
if (Expresión) Acción
Acción
Expresión
seejecutasilaexpresiónlógicaesverdadera
lógicaquedeterminasilaacciónsehadeejecutar
57
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
58
Lasentencia if funcionadelasiguientemanera.Si Expresión esverdadera, seejecuta Acción;encasocontrarionose
ejecutaAcción.
expresión
verdadera
falsa
acción
Figura 4.1. Diagrama de flujo de una sentencia básica if
EJEMPLO 4.1. Pruebadedivisibilidaddedosnúmerosenteros.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int numero1, numero2;
cout << "Introduzca dos enteros:";
cin >> numero1 >> numero2;
if (numero1 % numero2 == 0)
cout << numero1 << " es divisible por " << numero2 << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadosdeejecucióndelprogramaanterior
Introduzca dos enteros: 25 5
25 es divisible por 5.
EJEMPLO 4.2. Decidirsiunnúmeroesmayorque10.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float numero;
cout << "Introduzca un número :";
cin >> numero;
// comparar número con diez
if (numero > 10)
cout << numero << "es mayor que 10" << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
59
EJEMPLO 4.3. Leertresnúmerosenterosyvisualizarelmayor.
Serealizamedianteunalgoritmovoraz, detalmanera, queelmayordeunsolonúmeroessiempreelpropionúmero.
Siyasetieneelmayordeunalistadenúmeros, ysiaesalistaseleañadeunnue vonúmeroentonceselmayorobien
eselqueyateníamos, obieneselnuevo.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int n1, n2, n3, mayor;
cout << " introduzca tres numeros ";
cin >> n1 >> n2 >> n3;
mayor = n1;
if (mayor < n2)
mayor = n2;
if (mayor < n3)
mayor = n3;
cout << " el mayor es :" << mayor << endl;
system("PAUSE");
return EXIT_SUCCESS;
// candidato a mayor
// nuevo mayor
// nuevo mayor
}
Resultadosdeejecucióndelprogramaanterior:
EJEMPLO 4.4. Leeundatorealyvisualizasuvalorabsoluto.
include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float Dato;
cout << "Introduzca un numero: ";
cin >> Dato;
if (Dato < 0)
Dato = - Dato;
//Cambio de signo
cout << " Valor absoluto siempre positivo " << Dato << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
4.3. Sentencia if de dos alternativas: if-else
Elformatodelasentencia if-else tienelasiguientesintaxis:
if (exprresión)
Acción1 else Acción2
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
60
Cuandoseejecutalasentencia if-else, seevalúaExpresión.SiExpresión esverdadera, seejecutaAcción1 yencaso
contrarioseejecuta Acción2.
Expresión
verdadera
Acción1
falsa
Acción2
Figura 4.2. Diagrama de flujo de la representación de una sentencia if-else
EJEMPLO 4.5. Leerunanota, yvisualizar baja siesmenorque100y alta enotrocaso.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int nota;
cout << " dame nota: ";
cin >> nota;
if (nota < 100)
cout << " Baja ";
else
cout << "Alta";
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 4.6. Leerelsalarioylosimpuestos. Visualizarelsalarioneto.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float Salario_bruto, Impuestos, Salario_neto;
cout << " introduzca salario bruto e impuestos ";
cin >> Salario_bruto >> Impuestos;
//lectura de datos
if (Salario_bruto > 600)
// restar los impuestos
Salario_neto = Salario_bruto - Impuestos;
else
//no restar impuestos
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
Salario_neto = Salario_bruto;
cout << Salario_neto << Salario_bruto;
system("PAUSE");
return EXIT_SUCCESS;
61
// visualización
}
4.4. Sentencias if-else anidadas
Unasentencia if esanidadacuandolasentenciadelarama verdadera olarama falsa, esasuv ezesunasentencia if.Una
sentenciaif anidadasepuedeutilizarparaimplementardecisionesconv ariasalternativasomulti-alternativas.
Sintaxis
if (condición1)
sentencia1;
else if (condición2)
sentencia2;
.
.
.
else if (condiciónn)
sentencian;
else
sentencia;
EJEMPLO 4.7. Leerlacalificación(nota)enunavariablereal, ymediante if anidadosescribirelresultado:
Menorque0omayorque10
0a<5.0
5a<6.5
6.5a<8.5
8.5a<10
10
<0 o >10
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float nota;
cout <<" dame nota: ";
cin >> nota;
if(( nota < 0.0 ) || ( nota > 10 ))
cout <<" Error en nota ";
else if ( nota < 5.0 )
cout << "Suspenso";
else if( nota < 6.5 )
cout << "Aprobado";
else if ( nota < 8.5)
cout << "Notable";
Error en nota
Suspenso
Aprobado
Notable
Sobresaliente
Matrícula de honor
Error en nota
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
62
else if ( nota < 10)
cout <<"Sobresaliente";
else
cout <<"Matricula de Honor";
system("PAUSE");
return EXIT_SUCCESS;
}
4.5. Sentencia de control switch
Lasentencia switch esunasentenciaC++queseutilizaparahacerunaselecciónentremúltiplesalternati vas.
Sintaxis
switch (selector)
{
case etiqueta1 : sentencias1;
case etiqueta2 : sentencias2;
.
.
.
case etiquetan : sentenciasn;
default:
sentencias;
}
// opcional
Laexpresiónselector debeseruntipoordinal( int, char, bool perono float ostring).Cadaetiqueta esunvalorúnico, constante, ycadaetiquetadebetenerunvalordiferentedelosotros.Laexpresióndecontroloselector seevalúa.Sisuvaloresigualaunadelasetiquetascase—porejemplo, etiquetai—entonceslaejecucióncomenzaráconlaprimerasentencia
delasecuenciasecuenciai ycontinuaráhastaqueseencuentraelf inaldelasentenciadecontrol switch, ohastaencontrarla
sentenciabreak.
EJEMPLO 4.8. Sentenciaswitch parainformarsobrelalecturadeunaopcióndentrodeunrango.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int opcion;
cout << "introduzca opcion entre 0 y 3:";
cin >> opcion;
switch (opcion)
{
case 0:
cout << "Cero!" << endl;
break;
case 1:
cout << "Uno!" << endl;
break;
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
63
case 2:
cout << "Dos!" << endl;
break;
case 3:
cout << "Tres!" << endl;
break;
default:
cout << "Fuera de rango" << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 4.9. Sentenciaswitch concaracteres.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char nota;
cout << "Introduzca calificación (S, A, B, N, E) :";
cin >> nota;
switch (nota)
{
case 'E': cout << "Sobresaliente.";
break;
case 'N': cout << "Notable.";
break;
case 'B': cout << "Bien.";
break;
case 'A': cout << "Aprobado.";
break;
case 'S': cout << "Suspens.";
break;
default:
cout << "no es posible esta nota";
}
system("PAUSE");
return EXIT_SUCCESS;
}
4.6. Expresiones condicionales: el operador ?:
Unaexpresióncondicionaltieneelformato C ? A : B yesrealmenteunaoperaciónternaria(tresoperandos)enlaque C, A
yB sonlostresoperandosy ?: eseloperador.
Sintaxis
condición ? expresión1: expresión2
condición
expresión1 | expresión2
esunaexpresiónlógica
sonexpresionescompatiblesdetipos
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
64
Seevalúacondición, sielvalordecondición esverdadera(distintodecero)entoncessedevuelvecomoresultadoelvalorde expresión1;sielvalorde condición esfalsa(cero)sedevuelvecomoresultadoelvalorde expresión2.
EJEMPLO 4.10. Sentencia?: paradecidirelordendedosnúmeros.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int n1, n2;
cout << " introduzca dos numeros ";
cin >> n1 >> n2 ;
n1 > n2 ? cout << n1 << " > " << n2
: cout << n1 << " <= " << n2;
system("PAUSE");
return EXIT_SUCCESS;
}
#include <cstdlib>
#include <iostream>
using namespace std;
EJEMPLO 4.11. Escribeelmayordedosnúmerosusando?:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int n1, n2, mayor;
cout << " introduzca dos numeros ";
cin >> n1 >> n2 ;
mayor = n1 > n2 ? n1 : n2;
cout << " el mayor es: " << mayor << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadodeejecución
4.7. Evaluación en cortocircuito de expresiones lógicas
Laevaluaciónencortocircuitodeunaexpresiónlógicasignificaquesepuededetenerlae valuacióndeunae xpresiónlógica
tanprontocomosuv alorpuedaserdeterminadoconabsolutacerteza.C++realizae valuaciónencortocircuitoconlosoperadores && y ||, demodoquee valúaprimerolae xpresiónmásalaizquierda, delasdose xpresionesunidaspor && obien
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
65
por ||.Sideestaevaluaciónsededucelainformaciónsuf icienteparadeterminarelvalorfinaldelaexpresión(independientedelvalordelasegundaexpresión), elcompiladordeC++noevalúalasegundaexpresión.Estacaracterísticapermite, engeneral, disminuireltiempodeejecución.
EJERCICIOS
4.1.
¿Quéerroresdesintaxistienelasiguientesentencia?
if
x > 25.0
y = x
else
y = z;
4.2.
¿Quévalorseasignaa consumo enlasentencia if siguientesivelocidades 120?
if (velocidad > 80)
consumo = 10.00;
else if (velocidad > 100)
consumo = 12.00;
else if (velocidad > 120)
consumo = 15.00;
4.3.
¿Quésalidaproduciráelcódigosiguiente, cuandoseinsertaenunprogramacompleto?
int primera_opcion = 1;
switch (primera_opcion + 1)
{
case 1:
cout << "Cordero asado\n";
break;
case 2:
cout << "Chuleta lechal\n";
break;
case 3:
cout << "Chuletón\n";
case 4:
cout << "Postre de pastel\n";
break;
default:
cout << "Buen apetito\n";
}
4.4.
¿Quésalidaproduciráelsiguientecódigo, cuandoseinsertaenunprogramacompleto?
int x = 2;
cout << "Arranque\n";
if (x <= 3)
if (x != 0)
cout << "Hola desde el segundo if.\n";
else
cout << "Hola desde el else.\n";
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
66
cout << "Fin\n";
cout << "Arranque de nuevo\n";
if (x > 3)
if (x != 0)
cout << "Hola desde el segundo if.\n";
else
cout << "Hola desde el else.\n";
cout << "De nuevo fin\n";
4.5.
Escribirunasentenciaif-else quevisualicelapalabraAlta sielvalordelavariablenotaesmayorque 100 yBaja siel
valordeesanotaesmenorque 100.
4.6.
¿Cuáleslasalidadeestese gmentodeprograma?
int x = 1;
cout << x << endl;
{
cout << x << endl;
int x = 2;
cout << x << endl;
{
cout << x << endl;
int x = 3;
cout << x << endl;
}
cout << x << endl;
}
4.7.
Escribirunasentencia if-else queclasifiqueunenteroxenunadelassiguientescate goríasyescribaunmensajeadecuado:
x < 0
4.8.
obien
0 ≤ x ≤ 100
obien
x > 100
Escribirunprogramaquedeterminesiunañoesbisiesto.Unañoesbisiestosiesmúltiplode4(porejemplo1984).Sin
embargo, losañosmúltiplosde100sólosonbisiestoscuandoalavezsonmúltiplosde400(porejemplo, 1800noesbisiesto, mientrasque2000síloes).
PROBLEMAS
4.1.
Escribirunprogramaqueintroduzcaelnúmerodeunmes(1a12)yelañoyvisualiceelnúmer odedíasdeesemes.
4.2.
Cuatroenterosentre0y100r epresentanlaspuntuacionesdeunestudiantedeuncur sodeinformática.Escribirunpr ogramaparaencontrarlamediadeestaspuntuacionesyvisualizarunatabladenotasdeacuer doalsiguientecuadro:
Media
Puntuación
[90-100]
[80-90)
[70-80)
[60-70)
[0-60)
A
B
C
D
E
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
4.3.
67
Sedeseacalcularelsalarionetosemanaldelostr abajadoresdeunaempresadeacuerdoalassiguientesnormas:
Horassemanalestrabajadas<=38, aunatasadada.
Horasextras(38omás), aunatasa50por100superioralaordinaria.
Impuestos0por100, sielsalariobrutoesmenoroiguala300euros.
Impuestos10por100, sielsalariobrutoesmayorde300euros.
4.4.
Escribirunprogramaqueleadosnúmerosenterosyvisualiceelmenordelosdos.
4.5.
Escribirycomprobarunprogramaqueresuelvalaecuacióncuadrática (ax2 +bx +c =0).
4.6.
Escribirunprogramaqueleatresenterosyemitaunmensajequeindiquesiestánonoenor dennumérico.
4.7.
Escribirunprogramaquelealosvaloresdetresladosposiblesdeuntriánguloa, byc, ycalculeenelcasodequeformen
untriángulosuáreaysuperímetro, sabiendoquesuáreavienedadaporlasiguientee xpresión:
Área =œw
p(p –a)(p –w
b)(p –c)
dondepeselsemiperímetrodeltriángulo p =(a +b +c)/2
4.8.
Escribiryejecutarunprogramaquesimuleuncalculadorsimple.Leedosenterosyuncarácter.Sielcarácteresun+, se
visualizalasuma;siesun–, sevisualizaladifer encia;siesun*, sevisualizaelpr oducto;siesun/, sevisualizaelcociente;ysiesun%seimprimeelr esto.
4.9.
Escribirunprogramaquecalculelosángulosa gudosdeuntriángulorectánguloapartirdelaslongitudesdeloscatetos.
SOLUCIÓN DE LOS EJERCICIOS
4.1.
Laexpresióncorrectadebeserlasiguiente:
if (x > 25.0 )
y = x;
else
y = z;
Portanto, lefaltalosparéntesisenlae xpresiónlógicayunpuntoycomadespuésdelasentenciadeasignación y = x.
4.2.
Sivelocidadtomaelvalorde120entoncesnecesariamenteconsumo debetomarelvalorde10.00, yaqueseevalúalaprimeracondiciónyesciertaporloqueseejecutalasentencia consumo = 10.00;.
4.3.
Apareceescrito Chuleta lechal.Sia primera opción seleasignaraelvalorde2entoncesapareceescrito Chuletón y
enlasiguientelínea Postre depastel, yaque case 3: nollevalaordenbreak.
4.4.
Lasalidadelprogramaes:
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
68
4.5.
Unacodificacióneslasiguiente:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int nota;
cout << " dame nota: ";
cin >> nota;
if (nota < 100)
cout << " Baja ";
else if (nota > 100)
cout << "Alta";
system("PAUSE");
return EXIT_SUCCESS;
}
4.6.
Lasalidadelprogramaes:
4.7.
Unacodificacióneslasiguiente:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int x;
cout << " dato ";
cin >> x;
if (x < 0)
cout << "es negativo\n";
else if (x <= 100)
cout << "0 <= x = %d <=
else
cout << " > 100";
system("PAUSE");
return EXIT_SUCCESS;
}
100";
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
4.8.
69
Lavariablebooleanabisiestoseponea true sielañoesbisiesto.Estoocurrecuandoesdivibleelañopor400, oesdivisiblepor4ynopor100.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int x;
bool bisiesto;
cout << " introduzca año entero ";
cin >> x;
if (x % 400 == 0)
bisiesto = true;
else if (x % 100 == 0)
bisiesto = false;
else
bisiesto =(x % 4 == 0);
if (bisiesto)
cout << x << " es bisiesto\n";
else
cout << x << " no es un año bisiesto\n";
system("PAUSE");
return EXIT_SUCCESS;
}
SOLUCIÓN DE LOS PROBLEMAS
4.1.
Pararesolverelproblema, sehadetenerencuentaqueelmes2corr espondeafebreroquepuedetener29o28díasdependiendodesiesonobisiestoelañocorr espondiente.Deestaforma, ademásdeleerelmes, seleeelaño, ysedecidesi
elañoesbisiestodeacuerdoconloindicadoenelEjercicioresuelto4.8parasabersielmesdefebrerotiene28o29días.
Elrestodelomesestiene31díase xceptoabril, junio, septiembreynoviembrequecorrespondenalosmeses4, 6, 9y11.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int mes, ano;
bool bisiesto;
cout << " introduzca mes entre 1 y 12 ":
cin >> mes;
cout << " introduzca año entero ";
cin >> ano;
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
70
if (x % 400 == 0)
bisiesto = true;
else if (ano % 100 == 0)
bisiesto = false;
else
bisiesto = (ano % 4 == 0);
if (mes == 2)
if(bisiesto)
cout << " tiene 29 dias\n";
else
cout << " tiene 28 dias\n";
else
if((mes == 4) || (mes == 6) || (mes == 9) || (mes == 11))
cout << " tiene 30 dias \n";
else
cout <<" tiene 31 dias \n";
system("PAUSE");
return EXIT_SUCCESS;
}
4.2.
Elprogramaqueseescribe , leelascuatronotasenteras, calculalamediar eal, yescribelamediaobtenidaysupuntuacióndeacuerdoconlatablaindicadausandoifanidados.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int nota1, nota2, nota3, nota4;
float media;
cout << "Dame nota 1 ";
cin >> nota1;
cout << "Dame nota 2 ";
cin >>nota2;
cout << "Dame nota 3 ";
cin >>nota3;
cout << "Dame nota 4 ";
cin >>nota4;
media = (float)(nota1 + nota2 + nota3 + nota4) / (float)4;
if(( media < 0) || ( media > 100 ))
cout << "fuera de rango ";
else if( media >= 90)
cout << " media = " << media << " A";
else if(media >= 80)
cout << "media = " << media << " B";
else if(media >= 70)
cout << "media = " << media << " C";
else if(media >= 60)
cout << "media = " << media << " D";
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
71
else
cout << "media = " << media << "E";
system("PAUSE");
return EXIT_SUCCESS;
}
4.3.
SeescribeunprogramaqueleelasHoras, laTasa, ycalculalashorasextras, asícomoelSalarioBruto yelSalarioNedeacuerdoconlaespecificación, visualizandolosresultados.
to
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float Horas, Extras, Tasa, SalarioBruto, SalarioNeto;
cout << " dame Horas\n";
cin >> Horas;
if ( Horas <= 38 )
Extras = 0;
else
{
Horas = 38;
Extras = Horas - 38;
}
cout <<"introduzca Tasa\n";
cin >> Tasa;
SalarioBruto = Horas * Tasa + Extras * Tasa * 1.5;
if (SalarioBruto < 50000.0)
SalarioNeto = SalarioBruto;
else
SalarioNeto = SalarioBruto * 0.9;
cout <<" Salario bruto " << SalarioBruto << endl;
cout <<" Salario neto "<< SalarioNeto << endl ;
system("PAUSE");
return EXIT_SUCCESS;
}
Unresultadodeejecucióneselsiguiente:
4.4.
Sesolicitanlosdosnúmeros.Sinumero1 esmenorquenumero2, lacondiciónes“verdadera” (true);encasocontrariola
condiciónes“falsa” (false).Deestemodosevisualiza numero1 cuandoesmenorque numero2.
#include <cstdlib>
#include <iostream>
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
72
using namespace std;
int main(int argc, char *argv[])
{
int numero1, numero2;
cout << "Introduzca dos enteros:";
cin >> numero1 >> numero2;
if (numero1 < numero2)
cout << numero1 << endl;
else
cout << numero2 << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
4.5.
Pararesolverelproblemasehatenidoencuentaque:
• Sia <> 0 sepresentantrescasos: elprimerocondossolucionesdadasporlafórmulaquedalasolucióndelaecuación
b2 –4ac
–b± œw
desegundogradocuandoeldiscriminante d =b2 –4ac espositivox =
.Elsegundoconunasolución
2a
–b
dadaporlafórmulacuandoeldiscriminanteescerox = .Eltercerocondossolucionescomplejas, dadasporlafórmu2a
b2 –4ac –b
b2 –4ac
–b
œw
œw
la+
i
y+
i
cuandoeldiscriminanteesnegativo.
2a
2a
2a
2a
c
• Si a = 0 sepresentanasuv ezotrostrescasos: elprimeroescuando b <> 0 cuyasoluciónes x =– .Elsegundoes
b
cuandob = 0 yc = 0, queesevidentementeunaidentidad.Eltercerocuando b = 0 yc <> 0 quenopuedetenersolución.
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
int main(int argc, char *argv[])
{
float a, b, c, d, x1,x2;
cout << "introduzca los tres coeficientes\n";
cin >> a, b, c;
if (a != 0)
{
d = b * b - 4 * a * c;
if (d > 0)
{
cout << " dos soluciones reales y distintas\n";
x1 = (-b + sqrt(d)) / (2 * a);
x2 = (-b - sqrt(d)) / (2 * a);
cout <<" x1= " << x1 << " x2= "<< x2 << endl;
}
else if(d == 0)
{
cout << " dos soluciones reales e iguales\n";
x1 = (-b) / (2 * a);
cout << " x= " << x1;
}
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
else
{
cout
cout
x1 =
x2 =
cout
cout
cout
cout
cout
cout
}
73
<< " no tiene solucion real\n";
<< " tiene dos soluciones complejas \n";
-b / (2 * a);
sqrt(-d) / (2 * a);
<< " primera solucion\n";
<<" parte real "<< x1 << endl;
<<" parte imaginaria "<< x2 << endl;
<<" segunda solucion\n";
<<" parte real "<< x1 << endl;
<<" parte imaginaria "<< -x2 << endl;
}
else if (b != 0)
cout << " una solucion simple= " << -c / b;
else if (c == 0)
cout << " se introdujo la identidad 0 = 0\n";
else
cout <<" sin solucion\n";
system("PAUSE");
return EXIT_SUCCESS;
}
4.6.
Lacodificaciónusalasentencia ?: yademáslasentenciadeselección if.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int x, y, z;
bool ordenados;
cin >> x >> y >> z;
ordenados = x >= y ? true : false;
ordenados = ordenados && (y >= z ? true : false);
if (ordenados)
cout << " estan ordenados" << endl;
else
cout << " no ordenados " << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
4.7.
Paraqueeltriánguloe xistadebecumplir sequelosladosseantodospositivosy , además, quelasumadedosladoscualesquieraseamayorqueelotrolado.Elprogramaobtenidocompruebaquelosdatosleídoscumplenlascondiciones, yescribeencasodeformaruntriángulosuár eaysuperímetro.
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
// contiene la función pow
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
74
int main(int argc, char *argv[])
{
float a, b, c, p, area;
cout << "Introduzca el valor de los tres lados";
cin >> a >> b >> c;
if ((a <= 0) || (b <= 0) || (c <= 0) ||
((a + b) < c) || ((a + c) < b) || ((b + c) < a))
cout << " Los lados no dan un triángulo \n";
else
{
p =(a + b + c)/ 2;
area = pow(p * ( p - a ) * ( p - b ) * ( p - c) , 0.5);
cout << "la solucion es\n";
cout << "area = " << area << endl;
cout << " perimetro = " << p * 2 << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
4.8.
Elprogramaleelosdosoperadores, eloperandoyvisualizalasalidadeacuer doconlosolicitado.
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
int main(int argc, char *argv[])
{ int operando1, operando2;
char operador;
cout << " Introduzca dos numeros enteros ";
cin >> operando1 >> operando2;
cout << " Introduzca operador + - * / % ";
cin >> operador;
switch(operador)
{
case '+': cout << operando1 + operando2;
break;
case '-': cout << operando1 - operando2;
break;
case '*': cout << operando1 * operando2;
break;
case '/': cout << operando1 / operando2;
break;
case '%': cout << operando1 % operando2;
break;
default: cout << " fuera de rando";
}
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
4.9.
75
Secalculalahipotenusaporlafórmuladelteor emadepitágor as, yseobtieneelángulomediantelafunciónin versadel
senoquees asin( ) queseencuentraen math.h.Además, seconvierteelvalorde vueltoporlafunciónar cosenoagr ados(lafunciónarcosenodasuresultadoenradianes).
#include <cstdlib>
#include <iostream>
#include <math.h>
#define pi 3.141592
using namespace std;
int main(int argc, char *argv[])
{
float a, b, h, angulo;
cout << "Introduce los lados ";
cin >> a >> b;
if (( a <= 0 ) || ( b <= 0 ))
cout << " no solucion\n";
else
{
h = sqrt( a * a + b * b);
angulo = 180 / pi * asin( a /
cout << " hipotenusa = " << h
cout << "
angulo = " <<
cout << "otro angulo = " <<
}
system("PAUSE");
return EXIT_SUCCESS;
h); // ángulo en grados
<< endl;
angulo << endl;
90- angulo << endl;
}
Unresultadodeejecuciónes:
EJERCICIOS PROPUESTOS
4.1.
Expliquelasdiferenciasentrelassentenciasdelacolumnadelaizquierdaydelacolumnadeladerecha.
Paracadaunadeellasdeducirelv alorfinalde x, siel
valorinicialde x es0.
4.2.
if (x >= 0)
x = x+1;
else if (x >= 1);
x = x+2;
4.3.
if (x >= 0)
x = x+1;
if (x >= 1)
x = x+2;
¿Quéhaydeincorrectoenelsiguientecódigo?
if (x = 0) cout << x << " = 0\n";
else cout << x << " != 0\n";
¿Cuáleselerrordelsiguientecódigo?
if (x < y < z) cout << x << "<" << y << "<"
<< z << endl;
CAPÍTULO 4 Estructuras de control selectivas (if, if-else, switch)
76
4.4.
¿Cuáleselerrordeestecódigo?.
cout << "Introduzca n:";
cin >> n;
if (n < 0)
cout << "Este número es negativo. Pruebe
de nuevo .\n";
cin >> n;
else
cout << "conforme. n= " << n << endl;
4.5.
Determinarsielcarácterasociadoauncódigointroducidoportecladocorrespondeauncarácteralf abético,
dígito, depuntuación, especialonoimprimible.
PROBLEMAS PROPUESTOS
4.1.
EldomingodePascuaeselprimerdomingodespuésde
laprimeralunallenaposterioralequinocciodeprimavera, ysedeterminamedianteelsiguientecálculo:
A=añomod19
B=añomod4
C=añomod7
D=(19 ∗ A+24)mod30
E=(2 ∗ B+4 ∗ C+6 ∗ D+5)mod7
N=(22+D+E)
dondeN indicaelnúmerodedíadelmesdemarzo(si N
esigualomenorque30)oabril(siesmayorque31).
ConstruirunprogramaquedeterminefechasdedomingosdePascua.
4.2.
Construirunprogramaqueindiquesiunnúmerointroducidoportecladoespositi vo, igualacero, onegativo.
4.3.
Sequierecalcularlaedaddeunindi viduo, paraellose
vaatenercomoentradadosfechasenelformato día
(1 a31), mes (1a12)y año (enterodecuatrodígitos),
correspondientesalafechadenacimientoylafechaactual, respectivamente.Escribirunprogramaquecalcule yvisualicelaedaddelindividuo.Sieslafechadeun
bebé(menosdeunañodeedad), laedadsedebedaren
mesesydías;encasocontrario,
en años.
laedadsecalculará
4.4.
Sedesealeerlasedadesdetresdeloshijosdeunmatrimonioyescribirlaedadmayor , lamenorylamedia
delastresedades.
4.5.
Escribirunprogramaqueaceptefechasescritasde
modousualylasvisualicecomotresnúmeros.Por
ejemplo, laentrada15, Febrero1989producirálasalida
15021989.
4.6.
Escribirunprogramaqueacepteunnúmerodetresdígitosescritoenpalabrasy, acontinuación, losvisualice
comounvalordetipoentero.Laentradaseterminacon
unpunto.porejemplo, laentradadoscientos veinticinco, producirálasalida 225.
4.7.
Sedesearedondearunenteropositi vo N alacentena
máspróximayvisualizarlasalida.P araellolaentrada
dedatosdebeserloscuatrodígitos A, B, C, D, delentero
N.Porejemplo, si A es2, B es3, C es6y D es2, entoncesN será2362yelresultadoredondeadoserá2400.Si
N es2342, elresultadoserá2300, ysi N =2962, entonceselnúmeroserá3000.Diseñarelprogramacorrespondiente.
CAPÍTULO 5
Estructuras
de control repetitivas
( while, for, do-while)
Introducción
Enestecapítuloseestudianlas estructurasdecontroliterativas orepetitivas querealizanlaiteracióndeacciones.C++soportatrestiposdeestructurasdecontrol: losbucles while, for y do–while.Estasestructurasdecontrolosentenciasrepetitivascontrolanelnúmerodev ecesqueunasentenciaolistasdesentenciasseejecutan.
5.1. La sentencia while
Unbucle while tieneunacondición delbucle(expresiónlógica)quecontrolalasecuenciaderepetición.Laposicióndeesta
condicióndelbucleesdelantedelcuerpodelbucleysignificaqueunbuclewhile esunbuclepretest demodoquecuandose
ejecutaelmismo, seevalúalacondiciónantes dequeseejecuteelcuerpodelb ucle.
condición
falsa
verdadera
sentencia (acción)
Figura 5.1. Diagrama del bucle while
Sintaxis
1
while (condición_bucle)
sentencia;
cuerpo
77
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
78
2 while (condición_bucle)
{
sentencia-1;
sentencia-2;
.
.
.
sentencia-n;
}
cuerpo
Lassentenciasdelcuerpodelb ucleserepiten mientras quelae xpresiónlógica(condicióndelb ucle)seav erdadera.
Cuandoseevalúalaexpresiónlógicayresultaf alsa, seterminayse sale delbucleyseejecutalasiguientesentencia
deprogramadespuésdelasentencia while.
EJEMPLO 5.1. Buclemientras paraescribirdelosnúmerosdel1 al10.EncadaiteraciónseescribeelsímbolocarácterX, elcontenidodex, seincrementax enunaunidadysesaltadelínea.Comienzaelbucleconelvalordex en 1
ysesaledelbucleconelvalordex a11, peroelúltimovalorescritoes10, yaqueelincrementodelvalordex enuna
unidadserealizadespuésdehabersidoescritoelvalorde x.
int x = 1;
while ( x <= 10)
cout <<"X: " << x++ << endl;
EJEMPLO 5.2. Bucleinfinito.Elcontador seinicializaa1 (menorde100)ycomocontador-- decrementaen1 el
valordecontador encadaiteración, elvalordelcontador nuncallegaráavaler100, queeselvalornecesariopara
quelacondicióndelbucleseafalsa.
int contador = 1;
while (contador < 100)
{
cout << contador << endl;
contador--;
}
//decrementa en 1 contador
Bucles controlados por contadores
Sonbuclesenloscualeslavariabledecontrol contador seincrementaodecrementaencadaiteraciónenunacantidadconstante.Lavariabledecontrol contador seinicializaantesdecomenzarelb ucleaunvalor.Secompruebaelv alorde contador antesdequecomiencelarepeticióndecadab ucle, yencadaiteraciónopasadaseincrementaodecrementaenunacantidadconstante.
EJEMPLO 5.3. Lasumadelaserie1/2 + 1/3 + 1/4 + 1/5 + ... + 1/50 serealizamedianteelusodeuncontadorn.Porcadavalordelavariablecontador n delrango 1 hasta 50 seejecutalasentenciadeacumularen suma
elvalorde 1/n.Elfragmentodeprogramasiguienteinicializaelacumulador suma a 0, elcontador n a 1 posteriormenterealizalasumamedianteelcontadorr ealn (obligaaqueelcociente 1/n seareal)ypresentaelresultado.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
79
float suma = 0, n = 1;
while (n <= 10)
{
// n es real para que el cociente 1/n sea en coma flotante
suma += 1 / n;
n++;
}
cout << suma ;
system("PAUSE");
return EXIT_SUCCESS;
}
Elresultadodeejecucióndelprogramaanteriores: 2.92897
EJEMPLO 5.4. Elbucleadecuadopararesolverlatareadesumarlosenterosdelintervalo11..50, esunbuclecontroladoporun contador n.Seinicializaelacumulador suma a 0.Elcontadorenter o n seinicializaa 11, seincrementaencadaiter aciónenunaunidadhastalle gara 50.Elcontador n seacumulaenelacumulador suma encada
iteracióndelbuclewhile paralosvaloresdelrangocomprendidoentre11 y50.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int suma = 0, n = 11;
while (n <= 50)
{
suma = suma + n;
n++;
}
cout << suma ;
system("PAUSE");
return EXIT_SUCCESS;
}
Laejecucióndelprogramaanteriordacomoresultado: 1220.
Bucles controlados por centinelas
Uncentinelaesunvalordefinidoyespecificadoquesirveparaterminarelprocesodelb ucle.Estevalordebeserelegidocon
cuidadoporelprogramadorparaquenoseaunposibledatoyademásnoafectealnormalfuncionamientodelb ucle.
EJEMPLO 5.5. Leerlasnotasdeunalumnousandocomovalorcentinelapar alaentradadenotaselvalorde –1.
Sedefineunaconstanteenteracentinela conelvalorde –1.Enlavariable nota seleenlosdatosdelaentr ada.La
variable contador cuentaelnúmerototaldenotasintr oducidas, yelacumulador suma contienelasumatotaldelas
notasintroducidas.Elbuclewhile estácontroladoporelvalordecentinela.Encadaiteraciónseincrementaelcontador deenunaunidad, seleeunanuevanota yseacumulaen suma.Obsérvesequelavariable contador, siempre
contieneunaunidadmenosdelnúmerodedatosquehansidointr oducidos.
#include <cstdlib>
#include <iostream>
using namespace std;
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
80
int main(int argc, char *argv[])
{
const int centinela = -1;
float nota, contador = 0, suma = 0;
cout << "Introduzca siguiente nota -1 centinela: ";
cin >> nota;
while (nota != centinela)
{
contador++;
suma += nota;
cout << "Introduzca la siguiente nota: -1 centinela: ";
cin >> nota;
}
// fin de while
if (contador >0)
cout << "media = " << suma / contador << endl;
else
cout << " no hay notas ";
system("PAUSE");
return EXIT_SUCCESS;
}
Bucles controlados por indicadores (banderas)
Lasvariablestipo bool seutilizancomoindicadoreso banderasdeestado. Elvalordelindicadorseinicializa(normalmente
afalse)antesdelaentradaalbucleyseredefine(normalmenteatrue)cuandounsucesoespecíficoocurredentrodelbucle.
Unbuclecontroladoporbandera-indicador seejecutahastaqueseproduceelsucesoanticipadoysecambiaelv alordelindicador.
EJEMPLO 5.6. Seleenrepetidamentecaracteresdeltecladoysedetiene , cuandoseintroduceundígito.Sedef ine
unabanderadigito_leido queseinicializaa false, ysecambiaalvalorde true cuandoseleeundígito.Elb ucle
queresuelveelproblemaestácontroladoporlabander a digito_leido, yencadaiter aciónsolicitauncarácter, se
leeenlavariable car, ysiesundígitocambiaelvalordelabander a.Alfinaldelbucleseescribeeldígitoleído.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char car;
bool digito_leido = false;
// no se ha leído ningún dato
while (!digito_leido)
{
cout << "Introduzca un carácter dígito para salir del bucle :";
cin >> car;
digito_leido = (('0'<= car) && (car <= '9'));
}
// fin de while
cout << car << " es el dígito leído" << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
81
La sentencia break en los bucles
Lasentenciabreak seutiliza, aveces, pararealizarunaterminaciónanormaldelbucle.Dichodeotromodo, unaterminación
antesdeloprevisto.Susintaxises: break;
EJEMPLO 5.7. Elsiguientecódigoextraeyvisualizavaloresenterosdelaentradahastaqueseencuentraunvalor
enteroespecificado, previamenteleídodelteclado.
int Clave;
int Entrada_entera;
cin >> Clave;
while (cin >> Entrada_entera)
{
if (Entrada_entera != Clave)
cout << Entrada_entera << endl;
else
break;
}
//Salida del bucle
5.2. Repetición: el bucle for
Elbuclefor eselmásadecuadoparaimplementarbuclescontroladosporcontador quesonbuclesenlosqueunconjuntode
sentenciasseejecutanunavezporcadavalordeunrangoespecificado, deacuerdoalalgoritmo: porcadavalordeunavariablecontadordeunrangoespecíf ico: ejecutarsentencias.
Sintaxis
for (Inicialización; CondiciónIteración; Incremento)
Sentencias;
Elbuclefor contienelascuatropartessiguientes:
• La partedeInicializacióninicializalasvariablesdecontroldelbucle.
• LapartedeCondicióndeIteración contieneunaexpresiónlógicaquehacequeelbuclerealicelasiteracionesdelassentencias.
• LapartedeIncremento incrementalavariableovariablesdecontroldelbucle.
• Las Sentencias, accionesosentenciasqueseejecutaránporcadaiteracióndelb ucle.
Lasentencia for esequivalentealsiguientecódigo while:
inicialización;
while (condiciónIteración)
{
sentencias del bucle for
incremento;
}
EJEMPLO 5.8. Buclefor ascendentequeescribelos 5 primerosnúmerosnaturales, sucuadradoysucubo.Seinicializalavariableenter a n a 1 ymientraselvalorde n seamenoroiguala 5 seescribeelnúmero n, sucuadradoy
sucubo.Posteriormenteseincrementaenunaunidadelvalorde n.
#include <cstdlib>
#include <iostream>
using namespace std;
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
82
int main(int argc, char *argv[])
{
cout << "n
n*n
n*n*n" << endl;
for (int n = 1; n <= 5; n++)
cout << n << '\t' << n * n << '\t' << n * n* n <<endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadosdeejecución:
EJEMPLO 5.9. Bucle for descendentequeescribenúmerosrealesysur aízcuadrada.Seinicializalavariable n a
16.Encadaiteracióndelbuclesedecrementa n en 2.5.Elbucleterminacuando n esmenorque 1.
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
int main(int argc, char *argv[])
{
float n;
cout << "n
raiz(n)" << endl;
for (n = 16; n >= 1 ; n = n - 2.5)
cout << n << '\t' << sqrt (n) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadosdeejecución:
EJEMPLO 5.10. Buclefor quenoterminanunca.Lasalidadelbucleserealizaconlasentencia break.Cuandose
v max 1
cumplelacondicióndesalidadelbucle.Elejemplosumalosvmax primerostérminosdelaserie Σ
, siendovmax
c=1 c*c
undatodeprograma.Encadaiteraciónseincrementaelcontador c enunaunidad, seacumulaensumaelvalordel
1
1
términodelaserie
.Lacondición if decidesihayquesumareltérmino
alaserieosihayqueterminar
c*c
c*c
mediantelaejecucióndelasentenciabreak.Elprogramainicializaelcontadorc yelacumuladorsuma a0 yencada
iteracióndelbucle, cadavezquesesumauntérminoalaseriepr esentalosvaloresdelcontador c ydelasumaparcialdelacumulador suma.
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
83
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int c = 0;
float suma =0 ;
int vmax;
cout << "Cuantos terminos sumo de la serie ? ";
cin >> vmax;
for (;;)
// bucle for que no termina nunca
{
if(c <= vmax)
//test
{
c++;
//incremento
suma +=1/(float)(c*c);
cout << c <<" "<< suma << endl;
}
else
break;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadodeejecucióndelprogramaanterior:
5.4. Repetición: el bucle do...while
Lasentencia do-while seutilizaparaespecificarunbuclecondicionalqueseejecutaalmenosunav ez.
Sintaxis
Semántica
do
sentencia
sentencia
while (expresión)
verdadera
expresión
Después de cada ejecución de sentencia se
evalúa expresión. Si es
verdadera se repite el
cuerpo del b ucle (setencia). Si es f alsa, se termina el bucle y se ejecuta la siguiente sentencia.
falsa
Figura 5.2. Diagrama de flujo de la sentencia do
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
84
EJEMPLO 5.11. Buclequeescribelasletrasmayúsculasdelalfabeto.Seinicializalavariablecarácter car a'A', y
medianteunbucledo while queterminacuandoen car hayuncaráctermayorque 'Z', seiteraescribiendoelvalor
de car eincrementandoelvalorde car enunaunidadporloque car tomaelsiguientecarácterdelcódigo ASCII.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char car = 'A';
do
{
cout <<car << ' ';
car ++;
} while (car <= 'Y');
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadodelaejecución:
5.5. Comparación de bucles while, for y do–while
C++proporcionatressentenciasparaelcontroldeb ucles: while, for ydo–while.Elbuclewhile serepitemientras lacondiciónderepeticióndelbucleseaverdadera;elbuclefor seutilizanormalmentecuandoelconteoestéimplicado,obiencuandoelnúmerodeiteracionesrequeridassepuededeterminaralprincipiodelaejecucióndelb ucle.Elbucle do–while seejecutadeunmodosimilara while exceptoquelassentenciasdelcuerpodelb ucleseejecutansiemprealmenosunav ez.
EJEMPLO 5.12. Seescribenlosnúmeros10, 20, 30, 40, 50, 60, 70, 80, 90, 100, conunbuclewhile, con
unbuclefor, yconunbucledo while enunmismoprograma.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int
num = 10;
while (num <= 100)
{
cout << num << " ";
num += 10;
}
cout << endl << endl;
for (num = 10;num <= 100;num += 10)
cout << num << " ";
cout << endl<< endl;
//con bucle while
// con bucle for
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
num = 10;
do
{
cout << num << " ";
num += 10;
}
while (num <= 100);
system("PAUSE");
return EXIT_SUCCESS;
}
85
//con bucle do
while
EJEMPLO 5.13. Leerunnúmeroenteropositivoenunbucledowhile ycalcularsufactorial, medianteunbuclefor,
unbuclewhile yunbucledo while.(Nota: Factorialden =n ∗ (n –1)∗ (n –2)∗ ...∗ 2∗ 1).
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int numero, i, factorial;
do
{
cout << "dame numero entero: ";
cin >> numero;
} while ( numero <= 0);
for( factorial = 1, i = 1; i <= numero; i++)
factorial *= i;
cout << factorial << endl;
factorial = 1;
i = 1;
while( i < numero)
{
i++;
factorial *= i ;
}
cout << factorial << endl;
factorial = 1;
i = 0 ;
do
{
i++;
factorial *= i;
} while(i < numero);
cout << factorial << endl;;
system("PAUSE");
return EXIT_SUCCESS;
}
//con bucle for
//con bucle while
//con bucle do-while
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
86
5.6. Bucles anidados
Losbuclesanidados constandeunbucleexternoconunoomásb uclesinternos.Cadavezqueserepiteelb ucleexterno, los
buclesinternositeranreevaluándoselascomponentesdecontrolyejecutándoselasiteracionesrequeridas.
EJEMPLO 5.14. Elsiguienteprogramamuestradosbuclesfor anidadosquepresentanlastablasdemultiplicardel
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, perodeformainversa.Paracadavalordelavariable n enelrango1, 2, 3,
4, 5, 6, 7, 8, 9, 10, seejecutaunaordendeescriturayelbucleinterno for controladoporlavariableentera
m quetomalosvalores10, 9, 8, 7, ..., 1, escribiendoencadaiteraciónlosvaloresden, m ysuproducton * m.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int n, m;
for (n = 1; n <= 10; n++)
{
cout << " tabla de multiplicar del " << n << endl;
for (m = 10; m >= 1; m--)
cout <<n << " veces " << m << " = " <<n * m << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
EJERCICIOS
5.1.
¿Cuáleslasalidadelsiguientese gmentodeprograma?
for (int cuenta = 1; cuenta < 5; cuenta++)
cout << (2 * cuenta) << “ “;
5.2.
¿Cuáleslasalidadelossiguientesb ucles?
a) for (int n = 10; n > 0; n = n – 2)
{
cout << "Hola ";
cout << n << endl ;
}
b) for (double n = 2; n > 0; n = n - 0.5)
cout << m << " ";
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
5.3.
Considerarelsiguientecódigodeprograma.
using namespace std;
int main(int argc, char *argv[])
{
int i = 1 , n ;
cin >> n;
while (i <= n)
if ((i % n) == 0)
++i;
cout << i << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
a) ¿Cuáleslasalidasiseintroducecomov alorden, 0?
b) ¿Cuáleslasalidasiseintroducecomov alorden, 1?
c) ¿Cuál eslasalidasiseintroducecomov alorden, 3?
5.4.
Suponiendoquem=3yn=5¿Cuáleslasalidadelossiguientesse gmentosdeprograma?
a) for (int i = 0; i < n; i++)
{
for (int j = 0; j < i; j++)
cout << “ *”;
cout << endl;
}
b) for (int i = n; i > 0; i--)
{
for (int j = m; j > 0; j--)
cout << “ * ”;
cout << endl;
}
5.5.
¿Cuáleslasalidadeesteb ucle?
int i = 1 ;
while (i * i < 10)
{
int j = i;
while (j * j < 100)
{
cout << i + j << " ";
j *= 2;
}
i++;
cout << endl;
}
cout << "\n*****\n";
87
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
88
PROBLEMAS
5.1.
Escribaunprogramaquecalculeyvisualice1+2+3+...+(n-1)+n, dondenesunvalordeundatopositivo.
5.2.
Escribirunprogramaquevisualicelasiguientesalida:
1
1
1
1
1
1
1
2
2
2
2
2
3
3
3
4
5.3.
Diseñareimplementarunprogramaqueleauntotalde10númer osycuenteelnúmerodesusentradasquesonpositivos,
negativosycero.
5.4.
Diseñareimplementarunprogramaquesoliciteasuusuariounvalornonegativonyvisualicelasiguientesalida(n=6):
1
1
1
1
1
1
2
2
2
2
2
3 4 5 6
3 4 5
3 4
3
5.5.
Escribirunprogramaqueleaunlímitemáximoenteropositivo, unabaseenterapositiva, yvisualicetodaslaspotenciasde
labase, menoresqueelvalorespecificadolímitemáximo.
5.6.
Diseñarunalgoritmoquesumelosm=30primer osnúmerospares.
5.7.
Escribirunprogramaqueleaelradiodeunaesferayvisualicesuáreaysuvolumen.
5.8.
Escribirunprogramaquepresentelosvaloresdelafuncióncoseno(3x)-2xparalosvaloresdexiguala0, 0.5, 1.0, ...4.5, 5.
5.9.
Escribiryejecutarunprogramaqueinviertalosdígitosdeunenteropositivodadoleídodelteclado .
5.10. ImplementarelalgoritmodeEuclidesqueencuentr aelmáximocomúndivisordedosnúmer osenterosypositivos.
5.11. Escribirunprogramaquecalculeyvisualiceelmásgr ande, elmáspequeñoylamediadennúmer os(n>0).
n
5.12. Encontrarunnúmeronaturalnmáspequeñotalquelasumadelosnprimer ostérminosdelaserie Σ i *i –i –2 exceda
i=1
deunacantidadintroducidaporeltecladomáximo.
5.13. Calculartodoslosnúmerosdeexactamentetrescifrastalesquelasumadeloscuadradosdesusdígitosesigualalcociente
deladivisiónenteradelnúmeroentre3.
5.14. Elvalordee x sepuedeaproximarporlasuma:
ex =1+x +
x2
2!
+
x3
3!
+...+
xn
n!
n
xi
i=0
i!
=Σ
Escribirunprogramaqueleaunv alordex comoentradayvisualicelassumasparcialesdelaserieanterior , cuandoseha
realizadounasuma, dossumas, tressumas, ..., 15sumas.
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
89
5.15. Unnúmeroperfectoesunenteropositivo, queesigualalasumadetodoslosenterospositivos(excluidoelmismo)queson
divisoresdelnúmero.Elprimernúmer operfectoes6, yaquelosdivisor esestrictosde6son1, 2, 3y1+2+3=6.Escribirunprogramaqueleaunnúmeroenteropositivotopeyescribatodoslosnúmerosperfectosmenoresoigualesqueél.
5.16. Diseñarunprogramaqueproduzcalasiguientesalida:
ZYXWVTSRQPONMLKJIHGFEDCBA
YXWVTSRQPONMLKJIHGFEDCBA
XWVTSRQPONMLKJIHGFEDCBA
WVTSRQPONMLKJIHGFEDCBA
VTSRQPONMLKJIHGFEDCBA
...
....
.....
FEDCBA
EDCBA
DCBA
CBA
BA
A
5.17. Calcularlasumadelaserie 1/13 +1/23 +...+1/n3 donden esunnúmeropositivoqueseintroduceporteclado.
5.18. Calcularlasumadelos20primer ostérminosdelaserie: 12/32 +22/32 +32/33 +...+n2/3n.
5.19. Determinarsiunnúmeronaturalmayoroigualquelaunidadqueseleedeltecladoesprimo.
SOLUCIÓN DE LOS EJERCICIOS
5.1.
Lavariable cuenta tomalosvalores 1, 2, 3, 4, 5.Paralosvalores 1, 2, 3, 4, de cuenta seejecutalasentencia
cout << (2 * cuenta) << " ";delinteriordelb ucle for, porloqueseescribeeldobledelvalorde cuenta seguido
deunespacioenblanco.Cuandolavariable cuenta tomaelvalorde 5 sesaledelbucle.Lasalidatotaldelse gmentode
programaes: 2 4 6 8.
5.2.
a) Lavariablen seinicializaalvalor10.Encadaiteracióndelbucle, lavariablen sedecrementaendosunidades.Esdecirlosvaloresquetoma n son10, 8, 6, 4, 2, 0.Lassentenciasinterioresdelbuclecout << “Hola ”; cout <<
n << endl;seejecutanparalosvalorespositivosde n.Portantolasalidadelb uclees:
Hola 10
Hola 8
Hola 6
Hola 4
Hola 2
b) Enestesegundocasolavariablen seinicializaalvalor2 ysedecrementaencadaiteración0.5 unidadessaliendodel
buclecuandoesnegativaonula.Lasentenciacout << n << " ";sóloseejecutaparalosvalorespositivosden.Por
tantolasalidaes: 2 1.5 1 0.5.
5.3.
Lasolucióneslasiguiente:
a) Enesteprimercasocuando n tomaelvalorde0, noseentraenelbuclewhile, yaquela i sehainicializadoa 1.Por
lotantoseescribe 1.
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
90
b) Sin vale1, seentraenelbucleunavez, yaque1<=1.Comoelrestodeladivisiónenterade1 entre1 es0, seejecutala
sentencia++i porloqueelvalorde i es2.Altomari elvalorde 2, elbucleterminaylasalidadelprogramaes 2.
c) Alser 3 elvalorde n, seentraenelbucleperonuncaseejecutalasentencia ++i, yaqueelrestodeladivisiónentera
de1 entre3 essiempre1 queesdistintode 0.Deestaformaelb uclenuncatermina.Esunb ucleinfinito.
5.4.
Lasolucióneslasiguiente:
a) Elbucleexteriorseejecutacincovecestomandolavariable i losvaloresde 0, 1, 2, 4 y 5 alcomienzodecadaiter ación.Elb ucleinteriorcomienzaconelvalorde j en 0, yterminaconelvalorde j en i-1.Deestaformacuando i
tomaelvalor 0 noentra, cuando i tomaelvalor 1 seejecutaunasolavez, cuando i tomaelvalor 2 seejecuta2veces, etc.Elbucleinteriorcontroladoporelcontador j escribeunblancoseguidodeasterisco( *)cadavezqueseejecuta.Elbucleexteriorcontroladoporelcontador i ejecutaelbucleinteriorydaunsaltodelínea.Deestaformalos
dosbuclesanidadosescribenuntriángulorectángulodeasteriscos.
b) Elbucleexteriortomaahoralosvaloresde 5, 4, 3, 2, 1, 0, porloqueseejecutaseisveces.Elb ucleinteriorcomienza
conelvalorde j en3, yterminaconelvalorde j en1, porloquecadavezqueseejecutaescribetr esblancosseguidode*.Deestaformaseescribeunr ectángulodeasteriscosquetieneseisf ilasytrescolumnasdeasteriscos( *).
Alserejecutadoelsiguienteprogramaseobtieneelresultadoindicadoenlasalida .
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int n = 5, m = 3;
for (int i = 0; i < n;
{
for (int j = 0; j <
cout << " *";
cout << endl;
}
cout << endl;
for (int i = n; i > 0;
{
for (int j = m; j >
cout << " * ";
cout << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadodeejecución:
i++)
i; j++)
i--)
0; j--)
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
5.5.
91
Setratadedosbuclesanidadoscontroladosporunacondición.Elbucleexternocontroladoporelcontador i, yelinterno
controladoporlavariablej.Lavariablei, tomalosvalores1,2,3.Enelmomentoquei tomaelvalorde4, sesaledelbucleyaque 4 * 4 noesmenorque10.Enelb uclecontroladoporlavariable j, seobservaque j seinicializaenlosvalores 1, 2, 3, respectivamente, yencadaiter aciónsevamultiplicandopordos. Asícuando i vale 1 losvaloresquetomala
variablej son1, 2, 4, 8, ycuandotomaelvalorde16 sesaledelbucleyaque16 * 16 esmayorque100.Porconsiguiente,
seescribenlosvalor esde i + j = 2, 3, 5, 9.Cuando i vale 2, losvaloresquetomalavariable j son 2, 4, 8, ycuando
tomaelvalorde 16 sesaledelbuclealigualqueantes.Portanto, seescribenlosvaloresde i + j = 4, 6, 10.Cuandoi vale3, lavariable j tomalosvalores3, 6, ycuandotomaelvalor 12 sesaledelbucle.Deestaformaseescribenlos
valores6, 9.Siseintroducenlosbuclesanterioresenunprogramaprincipalyseejecutaseobtieneelsiguienter esultado:
SOLUCIÓN DE LOS PROBLEMAS
5.1.
Sedeclaranlasvariablesenterasi, n ysuma, inicializandoi a1 asícomo suma a0.Medianteunbucledo while seleeel
valorden asegurandoqueseapositivo.Medianteunbuclewhile controladoporelcontadori, sevanacumulandoensuma,
previamenteinicializadoa0, losvalores1+2+3+...+(n-1)+n. Alfinaldelprogramaseescribeelresultado.
Codificación
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int n, i = 1; suma = 0;
do
{
cout << " valor de n > 0 ";
cin >> n;
} while (n <= 0);
while (i <= n)
{
suma += i;
i++;
}
cout << " valor de la suma "<<
system("PAUSE");
return EXIT_SUCCESS;
}
suma << endl ;
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
92
Unresultadodeejecucióncuantoseintroduceportecladoelv alorde4eselsiguiente:
5.2.
Eltriángulosolicitadotienedospartesdiferenciadas.Laprimeraestáconstituidaporlascuatroprimerasfilasylasegundaporlastressiguientes.Paraescribirlascuatroprimerasfilasbastaconanidardosb ucles.Elbucleexteriorvaríadesdelasposiciones i = 1, 2, 3, 4, elinteriordesdelasposiciones j = 1, 2, ..., i.Paraescribirlasegundaparte, seanidan
denuevolosdosmismosbucles, peroahoraelexteriorcontroladoporelcontador i quevaríaentrelasposiciones 3, 2, 1.
Elbucleinteriorvaríadesdelasposiciones j =1, 2, ..., i.Eltriángulopedidoenelproblemaesfácilmentegeneralizable,
paraqueenlugardelle garalvalormáximo 4 llegueaunvalormáximo m.Elprogramaquesecodificahacelageneralizaciónindicada.Sepideyvalidaunvalorpositivom queenelproblemadeberíaser4, yposteriormenteseescribenlosbuclesdescritosanteriormente.
La codificación de este problema se encuentra en la página Web del libro.
Resultadodeunaposibleejecuciónparaelv alordeentrada m = 6
5.3.
Sedeclarancontadoresdenúmerospositivosnp, númeronegativosnn, ynúmerosnulos queseinicializanenlapropiadeclaracióna 0.Unbuclecontroladoporelcontador i iteraentrelosvalores 1, 2, ..., max, siendo max unaconstantedeclaradaenunasentencia define conelvalorde 10.Encadaiteraciónseleeunnúmeroenteroenlavariable dato, ydependiendodequeelvalorleídoseapositivonegativoonuloseincrementaelcontadordepositivos, negativosonulos.Alfinal
delprogramaseescribenloscontadores.
Codificación
#include <cstdlib>
#include <iostream>
#define max 10
using namespace std;
int main(int argc, char *argv[])
{
int np = 0, nn = 0 , nulos = 0, dato;
for (int i = 1; i <= max; i++)
{
cin >> dato;
if (dato > 0)
np++;
else if (dato < 0)
nn++;
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
93
else
nulos++;
}
cout <<"positivos
cout
negativos
<< np << "
nulos "<< endl;
" << nn <<"
" << nulos;
system("PAUSE");
return EXIT_SUCCESS;
}
5.4.
Sin espositivo, el“triángulo” genéricosolicitado, tieneuntotalde n filas, porloqueesnecesariocodificarunbuclecontroladoporuncontadorqueescribaencadaiter aciónunafiladenúmeros.Comoelnúmerodecolumnasdeltriángulova
decreciendo, elbuclequeiter alasfilasesconvenientesecodifiquedecrementandolavariabledecontr oldelbucle, para
quemedianteotrobucleinternoqueseaascendentesepuedanescribircadaunadelascolumnas.Esdecir , elcuerpodel
programaestágestionadopordosb uclesanidados.Elb ucleexternoestácontroladoporlavariable i quetomalosvaloresn, n – 1, ..., 1.Elbucleinternoesiteradoporelcontadorj quecomienzaen1 yterminaeni avanzandodeunoen uno.
Estebucleinternoescribeelvalorde j.Alterminarcadaejecucióndelb uclemásinternohayquedarunsaltodelínea.
Codificación
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i, j, n;
do
{
cout <<"valor de n positivo ";
cin >>n;
}
while (n <= 0);
// termina la lectura de n
for (i = n; i >= 1; i--)
{
// para cada una de las filas descendentemente
for (j = 1 ; j <= i; j++)
cout << " " <<
// para cada una de las columnas
j;
cout << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Unaejecucióndelprogramaanterioreslasiguiente:
// salta de línea
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
94
5.5.
Elproblemaplanteadoseresuelvemediantetresbucles.Elprimeroesunbucledo-while, quevalidalaentradadelvalor
especificadolímitelimite_maximo positivo.Elsegundobucledo-while, validalaentradadelabase enterapositiva.Por
último, medianteelbuclefor controladoporelvalorde potencia, seescribenlasdistintaspotenciaspedidas.Esteb ucle
inicializa potencia a 1, encadaiteraciónescribeelvalorde potencia ylamultiplicaporla base.Lacondicióndeterminaciónes potencia > limite_máximo.
La codificación de este problema se encuentra en la página Web del libro.
5.6.
Parasumarlosm = 30 númerospares, seusaelacumuladorsuma previamenteinicializadoa0.Enesteacumuladorsesumanlosrespectivosnúmerospares.Unbucle for controladoporelcontador i recorrelosnúmeros 1, 2, 3, ..., 20.Elnúmeroparqueocupalaposicióni es2 * i, porloqueparaobtenerlasumadetodosbastaconejecutarlasentencia suma
+= 2 * i.Elprogramaqueseimplementapresenta, además, elresultadodelasumamediantelafórmuladelosmprime(2–2*m)
rosnúmerospares
mqueseobtienealaplicarlacorrespondientesumadelostérminosdeunaprogresiónarit2
a1 +an
méticaS =·
n.
2
Codificación
#include <cstdlib>
#include <iostream>
#define m 30
using namespace std;
int main(int argc, char *argv[])
{
int i, suma = 0;
for (i = 1; i <= m; i++)
suma += 2 * i ;
cout << "La suma de los 20 primeros pares: " << suma << endl;
cout << " mediante formula: " << (2+ 2*m)*m/2 << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadosdeejecucióndelprogramaanterior:
5.7.
Teniendoencuentaquelasfórmulasquedaneláreayvolumendeunaesferason: area = 4pradio2, volumen = 4/3prapararesolverelproblemasólosetienequeleerelr adio(positivo), validarloenunbucledo while yaplicarlasfórmulas.Sedeclarap comoconstanteenunasentencia define.
dio3
Codificación
#include <cstdlib>
#include <iostream>
#define pi 3.2141592
using namespace std;
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
95
int main(int argc, char *argv[])
{
float radio, area, volumen;
do
{
cout << "valor del
cin
radio positivo " << endl;
>> radio;
} while (radio <= 0);
// fin entrada de datos
area = 4 * pi * radio * radio;
volumen = 4.0 / 3 * pi * radio * radio * radio;
cout <<"el area y volumen de la esfera de radio r = " << radio<<endl;
cout << "area = " << area << " volumen = " <<
volumen ;
system("PAUSE");
return EXIT_SUCCESS;
}
5.8.
SedefinelaconstantesimbólicaM como5 yuna“funciónenlínea” f(x) (tambiéndenominada“macroconargumentos”).
Elbucleserealiza11 veces.Encadaiteraciónelvalordex seincrementaen0.5, secalculaelvalordelafunciónyseescribenlosresultados.
Codificación
#include <cstdlib>
#include <iostream>
#include <math.h>
#define M 5
#define f(x) cos( 3 * x) – 2 * x
//función en línea
using namespace std;
int main(int argc, char *argv[])
{
for (double x = 0.0; x <= M; x += 0.5)
cout << x << "
" << f(x) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
5.9.
Pararesolverelproblemaseinicializaunavariable invertido acero.Seleeenunbucledo while elvalordeldato nuasegurandoqueespositivo.Enunb ucle for seinvierteeldatonuméricoleídoen numero, destruyendoeldatoyalmacenadoelresultadoenelnúmer o invertido.Encadaiter acióndelb uclesecalculaenlapr opiavariable numero, el
valordelcocienteenterode numero entre 10.Deestaforma, silavariable numero tomaelvalorde 234, enlassucesivas
iteraciones irátomandolosvalores 234, 23, 2 y 0.Encadaiteracióndelbucletambiénsevacalculandoel resto delcocienteenterodenumero entre10.Esdecir, sevancalculandolosvalores4, 3, 2 yalmacenándolossucesivamenteenlavariable resto.Paraconseguirobtenerelnúmeroinvertido, bastaconobservarque 432 = 4 * 10 * 10 + 3 * 10 + 2 =
= (((0 * 10 + 4) * 10 + 3) * 10 + 2).(métododeHorner deevaluacióndepolinomios).Esdecir, bastaconacumularen invertido elvalorde invertido multiplicadopor 10 ysumarel resto deladivisiónentera.
mero
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
96
Unposibleresultadodeejecucióndelprogramaanteriores:
5.10. Elalgoritmotransformaunpardeenterospositivos( mayor, menor)enotropar( menor, resto), dividiendorepetidamente
elenteromayor porelmenor yreemplazandoelmayor porelmenor yelmenor porelresto.Cuandoelresto es0, elotro
enterodelaparejaseráelmáximocomúndivisordelapar ejaoriginal.
Ejemplomcd: (532, 112)
Restos
4
1
3
532
112
84
28
84
28
00
Cocientes
mcd = 28
Lacodificaciónqueserealiza, leeprimeramentelosnúmerosenteros mayor y menor validandolaentradaenunb ucle do
medianteotrobuclewhile seefectúanlascorrespondientestransformacionesparaobtenerelmáximocomúndivisor.Seiteramientraselúltimo resto deladivisiónenteraseadistintode0.Enelcuerpodelb ucleserealizanloscambiosindicadosanteriormenteyademásseescribenlosresultadosintermedios.
while.Posteriormente,
La codificación de este problema se encuentra en la página Web del libro.
Unaejecucióndelprogramaanteriorparalaentrada 1100 436 eslasiguiente:
5.11. Elvalorden sesolicitayvalidaalprincipiodelprogramamedianteunbucledo while.Losnúmerossonintroducidospor
elusuario.Elprimerodelaserieinicializalasvariables Mayor, menor ysuma.Enunbuclefor seleenelrestodelosnúmeros, ymediantelatécnicavoraz(elmejordetodosesoelmejordetodoslosanterioresoeselqueacabodeleer)serecalculanlosnuevosmáximos, mínimos, ysumaenlasvariablesMayor, menor ysuma.Alfinalseescribenlosresultadosde
Mayor, menor y media queeselcociente suma / n.
La codificación de este problema se encuentra en la página Web del libro.
Unresultadodeejecucióndelprogramaanteriores:
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
97
5.12. Enprimerlugarseleeelvalordelacantidadintroducidaportecladomáximo validandolaentrada.Posteriormente, seacumulalaseriedadahastaquesee xcedaelvalorintroducidomedianteunbucle for.Estebucleinicializa suma y elcontadori a0.Encadaiteraciónseincrementaelcontadori en1, secalculaeltérminoi * i – i – 2 yseacumulaensuma.
Elbucle for terminacuando suma >= máximo.Elnúmerototaldetérminos n sumadosvienedadoporelvalordelavariablei.
Codificación
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i, n;
float suma, maximo;
do
{
cout << "valor maximo positvo ";
cin >> maximo;
} while (maximo <= 0);
for ( suma =0, i = 0; suma <= maximo;)
{
i++ ;
suma = suma + i * i - i- 2;
}
n = i;
cout << " valor de la suma = " << suma << endl;
cout <<" numero de terminos = " << n << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Unresultadodeejecucióndelprogramaanteriores:
5.13. Lasoluciónseplanteamedianteunbuclequerecorretodoslosnúmerosdetrescifras.Estebuclecomienzaen100 yterminaen999.Encadaiteración, secalcula, asuvez, cadaunadelosdígitosdelnúmeroysecompruebalacondiciónencuyo
casoseescribe.Sielnúmeroi = d3d2d1 entonceslacondiciónindicadaes i / 3 = d1 * d1 + d2 * d2 + d3 * d3.
Paracalcularlascifrasbastaconusarelcocienteyladivisiónenter adosvecestalycomoapar eceenlacodificación.
Codificación
#include <cstdlib>
#include <iostream>
using namespace std;
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
98
int main(int argc, char *argv[])
{
int d1, d2, d3, i, x;
cout << " lista de numeros que cumplen la condicion\n";
for(i = 100; i <= 999; i++)
{
x = i ;
d1 = x % 10;
x = x / 10;
d2 = x % 10;
x = x / 10;
d3 = x;
// ya se han calculado las tres cifras
if( d1 * d1 + d2 * d2 + d3 * d3 == i / 3)
cout << " numero " << i << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Elresultadodeejecucióndelprogramaanterioreselsiguiente:
5.14. Elproblemaseresuelveteniendoencuentaquepar acalcularelvalordelaserie , bastaconiracumulandolossucesivos
valoresdel termino eneaproximado, yquecadatérminodelaserieseobtienedelinmediatamenteanterior , multiplicandopor x, ydividiendopor i, siendo i uncontadorqueindicaelnúmer odetérminoqueseestásumando.P orejemplo
x3/3!= x2/2!*(x/3).Eltérminocer oes 1, eltérmino 1 es x, eltérmino2es x2/2! yasísucesivamente.Lacodificación
quesepresentaleeeldato x, inicializaadecuadamenteelvalorde eaproximado a1 yel termino a1.Medianteunbucle
controladoporelcontadoriseiter a15veces, secalculaencadaiteraciónelnuevotermino, seacumulasuvaloren eaproximado yescribeelresultado.Alfinalseescribeelvalordebibliotecadee x.
La codificación de este problema se encuentra en la página Web del libro.
5.15. Seleeelnúmerotope enunbucledo while validandolaentrada.Pararesolverelproblemabastaconprogramardosbuclesfor anidados.Elbucleexternorecorretodoslosnúmerosmenoresoigualesque tope, yelinternodecidesielnúmeroesperfecto.Enlacodif icaciónqueserealizaelbucle for externoestácontroladoporlavariableenter a n querecorre
todoslosnúmerosmenoresoigualesque tope.Elbuclefor, interno, serealizaconelcontador i encargándosedeprobar
todoslosposiblescandidatosadivisoresmenoresque n (bastaconempezar i en1 yavanzardeunoenunohastallegara
n – 1.Podríamejorarseelbuclellegandosóloalar aízcuadradade n).Todoslosdivisoresdelnúmero n (aquélloscuyo
restodeladivisiónenter ade n entre i sea 0)sevanacumulandoen acumulador, previamenteinicializadoa 0, paraque
unavezseterminaelb uclecomprobarlacondicióndeperfecto( n = = acumulador)ydarelmensajecorrespondiente.
La codificación de este problema se encuentra en la página Web del libro.
5.16. Enlaprimer alíneaseescribentodaslasletr asmayúsculasdelabecedarioenor deninversocomenzandoen Z.Enlasegundalíneaseescribenlasletrasmayúsculas, enordeninverso, perocomenzandoenlaY.Seobservaquehaytantaslíneas
comoletrasmayúsculasexistenenelabecedario, quetodaslaslíneasterminanenelcarácter A, yqueunalíneaconsecu-
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
99
tivadeotracomienzasiempreporlaletramayúsculainmediatamenteanterior.Paracodificarelprogramasenecesitandos
buclesanidados.Elbucleexterno: comienzaen 'Z';terminaen 'A';disminuyeencadaiter aciónenunaunidad;ejecuta
elbuclemásinterno;yrealizaunsaltodelínea.Elb ucleinternoiteracomenzandoenlaletradelbucleexternoytermina
tambiénen 'A'.Encadaiteraciónescribeelcarácterydecrementaelcontadorenunaunidad.
Codificación
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char car, Comienzo = 'Z';
for (Comienzo = 'Z'; Comienzo >= 'A'; Comienzo --)
{
for ( car = Comienzo; car >= 'A'; car--)
cout <<car << ' ';
cout << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
5.17. Pararealizarlasumadelaserie, bastaconacumularenunavariablesuma losdistintosvaloresdelostérminosterminoi =
= 1 / (i * i * i).Previamenteseleedelaentr adaelvalordelnúmerodetérminos n validandolaentradaenunbucledo while yposteriormenteconunbuclefor controladoporlavariable i sevarealizandolacorrespondienteacumulaciónenelacumulador suma, queseinicializaantesdecomenzarelb uclea 0.
La codificación de este problema se encuentra en la página Web del libro.
5.18. Pararealizarlasumadelaserie , bastaconacumularenunacumulador suma, previamenteinicializadoa 0 lostérminos
(terminosi = i * i / 3i).Elnúmerodetérminosasumarsedeclaracomounaconstanteveinte enunasentenciadefine yposteriormenteserealizalaacumulacióndelosvaloresde termino enelacumulador suma medianteunbuclefor
querecorrelosvalores1, 2, 3, ..., 20.
Codificación
#include <cstdlib>
#include <iostream>
#include <math.h>
#define veinte 20
using namespace std;
int main(int argc, char *argv[])
{
float termino, suma = 0;
for (float i = 1; i <= veinte; i++)
{
termino = i * i/ pow(3,i);
suma += termino;
}
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
100
cout << " valor de la suma = " << suma << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
5.19. Unnúmeromayorquelaunidadesprimo, sisusúnicosdivisoressonelunoyelpropionúmero.Teniendoencuentaquesi
hayunnúmeronaturalcontador quedividealavariablenumero queesmenorquelaraízcuadradadelnumero, entonces
hayotronúmeronaturalquetambiénlodividequeesmayorquelaraízcuadradadelnumero, setieneque: bastaconcomprobarlosposiblesdivisoresmenoresoigualesquelaraízcuadradadelnúmerodado.Elprogramaserealizaconunsolo
bucle, enelcualsevancomprobandolosposiblesdivisores, siempreycuando, nosehayaencontradoyaalgúndivisoranterior( primo = = false), onosetengaquecontr olarningúnotrodivisor( contador * contador <= numero).Primeramente, seleeenunb ucle do while elvalordel numero mayoroigualque 2.Seinicializaunavariable primo a true,
seiteraconunb ucle for controladopor contador einicializadoa 2, comprobandolosposiblesdivisoresquesonmenoresoigualesquelar aízcuadradadel numero eincrementandoencadaiteraciónel contador enunaunidad.Enelcuerpodelbuclefor lavariableprimo seponeafalse sicontador divideanumero.Enotrocasoprimo sigueestandoatrue.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
5.1.
¿Cuáleslasalidadelsiguienteb ucle?
suma = 0;
while (suma < 100)
suma += 5;
cout << suma << endl;
5.2.
¿Cuáleslasalidadelossiguientesb ucles?:
a) for (int i = 0; i < 10; i++)
5.3.
Describirlasalidadelossiguientesb ucles:
a) for (int i = 1; i <= 5; i++)
{
cout << i << endl;
for (int j = i; j >= 1; j—2)
cout << j << endl;
}
b) for (int i = 3; i > 0; i--)
cout << “ 2* ” << i << “ = ” << 2 * i
<< endl;
for (int j = 1; j <= i; j++)
for (int k = i; k >= j; k--)
cout << i << j << k << endl;
b) for (int i = 0; i <= 5; i++)
cout << 2 * i + 1 << “ ”;
c) for (int i = 1; i <= 3; i++)
c) for (int i = 1; i < 4; i++)
for (int j = 1; j <= 3; j++)
{
for (int k = i; k <= j; k++)
cout << i << j << k << endl;
cout << endl;
{
cout << i;
for (int j = i; j >= 1; j--)
cout << j << endl;
}
}
CAPÍTULO 5 Estructuras de control repetitivas ( while, for, do-while)
101
PROBLEMAS PROPUESTOS
5.1.
5.2.
5.3.
Diseñareimplementarunprogramaquee xtraigavaloresdelflujodeentradaestándary , acontinuación, visualiceelmayoryelmenordeesosv aloresenelflujo
desalidaestándar.Elprogramadebevisualizarmensajesdeadvertenciascuandonohayaentradas.
losnúmerosquef iguranencadalínea, cadacolumnay
cadadiagonalsonidénticos.Unejemploes:
Diseñareimplementarunprogramaquesoliciteal
usuariounaentradacomoundatotipofechay , acontinuación, visualiceelnúmerodeldíacorrespondientedel
año.Ejemplo, silafechaes30121999, elnúmerovisualizadoes364.
Unmétododeconstruccióndelcuadradoconsisteensituarelnúmero1enelcentrodelaprimeralínea, elnúmerosiguienteenlacasillasituadaencimayaladerecha,
yasísucesivamente.Esprecisoconsiderarqueelcuadradosecierrasobresímismo: lalíneaencimadelaprimeraesdehecholaúltimaylacolumnaaladerechadela
últimaeslaprimera.Sinembargo, cuandolaposicióndel
númerocaigaenunacasillaocupada, seeligelacasilla
situadadebajodelnúmeroqueacabadesersituado.
8
3
4
Uncarácteresunespacioenblancosiesunblanco
( ´ ´ ), unatabulación( ´\t´ ), uncarácterdenuevalínea(´ \n´ ) ounavancedepágina(´ \f´ ).Di-
señaryconstruirunprogramaquecuenteelnúmerode
espaciosenblancodelaentradadedatos.
5.4.
Realizarunprogramaqueescribatodoslosnúmerosparescomprendidosentre1y50.
5.5.
Escribirunprogramaquecalculeyvisualiceunatabla
conlas20potenciasde2.
5.6.
Imprimirloscuadradosdelosenterosde1a20.
5.7.
Escribirunprogramaquedeterminesiunañoesbisiesto.Unañoesbisiestosiesmúltiplode4(1988), exceptolosmúltiplosde100quenosonbisiestossalv oquea
suveztambiénseanmúltiplosde400(1800noesbisiesto, 2000sí).
5.8.
Escribirunprogramaquevisualiceuncuadradomágico
deordenimparn, comprendidoentre3y11;elusuario
eligeelvalorden.Uncuadradomágicosecomponede
númerosenteroscomprendidosentre1yn2.Lasumade
5.9.
1
5
9
6
7
2
ElmatemáticoitalianoLeonardoFibonaccipropusoel
siguienteproblema.Suponiendoqueunpardeconejos
tieneunpardecríascadamesycadanue vaparejase
hacefértilalaedaddeunmes.Sisedisponedeunaparejafértilyningunodelosconejosmuertos, ¿cuántas
parejashabrádespuésdeunaño?Mejorarelproblema
calculandoelnúmerodemesesnecesariosparaproducir
unnúmerodadodeparejasdeconejos.
5.10. Calcularlasumadelaserie1/1+1/2+...+1/Ndonde
N esunnúmeroqueseintroduceporteclado.
5.11. Calcularlasumadelostérminosdelaserie:
1/2+2/2 2 +3/23 +...+n/2 n
5.12. Encontrarelnúmeromayordeunaseriedenúmeros.
5.13. Escribirunprogramaquecalculelasumadelos50primerosnúmerosenteros.
5.14. Calculartodoslosnúmerosdetrescifrastalesquela
sumadeloscubosdelascifrasseaigualalvalordelnúmero.
CAPÍTULO 6
Funciones y módulos
Introducción
Lasfuncionescontienenvariassentenciasbajounsolonombre, queunprogramapuedeutilizarunaomásv ecesparaejecutardichassentencias.Ahorranespacio, reduciendorepeticionesyhaciendomásfácillaprogramación, proporcionandounmediodedividirunproyectograndeenmódulospequeñosmásmanejables.
Siseagrupanfuncionesenbibliotecas, otrosprogramaspuedenreutilizarlasfunciones;porestarazónsepuedeahorrar
tiempodedesarrollo.Ydadoquelasbibliotecascontienenrutinaspresumiblementecomprobadas, seincrementalafiabilidad
delprogramacompleto.
Estecapítuloexaminaelpapel(rol)delasfuncionesenunprogramaC++.Lasfuncionespuedene xistirdemodoautónomoobiencomomiembrosdeunaclase.Comoyaconoceellector , cadaprogramaC++tienealmenosunafunción main();
sinembargo, cadaprogramaC++constademuchasfuncionesenlugardeunafunción main() grande.Ladivisióndelcódigo
enfuncioneshacequelasmismassepuedanreutilizarensuprogramayenotrosprogramas.Despuésdequeescriba, pruebe
ydepuresufunción, sepuedeutilizarnue vamenteunayotrav ez.Parareutilizarunafuncióndentrodesuprograma, sólose
necesitallamaralafunción.
LasfuncionessonunadelaspiedrasangularesdelaprogramaciónenC++yunb uenusodetodaslaspropiedadesbásicasyaexpuestas, asícomodelaspropiedadesa vanzadasdelasfunciones, leproporcionaránunapotencia, avecesimpensable, asusprogramaciones.Lacompilaciónseparadaylarecursividadsonpropiedadescuyoconocimientoesesencialparaun
diseñoeficientedeprogramasennumerosasaplicaciones .
6.1. Concepto de función
Paraescribirunprogramalar goenC++, sedivideésteenv ariosmódulosofunciones.UnprogramaC++secomponedev ariasfunciones, cadaunadelascualesrealizaunatareaprincipal.Elmejormedioparaescribirunprogramaesescribirfunciones
independientesparacadatareaquerealiceelprograma.Cadafunciónrealizaunadeterminadatareaycuandoseejecutalasentenciareturn oterminaelcódigodelafunciónyseretornaalpuntoenquefuellamadaporelprogramaofunciónprincipal.
Consejo: Unabuenareglaparadeterminarlalongituddeunafunción(númerodelíneasquecontiene)esquenoocupemáslongitudqueelequivalenteaunapantalla.
103
CAPÍTULO 6 Funciones y módulos
104
6.2. Estructura de una función
Unafunciónesunconjuntodesentencias—conunnombrecomún—quesepuedenllamardesdecualquierpartedeunprograma.EnC++todaslasfuncionessone xternasoglobales, esdecir, puedenserllamadasdesdecualquierpuntodelprograma.LasfuncionesenC++nosepuedenanidar(nopuededeclararseunafuncióndentrodeotrafunción).Laestructuradeuna
funciónenC++semuestraacontinuación:
tipo_de_retorno nombre_Función (Lista_de_Parámetros_Formales)
{
cuerpo de la función
return expresión;
}
tipo_de_retorno
nombre_Función
Lista_de_Parámetros_Formales
expresión
Tipodevalordevueltoporlafunciónolapalabrareserv ada void silafunciónnodevuelveningúnvalor.
Identificadoronombredelafunción.
Listadedeclaracionesdelosparámetrosdelafunciónseparadosporcomas.
Valorquedevuelvelafunción.
Losaspectosmássobresalienteseneldiseñodeunafunciónson:
• Tipo_ de_ retorno. EseltipodedatoquedevuelvelafunciónC++.EltipodebeserunodelostipossimplesdeC++,
talescomo int, char ofloat, ounpunteroacualquiertipoC++, ountipo struct, previamentedeclarado(véaseCapítulo8). Sinodevuelveningúnvaloreltipoes void.
• nombre_Función.Unnombredeunafuncióncomienzaconunaletraounsubrayado(_)ypuedecontenertantasletras,
númerososubrayadoscomodesee.
• Lista_ de_ Parámetros_ Formales. Esunalistadeparámetroscontiposqueutilizanelformatosiguiente: tipo1
parámetro1, tipo2 parámetro2, ...
• Cuerpodelafunción.Seencierraentrellavesdeapertura( {)ycierre( }).
• Pasodeparámetros. PosteriormenteseveráqueelpasodeparámetrosenC++sepuedehacerporvaloryporreferencia.
• Declaraciónlocal. Lasconstantes, tiposdedatosyv ariablesdeclaradasdentrodelafunciónsonlocalesalamismay
noperduranfueradeella.
• Valordevueltoporlafunción.Unafunciónpuededevolverunúnicovalor.Mediantelapalabrareservadareturn sepuededevolverelvalordelafunción.Unafunciónpuedetenercualquiernúmerodesentencias return.Tanprontocomo
elprogramaencuentracualquieradelassentencias return, seretornaalasentenciallamadora.
• Lallamadaaunafunción. Unallamadaaunafunciónredirigiráelcontroldelprogramaalafunciónnombrada. Debe
serunasentenciaounaexpresióndeotrafunciónquerealizalallamada.Estasentenciadebesertalquedebehabercoincidenciaennúmero, ordenytipoentrelalistadeparámetrosformalesyactualesdelafunción.
• Nosepuedendeclararfuncionesanidadas. Todocódigodelafuncióndebeserlistadosecuencialmente, alolargodetodo
elprograma.Antesdequeaparezcaelcódigodeunafunción, debeaparecerlallavedecierredelafunciónanterior.
EJEMPLO 6.1. Codificarlafunción producto(), mostrarsuestructurayrealizarunallamada.
Tipo de resultado
Declaración
de variables
locales
cout << producto(3,4);
Lista de parámetros formales
float producto(float num1,float num2)
{
float pro;
pro = num1 * num2;
return pro;
}
Cabecera de la función
Valor devuelto
por la función
CAPÍTULO 6 Funciones y módulos
105
Lallamadaanteriorvisualizaelv alor 12 queeselresultadoretornadoporlafunción producto, yaquemultiplica num1
pornum2, cuyosvaloresenlallamadason 3 y4 respectivamente.
EJEMPLO 6.2. Lafunciónmin devuelveelmenordelosdosnúmerosenterosquesepasancomoparámetro.Lafunciónmain iterallamadasa min.
#include <cstdlib>
#include <iostream>
using namespace std;
int min (int x, int y)
{
if (x < y)
return x;
else
return y;
}
int main(int argc, char *argv[])
{
int m, n;
do {
cout << "introduzca dos numeros. Si primero es cero fin " ;
cin >> m >> n;
if ( m != 0)
cout << " el menor es :" << min(m, n) << endl;
////Llamada a min
}while(m != 0);
system("PAUSE");
return EXIT_SUCCESS;
}
Unresultadodeejecucióneselsiguiente:
EJEMPLO 6.3. Lafunciónnormadevuelvela norma euclídeadelastrescoordenadasdeunvectordeR 3.
Norma(x, y, z) =œw
x2 +y2 +z2
#include <cstdlib>
#include <iostream>
#include <math.h>
//contiene función Sqrt
using namespace std;
float Norma (float x, float y, float z)
{
return sqrt(x * x + y * y + z * z);
}
CAPÍTULO 6 Funciones y módulos
106
int main(int argc, char *argv[])
{
float x, y, z;
cout << " vector : (" << 3 << ","<< 4 << ","<< 5 << ")" ;
cout << " norma = " << Norma(3, 4, 5) << endl;
//Llamada a norma
cout << " introduzca las tres coordenadas de vector " ;
cin >> x >> y >> z;
cout << " vector : (" << x << "," << y << "," << z << ")" ;
cout << " norma = " << Norma(x, y, z) << endl;
//Llamada a norma
system("PAUSE");
return EXIT_SUCCESS;
}
Unresultadodeejecucióneselsiguiente:
EJEMPLO 6.4. Funciónquecalculayde vuelvelasumadelosdivisor esdeunnúmer oenteropositivoquer ecibe
comoparámetro.
Lafuncióndivisores calculalasumadetodoslosdivisoresdelnúmeroincluyendo 1 yelpropionúmero.Pararealizarlobastaconinicializarunacumulador acu a 0, ymedianteunbucle for recorrertodoslosnúmerosnaturalesdesde1 hastaelpropion, ycadavezqueunnúmeroseadivisorden sumarloalacumuladoracu correspondiente.Unavez
terminadoelbuclelafuncióntomaelvalorde acu.
int divisores(int n)
{
int i, acu;
acu = 0;
for(i = 1; i <= n; i++)
if (n % i == 0)
acu += i;
return acu;
}
6.3. Prototipos de las funciones
C++requierequeunafunciónsedeclareodef inaantesdesuuso.La declaración deunafunciónsedenomina prototipo.Específicamenteunprototipoconstadelossiguienteselementos: nombredelafunción;listadeparámetrosformalesencerrados
entreparéntesisyunpuntoycoma.Losprototipossesitúannormalmentealprincipiodeunprograma, antesdeladefinición
delafunciónmain().Ladefinición completadelafuncióndebeexistirenalgúnlugardelprograma;porejemplo, antesodespuésde main.
Elcompiladorutilizalosprototiposparav alidarqueelnúmeroylostiposdedatosdelosparámetrosactualesdela
llamadaalafunciónsonlosmismosqueelnúmeroytipodeparámetrosformales.Siunafunciónnotienear
gumentos, se
ha deutilizarlapalabrareserv ada void comolistadear gumentosdelprototipo(tambiénsepuedeescribirparéntesisv acíos). Unformatoespecialdeprototipoesaquelquetieneunnúmeronoespecif icadodear gumentos, queserepresentapor
trespuntos(...).
CAPÍTULO 6 Funciones y módulos
107
EJEMPLO 6.5. Prototipo, llamadaydefinicióndefunción.Lafunción media recibecomoparámetrosdosnúmeros
yretornasumediaaritmética.
#include <cstdlib>
#include <iostream>
using namespace std;
double media (double x1, double x2);
//Declaración de media. Prototipo
int main(int argc, char *argv[])
{
double med, numero1, numero2;
cout << "introduzca dos numeros " ;
cin >> numero1 >> numero2;
med = media (numero1, numero2);
cout << " lamedia es :" << med << endl;
system("PAUSE");
return EXIT_SUCCESS;
//Llamada a la función
}
double media(double x1, double x2)
{
return (x1 + x2)/2;
}
//Definición de media
Resultadodeunaejecución:
EJEMPLO 6.6. Prototiposinnombresdeparámetrosenladeclar aciónysinparámetr osformales. Calculaelárea
deunrectángulo.Elprogramasedescomponeendosfunciones, ademásde main().Lafunción entrada retornaun
númerorealqueleedelteclado.Lafunción area calculaeláreadelrectángulocuyosladosrecibecomoparámetros.
#include <cstdlib>
#include <iostream>
using namespace std;
float area_r(float, float);
float entrada();
//Prototipo. Nombres parámetros omitidos
//Prototipo sin parámetros
int main(int argc, char *argv[])
{
float base, altura;
cout << " Base del rectangulo. ";
base = entrada();
cout << " Altura del rectangulo. ";
altura = entrada();
cout<< " Area rectangulo: "<< area_r(base,altura) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 6 Funciones y módulos
108
float entrada()
{
float m;
//Retorna un numero positivo
do
{
cout << " Numero positivo: ";
cin >> m;
} while (m <= 0.0);
return m;
}
float area_r(float b, float a) //Se declaran los nombres de parámetros
{
return (b * a);
}
Resultadodeejecución:
6.4. Parámetros de una función
C++proporcionadosmétodosparapasarv ariables(parámetros)entrefunciones.Unafunciónpuedeutilizar parámetrospor
valor yparámetrosporreferencia, opuedenotenerparámetros.
Paso por valor (tambiénllamadopasoporcopia)significaquecuandoC++compilalafunciónyelcódigoquellamaa
lamisma, lafunciónrecibeunacopiadelosv aloresdelosparámetrosactuales.Lafunciónreceptoranopuedemodif icarla
variabledelafunción(parámetropasado).EnlaFigura6.1semuestraelpasode x porvalor.Laejecucióndelprograma, producelasiguientesalida: 6 6 7 6.
int main()
{
int x = 6;
cout << x;
func_1(x);
cout << x;
return 0;
}
6
void func_1(int y)
{
cout << y;
i++;
cout << y;
}
Figura 6.1. Paso de la variable x por valor
EJEMPLO 6.7. Pasodeparámetrosporvaloraunafunción .
#include <cstdlib>
#include <iostream>
using namespace std;
CAPÍTULO 6 Funciones y módulos
void paso_por_valor(int x);
109
//Prototipo
int main(int argc, char *argv[])
{
int x =20;
cout << " antes de la llamada a paso_por_valor " << x << endl;
paso_por_valor(x);
cout << " despues de la llamada a paso_por_valor " << x << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
void paso_por_valor(int x)
{
cout << " dentro de paso_por_valor " << x << endl;
x *= 2;
cout << " despues de x *=2 y dentro de paso_por_valor " << x << endl;
}
Resultadodeejecución:
Paso por referencia. Cuandounafuncióndebemodif icarelvalordelparámetropasadoyde volverestevalormodificadoalafunciónllamadora, sehadeutilizarelmétododepasodeparámetropor referencia odirección.
Paradeclararunav ariablequeesparámetroformal, comopasoporreferencia, elsímbolo & debeprecederalnombrede
lavariableenlacabeceradelafunción, yenlallamadaelparámetroactualcorrespondientedebeserelnombredeunav ariable.TambiénpuedeusarseelmétododelospunterosdeC: enladeclaracióndelav ariablequeesparámetroformal, elsímbolo * debeprecederalnombredelav ariable;enlallamadaalafuncióndeberealizarseelparámetroactualquedebeser &
variable.
Cuandosemodificaelvalordelparámetroformaldeunparámetroporreferencia(lav ariablelocal), estevalorquedaalmacenadoenlamismadireccióndememoria, porloquealretornaralafunciónllamadoraladireccióndelamemoriadonde
sealmacenóelparámetrocontendráelv alormodificado.
EJEMPLO 6.8. Pasodeparámetrosporreferenciaaunafunción, estiloC++.
#include <cstdlib>
#include <iostream>
using namespace std;
void referencia(int& x)
{
x += 2;
}
//Parámetro por referencia
int main(int argc, char *argv[])
{
int x = 20;
cout << " antes de la llamada
referencia (x);
" << " x= " << x << endl;
//Llamada con nombre de variable
CAPÍTULO 6 Funciones y módulos
110
cout << " despues de la llamada " <<" x= " << x << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadodeejecución:
EJEMPLO 6.9. Pasodeparámetrosporreferenciaaunafunción, estiloC.
#include <cstdlib>
#include <iostream>
using namespace std;
void intercambio(int* x, int* y)
{
int aux = *x;
*x
*y
//Declaración como puntero
= *y;
= aux;
}
int main(int argc, char *argv[])
{
int x = 20, y = 30 ;
cout << " antes de la llamada " ;
cout <<" x= " << x << " y= " << y << endl;
intercambio (&x, &y);
cout << " despues de la llamada " ;
cout <<" x= " << x << " y= " << y << endl;
system("PAUSE");
return EXIT_SUCCESS;
//Llamada con dirección
}
Resultadodeejecución:
Parámetros const en una función. Elespecificador const, indicaalcompiladorquesóloesdelecturaenelinteriordela
función.Siseintentamodificarenesteparámetroseproduciráunmensajedeerrordecompilación.
EJEMPLO 6.10. Usode const enladeclaración.
void error_en compilacion(const int x, const float & y)
{
x = 123;
//Fallo en tiempo de compilación
y = 21.2;
//Fallo en tiempo de compilación
}
CAPÍTULO 6 Funciones y módulos
111
Argumentos por omisión o defecto. UnacaracterísticapoderosadelasfuncionesC++esqueenellaspuedenestablecerv aloresporomisión oausencia (“pordefecto”)paralosparámetros.Sepuedenasignarargumentospordefectoalosparámetros
deunafunción.Cuandoseomiteelar gumentodeunparámetroqueesunar gumentopordefecto, seutilizaautomáticamente
éste.Laúnicarestricciónesquesedebenincluirtodaslasv ariablesdesdelaizquierdahastaelprimerparámetroomitido.Si
sepasanvaloresalosargumentosomitidosseutilizaesevalor;sinosepasaunvaloraunparámetroopcional, seutilizaelvalorpordefectocomoargumento.Elvalorpordefectodebeserunae xpresiónconstante.
EJEMPLO 6.11. Lafunciónasteriscostienetr esparámetros.Elprimeroindicaelnúmerodefilas, elsegundoindicaelnúmerodecolumnasyelterceroelcarácteraescribir.Elsegundoyeltercerparámetrossonporomisión.
#include <cstdlib>
#include <iostream>
using namespace std;
void asteriscos(int fila, int col =3,
{
for(int i = 0; i < fila; i++)
{
for (int j = 0; j < col; j++)
cout << c;
cout <<endl;
}
}
char c = '*')
int main(int argc, char *argv[])
{
asteriscos(4);
//Correcto dos parámetros por omisión
cout << endl;
asteriscos( 4,6);
//Correcto un parámetro por omisión
cout << endl;
asteriscos(4,6,'@');
//asteriscos()llamada incorrecta. Primer parámetro
obligatorio
//asteriscos(4, , '@');
llamada incorrecta
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadodeejecución:
CAPÍTULO 6 Funciones y módulos
112
Reglas de construcción de argumentos por defecto
• Losargumentospordefectosedebenpasarporv alor.Nuncaporreferencia.
• Losvaloresdelosar gumentospordefectopuedenserv aloresliteralesodef iniciones const.Nopuedenser variables.
• Todoslosargumentospordefectodebencolocarsealf inalenelprototipodelafunción.Despuésdelprimerargumentopordefecto, todoslosargumentosposterioresdebenincluirtambiénvalorespordefecto.
6.5. Funciones en línea (inline)
ExistendosopcionesdisponiblesparalageneracióndelcódigodelasfuncionesenC++: funcionesenlínea yfueradelínea.
Lasfunciones en línea (inline) sirvenparaaumentarlavelocidaddesuprograma.Suusoesconvenientecuandolafunciónseutilizamuchasv ecesenelprogramaysucódigoespequeño.P araunafunciónenlínea (inline), elcompiladorinsertarealmenteelcódigoparalafunciónenelpuntoenquesellamaalafunción.Estaacciónhacequeelprogramaseejecutemásrápidamente.
Unafunciónnormal, fuera de línea, esunbloquedecódigoquesellamadesdeotrafunción.Elcompiladorgeneracódigoparasituarladirecciónderetornoenlapila.Ladirecciónderetornoesladireccióndelasentenciaquesiguealainstr ucciónquellamaalafunción. Acontinuación, elcompiladorgeneracódigosquesitúancualquierar gumentodelafunciónen
la pilaamedidaqueserequiera.Porúltimo, elcompiladorgeneraunainstruccióndellamadaquetransf iereelcontrolala
función.
Tabla 6.1. Ventajas y desventajas de la función en línea
Funciones en línea
Funciones fuera de línea
Ventajas
Desventajas
Rápidadeejecutar.
Pequeñotamañodecódigo.
Tamañodecódigogrande.
Lentadeejecución.
Paracrearunafunciónenlínea (inline), insertarlapalabrareserv ada inline delantedeunadeclaraciónnormalydel
cuerpo, ysituarlaenelarchivofuenteantesdequeseallamada.Lasintaxisdedeclaraciónes:
inline TipoRetorno NombreFunción (Lista parámetros con tipos)
{cuerpo}
EJEMPLO 6.12. Funcionesenlíneaparacalcularelvolumenyelár eatotaldeuncilindrodelqueseleensur adio
yaltura.
El volumen deuncilindrovienedadopor: volumen =p *radio2 *altura.El Areatotal vienedadapor Areatotal =
=2*p *radio *altura +p *radio2.Pararesolverelproblemabastacondeclararlasv ariablescorrespondientes, declararlaconstante pi ylasdosfuncionesenlíneaquecodif icanlasfórmulasrespectivas.Elprogramaprincipalleeel
radio yla altura enunbuclewhile garantizandosuvalorpositivo.
#include <cstdlib>
#include <iostream>
using namespace std;
const float Pi = 3.141592;
inline float VOLCILINDRO(float radio,float altura)
{
return (Pi * radio * radio * altura);
}
// Función en línea
CAPÍTULO 6 Funciones y módulos
113
inline float AREATOTAL(float radio,float altura)
// Función en línea
{
return (2 * Pi * radio * altura + Pi * radio * radio);
}
int main(int argc, char *argv[])
{
float radio, altura, Volumen, Areatotal;
do
{
cout << "Introduzca radio del cilindro positivo: ";
cin >> radio;
cout << "Introduzca altura del cilindro positiva: ";
cin >> altura;
}while (( radio <= 0) || (altura <= 0));
Volumen = VOLCILINDRO(radio, altura);//llamada sustituye el código
// la sentencia anterior es equivalente a
// Volumen = Pi*radio*radio*altura;
Areatotal = AREATOTAL(radio, altura);//llamada sustituye el código
// la sentencia anterior es equivalente a
// Areatotal = 2*Pi*radio*altura+Pi*radio*radio;
cout << "El volumen del cilindro es:" << Volumen << endl;
cout << "El Area total del cilindro es:" << Areatotal << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadodeejecución:
Tambiénsonfuncionesenlínealasdef inidasconlasentencia define.Lasintaxisgenerales:
#define NombreMacro(parámetros sin tipos) expresión_texto
Ladefiniciónocuparásólounalínea, aunquesisenecesitamáste xto, sepuedesituarunabarrain vertida(\)alf inalde
laprimeralíneaycontinuarenlasiguiente, encasodesernecesariasmáslíneasprocederdeigualforma;deesamanerase
puedeformarunae xpresiónmáscompleja.Entreelnombredelamacroylosparéntesisdelalistadear gumentosnopuede
haberespaciosenblanco.Esimportantetenerencuentaqueenlasmacrosconar gumentosnohaycompr obacióndetipos.
EJEMPLO 6.13. Funciónenlíneaparadefinirunafunciónmatemática.
#include <cstdlib>
#include <iostream>
using namespace std;
#define fesp(x) (x * x + 2 * x –1)
int main(int argc, char *argv[])
{
float x;
CAPÍTULO 6 Funciones y módulos
114
for (x = 0.0; x <= 6.5; x += 0.3)
cout << x << " " << fesp(x) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
6.6. Ámbito (alcance)
Elámbitoeslazonadeunprogramaenelqueesvisibleunavariable.Existencuatrotiposdeámbitos:programa, archivofuente, función ybloque.Normalmentelaposicióndelasentenciaenelprogramadeterminaelámbito.
• Lasvariablesquetienenámbitodeprograma puedenserreferenciadasporcualquierfunciónenelprogramacompleto;
talesvariablessellamanvariablesglobales.Parahacerunavariableglobal, declárelasimplementealprincipiodeunprograma, fueradecualquierfunción.
• Unavariablequesedeclarafueradecualquierfunciónycuyadeclaracióncontienelapalabrareserv ada static tiene
ámbitodearchivofuente.Lasvariablesconesteámbitosepuedenreferenciardesdeelpuntodelprogramaenqueestán
declaradashastaelfinaldelarchivofuente.Unavariablestatic esaquellaquetieneunaduraciónfija.Elespaciopara
elobjetoseestableceentiempodecompilación;existeentiempodeejecuciónyseeliminasólocuandoelprogramadesaparecedememoriaentiempodeejecución.
• Unavariablequetieneámbitodeunafunción sepuedereferenciardesdecualquierpartedelafunción.Lasvariablesdeclaradasdentrodelcuerpodelafunciónsedicequeson locales alafunción.
• Unavariabledeclaradaenunbloquetieneámbitodebloque ypuedeserreferenciadaencualquierpartedelbloque, desdeelpuntoenqueestádeclaradahastaelfinaldelbloque.Lasvariableslocalesdeclaradasdentrodeunafuncióntienen
ámbitodebloquedelafunción;nosonvisiblesfueradelbloque.
EJEMPLO 6.14. Ámbitodeprogramaydefunción.Calculaelár eadeuncírculoylalongituddeunacir cunferenciaderadioleídodelaentrada.
EláreadeuncírculosecalculamediantelafórmulaArea =p *radio2;lalongituddeunacircunferenciaporLongitud =
=2*p *radio.Elparámetroformal r delasfunciones longitud yArea tienenámbitodebloque.LavariablePi (no
modificable)tieneámbitodeprograma.Lavariableradio tieneámbitodefunción.Elprogramaprincipalleeelradio
positivo, usandounblucle do while, ymediantellamadasalasfunciones longitud y Area visualizalosresultados.
#include <cstdlib>
#include <iostream>
using namespace std;
const float Pi = 3.141592;
float longitud(float r)
{
return Pi * r;
}
float Area(float r)
{
return (Pi * r * r);
}
int main(int argc, char *argv[])
{
float radio;
// Ámbito de programa
// El parámetro r tiene ámbito de función
// El parámetro r tiene ámbito de función
//Tiene ámbito de función
CAPÍTULO 6 Funciones y módulos
115
do
{
cout << "Introduzca radio positivo: ";
cin >> radio;
}while ( radio <= 0);
cout << " La longitud de la circunferencia es: " ;
cout << longitud(radio) << endl;
cout << " El area del circulo es: " << Area(radio) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Unresultadodeejecucióndelprogramaes:
EJEMPLO 6.15. Ámbitodefunciónydebloque.Lafunciónfactorialsedefinedelasiguienteforma: factorial(n)= 1
sin=0, yfactorial(n)=n*factorial(n–1)sin>0.
Lafunción factorial, seprogramanorecursivamente, usandounbucleascendente, inicializandoelacumuladora f
(Ámbitodefunción)a1 ymultiplicandoencadaiteraciónelacumuladorf porlavariabledecontroldelbuclei (Ámbitodebloque for).Elprogramaprincipalleelosv alorespositivos valor1 y valor2 ymedianteunb ucle for controladoporlavariablei llamasucesivamentealafunción factorial visualizandolosresultados.Lasvariablesvalor1,
valor2 e i tienenámbitodefunción.
#include <cstdlib>
#include <iostream>
using namespace std;
long int
factorial (int
n);
int main(int argc, char *argv[])
{
int valor1, valor2, i;
//Prototipo de función
// Ámbito función main
do
{
cout << "Introduzca dos numeros positivos x < y: ";
cin >> valor1 >> valor2;
}while (( valor1 <= 0) || (valor2 <= 0) || (valor1 > valor2));
for (i = valor1; i <= valor2; i++)
cout << i << " factorial " << factorial(i) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
long int factorial (int
{
long int f;
n)
//Ámbito función
CAPÍTULO 6 Funciones y módulos
116
f = 1.0 ;
for (int i = 1; i <= n; i++)
f = f * i;
return f;
//Ámbito bloque for
}
Unaejecucióndelprogramaes:
6.7. Clases de almacenamiento
Losespecificadoresdeclases(tipos)dealmacenamientopermitenmodif icarelámbitodeunav ariable.Losespecif icadores
puedenserunodelossiguientestipos: auto, extern, register, static ytypedef.
Variables automáticas. Lasvariablesquesedeclarandentrodeunafunciónsedicequesonautomáticas( auto), significandoqueselesasignaespacioenmemoriaautomáticamentealaentradadelafunciónyselesliberaelespaciotanprontose
salededichafunción.Lapalabrareserv adaauto esopcional.
EJEMPLO 6.16. Declaracióndevariablesautomáticas.
auto int xl;
auto float a,b;
auto char ch, cha1
esigualque
esigualque
esigualque
int x1;
float a,b;
char ch, ch1;
Variables registro. Precediendoaladeclaracióndeunav ariableconlapalabrareserv ada register, sesugierealcompiladorquelavariablesealmaceneenunodelosregistroshardware delmicroprocesador.Paradeclararunavariableregistro, hay
queutilizarunadeclaraciónsimilara: register int k;.Unavariableregistrodebeserlocalaunafunción, nuncapuedeser
globalalprogramacompleto.
Variables externas. Cuandounavariablesedeclarae xterna, seindicaalcompiladorqueelespaciodelav ariableestádefinidaenotroarchivofuenteyquepuedeserusadaenelarchi voactual.Unavariableglobaldefinidaenunarchivo, puedeser
usadaenlacompilacióndeotroarchivodistintoperosinreservarnuevoespacioenmemoria, paraquealsermontadasjuntas,
ambascompilacionesfuncionencorrectamente.Sinosehicieraladeclaracióndev ariableexterna, entoncesocuparíanposicionesdememoriadistintasyalmontarlosdosarchivosnofuncionaría.Sedeclaranprecediendoaladeclaracióndevariable,
lapalabra extern.
EJEMPLO 6.17. Lasfunciones LeerReal y EscribirReal leenyescribenrespectivamentelavariablereal r.Esta
variabler esglobalynoestáenelar chivofuentedelasfunciones.
// archivo fuente
axtern1.cpp
#include <iostream>
using namespace std;
void LeerReal(void)
{
extern float f;
// variable definida en otro archivo (extern2.cpp)
cout << " introduzca dato ";
cin >> f;
}
CAPÍTULO 6 Funciones y módulos
117
void EscribirReal(void)
{
extern float f;
// variable definida en otro archivo (extern2.cpp)
cout << f;
}
// archivo fuente extern2.cpp
#include <cstdlib>
#include <iostream>
using namespace std;
float f;
void LeerReal(void);
void EscribirReal();
int main(int argc, char *argv[])
{
LeerReal();
EscribirReal();
system("PAUSE");
return EXIT_SUCCESS;
}
Variables estáticas. Lasvariablesestáticas noseborran(nosepierdesuv alor)cuandolafunciónterminay, enconsecuencia, retienensusvaloresentrellamadasaunafunción.Alcontrarioquelasvariableslocalesnormales, unavariablestatic se
inicializasólounavez.Sedeclaranprecediendoaladeclaracióndelav ariableconlapalabrareservadastatic.
EJEMPLO 6.18. Calculalassucesivaspotencias a0, a1, a2, ..., an, usandounavariableestáticaf.
LafunciónpotenciaS tienecomovariablef comovariableestática, porloquerecuerdasuvalorencadallamada.En
laprimerallamadaelvalordef es1;almultiplicarf pora, f tomaelvalordea1, ysealmacenaenmemoria.Enlasiguientellamada, almultiplicar f por a, f tomaelvalorde a2, yasísucesivamente.Deestaforma, alserllamadocon
elbuclefor delprogramaprincipal, sevanvisualizandolassucesivaspotenciasde a.
Tambiénseprogramalafunción potencia, medianteunbuclequemultiplicaporsímismoelprimerparámetro a
tantasvecescomoindiqueelse gundo.Elprogramaprincipalleelabase a yelexponentepositivo n yrealizalasllamadascorrespondientes.Cambiandolallamadaalafunción potenciaS porlafunción potencia seobtienenlosmismosvaloresdesalida.
#include <cstdlib>
#include <iostream>
using namespace std;
float potenciaS (float a, int
{
static float f = 1.0 ;
n)
f *= a;
return f;
}
float potencia (float a, int
{
float f = 1.0;
n)
CAPÍTULO 6 Funciones y módulos
118
for ( int i = 1; i <= n; i++)
f *= a;
return f;
}
int main(int argc, char *argv[])
{
float a;
int n;
cout << " valor de a ";
cin >> a;
do
{
cout << " valor de n ";
cin >> n;
} while (n<=0);
for( int i = 1 ; i <= n ; i++)
cout << a << " elevado a " << i << " = " << potenciaS(a,i) <<endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadodeejecución:
EJEMPLO 6.19. Calculalafuncionxconvariablesestáticas.La funcionx sedefinedelasiguienteforma:
funcionx(0) = 0, funcionx(1) = 1 funcionx(2) = 2 funcionx(n) = funcionx(n–3)+ 2*funcionx(n–2)+funcionx(n–1) sin > 2.
Paraprogramarlasedefinentresvariableslocalesestáticasquealmacenalosúltimosvaloresobtenidosdelafunciónx.
Deestaforma, siselellamadesdeunb ucle for hastaelvalorquesequieracalcularseobtienelalistadev aloresde
lafunciónqueeslasiguiente: 0, 1, 2, 4, 9, 19, 41, ...
#include <cstdlib>
#include <iostream>
int resto(int n, int m);
using namespace std;
long int funcionx();
int main(int argc, char *argv[])
{
int n , i;
cout << " valor n de la funcionx ?: ";
cin >> n;
CAPÍTULO 6 Funciones y módulos
119
cout << " Secuencia de funcionx: 0,1,2";
for (i = 3; i <= n; i++)
cout <<"," << funcionx();
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
long int funcionx()
{
static int x = 0, y = 1, z = 2;
int aux;
aux = x + 2 * y + z ;
x = y;
y = z;
z = aux;
return z;
}
Resultadosdeejecución:
6.8. Concepto y uso de funciones de biblioteca
TodaslasversionesdeC++ofrecenunabibliotecaestándardefuncionesqueproporcionansoporteparaoperacionesutilizadasconmásfrecuencia.Las funcionesestándar opredefinidas, sedividenengrupos;todaslasfuncionesquepertenecenal
mismogruposedeclaranenelmismo archivodecabecera.Losnombresdelos archivosdecabecera estándarutilizadosen
losprogramassemuestranacontinuaciónencerradosentrecorchetestipoángulo:
<assert.h>
<limits.h>
<signal.h>
<stdlib.h>
<ctype.h>
<locale.h>
<stdarg.h>
<string.h>
<errno.h>
<math.h>
<stddef.h>
<time.h>
<float.h>
<setjmp.h>
<stdio.h>
Enlosmódulosdeprogramasepuedenincluirlíneas #include conlosarchi vosdecabeceracorrespondientesencualquierorden.
6.9. Miscelánea de funciones
Funciones de carácter. Elarchivodecabecera <ctype.h> defineungrupodefunciones/macrosdemanipulacióndecaracteres.Todaslasfuncionesde vuelvenunresultadodev alorverdadero (distintodecero)o falso (cero).(Véasela Tabla6.2.)
EJEMPLO 6.20. Realizarunbuclequeiterahastaqueseintroduzcas on.
include <cstdlib>
#include <iostream>
using namespace std;
// contiene <ctype.h>
CAPÍTULO 6 Funciones y módulos
120
int main(int argc, char *argv[])
{
char resp;
//respuesta del usuario
do
{ cout << " introduzca S = Si N = N0? ";
cin >> resp;
resp = toupper(resp);
} while ( (resp != 'S') && (resp != 'N'));
cout <<" respuesta leida " << resp;
system("PAUSE");
return EXIT_SUCCESS;
}
Tabla 6.2. Funciones de caracteres
Función
Prueba (test) de
intisalpha(intc)
intisdigit(intc)
intisupper(intc)
intislower(intc)
intisalnum(intc)
intiscntrl(intc)
intisxdigit(intc)
intisprint(intc)
intisgraph(intc)
intisspace(intc)
Verdaderosiesletramayúsculaominúscula.
Verdaderosiesdígito(1, 2, …, 9).
Verdaderosiesletramayúscula(A-Z).
Verdaderosiesletraminúscula(a-z).
isalpha(c)||isdigit(c).
Verdaderosiescarácterdecontrol.(Códigos ASCII0-31).
Verdaderosiesdígitohexadecimal.
VerdaderosiCarácterimprimibleincluyendoESPACIO.códigoASCII21a127.
Verdaderosiescarácterimprimiblee xceptoESPACIO.
Verdaderosicescarácterunespacio, nuevalínea(\n), retornodecarro(\r), tabulación(\t)otabulaciónvertical(\v).
Verdaderosiescarácterimprimiblenoespacio, dígitooletra.
Conviertealetramayúscula.
Conviertealetrasminúscula.
intispunct(intc)
inttoupper(intc)
inttolower(intc)
Funciones numéricas. Virtualmente, cualquieroperaciónaritméticaesposibleenunprogramaC++.Lasfuncionesmatemáticasdisponiblessonlassiguientes: trigonométricas;logarítmicas;exponenciales;funcionesmatemáticasdecaráctergeneral;
aleatorias.Lamayoríadelasfuncionesnuméricasestánenelarchivodecabeceramath.h;lasfuncionesdevalorabsoluto abs
ylabs estándefinidasen stdlib.h, ylasfuncionesde divisiónentera div yldiv tambiénestánen stdlib.h.
EJEMPLO 6.21. Generar10númerosaleatoriosmenoresque100yvisualizaelmenoryelmayor .
include <cstdlib>
#include <iostream>
#include <time.h>
#define randomize ( srand (time(NULL) ))
#define random(num) ( rand()%(num))
#define Tope 100
#define MAX( x, y)( x > y ? x : y )
#define MIN( x, y)( x < y ? x : y )
using namespace std;
int main(int argc, char *argv[])
{
int max, min, i;
randomize;
max = min = random(Tope);
//Macro para definir randomize
// Macro para definir random
// Macro para Maximo
// Macro para Mínimo
CAPÍTULO 6 Funciones y módulos
121
for (i = 1; i < 10; i++)
{
int x = random(Tope);
min = MIN(min,x);
max = MAX(max,x);
}
cout << "minimo "<< min << " maximo "<< max << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Funciones de fecha y hora. Losmicroprocesadorestieneunsistemaderelojqueseutilizaprincipalmenteparacontrolarel
microprocesador, peroseutilizatambiénparacalcularlafechaylahora.Elarchi vodecabecera time.h defineestructuras,
macrosyfuncionesparamanipulacióndefechasyhoras.Lafechaseguardadeacuerdoconelcalendariogre
goriano
(mm/dd/aa).Lasfunciones time yclock devuelven, respectivamente, elnúmerodesegundosdesdelahorabase yeltiempo
deCPU(UnidadCentraldeProceso)empleadoporelprogramaencurso.
Funciones de utilidad. Ellenguaje C++incluyeunaseriedefuncionesdeutilidadqueseencuentranenelarchi vodecabecerastdlib.h comolassiguientes: abs(n), quedevuelveelvalorabsolutodelargumenton; atof(cad) queconviertelosdígitosdelacadena cad anúmeroreal; atoi(cad), atol(cad) queconviertelosdígitosdelacadena cad anúmeroenteroy
enterolargorespectivamente.
Visibilidad de una función. Elámbito deunelementoessuvisibilidaddesdeotraspartesdelprogramayla duración deun
objetoessutiempodevida, loqueimplicanosólocuántotiempoexistelavariable, sinocuandosecreaycuandosehacedisponible.ElámbitodeunelementoenC++dependededóndesesitúeladef iniciónydelosmodificadoresqueleacompañan.
Sepuededecirqueunelementodefinidodentrodeunafuncióntieneámbitolocal (alcancelocal), osisedefinefueradecualquierfunción, sedicequetieneun ámbitoglobal.
Compilación separada. Losprogramasgrandessonmásfácilesdegestionarsisedividenenvariosarchivosfuente, también
llamadosmódulos, cadaunodeloscualespuedecontenerunaomásfunciones.Estosmódulossecompilanyenlazanporseparadoposteriormenteconun enlazador, obienconlaherramientacorrespondientedelentornodeprogramación.Cuandose
tienemásdeunarchivofuente, sepuedereferenciarunafunciónenunarchivofuentedesdeunafuncióndeotroarchivofuente.Alcontrarioquelasvariables, lasfuncionessonexternaspordefecto.Sidesea, porrazonesdelegibilidad, puedeutilizarla
palabrareservadaextern conelprototipodefunción.Sepuedehacerunafunciónvisiblealexteriordeunarchivofuenteutilizandolapalabrareservadastatic conlacabeceradelafunciónylasentenciadelprototipodefunción.Siseescribelapalabra static antesdeltipodev alordevueltoporlafunción, lafunciónnoserápúblicaalenlazador , demodoqueotrosmódulosnotendránaccesoaella.
6.10. Sobrecarga de funciones (polimorfismo)
Lasobrecarga defuncionespermiteescribiryutilizarmúltiplesfuncionesconelmismonombre, perocondiferentelistade
argumentos.Lalistadear gumentosesdiferentesitieneunar gumentoconuntipodedatodistinto, sitieneunnúmerodiferentedeargumentos, oambos.Lalistadear gumentossesueledenominar signaturadelafunción.
LasreglasquesigueC++paraseleccionarunafunciónsobrecar gadason:
• Siexisteunacorrespondenciaexactaentrelostiposdeparámetrosdelafunciónllamadorayunafunciónsobrecar gada,
seutilizadichafunción.
• Sinoexisteunacorrespondenciaexacta, perosíseproducelaconversióndeuntipoauntiposuperior(talcomounparámetro int a long, oun float aun double)yseproduce, entonces, unacorrespondencia, seutilizarálafunciónseleccionada.
• Sepuedeproducirunacorrespondenciadetipos, realizandoconversionesforzosasdetipos( moldes-cast).
• Siunafunciónsobrecargadasedefineconunnúmerovariabledeparámetros(medianteelusodepuntossuspensivos (...))
sepuedeutilizarcomounacoincidenciapotencial.
CAPÍTULO 6 Funciones y módulos
122
EJEMPLO 6.22. Sobrecargadefunciones.
#include <cstdlib>
#include <iostream>
using namespace std;
int Sobrecarga(int);
int Sobrecarga(int, int);
float Sobrecarga(float, float);
float Sobrecarga (float, float, float);
int main(int argc, char *argv[])
{
int x = 4, y = 5;
float a = 6.0 , b = 7.0, c = 9.0;
cout << "\n El cuadrado de " << x << " es: "
<< Sobrecarga(x);
cout << "\n El producto de "
<< x << "por " << y << " es: "
<< Sobrecarga(x, y);
cout << "\n La suma de " << a << "y " << b << " es: "
<< Sobrecarga(a, b);
cout << "\n La suma de " << a << "y " << b << " es: "
<< Sobrecarga(a, b) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
// Sobrecarga, calcula el cuadrado de un valor entero
int Sobrecarga(int valor)
{
return (valor * valor);
}
// Sobrecarga, multiplica dos valores enteros
int Sobrecarga(int valor1, int valor2)
{
return(valor1 * valor2);
}
// Sobrecarga, calcula la suma de dos valores reales
float Sobrecarga(float valor1, float valor2)
{
return (valor1 + valor2);
}
// Sobrecarga, calcula la media de tres valores reales
float Sobrecarga (float valor1, float valor2 , float valor3)
{
return (valor1 + valor2 + valor3)/3;
}
CAPÍTULO 6 Funciones y módulos
123
6.11. Plantillas de funciones
Lasplantillas de funciones (functiontemplates)proporcionanunmecanismoparacrearuna funcióngenérica.Unafunción
genéricaesunafunciónquepuedesoportarsimultáneamentediferentestiposdedatosparasuparámetrooparámetros.
Unaplantilladefuncióndetiponogenéricoperodear gumentosgenéricostieneelsiguienteformato:
template<classTipo>
Tipo_de_funcionFunc1(Tipoarg1, Tipoarg2)
{
//cuerpodelafunciónFunc1()
}
EJEMPLO 6.23. Funciónqueretornaelmenorcontiposdedatosg enéricos.
#include <cstdlib>
#include <iostream>
using namespace std;
template <class T>
T man(T a, T b)
{
if (a < b)
return a;
else
return b;
}
int main(int argc, char *argv[])
{
int x = 4, y = 5;
float a = 6.0 , b = 7.0;
char c = 'C', d = 'A';
cout << "\n El menor de "
cout << "\n El menor de "
cout << "\n El menor de "
system("PAUSE");
return EXIT_SUCCESS;
}
<< x << " y " << y << " es: " << man(x, y);
<< a << " y " << b << " es: " << man(a, b);
<< c << " y " << d << " es: " << man(c, d) << endl ;
CAPÍTULO 6 Funciones y módulos
124
EJERCICIOS
6.1.
EscribirunafunciónquetengaunargumentodetipoenteroyquedevuelvalaletraPsielnúmeroespositivo, ylaletraN
siesceroonegativo.
6.2.
Escribirunafunciónlógicadedosargumentosenteros, quedevuelvatrue siunodividealotroyfalse encasocontrario.
6.3.
Escribirunafunciónquecon viertaunatemper aturadadaengr adosCelsiusagr adosFahrenheit.Lafórmuladecon versiónes:
F =
6.4.
9
5
C +32
Escribirunafunciónlógica Vocal quedeterminesiuncarácteresunavocal.
PROBLEMAS
6.1.
Escribirunafunciónquetengacomoparámetr odosnúmerosenterospositivos num1 y num2, ycalculeelr estodeladivisiónenteradelmayordeellosentreelmenormediantesumayr estas.
6.2.
Escribirunafunciónquetengacomoparámetrosdosnúmerosenterospositivosnum1 ynum2 ycalculeelcocientedeladivisiónenteradelprimeroentreelsegundomediantesumasyrestas.
6.3.
Escribirunprogramaquecalculelosvaloresdelafuncióndefinidadelasiguienteforma:
funciony(0)=0,
funciony(1)=1
funciony(2)=2
funciony(n)=funciony(n–3)+3*funcion y(n–2)–funcionx(n–1)sin>2.
6.4.
Unnúmeroentero n sedicequeesperfectosilasumadesusdivisor esincluyendo1ye xcluyéndoseélcoincideconsigomismo.Codificarunafunciónquedecidasiunnúmeroesperfecto.Porejemplo6esunnúmeroperfecto 1 + 2 + 3 = 6.
6.5.
Escribirunafunciónquedecidasidosnúmer osenterospositivossonamigos.Dosnúmer ossonamigos, silasumadelos
divisoresdistintosdesímismodecadaunodeelloscoincideconelotr
onúmero.Ejemplo284 y220 sondosnúmerosamigos.
6.6.
Dadoelvalordeunángulo, escribirunafunciónquemuestr aelvalordetodaslasfuncionestrigonométricascorr espondientesalmismo.
6.7.
Escribirunafunciónquedecidasiunnúmer oenteropositivoesprimo.
6.8.
Escribirunafunciónparacalcularlascoordenadasxeydelatrayectoriadeunproyectildeacuerdoalosparámetrosángulodeinclinación alfa yvelocidadinicialvaintervalosde 0.1 s.
6.9.
Escribirunprogramaquemediantefuncionescalcule:
• Lasanualidadesdecapitalizaciónsiseconoceeltiempo, eltantoporcientoyelcapitalf inalapagar.
• Elcapitalcquerestaporpagaralcabodetañosconociendolaanualidaddecapitalizaciónyeltantoporciento.
• Elnúmerodeañosquesenecesitanpar apagaruncapitalcauntantoporcientor .
CAPÍTULO 6 Funciones y módulos
125
m!
m
6.10. Sedefineelnúmerocombinatoriomsobrendelasiguienteforma:
=
.Escribirunprogramaquelealosvan!(m
–n)!
n
loresdemydenycalculeelvalordemsobr en.
12
6.11. Dadounnúmeroreal p entreceroyuno, unnúmeroentero n positivo, yotronúmeroentero i comprendidoentre 0 y n, se
sabequesiunsucesotienepr obabilidaddequeocurr a p, yelexperimentoaleatorioserepite n veces, laprobabilidadde
queelsucesoocurr a i vecesvienedadoporlafunción binomial deparámetrosn, peidadaporlasiguientefórmula:
Probabilidad(X=i) =
n
1 i 2 p (1–p)
n –i
i
Escribirunprogramaquelealosvaloresde p, n ei, ycalculeelvalordadoporlafunción binomial.
6.12. Escribirunprogramautiliceunafunciónparaconvertircoordenadaspolaresarectangulares.
x=rcosq
y=rsenq
P(x,y)
r
q
ejex
O
6.13. Laleydeprobabilidaddequeocurraelsucesorvecesdeladistrib ucióndePoissondemediamvienedadopor:
Probabilidad(X =r) =
mr
r!
e–m
Escribirunprogramaquecalculemedianteunmenúelvalorde:
a) Elsucesoocurraexactamenterveces.
b) Elsucesoocurraalosumorveces .
c) Elsucesoocurraporlomenosrveces .
6.14. Escribirfuncionesquecalculenelmáximocomúndivisoryelmínimocomúnmúltiplodedosnúmer osenteros.
6.15. Escribirfuncionesparaleerfraccionesyvisualizarlas, representandolasfraccionespordosnúmerosenterosnumeradory
denominador.
6.16. Escribirunprogramaquemedianteunmenúpermitag estionarlasoper acionessumaresta, productoycocientedefr acciones.
6.17. Ladescomposiciónenbase2detodonúmero, permiteenparticularquetodonúmeroenelintervalo[1,2], sepuedaescrin
1
bircomolímitedelaserie Σ ± sg(i) i dondelaeleccióndelsignosg(i)dependedelnúmer oquesetrate.
2
i=1
Elsignodelprimertérminoessiempr epositivo.Unavezcalculadolossignosdelosnprimer os, paracalcularelsignodelsiguientetérminoseempleaelesquema: signoespositivosg(n+1)=+1 sisecumple:
n
1
Σ sg(i) 2i
i =1
2>x
encasocontrario, sg(n +1)=–1.
Escribirunprogramaquecalculeello garitmoenbasedosdeunnúmer ox >0 conunerrorabsolutomenoroigual
queépsilon(xyépsilonsondatos).
CAPÍTULO 6 Funciones y módulos
126
6.18. Lafunciónseno(sen)vienedefinidamedianteelsiguientedesarrolloenserie.
n
x2i+1
i=0
(2i +1)!
sen(x) =Σ
Escribirunafunci ónquerecibacomopar ámetroelvalordexas ícomounacotadeerr or, ycalculeelsenodexcon
unerrormenorquelacotaqueselepase .Ejecutelafunciónenunprogramaconvariosvaloresdeprueba.
6.19. LafuncióncosenovienedefinidamedianteelsiguientedesarrolloenseriedeTaylor.
n
x2i
i=0
(2i)!
cos(x) =Σ
Escribirunafunciónquerecibacomoparámetroelvalordexasícomounacotadeerror, ycalculeelcosenodexcon
unerrormenorquelacotaqueselepase .
6.20. Lafunciónclotoide vienedefinidaporelsiguientedesarrolloenserie, dondeA yΘ sondatos.
n
Θ2i
i=0
(4i +1)(2i)!
2Θ Σ (–1)i
x =Aœw
n
Θ2i+1
i=0
(4i +3)(2i +1)!
2Θ Σ (–1)i
y =Aœw
Escribirunprogramaquecalculelosvalor esdelaclotoidepar aelvalorde A =1 yparalosvaloresde q siguientes
0, p/20, 2p/20, 3p/20, ..., p.Laparadadelasumadelaserie, serácuandoelvalorabsolutodelsiguientetérminoasumar
seamenoroigualque 1 e–10.
SOLUCIÓN DE LOS EJERCICIOS
6.1.
Usandolafunciónisdigit(c) yteniendoencuentaquedevuelveunvalordistintodecerosiesundígitocomprendidoentre0y9, y0enotrocaso, unacodificacióneslasiguiente:
bool esdigito( char c)
{
return isdigit(c);
}
6.2.
Usandoeloperador%sucodificaciónes:
bool divisible( int m, int n)
{
return m % n;
}
6.3.
Unacodificaciónes:
int Fahrenheit(int celsius)
{
return 9 * celsius / 5 + 32;
}
CAPÍTULO 6 Funciones y módulos
6.4.
127
Secompruebasiesuncar ácteralfabéticononum érico, encuyocasosecon viertelaletr aenmay úscula, peraposteriormentecomprobarlacondición.
bool Esvocal( char c)
{
if (isalnum(c) && !isdigit(c))
c = toupper(c);
return ( c == 'A'||c == 'E'||c == 'I'||c == 'O'||c == 'U');
}
SOLUCIÓN DE LOS PROBLEMAS
6.1.
Unprogramaprincipalleelosdosnúmerosasegurándosequesonpositivosmedianteunbucledo-while yllamaalafunción resto queseencargaráderesolverelproblema.Lafunción resto, enprimerlugar, determinaelmayoryelmenor
delosdosn úmerosalmacenándolosenlasvariables Mayor y menor.Medianteunacumuladorinicializadoalavariable
menorymedianteunbuclewhile sesumaalacumuladorelvalorde menor, hastaqueelvalordelacumuladorseamayor
queelnúmeroMayor.Necesariamenteelrestodebeserelvalordelavariable Mayor menoselvalordelavariableacumulador máselvalordelavariable menor.
La codificación de este problema se encuentra en la página Web del libro.
6.2.
Medianteunacumulador acu inicializadoalavariable num2 yuncontador c, inicializadoa 0, secuentaelnúmerodevecesqueesnecesariosumar num2 parasobrepasar(serestrictamentemayor)aln úmeronum1.Comocsehainicializadoa
0, cuandoenelacumulador acu yasehasumandounavez num2, elresultadofinalpedidoseráeldadoporelcontador c.
int cociente(int num1, int num2)
{
int c = 0, acu = num2;
while (acu <= num1)
{
acu += num2;
c++;
}
return c;
}
6.3.
Elprogramaprincipalleeelvalorde n, yllamasucesivamentea funciony.Elvalordela funciony seobtienemediante
unbucle for queiteracalculandoencadaiter aciónelsiguientevalordelafunci ón.Paraello, almacenaenlavariable x
elvalorde funciony(n – 3), eny elvalorde funciony(n – 2), yen z elvalorde funciony(n – 1).Paracalcularelvalordefunciony(n) bastaconrealizarlaasignaciónaux = x + 3 * y – z , yreasignarlosnuevosvaloresx, y, z para
lasiguienteiteración.
La codificación de este problema se encuentra en la página Web del libro.
6.4.
Seprogramalafunci ón perfecto, detalmaneraques ólosesumanlosposiblesdivisor esdeln úmero n querecibecomo
parámetrocomprendidoentre 1 y n – 1.Estafunci ónesdetipol ógicoy, portanto, devuelveelvalordelae xpresión
acu = = n.
CAPÍTULO 6 Funciones y módulos
128
Codificación
bool perfecto(int n)
{
int i, acu = 0;
for(i = 1; i < n; i++)
if (n % i = = 0)
acu += i;
return (acu = = n);
}
6.5.
Pararesolverelproblemabastaconusarlafuncióndivisores implementadaenelEjemplo6.4yescribirlafunciónamiquedetectalacondición.
gos
(n = = divisores(m)) && (m = = divisores(n).
Secodificalafuncióndivisores.
bool divisores(int n)
{
int i, acu = 0;
for(i = 1; i < n; i++)
if (n % i = = 0)
acu += i;
return acu;
}
bool amigos (int n, int m)
{
return ((n = = divisores(m)) && (m = = divisores(n)));
}
6.6.
Seusaelarchivodecabeceramath.h.Lafunciónrecibeelánguloengrados, lotransformaaradianesparapresentarlos
resultados.Elprogramaprincipalleeel ángulopositivoyllamaalafunci óntrigonométrica.
La codificación de este problema se encuentra en la página Web del libro.
Unresultadodeejecuciónes:
6.7.
Unnúmeroenteropositivo n esprimo, sisólotienepordivisor eslaunidadyelpr opionúmero.Unaposibleformader esolverelproblemaconsisteencomprobartodoslosposiblesdivisoresdesdedos hastaunomenosdeldado.Elmétodoque
seusa, aplicalasiguientepropiedad: “siunnúmeromayorquelaraízcuadradaden dividealpropion esporquehayotro
númeroenteromenorquelara ízcuadradaquetambi énlodivide”. Porejemplo: si n vale 64 suraízcuadradaes 8, elnúmero 32 dividea 64 queesmayorque 8 perotambiénlodivideeln úmero 2 queesmenorque 8, yaque 2*32 = 64.De
estaformaparadecidirsiunn úmeroesprimobastaconcompr obarsitienedivisorespositivosmenoresoigualesquesu
raízcuadrada, porsupuestoeliminandolaunidad.
CAPÍTULO 6 Funciones y módulos
129
bool primo(int n)
{
int i, tope;
bool p = true;
tope = (int)sqrt(n);
i = 2;
while (p && (i <= tope))
{
p =!( n % i = = 0);
i++;
}
return (p);
}
6.8.
Lasfórmulasquedanlascoordenadasx ey delproyectilson:
x = v * cos(alfa) * t
y = v * seno(alfa) – a * t2 /2
dondealfa esunánguloqueestáenelprimercuadrantev eslavelocidadinicialy a = 40m/s2 eslaaceleración.
Lafunciónrecibecomoparámetrosalángulo alfa engradossexagesimalesylavelocidadinicial v.Convierteelánguloaunánguloequivalenteenradianes, inicializalasvariables t ey, eiteraenunbuclewhile hastaqueseobtieneun
valornegativodelaordenaday.
La codificación de este problema se encuentra en la página Web del libro.
6.9.
Elprogramasecodificadelasiguienteforma:
Lafunciónmenu, seencargadedevolveruncarácterentrelasopciones 1 a4.
Elprogramaprincipalllamaalafunci ón menu, leelosdatos, yrealizalasdistintasllamadasalasfunciones.Seiter a
medianteunbuclefor queterminacuando menu retornalaopción4.
Lafunciónaa calculalaanualidaddecapitalizaci ón, teniendoencuentaquevienedadapor:
aa =
cr
(1+r)((1+r)t –1)
Lafuncióncc calculaelapartadosegundoteniendoencuentaquevienedadaporlaf órmula:
1
cc =a(1+r)
(1+r)t –1
r
2
Lafuncióntt calculaeltercerapartado, teniendoencuentaquevienedadaporlaf órmula:
tt =
cr
log 1+ ________
a(1+r)
1
2
log(1+r)
La codificación de este problema se encuentra en la página Web del libro.
6.10. Elprogramasecodificausandolafunción factorial, quecalculaelproductodelos x primerosnúmerosnaturalespositivosyprogramandolafunción combinatorio, consuscorrespondientesllamadasalafunci ón factorial.Elprograma
principalseencargadeleerlosdatos m yn ydellamaralafunci óncombinatorio.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 6 Funciones y módulos
130
6.11. Enelproblema6.10sehacodif icadolafunci ón combinatorio.Seprogramalafunci ón potencia iterativamentemultiplicandoelvalordesupar ámetro a porsímismotantasvecescomoindicaelpar ámetro n.Lafunci ón binomial realiza
lasllamadascorrespondientesalafuncióncombinatorio ypotencia.Elprogramaprincipal, realizalalecturade p, n e
i dentrodelosrangosindicados, yllamaalafunci ón bionomial.
La codificación de este problema se encuentra en la página Web del libro.
6.12. Lafunción polares, transformalascoordenadaspolares r, zeta encoordenadascartesianas x, y, mediantelasfórmulas
correspondientes.Elprogramaprincipalleelosvalor esdelángulo zeta yelmódulo r positivos, delascoordenadas polares, llamaalafunciónpolares, paraobtenerlascoordenadascartesianasypresentalosresultados.
La codificación de este problema se encuentra en la página Web del libro.
Unresultadodeejecuciónes:
6.13. Seprogramaunafunciónmenu queeligeentrelastresopcionescorrespondientes.
r mi
mr –m
e ylaProbabilidad(X ≤ r)= Σ
e–m que
SeprogramaunafunciónPoisson quecalculaProbabilidad(X =r)=
r!
i=0 i!
resuelvenelapartadoayelb .Estosvaloresloretornanensuspar ámetrosporreferencia, x_igual_r, x_menor_r.Enla
m0 –m m1 –m m2 –m
mr –m
e ,
e ,
e , ...,
e , yenlavariable acu sevan
variable valor sevancalculandolossucesivosvalor esde
0!
1!
2!
r!
acumulandolosvalores, porloquealfinaldelbuclefor, losresultadosestánalmacenadosenlasvariables valor yacu.
Pararesolverelapartadocbastaconobservarque:
Probabilidad(X≥ r)=1–Probabilidad(X=r)–Probabilidad(X≤ r)
Elprogramaprincipal, leelosvaloresde r, elvalordelamedia m yllamaa menu.
La codificación de este problema se encuentra en la página Web del libro.
6.14. ElalgoritmodeEuclidesparacalcularelmáximocomúndivisordedosnúmerosenterospositivosn yd eselsiguiente: calcularelrestor deladivisiónenterade n entred.Sielrestoes 0 pararyenotrocaso: asignara n elvalorde d;adelvalorde r eiterar.Lafunción mcd recibedosnúmerosenteros n y d con d <> 0, losconvierteenpositivoyaplicaelalgoritmodeEuclides.Elcálculodelmínimocomúnmúltiplomcm, secalculausandolasiguientepropiedad: elmáximocomún
divisor mcd multiplicadoporelm ínimocomúnmúltiplo mcm dedosnúmeros n y d coincideconelproductodelosdosn úmeros.mcd * mcm = n * d.
La codificación de este problema se encuentra en la página Web del libro.
6.15. Lasfraccionesser epresentanpordosn úmerosenterosnumerador n ydenominador d, siendo d > 0.Lafunci ón leerfracciones leedosfraccionesrealizandodosllamadasalafunciónleerf.Lafunciónleerf seencargadeleerunafracción, asegurándosedequeeldenominadorseadistintodecer oyque, además, elnumeradorydenominadorseanprimos
entresí, paraloquenecesitallamaralafunci ón simplificaf.Estafunci ón simplificaf, simplificaunafr acciónhaciendoqueelnumeradoryeldenominadordelafracciónseanprimosentresí, dejandosiempreelsignonegativo, encaso
dequelafracciónseanegativaenelnumerador.Parahacerlobastacondividirelnumeradoryeldenominadorporelmáximocomúndivisor mcd.Lafunci ón mcd sehacodificadoenelPr oblema6.14.Lafunci ón escribef, recibecomopar ámetroselnumeradorn yeldenominador d ylovisualiza.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 6 Funciones y módulos
131
6.16. Escribirunpr ogramaprincipalquemedianteun menu seencargadellamaralascorr espondientesopcionessolicitadas
ademásdelaopci óndeleerfr acciones.Seusanlasfuncionescodif icadasenlosProblemas6.14, 6.15, delasquesehan
incluidosusprototipos, noasísucodificaciónquepuedeconsultarseenlosdosproblemasanteriores.Lasfuncionespedidasusanlasf órmulasqueacontinuaci ónsee xponen, convenientementesimplificadas, parahacerquelafr acciónresultanteseairreducible.Lascuatrofunciones, llevancuatroparámetrosporvalorpar arecibirlasdosfr acciones, ydospor
referenciapararetornarelresultado.
n1 ∗ mcm( d1, d 2) n2 ∗ mcm( d1, d 2)
+
d1
d2
sumaf (n1, d1, n2, d 2) =
mcm( d1, d 2)
n1 ∗ mcm( d1, d 2) n2 ∗ mcm( d1, d 2)
−
d1
d2
retaf (n1, d1, n2, d 2) =
mcm( d1, d 2)
n1 ∗ n2
d1 ∗ d 2
n1 ∗ d 2
dividef (n1, d1, n2, d 2) =
n2 ∗ d1
multiplicaf (n1, d1, n2, d 2) =
La codificación de este problema se encuentra en la página Web del libro.
6.17. Si x estáenelintervalo(0,1)entonces log2(x) = –log2(1/x).Si x esmayorque 2 entoncesesobvioque log2(x) =
= 1 + log2(x/2).
Portantoparaprogramarlafunciónlog2() bastacontenerencuentalaspropiedadesanteriores.Elproblemaseresuelveescribiendolassiguientesfunciones:
• Alog2 quecalculaellogaritmoenbase2decualquier x.Estafunciónllamaalasfunciones: alog01, six estáenelintervalo(0,1); alog12, sixestáenelintervalo [1,2];obien alog1i six esmayorque 2.Si x esmenoroigualque 0 da
unmensajedeerror, yaquenoexisteellogaritmo.
• Alog12 seprogramateniendoencuentaeldesarrollodelaserieenelintervalo [1,2].Enlavariabletérminosevanobteniendoloscorrespondientestérminosdelaserie, yensumasevanacumulandoloscorrespondientestérminos.Paracontrolarelsignodelsiguientet érminoasumar, seusalaexpresión exp(log(2) * suma ) <= x, queesequivalenteala
dadaenlafórmuladelenunciado.
• Lafunciónsigno nosecodifica, yaquequedaimplícitaenelcalculodelafunci ónalog12.
• LafunciónAlog01, seprograma, deacuerdoconlapropiedaddelintervalo(0,1).Llamará, obienalafunciónalog12,
obienalafunci ónalog1i, dependiendodeque 1/x seamenor, oigualquedos, obienseaestrictamentemayor.
• Lafunción alog2i, seprogramadeacuerdoconlapr opiedaddelosn úmerosestrictamentemayoresquedos.Unb ucle
vadividiendopordos x, ysumando 1 alacumulador acu, hastaconseguirque x estéenelintervalo [1,2].
• Elprogramaprincipalleelacotadeerr or, yllamaalafunci ón alog2 paravariosvaloresdeprueba.Semuestr aelresultadoobtenidodelafunci ón alog2 yconlafunci óndelibr ería log() debiblioteca, paracomprobarlosr esultados.
La codificación de este problema se encuentra en la página Web del libro.
6.18. Lasfórmulaquecalculalosvaloresdesen(x)puedeobtener sedelasiguienteforma:
sen(x)= t1+ t3+t5+t7+t9+.........
donde t1=x
x∗x
y ti =–
ti–2
i(i –1)
Lafunciónseno seprogramateniendoencuentalasfórmulasanterioresy, además, laparadaserealiza, cuandosehansumado, comomáximo20t érminos( i==20), oelsiguientet érminoasumartieneunvalorabsolutomenorqueunacotade
errorqueselepasacomopar ámetro.Lavariable xx contienex*x paraahorrarencadaiteraciónunproducto.
CAPÍTULO 6 Funciones y módulos
132
Elprogramaprincipalleelosvalor esde valor1, valor2, incremento, ycotadeerr oryllamealafunci ónsenode
bibliotecaylacompareconelvalorcalculadomediantelafunci ónprogramada, paralosvalores:
valor1, valor1+incremento, valor1 + 2 * incremento ,...
hastaquesesobrepaseel valor2.
Comolafunciónsenodebibliotecatrabajaconradianes, sedefineunavariable propor quedebidamenteinicializada
3.1415/180 transformalosgradosenradianes.Si valor1 estáengrados, entonces valor1*propor estáenradianes.
La codificación de este problema se encuentra en la página Web del libro.
6.19. Lafórmulaquecalculalosvaloresde cos(x) puedeobtenersedelasiguienteforma:
cos(x)= t0+ t2+t4+t6+t8+...
dondet0 =1
y
x∗x
ti =–
ti–2
i(i –1)
Lafunción coseno seprogramadeunaformasemejantealafunci ónseno, sólosediferenciaenlainicializaci óndel
términoterm ydelacumulador suma.
float coseno( float x, float error)
{
float term = 1.0, suma = 1.0, xx =x*x;
int i = 0;
while (fabs( term ) > error && i < 20)
{
i += 2;
term = –term * xx/(i * (i – 1));
suma = suma + term;
}
return(suma);
}
6.20. Lasfórmulasquecalculanlosdistintosvaloresde x yde y, puedenobtenersedelasiguienteforma:
x = t0–t2+t4–t6+t8–........
y = t1–t3+t5–t7+t9–........
2Θ
siendot0 =Aœw
y ti =
2i –1
i(2i +1)
Θti–1
Seprogramalafunciónterm, quecalcula ti enfunciónde ti–1, i, q.
Lafunciónclotoide recibecomodatoselvalorde a yeldeq ydevuelvecomoresultadolosvaloresdex ey.Encada
iteracióndelbucleserecalculandostérminosquesonacumuladosr espectivamentealosacumulador es x e y, porloque
encadaiteraciónhayquecambiardesignoelt érmino.Esdecir, enprimerlugarsesumandospositivos, enlasiguiente
iteración, dosnegativos, enlasiguientedospositivosyasísucesivamente.Antesdecomenzarunaiteracióndelbuclesetieneyacalculadounvalordelsiguientet érminoparasumar, queesacumuladoenlavariable x.Posteriormente, serecalculaelsiguientetérminoimparyseacumulaalavariable y, paraterminarcalculandodenue voelsiguientetérminopar.
Elbucleterminacuandoelvalorabsolutodelsiguientet érminoasumarseamenorque épsilon.
Elprogramaprincipal, calculaelvalorde p mediantelafunci ón arcocoseno, (p = acos(–1.0)) paraposteriormente, medianteunbucle, realizarlasdistintasllamadasalafunci ónclotoide.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 6 Funciones y módulos
133
EJERCICIOS PROPUESTOS
6.1.
6.2.
EscribirunafunciónRedondeoqueacepteunvalorreal
CantidadyunvalorenteroDecimalesydevuelvaelvalorCantidadredondeadoalnúmeroespecificadodeDecimales.Porejemplo, Redondeo(20.563,2)de vuelve
losvalores20.0, 20.5y20.54respectivamente.
Escribirunprogramaquepermitaalusuarioele girel
cálculodel áreadecualquieradelasf igurasgeométri-
cas: círculo, cuadrado, rectángulootriángulo, mediante
funciones.
6.3.
Determinaryvisualizareln úmerom ásgrandededos
númerosdados, medianteunsubprograma.
6.4.
Codifiqueunafunci ónqueescribanl íneasenblanco.
PROBLEMAS PROPUESTOS
6.1.
Escribirunafunciónquecalculelamediadeunconjuntode n>0 númerosleídosdelteclado.
6.2.
Escribirunafunciónquedecidasiunn úmeroenteroes
capicúa.Elnúmero24842escapicúa.Elnúmero134no
loes.
6.3.
Escribirunprogramaqueencuentreelv alormayor, el
valormenorylasumadelosdatosdeentrada.Obtener
lamediadelosdatosmedianteunafunci ón.
6.4.
Escribirunafunciónquepermitacalcularlaserie:
n(n +10)(2n +1)
12 +22 +32 +...+n2 ==
6
=n∗ (n+10)∗ (2∗ n +1)/6
6.5.
Escribirunafunciónquesumelos30primerosnúmeros
impares.
6.6.
Escribirunafunci ónquecalculelasumadelos20primerosnúmerosprimos.
6.7.
Escribirunafunci ónqueencuentreyescribatodoslos
númerosperfectosmenoresqueunvalorconstantemax.
6.8.
Escribirunprogramaqueleadosnúmerosx yn ycalculelasumadelaprogresióngeométrica.1+x +x2+x3+
+...+xn
6.9.
Escribirunprogramaquemediantefuncionesdetermineel áreadelc írculocorrespondientealacircunferenciacircunscritadeuntri ángulodelqueconocemoslas
coordenadasdelosvértices.
6.10. Escribirunprogramaqueleadosenterospositivosn yb
ymedianteunafunci ón CambiarBase visualicelacorrespondienterepresentacióndelnúmeron enlabase b.
6.11. Escribirunprogramaquesolicitedelusuariouncar ácteryquesitúeesecarácterenelcentrodelapantalla.El
usuariodebepoderacontinuaci óndesplazarelcarácter
pulsandolasletras A (arriba), B (abajo), I (izquierda),
D (derecha)yF (fin)paraterminar.
6.12. Escribirunafunciónquedeterminesiunacadenadecaracteresesunpal índromo(unpal índromoesunte xto
queseleeigualensentidodirectoyenin verso: radar).
6.13. Escribirelinversodeunnúmeroenterodado(1234, inverso4321).
6.14. Escribirunprogramamedianteunafunci ónqueacepte
unnúmerodedía, mesyañoylovisualiceenelformato: dd//mm/aa.Porejemplo, losvalores8, 10y1946se
visualizancomo: 8/10/46.
6.15. Escribirunprograma, mediantefunciones, quevisualiceuncalendariodelaforma:
L
M
M
6
13
20
27
7
14
21
28
8
15
22
29
J
1
9
16
23
30
V
3
10
17
24
S
4
11
18
25
D
5
12
19
23
Elusuarioindica únicamenteelmesyela ño.Laf órmulaquepermiteconocereld íadelasemanacorrespondienteaunafechadadaes:
CAPÍTULO 6 Funciones y módulos
134
a) Mesesdeeneroofebrero n = a +31 ∗ (m –1)+
+ d(a –1)div4–3∗((a +99)div100)div4;
b) Restantesmeses n = a +31 ∗ (m –1)+ d –(4 ∗
m +23)div10+a div4–(3∗ (a div100+1))div4;
dondea =año, m =mes, d =día.
Nota: n mod7indicaeld íadelasemana(1=lunes,
2=martes, etc.).
6.16. Escribirunafuncióncondosparámetros, x yn, quedevuelvalosiguiente:
x +
xn
xn+2
–si
n n +2
xn+1
xn–1
–si
n +1 n –1
x >=0
x <0
CAPÍTULO 7
Arrays (ar reglos, listas
o tablas)
Introducción
Enestecapítuloaprendeelconceptoytratamientodelosarrays.Un array (arreglo)almacenamuchoselementosdelmismo
tipo, talescomoveinteenteros, cincuentanúmerosdecomaflotanteoquincecaracteres.Elarrayesmuyimportantepordiversasrazones.Unadeellasesalmacenarsecuenciasocadenas detexto.HastaelmomentoC++proporcionadatosdeunsólo
carácter;utilizandoeltipoarray, sepuedecrearunavariablequecontengaungrupodecaracteres
7.1. Arrays (arreglos)
Unarray (arreglo, listaotabla)esunasecuenciadeobjetosdelmismotipo, quesenumeranconsecutivamente0, 1, 2, 3.Estosnúmerossedenominan valoresíndice osubíndice delarray.Cadaítemdelarraysedenomina elemento. EltipodeelementosdelarraypuedesercualquiertipodedatodeC++, incluyendoestructurasdefinidasporelusuario.Sielnombredel
arrayes a, entoncesa[0] eselnombredelelementoqueestáenlaposición 0, a[1] eselnombredelelementoqueestáenla
posición1, etc.Engeneral, elelementoi-ésimo estáenlaposición i-1.Demodoquesielarraytiene n elementos, susnombresson a[0], a[1],...,a[n-1].
Unarraysedeclarademodosimilaraotrostiposdedatos, exceptoquesedebeindicaralcompiladorel tamaño olongitud delarray.Paraindicarel tamaño olongituddelarraysedebehacerse guiralnombre, eltamañoencerradoentrecorchetes.Lasintaxis paradeclararunarraydeunadimensióndeterminadaes:
tipo nombreArray[numeroDeElementos];
Elíndicedeunarraysedenomina, confrecuencia, subíndicedelarr ay.Elmétododenumeracióndelelemento i-ésimo
conelíndiceosubíndice i-1 sedenominaindexaciónbasadaencero.Todoslossubíndicesdelosarrayscomienzancon0.
Suusotieneelefectodequeelíndicedeunelementodelarrayessiempreelmismoqueelnúmerode“pasos” desdeelelementoiniciala[0] aeseelemento.Porejemplo, a[4] estáa4 pasosoposicionesdelelementoa[0].Enlosprogramassepuedenreferenciarelementosdelarrayutilizandofórmulasoe xpresionesenterasparalossubíndices.
Loselementosdelosarrayssealmacenanenbloquescontiguosdememoria.Losarraysquetienenunsolosubíndicese
conocencomoarraysunidimensionales (unasoladimensión).Cadabloquedememoriatieneeltamañodeltipodedato.Hay
quetenerencuentaqueC++nocompruebaquelosíndicesdelarrayestándentrodelrangodefinido, porloquedebesercontroladoporelusuario.Sedebetenercuidadodenoasignarv aloresfueradelrangodelossubíndices, debidoaquesesobreescribiríandatosocódigo.
135
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
136
EJEMPLO 7.1. Posicionesválidasdeunarray.Enladeclaracióndelarrayint a[7] losíndicesválidosson a[0],
a[1],..,a[6].Perosisepone a[10] nosedamensajedeerroryelresultadopuedeserimpredecible.
EJEMPLO 7.2. Posicionesocupadasporloselementosdeunarr ay.Si a esunarraydenúmerosrealesycadanúmerorealocupa 4 bytes, entoncessielelemento a[0] ocupaladir eccióndelelemento a[i], ocupaladir ecciónde
memoriad + ( i – 1 ) * 4.
Eloperador sizeof devuelveelnúmerodebytesnecesariosparacontenersuar gumento.Alusar sizeof parasolicitareltamañodeunarray, seobtieneelnúmerodebytesreservadosparaelarraycompleto.Conociendoeltipodedato
almacenadoenelarrayysutamaño, sepuedecalcularlalongituddelarray , medianteelcociente sizeof(a)/tamaño(dato).
EJEMPLO 7.3. Protecciónfrenteaerroresenelintervalo(r ango)devaloresdeunavariabledeíndicequer epresentaunarray.Si n estáfueraderangoseretornaerror, enotrocasosecalculalamediadelosnúmer osalmacenadosenelarray.
float media (double m[], int n)
{
if (n * sizeof(float) > sizeof(m))
return - 32767;
float Suma = 0;
// error
for(int i = 0; i < n; i++)
Suma += m[i];
return Suma / n;
}
EJEMPLO 7.4. Almacenamientoenmemoriadeunarr ayde 5 elementos.Sedeclaraelarray a de5 elementosyse
almacenanenlasposicionesdememorialos5 primerosnúmerosparespositivos.
int a[4];
for(int i = 0; i < 5; i++)
a[i] = 2 * i + 2;
Posición índice
0
1
2
3
4
Valor almacenado
2
4
6
8
10
7.2. Inicialización de arrays
Antesdequeunarrayseausadosedebenasignarv aloresasuselementos, talcomoseasignanvaloresavariables.Paraasignarvaloresacadaelementodelarrayde 4 enterosa, sepuedeescribir:
a[0] = 0; a[1] = 10; a[2] = 20; a[3] = 30
Laprimerasentenciaponeen a[0] elvalor 0, en a[1] elvalor 10, etc.Sinembargo, estemétodonoesprácticocuando
elarraycontienemuchoselementos.Enestecasopuedenusarsesentenciasdeasignaciónenb ucles.
EJEMPLO 7.5. Elsiguientefragmentodeprogramadeclaraunarrayde 10 enterosloinicializa, ylopresenta.
#define max 50
int a[max];
for(int i = 0; i < max; i++)
a[i] = 10 * i;
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
137
for(int i = 0; i < max; i++)
cout << a[i] << endl;
Unmétodoutilizado, parainicializarunarraycompletoeshacerloenunasentenciadeinicialización, enlaqueseincluyenlasconstantesdeinicialización.Estasconstantesseseparanporcomasyseencierranentrella ves.
int vector[] = {15, 25, -45, 0, 50, 12, 60};
Elcompiladorasignaautomáticamente7elementosa vector.
EJEMPLO 7.6. Declaracioneseinicializaciónsimultáneadearr ays.
int num[5]={10,20,30,40,50};
//declara e inicializa un array de 5 enteros
float x[ ] = {1.0,22.0,3.5}
//declara e inicializa un array de 3 reales
// Se pueden asignar constantes simbólicas como valores numéricos
const int ENE = 31, FEB = 28, MAR = 31, ABR = 30, MAY = 31, JUN = 30,
JUL = 31, AGO = 31, SEP = 30, OCT = 31,NOV = 30, DIC = 31;
int meses[12] = {ENE, FEB, MAR, ABR, MAY, JUN, JUL, AGO, SEP, OCT,
NOV, DIC};
Arrays de caracteres y cadenas de texto
Unacadena de texto esunconjuntodecaracteres, talescomo "abcdef".Lascadenas contienencarácternulo (´\0´), cuyo
valorenelcódigoASCIIes0 alfinaldelarraydecaracteres.Elmediomásfácildeinicializarunarraydecaractereseshacer
lainicializacióndeladeclaración.
EJEMPLO 7.7. Inicializacióndearraysdecaracteresycadenasenladeclar ación.
char ch[] = {'L','u','i','s',' ', 'y',' ','L','u','c','a','s'};
//Declara un array de 12 caracteres
char ch[] = {"Ejemplo"}
char cadena[] = "abcdef";
//Los arrays pueden inicializarse con una constante cadena. El array
//anterior tiene 7 elementos, ya que se almacena el carácter nulo \0.
Lascadenassedebenalmacenarenarraysdecaracteres, peronotodoslosarraysdecaracterescontienencadenas.Sólo
soncadenasaquellasqueterminanenelcarácternulo.
EJEMPLO 7.8. Asignacióndecadenasdecar acteres.Lascadenasdecar acterespuedenasignar seenlainicializacióndeunarr ayomediantelafuncióndelabibliotecaestándar strcpy() ("copiarcadenas")permitecopiar
una constantedecadenaenunacadena.Sinembar go, nopuedeasignar seunvaloraunacadenaconlaasignación=.
char Cadena[6];
strcpy(Cadena,"abcde");
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
138
Esequivalentealasiguientedeclaración.
char Cadena[6] = "abcde";
char Cadena[7] = "abcde";
Cadena
0
1
2
3
4
6
a
b
c
d
e
\0
Lassentenciasanteriorescolocanlacadenaenmemoriatalycomoindicalatablaanterior .Pero, nosepuedeasignaruna
cadenaaunarraydelsiguientemodo:
char Cadena[6];
Cadena = "abcde";
//asignación incorrecta
7.3. Arrays multidimensionales
Losarraysmásusualessonlosdedosdimensiones, conocidostambiénporelnombrede tablas omatrices.Sinembargo, es
posiblecreararraysdetantasdimensionescomorequieransusaplicaciones, éstoes, tres, cuatroomásdimensiones.Lasintaxisparaladeclaracióndeunarraydedosdimensioneses:
<TipoElemento><nombrearray>[<NúmeroDeFilas<][<NúmeroDeColumnas>]
Unarraydedosdimensionesenrealidadesun arraydearrays.Esdecir, esunarrayunidimensional, ycadaelementono
esunvalorenterodecomaflotanteocarácter , sinoquecadaelementoesotroarray.
Lasintaxisparaladeclaracióndeunarraydetresdimensioneses:
<tipodedatoElemento><nombrearray> [<Cota1>] [<Cota2>][<Cota3>]
EJEMPLO 7.9. Declaraciónyalmacenamientodeunarr aybidimensionalenmemoria.Ladeclar acióndeunarray
deenterosquetiene 4 filasy 6 columnas, surepresentaciónyalmacenamientoporfilaseselsiguiente:
int a[4][6];
//la declaración se almacena en memoria por filas
Tabla 7.1. Almacenamiento de Array bidimensional de 4 filas y 6 columnas
A[5][6]
C
o
f
i
l
a
a[0][0]
.
.
a[3][0]
a[0][1]
.
.
a[3][1]
l
u
m
. . . . . . .
. . . . . . .
n
a
a[0][5]
.
.
a[3][5]
a[0][6]
.
.
a[3][6]
a[0][0], a[0][1], a[0][2],..., a[0][5], a[0][6], a[1][0], a[1][1],
a[1][2],..., a[1][5] a[1][6],................., a[3][0], a[3][1],
a[3][2],...., a[3][5], a[3][6].
Losarraysmultidimensionalessepuedeninicializar, aligualquelosdeunadimensión, cuandosedeclaran.Lainicializaciónconstadeunalistadeconstantesseparadasporcomasyencerradasentrella ves
EJEMPLO 7.10. Inicializacióndearraysbidimensionalesenladeclaración.
int ejemplo[2][3] = {1,2,3,4,5,6};
int ejemplo [2][3] = { {1,2,3}, {4,5,6}}
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
139
Losarraysmultidimensionales(sinosonglobales)noseinicializanav aloresespecíficosamenosqueseasignenv aloresenelmomentodeladeclaraciónoenelprograma.Siseinicializanunoomáselementos,
peronotodos, C++
rellenaelrestoconcerosov aloresnulos( '\0').Sisedeseainicializaracerounarraymultidimensional, utiliceuna
sentenciatalcomoésta:
float a[3][4] = {0.0};
Elformatogeneralparaasignacióndirectadev aloresaloselementosdeunarraybidimensionaleslasiguiente:
<nombre array>[indice fila][indice columna] = valor elemento;
Paralaextraccióndeelementos:
<variable> = <nombre array> [indice fila][indice columna];
Lasfuncionesdeentradaosalidaseaplicandeigualformaaloselementosdeunarrayunidimensional.Sepuedeacceder
aloselementosdearraysbidimensionalesmedianteb uclesanidados.Susintaxisgenerales:
int IndiceFila, IndiceCol;
for (IndiceFila = 0; IndiceFila < NumFilas; ++IndiceFila)
for (IndiceCol = 0; IndiceCol < NumCol; ++IndiceCol)
Procesar-elemento[IndiceFila][IndiceCol];
EJEMPLO 7.11. Lecturayvisualizacióndeunarrayde3 filasy5 columnas.Sedeclaranlasconstantesmaxf y maxc
a5 y, posteriormente, sedeclaraelarraybidimensional a yseleeyvisualizaporf ilas.
#include <cstdlib>
#include <iostream>
#define maxf 3
#define maxc 5
using namespace std;
int main(int argc, char *argv[])
{
float a[maxf] [maxc];
int f, c;
// leer el array
for(f = 0; f < maxf; f++)
for(c = 0; c < maxc; c++)
cin >> a[f][c];
// escribir el array
for(f = 0; f < maxf; f++)
{
for(c = 0; c < maxc; c++)
cout << a[f] [c] ;
cout << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 7.12. Leerunamatrizcuadradadeorden5(5filasy5columnas), yescribirlasumadetodoslosnúmerosquenoestánenladiagonalprincipal.Elproblemaseresuelveenunsoloprogramaprincipal.Dosbuclesfor anidadosleenlamatriz, otrosdosbuclesfor anidadosseencarganderealizarlasumadeloselementosquenoestánen
ladiagonalprincipal, quesonaquellosquecumplenlacondición i esdistintode j, siendoi yj losíndicesdelafila
ycolumnarespectivamente.
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
140
#include <cstdlib>
#include <iostream>
#define filas 5
using namespace std;
int main(int argc, char *argv[])
{
int i,j, suma, A[filas][filas];
// lectura por filas
for(i = 0; i < filas; i++)
for(j = 0; j < filas; j++)
cin >> A[i][j];
for(i = 0; i < filas; i++)
for (j = 0; j < filas; j++)
if(!(i == j))
suma += A[i][j];
cout << " suma " << suma;
system("PAUSE");
return EXIT_SUCCESS;
//realización de la suma
}
EJEMPLO 7.13. Arraytridimensional.Sedeclaraunarraytridimensionalparaalmacenarlastemperaturasdecada
unodelos60 minutos delas24 horas deunmes de31 días.Sedeclarancomoconstantes dias, horas yminutos.
Entresbuclesanidadosseleenlatemper aturadecadaunodelos 60 minutos, delas 24 horas, delos 31 díasdeun
mes.Posteriormente, secalculayseescribelamediadetemper aturadecadadía.
#include <cstdlib>
#include <iostream>
#define dias 31
#define horas 24
#define minutos 60
using namespace std;
int main(int argc, char *argv[])
{
int i, j, k;
float A[dias][horas][minutos], media;
//lectura de las temperaturas.
for(i = 0; i < dias; i++)
for (j = 0; j < horas;j++)
for (k = 0; k < minutos; k++)
cin >> A[i][j][k];
for(i = 0; i < dias; i++)
{
//cálculo de la media de cada uno de los días.
media = 0;
for ( j = 0 ; j < horas; j++)
for ( k = 0; k < minutos; k++)
media += A[i][j][k];
cout<<" dia " << i+1 << " " << media /(horas * minutos) << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
141
7.4. Utilización de arrays como parámetros
EnC++todoslosarrayssepasanporreferencia (dirección).C++trataautomáticamentelallamadaalafuncióncomosihubierasituadoeloperadordedirección & delantedelnombredelarray.
Ladeclaraciónenlafuncióndequeunparámetroesunarrayserealiza:
<tipo de datoElemento> <nombre array> [<Cota1>].
<tipo de datoElemento> <nombre array> []. Obien
<tipo de datoElemento> *<nombre array>
Omejor
Enestesegundocasoesconvenientedeclararotroparámetroqueindiqueeltamañodelarr ay.
EJEMPLO 7.14. Declaracióndefuncionesconparámetrosarray, yllamadas.
float suma(float a[5]);
float calcula(float a[], int n);
float media (float * a, int n);
//n es número de datos no obligatorio
//n es no obligatorio, pero conveniente
Dadasladeclaracionesdearrayssiguientes:
int b[5], a[6];
Sonposiblesllamadasválidas:
cout
cout
cout
<<
<<
<<
suma(a);
calcula (b, 5);
media (b, 5);
EJEMPLO 7.15. Lecturaescrituradeunvectorconfunciones.Elnúmerodeelementosdelvectoresindicadoacada
funciónenelparámetron, yelvectorsedeclaraenelparámetroconcorchetesvacíos.Elprogramadeclaraunaconstantemax paradimensionarlosvectores.Secodificanlasfuncioneslee, escribe, queleenyescribenrespectivamenteunvectorde n datosquerecibencomoparámetros, asícomolafunción suma querecibecomoparámetrosdosvectoresde n datos, ycalculaelvectorsumaalmacenadoelr esultadoen c.Elprogramaprincipalllamaalasfunciones
anteriores.
#include <cstdlib>
#include <iostream>
#include <math.h>
#define max 11
using namespace std;
void lee( float a[], int n);
void escribe (float a[], int n);
void suma(float a[], float b[], float c[], int n);
int main(int argc, char *argv[])
{
int n;
float a[max], b[max],c[max];
n = 3;
lee(a, n);
lee(b, n);
cout << " vector a\n";
escribe(a, n);
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
142
cout << " vector b\n";
escribe(b, n);
suma (a, b, c, n);
cout << " vector suma \n";
escribe(c, n);
system("PAUSE");
return EXIT_SUCCESS;
}
void suma( float a[], float b[], float c[], int n)
{
int i;
for (i = 0; i < n; i++)
c[i] = a[i] + b[i];
}
void escribe(float a[], int n)
{
int i;
for (i = 0; i < n; i++)
cout << a[i] << "
" ;
cout << endl;
}
void leer(float a[], int n)
{
int i;
for (i = 0; i < n; i++)
{
cout << " dame dato posicion i =" << i + 1 << "
cin >> a[i];
}
";
}
EJEMPLO 7.16. Lasfunciones cero y resta, recibencomoparámetrosvectores, peroelnúmerodeelementosdel
vectoratratarvienedadoporlaconstanteglobal max queesusadaparaelcontroldelosbuclesinternos.Enlosparámetrosdelasfuncioneselvectorsedeclar aconelnúmerodeelementosquetienemediantelaconstante max entre
corchetes.Lafunción cero rellenadeceroselvector.Lafunción resta calculaladiferenciadelosvectoresquerecibecomoparámetro.
#include <cstdlib>
#include <iostream>
#include <math.h>
#define max 10
//librería de funciones matemáticas
void resta( float a[max], float b[max], float c[max]);
void cero(float c[max]);
int main(int argc, char *argv[])
{
float a[max], b[max], c[max];
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
143
cero (a);
.....
.....
resta (a, b, c);
system("PAUSE");
return EXIT_SUCCESS;
}
void cero (float c[max])
{
int i;
for (i = 0; i < max; i++)
c[i] = 0;
}
void resta( float a[max], float b[max], float c[max])
{
// el vector c es la diferencia de a y b; c = a – b.
int i;
for(i = 0; i < max; i++)
c[i] = a[i]- b[i];
}
EJEMPLO 7.17. Funciónqueleeloselementosdeunvector.Elnúmerodeelementosleídossede vuelveporlafunciónenelparámetroporreferencia n.Laconstanteglobal max, esusadaporlafunciónpar aasegurarquelosdatos
leídosestándentrodelrangopermitido.Elb ucledelecturadedatosesinterrumpidocuandoseleeelvalordecer o
medianteelusodeunasentencia if yunasentencia break.
#define max 10
void leerArray(int a[], int& n)
{
cout << "Introduzca datos. Para terminar pulsar 0:\n";
for(n = 0; n < max; n++)
{
cout " dato " << n << ":";
cin >> a[n];
if (a[n] == 0)
break;
}
}
EJEMPLO 7.18. Funciónquecalculalamediacuadráticayarmónicadeunvectorquerecibecomoparámetroden
elementos.Lamediacuadrática mc ymediaarmónica ma deunvectordeunvectorde n elementosvienendadaspor
n –1
lasexpresiones: mc =
∑ a( i )
2
i=0
n
ma =
n
n –1
i=0
float mc ( float a[], int n)
{
float aux = 0;
1
∑ a( i )
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
144
for(int i = 0; i < n; i++)
aux += a[i] * a[i];
return sqrt(aux / n);
}
float ma(float a[], int n)
{
float aux = 0;
for( int i = 0; i < n; i++)
aux += 1 / a[i];
return n / aux;
}
Paso de matrices como parámetros
Paraarraysbidimensionalesesobligatorioindicarelnúmerodecolumnasenladeclaracióndelnumerodeparámetrosdela
siguienteforma:
<tipo de datoElemento> <nombre array> [<Cota1>][cota2].
<tipo de datoElemento> <nombre array> [][cota2]
Obien,
Enestese gundocasoestambiéncon venientedeclararotroparámetroqueindiqueelnúmerodef ilas.Lallamadaauna
funciónquetengacomoparámetrounarrayserealizaconelnombredelarray .
EJEMPLO 7.19. Declaracióndefuncionesconparámetrosarraybidimensionales, yllamadas.
void matriz (float M[3][5]);
void matriz1(float M[][5], int nf);//nf no obligatorio, pero conveniente
Dadaladeclaraciónsiguiente:
float M1 [3][5];
Sonposiblesllamadasválidas:
matriz (M1);
matriz1(M1, 3);
EJEMPLO 7.20. Funcionesquer ecibencomoparámetr odosmatricescuadr adaslassumanylasmultiplican.La
sumayproductodematricesvienendefinidasporlasexpresiones:
Suma
c(i, j)=a(i, j)–b(i, j)
Producto
c(i, j)= Σ a(i, k)*b(k, j)
n–1
k=0
Pararealizarlasumabastaconrecorrerconlosíndiceslasposicionesdelamatriz c ysumarlascorrespondientes
posicionesdela a yla b.
Pararealizarelproducto, hayqueacumularen acumulador elvalordelasuma, yelresultadoalmacenarloenla
posiciónc[i][j].
#define max 11
void Suma(float a[][max] , float b[][max] , float c[][max], int n)
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
c[i][j] = a[i][j] + b[i][j];
}
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
145
void Producto(float a[][max] , float b[][max] , float c[][max], int n)
{
float acumulador;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
acumulador = 0;
for (int k = 0; k < n; k++)
acumulador += a[i][k] * b[k][j];
c[i][j] = acumulador;
}
}
EJEMPLO 7.21. Funcionesquerecibencomoparámetrounamatrizcuadradaconlosdosíndicesconstantes.
i =j
51→
0→ i ≠ j
Identidad
c(i, j)=
Asigna
a(i, j)=b(i, j)
Sí
Sí
#define max 20
void Identidad(float c[max][max])
{
for (int i = 0; i < max; i++)
for (int j = 0; j < max; j++)
if (i == j)
c[i][j] = 1;
else
c[i][j] = 0;
}
void asigna( float a[max][max], float b[max][max])
{
for (int i = 0; i < max; i++)
for (int j = 0; j < max; j++)
a[i][j]= b [i][j];
}
Cuandoseutilizaunav ariablearraycomoar gumento, lafunciónreceptorapuedenoconocercuántoselementose xisten
enelarray.Aunquelavariablearrayapuntaalcomienzodeél, noproporcionaningunaindicacióndedondeterminaelarray
Sepuedenutilizardosmétodosalternativosparapermitirqueunafunciónconozcaelnúmerodeargumentosasociados
conunarrayquesepasacomoar gumentodeunafunción:
• situarunv alordeseñalalf inaldelarray, queindiquealafunciónquesehadedetenerelprocesoenesemomento;
• pasarunsegundoargumentoqueindicaelnúmerodeelementosdelarray .
Paso de cadenas como parámetros
Latécnicadepasararrayscomoparámetrosseutilizaparapasarcadenasdecaracteresafunciones.Lascadenasterminadas
ennulo ('\0') utilizanelprimermétododadoanteriormenteparacontrolareltamañodeunarray .
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
146
EJEMPLO 7.22. Funciónquer ecibecomoparámetrounnúmeroenterocomocadenadecar acteresycon viertela
cadenadecaracteresenunnúmeroentero.Lavariable cadena sirveparaleerelnúmerointroducidoportecladoen
unavariabletipocadenadecar acteresdelongitudmáxima 80.Lafunción valor_numerico, conviertelacadenade
caracteresenunnúmeroenteroconsusigno.Estafunciónsesaltatodoslosblancosytabuladoresqueseintroduzcan
antesdelnúmeroenteroqueesundatoleídopreviamente.Paraconvertirlacadenaennúmeroseusaladescomposición: '2345'= 2*1000+3*100+4*10+5.Estasoperacionesserealizanporelmétodode Horner deevaluacióndepolinomios: 2345 = ( ( (0*10+ 2)*10+3)*10+4)*10+5.Laobtención, porejemplodelnúmero3 sehaceapartirdel
carácter'3' : 3 = '3'-'0'.
#include <cstdlib>
#include <iostream>
using namespace std;
int valor_numerico(char cadena[]);
int main(int argc, char *argv[])
{
char cadena[80];
cout << "dame numero: ";
cin >> cadena;
cout << " numero como cadena " << cadena << endl;
cout<<" valor leido como numero \n "<<valor_numerico(cadena)<<
system("PAUSE");
return EXIT_SUCCESS;
endl;
}
int valor_numerico(char cadena[])
{
int i, valor, signo;
for (i = 0; cadena[i] ==' ' ||
// salto de blancos y tabularores
cadena[i] == '\t'; i++);
//determinación del signo
signo = 1;
if(cadena[i] == '+' || cadena[i] == '-')
signo = cadena[i++] == '+' ? 1:-1;
// conversión a número
for ( valor = 0 ; cadena[i] >= '0' && cadena[i] <= '9' ; i++)
valor = 10 * valor + cadena[i] - '0';
return (signo * valor);
}
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
EJERCICIOS
7.1.
¿Cuáleslasalidadelsiguientepr ograma?
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i, Primero[21];
for i = 1; i <= 6; i++)
cin >> Primero[i];
for(i = 3; i > 0; i--)
cout << Primero[2 * i];
system("PAUSE");
return EXIT_SUCCESS;
}
7.2.
¿Cuáleslasalidadelsiguientepr ograma?
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i,j,k, Primero[10];
for(i = 0; i < 10; i++)
Primero[i] = i + 3;
cin >> j >> k;
for(i = j; i <= k; i++)
cout << Primero[i] << " ";
system("PAUSE");
return EXIT_SUCCESS;
}
7.3.
¿Cuáleslasalidadelsiguientepr ograma?
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i, j ,k, Primero[11], Segundo[11];
for(i = 0; i < 11; i++)
Primero[i] = 2 * i + 2;
for(j = 0; j < 6; j++)
Segundo[j] = Primero[2 * j] + j;
147
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
148
for(k = 3; k < 6; k++)
cout << Primero[k + 1]<< "
system("PAUSE");
return EXIT_SUCCESS;
"
<< Segundo [k – 1] << endl;
}
7.4.
Escribirunafunciónquer elleneunarrayconlos10primer osnúmerosimpares, yvisualiceloscontenidosdelvectorcuyosíndicesson: 0, 2, 4, 6, 8.
PROBLEMAS
7.1.
Escribirunprogramaquelea10númerosenteros, losalmaceneenunvector, ycalculelasumadetodosellos, asícomosu
mediaaritmética.
7.2.
Unvectorsedicequeessimétricosielelementoqueocupalaposicióni_ésimacoincideconelqueocupalaposición
n-i_ésima, siemprequeelnúmerodeelementosquealmaceneelvectorsea n.Porejemploelvectorquealmacenalosvalores2, 4, 5, 4, 2essimétrico.Escribirunafunciónquedecidasielvectordendatosquer
ecibecomoparámetr oes
simétrico.
7.3.
Unvectorquealmacena n datossedicequeesmayoritario, siexisteunelementoalmacenadoenelvectorqueseapar ece
enelvectormásde n / 2 veces.Escribirunafunciónquedecidasiunvectoresmayoritario.
7.4.
Diseñarfuncionesquecalculenelproductoescalardedosvectores, lanormadeunvectoryelcosenodelánguloqueformandefinidosdelasiguienteforma:
pe( a, b, n) =
n −1
∑ a( i ) ∗ b ( i )
norma( a, n) =
i=0
n −1
∑ a( i ) ∗ a( i )
i=0
n −1
cos( a, b, n) =
∑ a( i ) ∗ b( i )
i=0
n −1
n −1
i=0
i=0
∑ a ( i ) ∗ a( i ) ∗ ∑ a( i ) ∗ b( i )
7.5.
Escribirunalgoritmoquecalculeyescribaunatablaconlos100primer osnúmerosprimos.Unnúmeroesprimosisólo
tienepordivisoreslaunidadyelpropionúmero.
7.6.
Escribirunprogramaquegenerealeatoriamentelosdatosdeunvector , lovisualice, ycalculesumediam, sudesviación
mediadmsudesviacióntípicadt, dadasporlassiguientesexpresiones:
n −1
n −1
m = ∑ a(i) / n
i =0
7.7.
dm =
∑ abs(a(i) − m)
i =0
n
n −1
dt =
∑ (a(i) − m)
2
i =0
n
Escribirunafunciónquer ecibacomoparámetrounamatrizcuadradadeordenn, ycalculelatraspuestadelamatrizalmacenandoelresultadoenlapropiamatriz.
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
149
7.8.
Sedicequeunamatriztieneunpuntodesillasialgunaposicióndelamatrizeselmenorvalordesuf ila, yalavezelmayordesucolumna.Escribirunafunciónquetengacomoparámetr ounamatrizdenúmer osreales, ycalculeyescribalos
puntosdesillaquetenga, asícomolasposicionescorrespondientes.
7.9.
Escribirunprogramaqueleaunnúmeronaturalimparnmenoroigualque11, calculeyvisualiceelcuadradomágicode
ordenn.Uncuadradodeordenn*n sedicequeesmágicosicontienelosvalores1, 2, 3, ..., n*n, ycumplelacondiciónde
quelasumadelosvaloresalmacenadosencadafilaycolumnacoincide.
7.10. Escribirunafunciónqueencuentreelelementomayorymenordeunamatriz, asícomolasposicionesqueocupaylosvisualiceenpantalla.
7.11. Escribirunafunciónquerecibacomoparámetrounamatrizcuadradadeordennydecidasiessimétrica.Unamatrizcuadradadeordennessimétricasia[i][j]==a[j][i]par atodoslosvaloresdelosíndicesi, j.
7.12. CodificarunprogramaC++quepermitavisualizareltriángulodeP ascal:
1
1
1
1
1
1
3
4
5
1
2
1
3
6
10
1
4
10
1
5
1
EneltriángulodePascalcadanúmeroeslasumadelosdosnúmer ossituadosencimadeél.Esteproblemasedeberesolverutilizandoprimeramenteunarraybidimensionaly, posteriormente, unarraydeunasoladimensión.
7.13. Escribirunprogramaqueleaunte xtodelaentr adaycuente: elnúmerodepalabr asleídas;númerodelíneasyvocales
(letrasa;letrase;letrasi;letraso;letrasu).Elfinaldelaentradadedatosvienedadoporcontr ol+Z.
7.14. CodificarunprogramaC++queleaunafr ase, ydecidasiespalíndroma.Unafrasesedicequeespalíndromasidespués
dehabereliminadolosblancos, sepuedeleerdeigualformaenlosdossentidos.
7.15. Escribirunafunciónquer ecibaunnúmeroescritoenunaciertabasebcomocadenadecar acteresylotr ansformeenel
mismonúmeroescritoenotr aciertabaseb1comocadenadecar acteres.Lasbasesbyb1sonmayor esoigualesque2y
menoresoigualesque16.Puedesuponerqueelnúmer ocabeenunavariablenuméricaenter olargo, yusarlabase10
comobaseintermedia.
7.16. Diseñarycodificarunprogramaqueleauntextoydeterminelafrecuenciadeaparicióndecadaletramayúscula.Elfinde
lecturavienedadopor(Control+Z).
7.17. Escribirunprogramaqueleaunafr asey, acontinuación, visualicecadapalabradelafraseencolumna, seguidodelnúmerodeletrasquecomponecadapalabra.
SOLUCIÓN DE LOS EJERCICIOS
7.1.
Lasalidadelprogramadependedelaentradadedatos.Hayquetenerencuentaqueseleenuntotalde6valor esyseescribenlosqueocupanlasposiciones 6, 4, 2.Silaentradadedatosesporejemplo: 3 7 4 –1 0 6, éstossecolocanenlas
posicionesdelarraynúmero 1, 2, 3, 4, 5, 6 y, portanto, lasalidaserá 6 –1 7 yaqueelb ucleesdescendenteyse
escribenlasposicionesdelarraynúmeros6 4 y2.
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
150
7.2.
Elprogramarellenaelvector Primero conlosvalores3, 4, 5, ..., 11, 12 enlasposiciones 0, 1, 2, ..., 9 delarray.Silaentradadedatoses, porejemplo, 8 3, elprogramanotendráningunasalidayaqueelse gundobucleesascendenteyellímiteinferior j = 8 esmayorqueelsuperior k = 3.Silaentr adadedatoses, porejemplo, 3, 8, elprogramaescribirá
lasposicionesdelarray 3, 4, 5, 6, 7, 8 quesehaninicializado, previamente, conlosvalores 6, 7, 8, 9, 10, 11.Silaentradadedatosestalquelosíndicesquer ecorrenlasalidadelvectornosonmenor esque 9, entonceslosresultadossonimprevisibles.
7.3.
Losvaloresdelvector Primero sonrellenadosporelprimerbucleysonlossiguientes:
Índice
0
1
2
3
4
5
6
7
8
9
10
valor
2
4
6
8
10
12
14
16
18
20
22
Losvaloresdelvector Segundo sonrellenadosporelsiguientebucle, ysonlossiguientes:
Índice
0
1
2
3
4
5
valor
2
7
12
17
22
27
Eltercerbucledelcódigoescribelassiguientesposicionesdelarr ay.
Primero
Segundo
4
2
5
3
6
4
Lasalidadelprogramavienedadaporloscontenidosdeesasposicionesqueenestecasoson:
1012
1217
1422
Alejecutarelprogramasecompruebalosresultados:
7.4.
Sedeclaralaconstante max como 10.Medianteunb ucle for serellenaelvectorpreviamentedeclaradocomoentero, almacenadoenelíndice i delvectorelvalorde 2 * i + 1 yaqueeselcorrespondientenúmeroimparasociado.Observar
queelbucle for sehaprogramadoconelincrementodelavariabledecontr oldelbucledentrodelapropiasentenciade
asignaciónvector[i++] = 2 * i + 1.Medianteotrobuclefor, sepresentanlosíndicesdelarrayqueocupanposicionespares0, 2, 4, 6, 8.
Codificación
#include <cstdlib>
#include <iostream>
#define max 10
using namespace std;
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
151
int main(int argc, char *argv[])
{
int i, vector[max];
for(i = 0; i < max; )
vector[i++] = 2 * i +1 ;
for (i = 0; i < max; i += 2)
cout << vector[i] << " ";
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Elresultadodeejecucióndelprogramaanteriores:
SOLUCIÓN DE LOS PROBLEMAS
7.1.
Laconstante max sedeclaracomo 5.Sedeclaraelvectordedatosyenunprimerb uclefor seleenlosvaloresdeentrada
almacenándolosenelvectordatos.Medianteotrobuclefor sepresentanlosvaloresleídos, altiempoqueseacumulanen
elacumulador suma losvalores.Finalmentesepresentanlosresultados.
La codificación de este problema se encuentra en la página Web del libro.
7.2.
Teniendoencuentaladefinición;paraqueelvectorseasimétrico, debeocurrirque: elcontenidodelaposición 0 (elprimero)coincidaconelcontenidodelaposición n – 1 (elúltimo);elcontenidodelaposición 1 (elsegundo)coincidacon
eldelaposiciónn – 1 – 1 (elpenúltimo);etc.Esdecir, elcontenidodelaposicióni debecoincidirconeldelaposición
n – i – 1.Portanto, pararesolverelproblemabastaconcomprobarsolamentelamitaddelosvalor esdelvector(hastan / 2).Lafunciónquesecodificarecibeelvectorv comoparámetro, asícomoelnúmerodeelementosalmacenadosn.
Medianteunbucle for secompruebalacondicióndesersimétrico, yseiteramientraselcontadorseamenoroigualque
n / 2 ylaparteanteriormenterecorridaseasimétrica.
Codificación
bool simetrica (float v[], int n)
{
int i;
bool sime = true;
for (i = 0; i <= n / 2 && sime; i++)
if (v[i] != v[n - 1 - i])
sime = false;
return sime;
}
7.3.
Sielvectoresmayoritario, necesariamenteelelementoqueserepitemásde n / 2 vecesdebeaparecerenlaprimeramitaddelarr ay.Deestaforma, pararesolverelpr oblemabastaconcompr obarelnúmer odevecesqueser epitenlosele-
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
152
mentosqueocupanlaprimeramitaddelvector, quedándoseconelquemásser epite, ysielnúmerodevecesqueaparece
elelementomásrepetidoesmayorquen / 2 larespuestaesafirmativa, yenotrocasoesnegativa.Medianteunbuclefor
controladoporelcontador i, serecorrenloselementosdelaprimer amitaddelarrayv.Medianteotrobuclefor interno,
secuentaelnúmerodeveces nveces queaparecerepetidoelelemento v[i] asuderecha.Detodosestosvalor esobtenidosconelb ucleexternohayquequedar seconelnúmerodevecesmáximo nvmaximo, paraalfinalretornarelvalor nvmaximo > n / 2 queserá true cuandoelvectorseamayoritario.
Codificación
bool mayoritario( float v[], int n)
{
int i, j, nveces, nvmaximo = 0;
for (i = 0 ; i <= n / 2 ; i++)
{
nveces = 1;
for (j = i + 1 ; j < n; j++)
if(v[i] == v[j])
nveces++;
if (nveces > nvmaximo)
nvmaximo = nveces;
}
return (nvmaximo > n / 2);
}
7.4.
Seprogramalafunciónpr oductoescalardefinidocomo pe( a, a, n) =
n −1
∑ a(i) ∗ b(i) medianteunbucle for, controladopor
i=0
elcontador i quecomienzaen 0 yterminaen n – 1.Encadaiter ación i delbucleseacumulaenelacumulador acu el
valorde a[i] * b[i].Esteacumulador acu seinicializaa 0 yseretornasucontenidoalfinaldelafunción.Teniendoen
cuentaquelanormadeunvectorsatisfacelaigualdad:
norma( a, n) =
n −1
∑ a( i ) ∗ a ( i ) =
pe( a, a, n) , paraprogramarlafunciónsolicitada, bastaconllamaralafunciónproducto
i=0
escalarconelvector a comoparámetroenlosdosargumentos, yextraersuraízcuadrada.
Elcosenodelánguloqueformandosvector esde n componentessatisfacelasiguienteigualdad:
n −1
cos( a, b, n) =
∑ a( i ) ∗ b( i )
i=0
n −1
n −1
i=0
i=0
∑ a ( i ) ∗ a( i ) ∗ ∑ a( i ) ∗ b( i )
=
pe( a, b, n)
norma( a, n) ∗ norma(b, n)
porloquelaprogramacióndelafunción coseno sereducealasllamadascorrespondientesalafunciónproductoescalar
delosvectoresa yb ylasnormasdelosdosvector escitadosvectores.
La codificación de este problema se encuentra en la página Web del libro.
7.5.
Lasolucióndelproblemasehaestructuradodelasiguienteforma:
• Sedeclaralaconstante max como 100 paradeclararunvectorquealmacenelos 100 primerosnúmerosprimos.Elprogramaprincipalseencargadedeclararunarraya paraalmacenarlosmax númerosprimos, ymedianteunbuclefor rellenarelvectordenúmerosprimos, llamandoalafunciónprimo quedecidesielnúmeronaturalqueselepasacomopa-
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
153
rámetroesprimo. Todoslosnúmerosprimossonimpar es, exceptoelnúmero 2 queademáseselprimer o, porloquees
introducidoantesdecomenzarelbucleenlaposición 0 delvectora.Unavezqueen n setieneelprimercandidatoanúmeroprimo, enestecasoelimpar 3, lossiguientescandidatosanúmer osprimos, seobtienendelanteriorsumándole2
unidades.Deestaforma, siseinicializalavariableenter a n a 3 paracalcularelsiguientenúmeroprimo, bastausarun
bucle while queiteremientras, número n noseaprimoelincr ementandoelcontador n en 2 unidades while (!primo(n)) n += 2;.Cadavezqueelb uclesepara, esporquehadecididoque n esunnúmeroprimo, porloquehayque
almacenarloenelvector a yrecalcularelsiguientecandidatoanúmeroprimo n += 2.
• Funciónprimo.Unnúmeroenteropositivoesprimo, sisólotienepordivisoreslaunidadyelpropionúmero.Elmétodo
queseusa, aplicalasiguientepropiedad: “siunnúmeromayorquelaraízcuadradaden dividealpropion esporquehay
otronúmeroenteromenorquelaraízcuadradaquetambiénlodivide”.Porejemplo.Sin vale64 suraízcuadradaes8. El
número32 dividea64 queesmayorque 8 perotambiénlodivideelnúmero2 queesmenorque 8, yaque2 * 32 = 64.
Deestaforma, paradecidirsiunnúmeroesprimobastaconcomprobarsitienedivisoresmenoresoigualesquesur aíz
cuadrada, porsupuestoeliminandolaunidad.
• Funciónescribe realizalavisualizacióndelalistadelos 100 númerosprimosen 10 líneasdistintas.Estafunciónrecibeensuparámetrovector lainformación, yescribeenunbuclefor losmax númerosquealmacena.
La codificación de este problema se encuentra en la página Web del libro.
7.6.
Lafunción main( ) queseencargadellamaralasdistintasfuncionesquer esuelvenelproblema.Enelprogramaprincipalmain( ) sedeclarael vector demax datos, siendomax unaconstantedeclaradaenunasentencia define.
• Lafunción aleatorio generaelnúmerodeelementos n quetieneelvectoraleatoriamente , eintroduce n númerosaleatoriosenelvectorquerecibea comoparámetro.
• Eslafunción escribe laencargadadevisualizarelvectorquer ecibecomoparámetro.
• Elcálculodelamedialor ealizaconunafunción m, sumandoenunbuclevorazfor losn elementosdelvector a querecibecomoparámetro, ydividiendoelresultadodelasumaentreelnúmerodeelementos n quetiene.
• Ladesviaciónmediasecalculamediantelafunción dm, queacumulaenelacumulador aux losvaloresde fabs(a[i]media), siendo media elvalordelamediadeloselementosdelvector a.Elvalorobtenidoenelacumulador aux sedivideentren.
• Ladesviacióntípicasepr ogramaenlafunción dt.Laprogramacióndelafunciónesmuysimilaraladelafunción dm,
conladiferenciaqueahoraseacumulaelvalorde (a[i] - media) * (a[i] - media), yelresultadoeslaraízcuadradadelacumuladordivididoentren.
La codificación de este problema se encuentra en la página Web del libro.
7.7.
Latraspuestadeunamatriz a vienedadaporlamatrizqueseobtienecambiandolaf ilai porlacolumna i.Esdecir, b es
lamatriztraspuestade a sisetieneque b[i][j) = a[j][i] paratodolosposiblesíndices i, j.Portanto, paracalcular
latraspuestadelamatriz a sobresímisma, bastaconintercambiarlosvaloresdea[i][j] cona[j][i], parai = 0, 1,
..., n – 1, yj = 0, 1, 2, ... i – 1.Lafuncióntraspuestarecibecomoparámetrolamatrizcuadradaa, asícomo
ladimensión n.
Codificación
#define max 11
void traspuesta(float a[][max], int n)
{
float aux;
for (int i = 0; i < n; i++)
for (int j = 0; j < i; j++)
{
aux = a[i][j];
a[i][j] = a[j][i];
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
154
a[j][i] = aux;
}
}
7.8.
Pararesolverelproblemasesuponequelamatriznotieneelementosr epetidos.Lafunciónrecibecomoparámetrolamatrizderealesa[max] (max esunaconstantepreviamentedeclarada), yladimensión n.Lacodificaciónsehaplanteadode
lasiguienteforma: unprimerbuclerecorrelasdistintascolumnasdelamatriz.Dentr odeesebuclesecalculaelelementomayor delacolumnaylaposicióndelafilaenlaqueseencuentra.Posteriormente, secompruebasilafilaenlaquese
haencontradoelelementomayordelacolumnacumplelacondicióndequeeselelementomenordelaf ila.Encasopositivosehaencontradounpuntodesillaysevisualizaelr esultado.
La codificación de este problema se encuentra en la página Web del libro.
7.9.
Enunarraybidimensionalsealmacenaráelcuadr adomágico.Lafunción main( ) leeygarantizamedianteunbucle do
queelnúmeron queseleeesimparyestáenelr ango1 a11.Elproblemaseresuelveusandolasfunciones:
while
• siguiente tienecomoparámetrodosnúmerosenteros i y n, detalmaneraque i esmayoroigualquecer oymenoro
igualque n – 1.Lafuncióndevuelveelsiguientevalorde i quees i + 1.Enelcasodequealsumarlea i elvalor 1,
i tomeelvalor n, seleasignaelvalorde0.Sirvepar airrecorriendolosíndicesdelasfilasdelamatrizquealmacenaráelcuadr adomágicodeor den n.Enlacodif icaciónseprogramaincrementando i enunaunidad, yasignandoa i el
restodeladivisiónenterade i entren.
• anterior tienecomoparámetrodosnúmerosenteros i y n, detalmaner aque i esmayoroigualquecer oymenoro
igualque n – 1.Lafuncióndevuelveelanteriorvalorde i quees i – 1.Enelcasodequealr estarlea i elvalor 1, i
tomeelvalor–1 seleasignaelvalorden – 1.Sirveparairrecorriendolosíndicesdelascolumnasdelamatrizquealmacenaráelcuadradomágicodeordenn.
• comprueba escribelamatrizquealmacenaelcuadradomágicoy, además, escribelasumadelosvaloresdecadaunade
lasfilasydecadaunadelascolumnas, visualizandolosresultados, parapodersercomprobadoporelusuario.
• cuadrado calculaelcuadradomágicomedianteelsiguientealgoritmo:
Seponetodalamatrizaceros, paraindicarquelascasillasestánlibres.
Seinicializalafilai = 0 lacolumna j = n / 2.
Medianteunbuclequecomienzaporelvalor1, sevancolocandolosvaloresenordencrecientehastael n * n dela
siguienteforma:
Silaposiciónfilai columnaj delamatrizestálibre(tieneelv alorde 0)sealmacena, yserecalculalafilacon
lafunción anterior ylacolumnaconlafunción siguiente.
Silaposiciónfilai columnaj delamatrizestáocupada(tienevalordistintode0)serecalculai aplicándoledos
veceslafunción siguiente yserecalcula j aplicándoleunavezlafunción anterior.Sealmacenaelv aloren
laposiciónfilai columnaj (siempreestálibre), para, posteriormente, recalcularlafilaconlafunciónanterior
ylacolumnaconlafunción siguiente.
La codificación de este problema se encuentra en la página Web del libro.
7.10. Lasoluciónsepresentamedianteunafunciónquerecibelamatriz a comoparámetro, ladimensiónn, ycalculael mayor y
menor mediantelatécnicavoraz.Seinicializa menor y mayor alelemento a[0][0], asícomolosrespectivosíndices.Dos
buclesanidadosrecorrentodoslosíndicesdelamatrizcuadr adayparacadaelementodelamatrizhacencompar aciones
conelanterior menor yelanterior mayor, decidiendoquedarseconunnue vo menor ounnuevo mayor asícomolosíndicesqueocupan, siesnecesario.Alfinaldelafunciónsepresentanlosresultados.
La codificación de este problema se encuentra en la página Web del libro.
7.11. Unamatrizcuadradaessimétricasi a[i][j] == a[j][i] paratodo i yparatodo j.Portanto, bastaqueunpardeíndices i, j nosatisfagalacondición, paraquelamatrizseanosimétrica.P orotrolado, paracomprobarquelamatrizes
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
155
simétricabastaconhacerlopar alosvalores i= 0, 1, ..., n–1, y j = 0, ..., i – 1, yaquesecompruebalaparteinferior
de ladia gonalprincipalconlapartesuperiordeladia gonalprincipaly , portanto, secompruebatodalamatriz.La
programaciónsehahec hoconlosdosb uclesanidadosindicadosanteriormente , añadiendocomocondicióndesalida
de ambosbucles, quenosehayadetectadoalgunadiscr epanciaentre a[i][j] con a[j][i], encuyocasolavariable
interruptor sime tomaelvalorde false, yaquesesabequelamatrizcuadr adarecibidacomoparámetr onoessimétrica.
Codificación
bool simetrica (float a[][max], int n)
{
bool sime = true;
for (int i = 0; i < n && sime; i++)
for (int j = 0;j < i && sime; j++)
if (a[i][j] != a[j][i])
sime = false;
sime;
return
}
7.12. EltriángulodePascalpuederepresentarsedelasiguienteformaparafacilitarlacodificacióndelalgoritmos, sibienlavisualizaciónesligeramentedistinta:
1
1
1
1
1
1
1
2
3
4
5
1
3
6
10
1
4
10
1
5
1
Sepidendossolucionesalpr oblema.Laprimer aconunarr aybidimensional matriz, ylase gundaconunarr ayunidimensionalvector.Tantolamatriz comoel vector sedeclarandeunalongitudmáximade max = 11.Lasoluciónseestructuradelasiguienteforma:
• Lafunciónprincipal main( ), declaralamatriz yelvector, leeelorden enunbucle do while, validandolaentrada
yrealizalasllamadasalasfunciones .
• Unafuncióntriánguloendosdimensiones Tdosdim tienecomoparámetroselarraybidimensional matriz yunavariableentera orden ycalculaeltriángulodeP ascaldel orden quesepasacomoparámetr o.EltriángulodeP ascalsecolocaenlamatrizpordebajodeladia gonalsuperior.Lacodificaciónserealizacondosb uclesanidados.Elb ucleexteriorescontroladoporelcontador i, iteradesde 0 hasta n – 1, yelbucleinteriorqueescontr oladoporelcontador j
queiteradesde 0 hastai.Seobservaque matriz[i][j] tomaelvalor 1 sij == 0, obiensi i == j.Enotrocaso matriz[i][j] = matriz[i - 1][j - 1] + matriz[i - 1][j].
• Lafunciónescribetriángulodedosdimensiones ETdosdim tienecomoparámetroselarraybidimensional matriz yuna
variableenteraorden seencargadevisualizareltriángulodepascaldel orden querecibecomoparámetro.
• LafunciónTriángulo enunadimensiónTunadim tienecomoparámetroselarrayunidimensionalvector yunavariable
enteraorden, calculayescribeeltriángulodePascaldelorden querecibecomoparámetro.Enestafunciónelbucleinterior j sehacedescendentepar ano“pisar” losvaloresanteriormentecalculados.Enestecasosi i == j || j == 0
entoncesvector[j] = 1.Enotrocaso vector[j] = vector[j] + vector[j - 1];
La codificación de este problema se encuentra en la página Web del libro.
156
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
Enelresultadodeejecucióndelprogramaanterior , puedenvisualizarselosdostriángulosdeP ascaldeorden7realizados
conunamatrizyconunv ector.
7.13. Sedeclaraunvectorenterocontador decincocomponentesquesirveparacontarlasvocalescorrespondientes, queesinicializadoa 0 enelbuclecontroladoporelcontador i.Elcontador npalabras, cuentaelnúmerodepalabrasdelaentrada, yotrocontadornlineas cuentaelnúmerodelíneas.Unbucleiteramientrasnoseafindefichero(control+Z), yotro
bucleiteramientrasseencuentreenunapalabra.Cadavezqueterminaestebuclesecuentaunapalabra.Elbucleinterior
leeuncarácterenlavariable c eincrementaelcontadordelavocalcorrespondienteencasodequelosea.Cadavezque
ctomaelvalor '\n', secuentaunanuevalínea.
La codificación de este problema se encuentra en la página Web del libro.
7.14. Unafraseespalíndromasipuedeleersedeigualformadeizquierdaaderecha, quedederechaaizquierda, despuésdehabereliminadolosblancos.Porejemplolafrase“dabalearrozalazorraelabad” espalíndroma.Pararesolverelproblema,
seleeunafr aseenunacadenadecar acteres Cad.Secopialafr aseenunarr aydecaracteres Cad1, eliminandolosblancos, ycontandoloscar acteresqueseponenenelcontador c1.Posteriormente, medianteunbuclecontroladoporelcontador c quecomienzaen 0 yterminaenlamitaddelalongituddeloscar acteresdelafrase, unavezeliminadoslosblancos, c1 / 2, secompruebasilaletraqueocupalaposiciónc_ésimacoincideconlacorrespondientequeocupalaposición
c1-1-c_ésima, Cadaux[c] == Cadaux[c1 - 1 - c].LavariablebooleanaEspalindroma seponeatrue, ysólosecambiaa false silafraseesnopalíndroma.
La codificación de este problema se encuentra en la página Web del libro.
7.15. Pararesolverelproblemaseusacomobaseauxiliarintermedialabase 10, ysesuponequeelnúmeroqueserecibecomo
parámetrocabeenunenterolargo.Lafunciónpedidaes cambiodoble.Parapasardeunnúmeroalmacenadoenunacadenadecaracteresentrada yescritoenlabase base almismonúmeroalmacenadoenotracadenadecaracteressalida
yescritoenotrabasebase1, bastallamaralasfunciones numero = valorBase10 (entrada, base), quetransformala
entradaaundatonumérico numero escritoenbase10 y, posteriormente, llamaralafunción cambioBase(numero,
base1, salida), quetransformaelnúmeroenbase 10 alacadenadecaracteres salida escritaen base1.
Lafunción cambiobase recibeeldatoenbase 10 enlavariableenteralarganumero ytransformaeldatoaunacadenadecaracteressalida querepresentaeldatoescritocomocadenadecaracteresenlabase base.Parapoderrealizarlo
indicado, usaunacadenadecar acteresllamada bases quealmacenalosdistintoscar acteresalosquesetr ansformarán
losnúmeros: así, porejemplo, elnúmero5 setransformaen'5', elnúmero10 setransformaen'A', elnúmero11 en'B',
etcétera(sólopuedenusarsebasesentre2y16).Sedefineunvectordeenterosauxiliar quealmacenaencadaunadelas
posiciones(comoresultadointermedio), eldígitoenteroalquecorrespondecuandosepasaeldatoalabasequeserecibe
comoparámetro.Parahaceresto, seusaelesquemasiguiente: mientras lavariable numero seadistintadecerohacer en
laposición c delvector auxiliar almacenarelrestodeladivisiónenter adelnúmero numero entrela base, paraposteriormentealmacenarenlavariable numero elcocientedeladivisiónenter adelnúmeroentrela base.Paraterminarse
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
157
pasaelnúmeroacadenadecar acteres salida usandoelarray bases, comoindexación, salida[n – c] = bases[auxiliar[c]].
Lafunción valorBase10 recibecomoparámetroeldatoalmacenadoenlacadenadecar acteres cadena ylabaseen
elqueestáescrito, ylotrasformaasucorrespondientevalornuméricoenbase 10 devolviéndoloenlapropiafunción, que
esdeclaradacomodetipo enterolargo.Pararealizarlaoperaciónseusa, elmétodode Horner deevaluacióndeunpolinomioescritoenunaciertabase:
'2345'base=( ( (0 * base + 2)* base + 3) * base + 4)* base + 5.
Medianteunbuclefor serecorrentodaslasposicionesdelacadena, hastaquenoquedendatoscadena[c] == '\0'.
Elcarácteralmacenadoenlaposición c de cadena setransformaenundatonuméricoconlae xpresión valor = cadena[c]-'0', siesundígito, ymediantelaexpresiónvalor = cadena[c] –'A'+ 10, enelcasodequeseauncarácterde
entre'A','B','C','D','E','F'.
La codificación de este problema se encuentra en la página Web del libro.
7.16. Sedeclaralaconstante máximo, quesirveparadimensionarelarraycontador, queesdondesecuentanlasletrasmayúsculasqueseleendeltexto.Enunbuclefor, seinicializaelarraycontadora0.Enunbuclewhile, mientasnosedéfinde
fichero(control+Z), seleeuncarácter, ysiesunaletr amayúsculaseincrementaelcontadordeíndice c – 'A', enuna
unidad( contador[ c - 'A']++).Unavezterminadalalectur a, seescribentodosaquellosíndicesdecontador esnonulos, quesonaquellosquehacenreferenciaaletrasmayúsculasquehanaparecidoeneltexto.
La codificación de este problema se encuentra en la página Web del libro.
7.17. Sedeclarandoscadenasdecar acteres.Laprimera Cad sirveparaleerlafr asedelaentr ada.Lasegunda Cadaux seusa
paraalmacenarcadaunadelaspalabrasqueseextraendeCad ypoderescribirelnúmerodeletrasqueloforman.Seconsideranseparadoresdepalabrasloscaracteres(coma, blancoypunto, ',', ' ' y'.').Lacodificaciónserealizamediante
unbuclewhile queiterahastaqueseterminalacadenadecaracteresCad.Estebuclelocontrolaelcontadorc queseinicializaa0, eindicaencadamomentolaposicióndelcarácteralmacenadoen Cad queseestátratando.Dentrodeestebuclehayotrobuclewhile queeselencargadodeextraerlapalabraycontarelnúmerodecaracteresquetiene.Estebucle
estácontroladoporelfindecadena, deCad yelnohaberencontradounseparadorenCad.Elcontador c1, seinicializaa
0, ycadavezquesedebealmacenaruncarácterenlacadenaauxiliar Cadaux, seincrementaenunaunidad.Unavezterminadoestebucle, seconvierte Cadaux enunacadenaañadiéndoleelcarácterdef indecadena '\0', yseescribelapalabraysunúmerodeletrasdadoporelcontador c1.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
7.1.
¿Cuáleselerrordelfragmentodelsiguientefragmento
deprograma?
int j, x[8] ;
for ( j = 1; j<= 9; )
x[j] = 2 * j;
7.2.
Determinarlasalidadelcadase gmentodeprograma:
int i ,j ,k;
int Primero[6];
for( j = 0; j < 7; )
cin >> Primero[j++];
i = 0; j = 1;
while (( j < 6) && (Primero[j – 1 ] <
Primero[j]))
{
i++; j++;
}
for( k = -1; k < j + 2; k+=2)
cout << Primero[ ++ k] << endl;
silaentradadedatoseslasiguiente: 20 60 70 10 0
40 30 90
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
158
7.3.
¿Cuáleselerrordelsiguientefragmentodeprograma?
7.6.
float X[char]
char j =1;
X[j] = 14.325;
7.4.
7.5.
int i, j, k , Primero[10];
for (i = 0; i< 10 ; i++)
Primero[i] = i + 3;
cin >> j >> k;
for (i = j; i<= k ; i++)
cout << Primero[i] << endl;
Determinarlasalidadecadase gmentodeprograma.
int i,j,k;
int Tercero[6][12];
for(i = 0; i < 3; i++)
for(j = 0; j < 12; j++)
Tercero[i][j] = i + j + 1;
for(i = 0; i < 3; i++)
{
j = 2;
while (j < 12)
{
cout << i << " " << j << " "<<
Tercero[i][j]);
j += 3;
}
}
7
7.7.
3
7
4
-1
0
2
3
9
Escribirunprogramaqueleaelarray:
4
2
3
7
0
1
1
6
2
3
9
6
5
7
4
ylovisualicecomo:
4
7
1
3
5
¿Cuáleslasalidadelsiguientese gmentodeprograma
paralaentradadedatosdadaalf inal?
int i, Primero[10];
for (i = 0; i < 6 ; i++)
cin >>Primero [i];
for (i = 2; i >= 0; i--)
cout << Primero [2 * i] << "
¿Cuáleslasalidadelsiguientese gmentodeprograma
paralaentradadedatosdadaalf inal?
7.8.
2
0
6
9
7
3
1
2
6
4
Escribirunafunciónqueintercambielaf ilai-ésima por
laj-ésima deunarray mxn.
";
6
PROBLEMAS PROPUESTOS
7.1.
Escribirunprogramaquecon viertaunnúmeroromano
(enformadecadenadecaracteres)ennúmeroarábigo.
Reglasdeconversión:
M
D
C
L
X
V
I
7.2.
1000
500
100
50
10
5
1
Escribirunafunciónalaqueseleproporcioneunafecha(día, mes, año), asícomounnúmerodedíasaaña-
diraestafecha.Lafuncióndebecalcularlanuevafecha
yvisualizarla.
7.3.
Escribirunafunciónqueaceptecomoparámetroun
vectorquepuedecontenerelementosduplicados.La
funcióndebesustituircadav alorrepetidopor –5 ydevolveralpuntodondefuellamadoelv ectormodificado
yelnúmerodeentradasmodif icadas.
7.4.
Escribirunprogramaqueleaunacoleccióndecadenas
decaracteresdelongitudarbitraria.Porcadacadenaleída, suprogramasharálosiguiente:
a) Visualizarlalongituddelacadena.
CAPÍTULO 7 Arrays (ar reglos, listas o tablas)
159
'dd/mm/aa', como17/11/91yladevuelvaenformatode
texto: 17noviembre1991.
b) Contarelnúmerodeocurrenciadepalabrasdecuatroletras.
c) Sustituircadapalabradecuatroletrasporunacadenadecuatroasteriscoseimprimirlanue vacadena.
7.9.
7.5.
Escribirunprogramaqueleaunafrase, sustituyatodas
lassecuenciasdedosomásblancosporunsoloblanco
yvisualicelafraserestante.
7.10. Buscarunapalabraenunacadenaycalcularsufrecuenciadeaparición.
7.6.
Escribirunprogramaquedesplaceunapalabraleídadel
tecladodesdelaizquierdahastaladerechadelapantalla.
7.7.
Escribirunprogramaqueleaunaseriedecadenas,
a
continuación, determinesilacadenaesunidentificador
válidoC++.Sugerencias: utilizarlossiguientessubprogramas: longitud(tamañodelidentif icadorenelrango
permitido);primero(determinarsielnombrecomienza
conunsímbolopermitido);restantes(compruebasilos
restantessoncaracterespermitidos).
7.8.
Escribirunafuncióncon versiónquerecibacomoparámetrounacadenarepresentandounafechaenformato
Escribirunprogramaquepermitaescribirensentidoinversounacadenadecaracteres.
7.11. Escribirunprogramaenelquesegenerealeatoriamenteunvectorde20númerosenteros.Elvectorhadequedardetalformaquelasumadelos10primeroselementosseamayorquelasumadelos10últimos
elementos.Mostrarelv ectororiginalyelv ectorconla
distribuciónindicada.
7.12. Eljuegodelahorcadosejuegacondospersonas(ouna
personayunacomputadora).Unjugadorseleccionauna
palabrayelotrojugadortratadeadivinarlapalabraadivinandoletrasindi viduales.Diseñarunprogramapara
jugaralahorcado. Sugerencia: almacenarunalistade
palabrasenunarrayyseleccionarpalabrasaleatoriamente.
CAPÍTULO 8
Registros (estr ucturas
y uniones)
Introducción
Estecapítuloe xaminaestructuras, uniones, enumeracionesytiposdef inidosporelusuarioquepermitenaunprogramador
crearnuevostiposdedatos.LacapacidadparacrearnuevostiposesunacaracterísticaimportanteypotentedeC++yliberaa
unprogramadorderestringirsealusodelostiposofrecidosporellenguaje.Una estructura contienemúltiplesvariables, que
puedenserdetiposdiferentes.Porotraparte, launiónesotrotipodedatonotanimportantecomolasestructurasarray , pero
sínecesariaenalgunoscasos.Untipodedatoenumerado(enumeración)esunacoleccióndemiembrosconnombrequetienenvaloresenterosequivalentes.Untipodefinidoporelusuario , typedef, esdehecho, nounnuevotipodedatosino, simplementeunsinónimodeuntipoe xistente.
8.1. Estructuras
Unaestructuraesuntipodedatodef inidoporelusuario, quesedebedeclararantesdequesepuedautilizar .Unaestructura
esunacoleccióndeunoomástiposdeelementosdenominados miembros, cadaunodeloscualespuedeseruntipodedato
diferente.Puedecontenercualquiernúmerodemiembros, cadaunodeloscualestieneunnombreúnico, denominadonombre
delmiembro.Losmiembrosdelasestructuraspuedenserarrays.Delmismomodoquesucedeenotrassituaciones, enC++
existendosconceptossimilaresaconsiderar, declaración ydefinición.
Declación de una estructura. Unadeclaraciónespecificasimplementeelnombreyelformatodelaestructuradedatos,pero
noreservaalmacenamientoenmemoria.Elformatodeladeclaraciónes:
struct <nombre de
{
<tipo de dato
<tipo de dato
...
<tipo de dato
};
la estructura>
miembro1> <nombre miembro1>
miembro2> <nombre miembro2>
miembron> <nombre miembron>
Definición de variables de estructura. Unadefinición devariableparaunaestructuradada, creaunáreaenmemoriaendondelosdatossealmacenandeacuerdoalformatoestructuradodeclaradoenladef inicióndelaestructura.
161
CAPÍTULO 8 Registros (estr ucturas y uniones)
162
Lasvariablesdeestructurassepuedendef inirdedosformas:
1. Listándolasinmediatamentedespuésdelalla vedecierredeladeclaracióndelaestructura.
2. Listandoeltipodelaestructuracreadaseguidaporlasvariablescorrespondientesencualquierlugardelprogramaantesdeutilizarlas.
Aunaestructuraseaccedeutilizandounav ariableov ariablesquesedebendef inirdespuésdeladeclaracióndelaestructura.
Uso de estructuras en asignaciones. Comounaestructuraesuntipodedatosimilaraun int oun char, sepuedenasignar
variablesdeunaestructuraaotraentresí.
EJEMPLO 8.1. Declaracióndeunaestructura, definicióndevariablesdetipoestructur ayasignacióndevariables.
Sedeclaraunaestructuralibro cuyosmiembrossontitulo, autor, editorial, anyo, precio, fecha-compra, yvariablesdetipo libro l1, l2, l3, l4, l5, l6.
struct libro
{
char titulo[30];
char autor[25];
char editorial[30];
int anyo;
float precio;
char fecha_compra[8];
} l1, l2, l3;
libro l4, l5, l6;
// nombre de la estructura
// l1, l2, l3 son variables de tipo libro
//l4,l4,l6 son variables de tipo libro
int main(int argc, char *argv[])
{
...
l1= l2 =l3;
system("PAUSE");
return EXIT_SUCCESS;
}
// asignación de estructuras
Inicialización de una declaración de estructuras. Sepuedeinicializarunaestructuradedosformas:
1. Comopartedelaseccióndecódigodesuprograma.
2. Comopartedeladef inición.Cuandoseinicializaunaestructuracomopartedeladef inición, seespecificanlosvaloresiniciales, entrellaves, despuésdeladefinicióndevariablesestructura.Elformatogeneralenestecaso:
struct <tipo> <nombre variable estructura> =
{
valor miembro1,
valor miembro2,
valor miembron
};
EJEMPLO 8.2. Inicializacióndeestructuras.Seinicializalavariablel1detipolibro, ysehaceotradeclaracióncon
unainicializacióndeltipodedatocomplejo:
struct complejo
{
float real;
float imaginaria;
} c1 = { 23.2, 10,1}
CAPÍTULO 8 Registros (estr ucturas y uniones)
163
//dada la declaración de libro realizada en el ejemplo 8.1
//la siguiente es una declaración de variable e inicialización
libro l7 = { "Programación en C",
"Joyanes, Luis",
"McGrawHill",
2002,
20,
"02/6/05"
};
El tamaño de una estructura. Eloperador sizeof sepuedeaplicarparadeterminareltamañoqueocupaenmemoriauna
estructura.Elresultadoseobtienedeterminandoelnúmerodebytesqueocupalaestructura:
EJEMPLO 8.3. Visualizaeltamañodedosestructur as.
#include <cstdlib>
#include <iostream>
using namespace std;
struct complejo
{
float real;
float imaginaria;
};
struct Persona
{
char nombre[30];
int edad;
float altura;
float peso;
};
// tiene tamaño 8 = 2*4 byes
// tiene tamaño 44 = 30 + 2 + 4 + 4
int main(int argc, char *argv[])
{
cout << "sizeof(Persona): " << sizeof(Persona) << endl;
cout << "sizeof(complejo): " << sizeof(complejo)<< endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Elresultadodeejecución:
Determinacióndelnúmerodebytesqueocupalaestructura:
Complejo
real, imaginaria
Persona
nombre[30]
edad
altura
peso
Total
Miembros
char(1)
int(2)
float(4)
float(4)
Tamaño (bytes) Persona
Tamaño (bytes) complejo
30
2
4
4
42
8
8
CAPÍTULO 8 Registros (estr ucturas y uniones)
164
Acceso a estructuras. Elaccesoalosmiembrosdeunaestructuraserealizacuando : seaccedeaunaestructura;sealmacenainformaciónenlaestructura;serecuperalainformacióndelaestructura.Sepuedeaccederalosmiembrosdeunaestructuradeunadeestasdosformas: (1) utilizandoeloperadorpunto (.), obien(2) utilizandoeloperadorflecha (->).
Laasignacióndedatosalosmiembrosdeunavariableestructurasehacemedianteeloperadorpunto.LasintaxisenC++es:
<nombre variable estructura>.<nombre miembro> = datos;
El operador punto , ., proporcionaelcaminodirectoalmiembrocorrespondiente.Losdatosquesealmacenanenun
miembrodadodebenserdelmismotipoqueeltipodeclaradoparaesemiembro.
Eloperador puntero, ->, sirveparaaccederalosdatosdelaestructuraapartirdeunpuntero.Parautilizaresteoperador
sedebedefinirprimerounavariablepunteroparaapuntaralaestructura.Acontinuación, utilicesimplementeeloperadorpunteroparaapuntaraunmiembrodado.Laasignacióndedatosaestructurasutilizandoeloperadorpunterotieneelformato:
<puntero estructura> -> <nombre miembro> = datos;
Previamentehabríaquecrearespaciodealmacenamientoenmemoria;porejemplo, conlafunción new.
EJEMPLO 8.4. Asignacióndevaloresalosmiembrosdevariablesestructura.Serealizanasignacionesavariables
detipo Persona declaradaenelEjemplo8.3.
Persona p, *p1;
// p es una variable estructura.
strcpy(p.nombre ," Angel Hernández");
// Asignación de cadenas
p.edad = 20;
p.altura = 1.75;
p.peso = 78;
// p1 es una variable puntero a estructura.
strcpy(p1->nombre ," Fernando Santos");
// Asignación de cadenas
p1->edad = 21;
p1->altura = 1.70;
p1->peso = 70;
Sisedeseaintroducirlainformaciónenlaestructurabastaconaccederalosmiembrosdelaestructuraconeloperador
puntooflecha(puntero).Sepuedeintroducirlainformacióndesdeeltecladoodesdeunarchi vo, oasignarvalorescalculados
(cin).Serecuperainformacióndeunaestructurautilizandoeloperadordeasignaciónounasentenciadesalida( cout).Igual
queantes, sepuedeempleareloperadorpuntooeloperadorflecha(puntero).Elformatogeneraltomaunodeestosformatos:
<nombre variable> = <nombre variable estructura>.<nombre miembro>;
obien
<nombre variable> = <puntero de estructura> -> <nombre miembro>;
EJEMPLO 8.5. Lectura, recuperacióndeinformacióndeestructur asdeltipodedato Persona definidaenelEjemplo8.3.
Persona p, *p1;
char nombre1[30];
int edad1;
float altura1;
float peso1;
// variable p
cout <<" introduzca nombre : ";
cin.getline( p.nombre, 30);
// lee nombre de
variable estructura p
CAPÍTULO 8 Registros (estr ucturas y uniones)
165
cout << " introduza edad altura peso :";
cin >> p.edad >> p.altura >> p.peso;
// lee resto de información
cout << p.nombre <<" " << p.edad <<" " << p.altura << " " << p.peso << endl;
//variable *p1
cin.getline(p1->nombre, 2); // leer retorno de carro no leído en cin
cout <<" introduzca nombre : ";
cin.getline(p1->nombre, 30);
// lee nombre de variable puntero estructura p1
cin >> p1->edad >> p1->altura >> p1->peso;
cout << p1->nombre<<" " << p1->edad << p1->altura << p1->peso<< endl;
strcpy(nombre1,p.nombre);
strcpy(p.nombre, p1->nombre);
edad1 = p.edad;
altura1 = p1-> altura
Estructuras anidadas. Unaestructurapuedecontenerotrasestructurasllamadas estructurasanidadas.Lasestructurasanidadasahorrantiempoenlaescrituradeprogramasqueutilizanestructurassimilares.Sehandedef inirlosmiembroscomunes, sólounavezensupropiaestructuray, acontinuación, utilizaresaestructuracomounmiembrodeotraestructura.Elaccesoamiembrosdatodeestructurasanidadasrequiereelusodemúltiplesoperadorespunto.Lasestructurassepuedenanidar
acualquiergrado.Tambiénesposibleinicializarestructurasanidadasenladef inición.
EJEMPLO 8.6. Estructurasanidadas.Sedeclarauntipodedatoestructurapararepresentaraunalumno.Losmiembrosquetieneson: nombre, curso, edad, direcciónynotasdelas6asignatur as.Sedeclaraotrotipoestructurapara
representaraun profesor.Losmiembrosquedebetenerson: nombre, cargo, nombredelas4asignatur asquepuedeimpartirydir ección.Sedeclar alaestructur ade datos quecontienelosatrib utos nombre y dirección.Lasestructurasalumno yprofesor tienenanidadaslaestructuradatos.
Larepresentacióngráficadelasestructurasanidadases:
profesor
alumno
Curso
Edad
datos:
Notas
Cargo
0
nombre
direccion
1 2 3 4
datos:
5
asignaturas
nombre
dirección
0 1 2 3
struct datos
{
char nombre[40],direccion[40];
};
struct alumno
{
datos dat;
int curso, edad, notas[6];
};
struct profesor
{
int cargo;
datos dat;
char asignaturas[4][10];
};
// nombre de asignaturas que imparte
CAPÍTULO 8 Registros (estr ucturas y uniones)
166
Sepuedecrearunarraydeestructurastalcomosecreaunarraydeotrostipos.MuchosprogramadoresdeC++utilizan
arraysdeestructurascomounmétodoparaalmacenardatosenunarchi vodedisco.Sepuedenintroducirycalcularsusdatos
almacenadosendiscoenarraysdeestructurasy , acontinuación, almacenaresasestructurasenmemoria.Losarraysdeestructurasproporcionantambiénunmediodeguardardatosqueseleendeldisco.
EJEMPLO 8.7. Arraydeestructuras.Hayuntotalde100clientes.Losclientestienenunnombr e, elnúmerodeunidadessolicitadasdeundeterminadoproducto, elpreciodecadaunidadyelestadoenqueseencuentra: moroso, atrasado, pagado.Elprogramaleelainformacióndelos100clientes.
Sedefinelaestructura cliente siguiendolasespecificacionesyconellasedeclaraunarrayquealmacenarálainformacióndecadacliente.El arraydeestructuras funcionacomounabasededatosrelacional, enlaquecadamiembro
delaestructurafuncionacomounacolumnadelabasededatosycadaestructuracorrespondeaunalíneaore gistro
dedichabase.
#include <cstdlib>
#include <iostream>
using namespace std;
struct cliente
{
char nombre[20];
int numUnidades;
float precio;
char estado;
};
int main(int argc, char *argv[])
{
cliente listado [100],buffer[4];
//buffer para limpiar entrada de cin
for (int i = 0; i < 100; i++)
{
cout << "Introduzca nombre del cliente: ";
cin.getline (listado[i].nombre, 20);
cout << "\n Introduzca el número de unidades solicitadas: ";
cin >> listado[i].numUnidades;
cout << "\n Introduzca el precio de cada unidad:";
cin >> listado[i].precio;
cout << "\n Introduzca el estado del cliente (m/a/p)";
cin >> listado[i].estado;
cin.getline(buffer,2); // limpiar buffer de entrada por número
}
system("PAUSE");
return EXIT_SUCCESS;
}
C++permitepasarestructurasafunciones, bienporvalorobienporreferencia, utilizandoeloperador &.Silaestructura
esgrande, eltiemponecesarioparacopiarunparámetro struct alapilapuedeserprohibiti vo.Entalescasos, sedebeconsiderarelmétododepasarladireccióndelaestructura.
EJEMPLO 8.8. Parámetrostipoestructuraporreferenciaafunciones.Seleelainformacióndelasestructur asdeclaradasenelEjemplo8.6deunalumnoydeunpr ofesor, mediantefunciones.
Lafunciónleer_datos leelosdatosdelaestructuradatos.Lafunciónleer_alumno, leelainformacióndeunalumnosusandolafunción leer_datos.Lalecturadelainformacióndeunprofesorserealizacon leer_profesor.
CAPÍTULO 8 Registros (estr ucturas y uniones)
167
void leer_datos (datos &dat)
{
cout << " nombre : ";
cin.getline(dat.nombre, 40);
cout << " direccion: ";
cin.getline (dat.dirección, 40);
}
// estructura por referencia
void leer_alumno(alumno &a)
{
cout << " datos de alumno: " << endl;
leer_datos(a.dat);
cout << " curso: ";
cin >> a.curso;
cout << " edad: ";
cin >> a.edad;
for (int i = 0; i < 6 ;i++)
{
cout << " nota " << i;
cin >> a.notas[i];
}
}
// estructura por referencia
void leer_profesor(profesor &p)
{
cout << " datos de profesor: " << endl;;
leer_datos(p.dat);
cout << " cargo: ";
cin >> p.cargo;
// estructura por referencia
for (int i = 0; i < 4 ;i++)
{
cout << " asignatura " << i;
cin.getline(p.asignaturas[i],10);
}
}
EJEMPLO 8.9. Parámetrostipoestructur aporvalorafunciones.Seescribelainformacióndelasestructur asdeclaradasenelEjemplo8.6deunalumnoydeunpr ofesor, mediantesendasfunciones.
Lafunción escribir_alumno, escribelainformacióndeunalumnousandolafunción escribir_datos.Estaúltima
funciónescribelosdatosdelaestructura datos.Laescrituradelainformacióndeunprofesorserealizacon escribir_profesor.
void escribir_datos (datos dat)
{
cout << " nombre : " << dat.nombre << endl;
cout << " direccion: " << dat.direccion << endl;
}
void lescribir_alumno(alumno a)
{
cout << " datos de alumno: " << endl;;
escribir_datos(a.dat);
cout << " curso: " << a.curso << endl;
cout << " edad: " << a.edad << endl;
CAPÍTULO 8 Registros (estr ucturas y uniones)
168
for (int i = 0; i < 6 ;i++)
{
cout << " nota " << i << " " << a.notas[i];
}
cout << endl;
}
void escribir_profesor(profesor p)
{
cout << " datos de profesor: " << endl;
escribir_datos(p.dat);
cout << " cargo: " << p.cargo << endl;
for (int i = 0; i < 4 ;i++)
{
cout << " asignatura " << i << " "<< p.asignaturas[i];
}
cout << endl;
};
8.2 Uniones
Lasunionessonsimilaresalasestructurasencuantoqueagrupanaunaseriedev ariables, perolaformadealmacenamiento
esdiferentey, porconsiguiente, susefectossontambiéndiferentes.Unaestructura( struct)permitealmacenarvariablesrelacionadasjuntasyalmacenarlasenposicionescontiguasenmemoria.Lasuniones,declaradasconlapalabrareservadaunion,
almacenantambiénmiembrosmúltiplesenunpaquete;sinembar go, enlugardesituarsusmiembrosunosdetrásdeotros, en
unaunión, todoslosmiembrossesolapanentresíenlamismaposición.Eltamañoocupadoporunauniónsedeterminaasí:
esanalizadoeltamañodecadav ariabledelaunión, elmayortamañodev ariableseráeltamañodelaunión.Lacantidadde
memoriareservadaparaunauniónesigualalaanchuradelav ariablemásgrande.Eneltipo union, cadaunodelosmiembrosdatocompartememoriaconlosotrosmiembrosdelaunión.
Lasintaxisdeunaunióneslasiguiente:
union nombre
{
tipo1 miembro1;
tipo2 miembro2;
...
};
Unarazónparautilizarunauniónesahorrarmemoria.Enmuchosprogramassedebetenerv ariasvariables, perononecesitanutilizarsetodasalmismotiempo.Parareferirsealosmiembrosdeunaunión, seutilizaeloperadorpunto(.), obienel
operador->sisehacedesdeunpunteroaunión.
EJEMPLO 8.10. Definicionesdeuniones, yaccesoconvariablesdiferentes.
#include <cstdlib>
#include <iostream>
using namespace std;
union ejemplo
{
int valor;
char car[2];
} Ejeunion;
CAPÍTULO 8 Registros (estr ucturas y uniones)
169
int main(int argc, char *argv[])
{
cout << " Introduzca un numero entero: ";
cin >> Ejeunion.valor;
cout << " La mitad mas significativa es : ";
cout << (int)Ejeunion.car[1]<< endl;
cout << " La mitad menos significativa es : ">;
cout << (int)Ejeunion.car[0] << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 8.11. Arraydeestructurasquecontieneunaunióndeestructuras.Ununiversitariopuedeserunalumno
ounprofesor.Pararepresentarloseusaunaunion universitario quepuedeserlaestructuraalumno olaestructuraprofesor delosEjemplos8.6, 8.8obien8.9.Seleenyescribenlosdatosdeungrupocompletodeuniver sitarios.
Enlaimplementación, sedeclaraunaestructura datos_grupo quetieneunmiembrointerruptor sw paraindicarsise
almacenaunalumnoounprofesor , enelmiembro persona delaunión universitario.Seusanlasdeclaracionesy
funcionesdelosEjemplos8.6, 8.8, 8.9.Lafunción leer_universitario, leeun universitario, retornandoelresultadoenelparámetroporreferencia u, recibiendolainformación, desiesun profesor oun alumno enlavariable
lógica sw.Lafunción escribir_universitario, escribeel universitario, querecibecomodatoenelparámetro
porv alor u.Lainformacióndeserun profesor oun alumno estádadaporlav ariablelógica sw.Lasfunciones
leer_datos_grupo y escribir_datos_grupo, leenyescribenrespecti vamentelosdatosdeungrupocompletode
universitariosenunaarrayquesepasacomoparámetro.
#include <cstdlib>
#include <iostream>
#define max 100
// máximo número de universitarios de un grupo.
using namespace std;
...
...
union universitario
{
//un universitario, puede ser un alumno o un profesor
alumno a;
profesor p;
};
struct datos_universitario
{
bool sw;
// si es true la persona univesitaria es un alumno.
universitario persona;
};
void leer_universitario(universitario &u, bool sw)
{
if (sw)
leer_alumno(u.a);
else
leer_profesor(u.p);
}
CAPÍTULO 8 Registros (estr ucturas y uniones)
170
void escribir_universitario(universitario &u, bool sw)
{
if (sw)
escribir_alumno(u.a);
else
escribir_profesor(u.p);
}
void leer_datos_grupo (datos_universitario grupo[], int n)
{
char ch;
cout<< " lectura datos grupo \n";
for (int i = 0; i < n; i++)
{
do
{
cout <<" elija a alumno p profesor del universitario "<<i<<endl;
cin >> ch;
ch = toupper( ch); // mayúscula
} while ( ch != 'A' || ch != 'P');
grupo[i].sw = ch == 'A';
leer_universitario(grupo[i].persona, grupo[i].sw);
}
}
void escribir_datos_grupo (datos_universitario grupo[], int n)
{
cout<< " visualización datos grupo \n";
for (int i = 0; i < n; i++)
{
cout << " universitario " << i << endl;
escribir_universitario(grupo[i].persona, grupo[i].sw);
}
}
int main(int argc, char *argv[])
{
datos_universitario grupo[max];
leer_datos_grupo(grupo, max);
escribir_datos_grupo(grupo, max);
system("PAUSE");
return EXIT_SUCCESS;
}
8.3. Enumeraciones
Untipoenum esuntipodefinidoporelusuarioconconstantesdenombredetipoentero.Enladeclaracióndeuntipo enum se
escribeunalistadeidentificadoresqueinternamenteseasocianconlasconstantesenteras0, 1, 2, ...Formatosdedeclaración.
enum
{enumerador1, enumerador2, ...enumeradorn};
enum nombre
{enumerador1, enumerador2, ...enumeradorn};
CAPÍTULO 8 Registros (estr ucturas y uniones)
171
Enladeclaracióndeltipo enum puedenasociarsealosidentif icadoresvaloresconstantesenvezdelaasociaciónquepor
defectosehace(0, 1, 2...).Paraelloseutilizaesteformato:
enum nombre
{
enumerador1 = expresión_constante1,
enumerador2 = expresión_constante2,
...
enumeradorn = expresión_constanten
};
EJEMPLO 8.12. Usostípicosde enum: Interruptor, colores, semanaymenu.
enum Interruptor
{ // valor por defecto de On 0, y de Off 1
On;
Off;
};
// On, activado
// Off desactivado
enum colores
{ // cambio de valores por defecto
Rojo = 7, Anaranjado = 6 , Verde =4, Azul = 4 Anyl =3, Violeta = 2;
};
enum semana
{
lunes, martes, miércoles, jueves, viernes, sabado domingo
}
// uso de enum para la creación de un menu
#include <cstdlib>
#include <iostream>
using namespace std;
enum tipo_operacion {anadir, borrar, modificar, visualizar};
....
int main(int argc, char *argv[])
{
tipo_operación op;
...
switch (op)
{
case anadir:
anade_estructura(argumentos);
break;
case borrar:
borra_estructura(argumentos);
break;
case modificar:
modifica_estructura(argumentos);
break;
case visulizar:
visualiza_estructura(argumentos);
break;
default:
escribe_error(argumentos);
}
system("PAUSE");
return EXIT_SUCCESS;
}
Eltamañoenbytesdeunaestructura, deunauniónodeuntipoenumeradosepuededeterminarconeloperador sizeof.
CAPÍTULO 8 Registros (estr ucturas y uniones)
172
8.4. Sinónimo de un tipo de dato typedef
Untipodedato typedef permiteaunprogramadorcrearunsinónimodeuntipodedatodef inidoporelusuarioointegralya
existente.Noesnuevotipodedatosinounsinónimodeuntipoe xistente.Laventajadetypedef esquepermitedarnombres
detiposdedatosmásacordesconloquerepresentanenunadeterminadaaplicación, yayudaalatransportabilidad.
EJEMPLO 8.13. Usostípicosde typedef.
typedef double Longitud;
typedef char caracter;
//el tipo double se denomina también Longitud
//tipo char se denomina además caracter
typedef char* String;
// String alamcena puntero a carácter, cadena
typedef struct datos1
{
char nombre[20];
float salario;
} nuevosdatos;
Laestructuratienedosnombressinónimos.Puedendeclararsev ariablescomo:
datos1 dat;
nuevosdatos dat1;
struct registro_operacion
{
long numero_cuenta;
float cantidad;
TipOperacion operacion;
Fecha f;
Tiempo t;
};
typedef struct registro_operacion RegistrOperacion;
//Se tienen dos nombres sinónimos.
8.5. Campos de bit
EllenguajeC++permiterealizaroperacionesconlosbitsdeunapalabra.Uncampodebitsesunconjuntodebitsadyacentes
dentrodeunapalabraentera.Conlos camposdebit, C++permiteaccederaunnúmerodebitsdeunapalabraentera.Lasintaxisparadeclararcamposdebitssebasaenladeclaracióndeestructuras.Elformatogenerales:
struct identificador_campo {
tipo nombre1:longitud1;
tipo nombre2:longitud2;
tipo nombre3:longitud3;
.
.
.
tipo nombren:longitudn;
};
CAPÍTULO 8 Registros (estr ucturas y uniones)
173
donde tipo hadeserentero, int;generalmente unsigned int. longitud eselnúmerodebitsconsecuti vosquesetoman.
Aldeclararcamposdebits, lasumadelosbitsdeclaradospuedee xcedereltamañodeunentero;enesecasoseemplealasiguienteposicióndealmacenamientoentero.Noestápermitidoqueuncampodebitssolapeloslímitesentredos int.
Aldeclararunaestructurapuedehabermiembrosqueseanv ariablesyotroscamposdebits.Loscamposdebitsseutilizanpararutinasdeencriptacióndedatosy , fundamentalmente, paraciertosinterfacesdedispositivosexternos.
Loscamposdebitstienenciertasrestricciones.Así, nosepuedetomarladireccióndeunavariablecampodebits;nopuedehaberarraysdecamposdebits;nosepuedesolaparfronterasde int.Dependedelprocesadorelqueloscamposdebitsse
alineendeizquierdaaderechaodederechaaizquierda(convienehacerunacomprobaciónparacadaprocesador, utilizarpara
ellounaunion convariableenteraycamposdebits).
EJEMPLO 8.14. Definicióndeestructurasconcamposdebit.
struct ejemplo
{
char nombre[50], dirección[30], telefono[10];
int edad:4;
// edad menor o igual que 127 años
int sexo:1;
// 1= hombre 0= mujer
int codigo:3;
// codigo de departamento < 8
int contrato:2;
// hay cuatro tipos de contrato
};
EJEMPLO 8.15. Campodebitsyuniónparavisualizarladecodificaciónenbitsdecualquiercarácterleídoporteclado.
Sedeclarauntipoestructuracampodebits, contantoscamposcomobitstieneunbyte, queasuv ezeselalmacenamientodeuncarácter.Sedecodificadeclarandounaunion entreunavariablecarácteryunavariablecampodebitsdel
tipoindicado.
#include <cstdlib>
#include <iostream>
using namespace std;
struct byte {
unsigned int a: 1;
unsigned int b: 1;
unsigned int c: 1;
unsigned int d: 1;
unsigned int e: 1;
unsigned int f: 1;
unsigned int g: 1;
unsigned int h: 1;
};
union charbits
{
char ch;
byte bits;
}caracter;
void decodifica(byte b)
{
// Los campos de bits se alinean de derecha a izquierda, por esa
//razón se escriben los campos en orden inverso
cout << b.h << b.g << b.f << b.e << b.d << b.c << b.b << b.a << endl;
}
CAPÍTULO 8 Registros (estr ucturas y uniones)
174
int main(int argc, char *argv[])
{
cout << "Teclea caracteres. Para salir caracter X \n";
cout << "caracter ascii binario\n";
do
{
cin >> caracter.ch;
cout << caracter.ch << "
"<< (int)caracter.ch << "
: ";
decodifica(caracter.bits);
}while (toupper(caracter.ch)!='X');
// mayúsculas
system("PAUSE");
return EXIT_SUCCESS;
}
EJERCICIOS
8.1.
Declararuntipodedatospar arepresentarlasestacionesdelaño.
8.2.
Escribirunfunciónquede vuelvalaestacióndelañoquesehaleídodelteclado.Lafuncióndebedeserdeltipodeclar adoenelEjercicio8.1.
8.3.
EscribirunafunciónquerecibaeltipoenumeradodelEjercicio8.1ylovisualice.
8.4.
Declararuntipodedatoenumer adopararepresentarlosmesesdelaño, elmesenerodebedeestarasociadoaldatoentero1, yasísucesivamentelosdemásmeses.
8.5.
Encuentreloserroresdelsiguientecódigo:
#include <stdio.h>
void escribe(struct fecha f);
int main()
{
struct fecha
{
int dia;
int mes;
int anyo;
char mes[];
} ff;
ff = {1,1,2000,"ENERO"};
escribe(ff);
return 1;
}
8.6.
¿Con typedef sedeclarannuevostiposdedatos, obienpermitecambiarelnombredetiposdedatosyadeclar ados?
CAPÍTULO 8 Registros (estr ucturas y uniones)
175
PROBLEMAS
8.1.
Escribirunprogramaqueleayescribalainformaciónde100clientesdeunadeterminadaempresa.Losclientestienenun
nombre, elnúmerodeunidadessolicitadas, elpreciodecadaunidadyelestadoenqueseencuentr a: moroso, atrasado,
pagado.
8.2.
Añadiralprogramaanteriorunafunciónquepermitamostr arlafacturadetodoslosclientesdecadaunadelascate goríasmoroso, atrasadoopagado.
8.3.
ModificarelprogramadelosProblemas8.1y8.2paraobtenerlossiguienteslistados:
• Clientesenestadomoroso, confacturainferioraunacantidad.
• Clientesenestadopagadoconfacturamayordeunadeterminadacantidad .
8.4.
Sedesearegistrarunaestructura PersonaEmpleado quecontengacomomiembr oslosdatosdeuna persona elsalarioy
elnúmerodehorastrabajadasporsemana.Una persona, asuvezesotraestructuraquetienecomomiembroselnombre,
laedad, laaltura, elpeso, ylafechadenacimiento.Porsuparte, lafechadenacimientoesotraestructuraquecontieneel
día, elmesyelaño.Escribirfuncionespar aleeryescribirunempleadodetipo PersonaEmpleado.
8.5.
Escribirfuncionesquepermitanhacerlasoperacionesdesuma, restaymultiplicaciónycocientedenúmeroscomplejosen
formabinómica, a+bi.Eltipocomplejohadedef inirsecomounaestructura.
8.6.
AñadiralProblema8.5funcionesparaleeryescribirnúmeroscomplejos, yunprogramaquepermitainteractivamenterealizaroperacionesconnúmeroscomplejos.
8.7.
Escribiruntipodedatospar arepresentarnúmeroscomplejosenformapolar(módulo, argumento), ycodificardosfunciones, parapasarunnúmerocomplejodeformapolarabinómicaydeformabinómicaapolarr espectivamente.
8.8.
Escribirfuncionesquepermitanhacerlasoper acionesdemultiplicaciónycocienteypotenciadenúmer oscomplejosen
formapolar.
8.9.
Sequiereinformatizarlosresultadosobtenidosporlosequiposdebaloncestoydefútboldelalocalidadalcarr eñaLupiana.Lainformacióndecadaequipo:
• Nombredelequipo.
• Númerodevictorias.
• Númerodederrotas.
Paralosequiposdebaloncestoañadirlainformación:
•
•
•
•
Númerodeperdidasdebalón.
Númeroderebotescogidos.
Nombredelmejoranotadordetriples.
Númerodetriplesdelmejortriplista.
Paralosequiposdefútbolañadirlainformación:
•
•
•
•
•
Númerodeempates.
Númerodegolesafavor.
Númerodegolesencontra.
Nombredelgoleadordelequipo.
Númerodegolesdelgoleador.
Escribirunprogramaparaintroducirlainformaciónparatodoslosequiposintegrantesenambasligas.
CAPÍTULO 8 Registros (estr ucturas y uniones)
176
8.10. ModificarelprogramadelEjercicio8.9paraobtenerlossiguientesinformesodatos.
•
•
•
•
Listadodelosmejorestriplistasdecadaequipo.
Máximogoleadordelaligadefútbol.
Suponiendoqueelpartidoganadosontr espuntosyelempate1punto: equipoganadordelaligadefútbol.
Equipoganadordelaligadebaloncesto.
8.11. Unpuntoenelplanosepueder epresentarmedianteunaestructuracondoscampos.Escribirunprogramaquerealicelas
siguientesoperacionesconpuntosenelplano.
• Dadosdospuntoscalcularladistanciaentr eellos.
• Dadosdospuntosdeterminarelpuntomediodelalíneaquelosune .
8.12. LosprotocolosIPdedireccionamientoderedInternetdefinenladireccióndecadanododeunaredcomounenterolargo,
perodichoformatonoesmuyadecuadopar alosusuarios.Paralavisualizaciónalosusuariossesuelensepar arloscuatrobytesseparándolosporpuntos.EscribirunafunciónquevisualiceunenterolargocomounadireccióndereddelosprotocolosdeInternet(cuatrobytesdelenterolargoseparadosporpuntos).
8.13. Unalibreríadeseatenerelin ventariodelibr os.Paraelloquier ecrearunabasededatosenlaquesealmacenanlasiguienteinformaciónporlibro: títulodellibro;lafechadepublicación;elautor;elnúmerototaldelibrosexistentes;elnúmerototaldelibrosexistentesenpedidos;elpreciodeventa.Escribirfuncionesquepermitanleerlosdatosdelabasede
datosyvisualizarlabasededatos.
SOLUCIÓN DE LOS EJERCICIOS
8.1.
Unaformaderealizarloesmedianteuntipoenumeado.
enum Estaciones {Primavera = 1, Verano = 2, Otonyo = 3, Invierno = 4};
8.2.
Eltipoenumeradoasociaenterosanombressimbólicos, peroestosnombressimbólicosnopuedenserleídosdesdeunafunciónestándarcomocin.Porconsiguiente, lafunciónquesecodifialeer_Estacion leelosvaloresenterosylostraducea
losnombressimbólicosquesecorrespondensegúnladefinicióndeltipoenumerado.
Estaciones Leer_Estacion (void)
{
int est;
cout << " Introduzca el número de la estación del año: ";
cout << " 1 - Primavera\n";
cout << " 2 - Verano\n";
cout << " 3 - Otoño\n";
cout << " 4 - Invierno\n";
cin >> est;
switch (est)
{
case 1: return
case 2: return
case 3: return
case 4: return
Primavera;
Verano;
Otonyo;
Invierno;
CAPÍTULO 8 Registros (estr ucturas y uniones)
177
default: cout << "Entrada errónea \n";
}
}
8.3.
Lafunción Escribir_Estacion transformalasalidadeltipoenumer adoeninformaciónlegibleparaelusuario.
void Escribir_Estacion (Estaciones est )
{
switch (est)
{
case Primavera: cout <<" Primavera\n";
case Verano: cout << " Verano\n";
case Otonyo: cout << " Otonyo\n";
case Invierno: cout << " Invierno\n";
}
}
8.4.
Unasoluciónes:
enum meses {Enero = 1, Fefrero = 2, Marzo = 3, Abril = 4, Mayo = 5,
Junio = 6, Julio = 7, Agosto = 8, Septiembre = 9,
Octubre = 10, Noviembre = 11, Diciembre = 12};
8.5.
Lainicializacióndeunaestructurapuedehacersesolamentecuandoesunavariableestáticaoglobal.Nosepuededef inir
unarraydecaracteressinespecificareltamañoy, además, haycoincidenciadenombres.Lamayorpartedeloscompiladorestampocopermiteasignarvaloresaestructurastalycomoquedareflejado;hayquehacerlomiembroamiembro.Seríaconvenientehacerlomejorenlainicialización.P orúltimo, lafunción escribe tienecomoparámetr olaestructur a
fecha, quenoesglobal, yaquesedeclaralocalmenteenelprogramaprincipal.Unacodificaciónpodríaserlasiguiente:
#include <stdio.h>
struct fecha
{
int dia;
int mes;
int anyo;
char mesc[10];
} ff = {1,1,2000,"ENERO"};
void escribe(fecha f)
{
....
}
// declaración global
// se cambia el nombre
// incialización
// fecha ya está declarada
int main()
{ ....
escribe(ff);
return 1;
}
8.6.
LasentencianoañadeningúntipodedatosnuevosalosyadefinidosenellenguajeC++.Simplementepermiterenombrar
untipoyae xistente, inclusoaunqueseaunnue vonombreparauntipodedatosbásicodellenguajecomo int o char o
float.
CAPÍTULO 8 Registros (estr ucturas y uniones)
178
SOLUCIÓN DE LOS PROBLEMAS
8.1.
Sedefineunaestructurasiguiendolaespecificacióndelproblemayconlamismasehadeclaradounarrayquedemax clientesquealmacenalainformacióndecadaunodelosclientes.Lafunciónleer_clientes solicitaalusuariolainformación
decadaunodelosclientes,
medianteunb ucle for quer ecorrelosvalor es 0,1,2,...,max-1.Lafunción
escribir_clientes, visualizalainformaciónalmacenadaenlaestructur adedatos.Elpr ogramaprincipalllamaalas
dosfuncionesanteriores.
La codificación de este problema se encuentra en la página Web del libro.
8.2.
Seprogramalafunciónfactura_clientes querecibecomoparámetroslalistadeclientesylainformacióndelestadode
losclientesquedebenservisualizadas.Estafunciónvisualizalainformacióndetodoslosclientescuyoestadocoincidacon
elcontenidodelparámetroporvalor est, asícomoelimportedelafactur a.Parahacerlo, serecorreelarrayconunbuclefor comprobandolacondición.Tambiénseprogramalafuncion facturacion_clientes, quemedianteunmenúsolicitaalusuarioeltipodeclientesquequier equesevisualicelafactur a, yrealizalallamadacorrespondientealafuncion
factura_clientes.
La codificación de este problema se encuentra en la página Web del libro.
8.3.
Pararesolverambosapartadosesnecesarior ecorrermedianteunb ucle for todoslosclientesalmacenadosenlaestructuradedatos, yvisualizaraquellasestructur asylasfactur asasociadasquecumplanlascondicionesindicadas.Sepr ogramanlasfunciones clientes_morosos_menor y clientes_pagado_mayor, queresuelvencadaunaloscorr espondientesapartados.
La codificación de este problema se encuentra en la página Web del libro.
8.4.
Setratadeunprogramadelecturayvisualizacióndeestructur asanidadasmediantedosfunciones.Primer amente, sedeclaralaestructurafecha, conlosatributosindicados.Posteriormente, sedeclaralaestructurapersona, consusatributos,
y, porúltimo, laestructurapersona_empleado.Lafunciónentrada tienecomoparámetroporreferenciaunapersonaempleadope, enlaquesealmacenayretornatodalainformaciónqueintroduceelusuario.Porsupartelafunción muestra,
presentalosvaloresquerecibeenelparámetroporvalorenlaconsola.Laestructur adelosregistrosanidadospuedevisualizarseenlasiguientefigura:
Persona empleado:
Empleado:
Nombre
Altura
Edad
Peso
Fecha:
Dia
Mes
anyo
Salario
horas_por_semana
La codificación de este problema se encuentra en la página Web del libro.
8.5.
Unnúmerocomplejoestáformadopordosnúmerosreales, unodeloscualessedenominaparte real yelotroparte imaginaria.Laformanormalderepresentarenmatemáticasunnúmerocomplejoeslasiguiente: real +i*imaginario (for–1).Debimabinómica).Dondeelsímboloisedenomina“unidadima ginaria” ysimbolizalaraízcuadradade–1(i =œw
doasunaturalezacompuesta, unnúmerocomplejoserepresentadeformanaturalporunaestructuracondoscamposde
tiporealquecontienenlaparte real yla imaginaria delnúmeroconcreto.Lasfuncionesquesecodif icantraducenlas
operacionesmatemáticastalycomosedef inenenlaaritméticadenúmer oscomplejosrepresentadosmedianteunaestru-
CAPÍTULO 8 Registros (estr ucturas y uniones)
179
tura complejo quetienesuparte real ysuparte imaginaria.Lasfuncionesmatemáticasdef inidassobrecomplejosen
formabinómicasonlassiguientes:
(a +bi)+(c +di)=(a +b)+(c +d)i
(a +bi)–(c +di)=(a –b)+(c –d)i
(a +bi)∗ (c +di)=(a ∗ c –b ∗ d)+(a ∗ d +c ∗ b)i
(a +bi)/(c +di)=
a ∗c +b ∗ d
b ∗b +d ∗ d
+
–a ∗d +c ∗ b
b ∗b +d ∗ d
i
La codificación de este problema se encuentra en la página Web del libro.
8.6.
Lafunción leer_complejo solicitayleeunnúmerocomplejo.Lainformaciónlar etornaenunparámetroporreferencia.
Lafunción escribir_complejo, visualizalaparterealylaparteimaginariadelnúmerocomplejoquerecibecomoparámetroporvalor. elige_opcion_entre, recibecomoparámetrodosnúmerosenteros, x e y, yretornaotronúmeroentero
quenecesariamentedebeestarentreellos.Estafunciónesllamadaporlafunción menu ygarantizaqueelusuarioeligeun
númerodentrodelrango0, 5parapoderrealizarlasllamadasalascorr espondientesfuncionesdetr atamientodenúmeroscomplejosenformabinómicatalycomopideelenunciado.
La codificación de este problema se encuentra en la página Web del libro.
8.7.
Unnumerocomplejodadoenformapolar , serepresentaporsumóduloysuar gumento.Parapasarunnúmer ocomplejo
deformabinómicaaformapolarseusalasiguientetr ansformación: lapartereal=modulo*seno(ar gumento);laparte
imaginaria=modulo*cos(argumento).Lafunción pasar_a_binomica, realizalatransformaciónindicada.
Parapasardeformabinómicaapolarseusalasiguientetr ansformación: elmoduloesigualalar aízcuadradadela
sumadeloscuadr adosdelaparter ealeimaginaria, yelargumentoeselarcotangentedelaparter ealdivididoentrela
parteimaginaria.Debidoaqueelar cotangentenodistingueentreprimerytercercuadranteasícomoentreelsegundoy
cuartocuadrante, esnecesariotenerencuentaquesilaparteima ginariaesnegativa, entonceselargumentodebeserincrementadoenelvalordepi =atag(–1.0).Lafunción pasar_a_polar, realizalatransformación.
P(real, imaginaria)
módulo
real
argumento
real = módulo ∗ cos(argumento)
imaginaria = módulo ∗ seno(argumento)
imaginaria
La codificación de este problema se encuentra en la página Web del libro.
8.8.
Deacuerdoconlasfórmulasmatemáticasdetr atamientodenúmeroscomplejosenformapolarsetieneque: paramultiplicardosnúmeroscomplejosenformapolar, bastaconmultiplicarsusmódulosysumarsusar gumentos;paradividirlos
bastaconcalcularelcocientedelosmódulos, yrestarlosargumentos;paraelevaraunapotenciaunnúmerocomplejoen
formapolar, bastaconelevarelmóduloalapotenciaindicada, ymultiplicarelargumentoporlapotenciacorrespondiente.
La codificación de este problema se encuentra en la página Web del libro.
8.9.
Sedefinelaestructur a equipo conlainformacióncorr espondienteycomúnalasdosestructur as, tantode baloncesto,
comode futbol.Setratapuesdedef inirdosestructurasqueanidenensuinteriorlaestructur a equipo.Secodificauna
funciónleer_equipo, quesolicitaalusuariolainformacióncorrespondienteaunequipoylaretornaenunparámetropor
referencia.Lasfunciones leer_Equipo_Baloncesto y leer_Equipo_Futbol, realizanlaoper aciónanálo gaalade
leer_equipo, peroahorasolicitanlainformacióndeunequipodebaloncesto, odeunequipodefúbolr espectivamente.
CAPÍTULO 8 Registros (estr ucturas y uniones)
180
Sedefinendosarraydeestructurasdetamaño max paraalmacenarlainformacióncorr espondientedelosequiposdefútbolylosequiposdebaloncesto.Lainformacióncorrespondienteacadaequipoessolicitadaensendosbuclesfor delprogramaprincipal: unoparalosequiposdefútbolyotr oparalosequiposdebaloncesto.
La codificación de este problema se encuentra en la página Web del libro.
8.10. Lafunción mejores_Triplistas recorreelarraydeequiposdebaloncestoyvisualizandoelnombr edelmejortriplista.
Eslafunciónmaximo_Goleador laquemedianteunbuclevorazencuentraelíndicedelmáximogoleadordelarraydeequiposdefútbol.Paracalcularelequipoganadordefútbol equipo_Ganador_Futbol seobtienenlospuntosdecadaequipo
yseencuentr aelequipoconmayornúmer odepuntosalmacenándoloenlavariable maxpuntos.Estemismopr ocesose
realizaparalafunciónequipo_Ganador_Baloncesto.Semuestralacodificacióndelasfunciones.Lasllamadasalasmismashayquer ealizarlasmedianteunparámetr oquedebeserelnombr edelarr ayquecontienelosr egistrosdetodoslos
equipostantodefútbol, comodebaloncesto.
La codificación de este problema se encuentra en la página Web del libro.
8.11. Lascoordenadasdeunpuntoenelplanosondosnúmer osrealesqueserepresentaenesteproblemacomounaestructura
punto, consusdoscoordenadas, xey.Secodificanlasfunciones:
• leer notieneningúnparámetr o.Realizalalectur adelosdatosdeunpuntomediantelafunción cin, queleelosdatos
decadaunodesusmiembrosparaposteriormenteretornarelresultadoenlapropiafuncióndefinidadetipopunto.
• Ladistanciaentredospuntossecalculaporlafórmulacorr espondientedematemáticasqueeslasiguiente
(x1 –x2)2 +w
(y1 –y2)2
dis =œw
Lafuncióndistancia, recibecomoparámetrosporvalorlosdospuntos, ycalculaladistanciacorrespondientemediantelaexpresiónanteriormenteexpresada.
• Elpuntomedioseobtienesumandolasdoscoordenadasxdecadaunodelospuntosylasdoscoordenadasydelospuntosydividiendoelresultadoentredos.Másconcretamentelaexpresiónmatemáticaeslasiguiente:
1
x1 +x2 y1 +y2
,
2
2
2
Eslafunción medio laencargadaderetornarelpuntomediodelosdospuntosalmacenadosensendasestructur asque
recibecomoparámetrolaencargadadecodificarelresultado.
La codificación de este problema se encuentra en la página Web del libro.
8.12. LaconversiónpedidaessencillasiseusalacaracterísticadelasunionesdeC++paraaccederaunainformacióndeformadiferente.Eslafunción direccion_IP, laquerecibecomoparámetroelenterolargo d yvisualizaladir ecciónIP, en
laformaclásicaenlaquenormalmentesepr esentaalusuario.Esteenterolargod recibidocomoparámetro, loalmacena
enunauniónalaquesepuedeaccederconunafunciónmiembr o enterolargo, obienconunarr ayde 4 caracteressin
signo( unsigned char elbitdesignoaltoactivadonoseconsider anegativo).Cadaunodeestos 4 caracteres, queinternamentesecorrespondenconunbyte representaunnúmeronaturalquepuedeserescritocomotal.Sientredosbytesconsecutivosseescribe, además, unpunto, setienelaescrituradelprotocolodeInternet.Observación: estafunciónpuederetornarunacadenadecar acteresdondesealmaceneladir ecciónIP, yutilizarlaposteriormenteenotr afunción, yhacer
máseficienteelcódigodeejecución.
La codificación de este problema se encuentra en la página Web del libro.
8.13. Sedeclaralaestructura libro ylasfuncionesmiembr odefinidasenelenunciado.Elin ventariosealmacenaenelarr ay
deregistrosa detipolibro.Elnúmeromáximodelibrossedefinecomo100enlaconstante max.Lavariable total indica
encadamomentoelnúmer ototaldelibrosquehayenelin ventario.Lafunción leer_inventario, recibecomoparámetosporreferenciaelarraydelibros a, asícomolavariable total.Estafuncióninicializa total a 0, eincrementalava-
CAPÍTULO 8 Registros (estr ucturas y uniones)
181
riabletotal, cadavezqueleelosdatosdeunlibro.Elfinaldelaentradadedatos, vieneindicadoportomar total elvalorde max, obienquelarespuestadelusuariosea S, unavezquesesolicitalaposibilidaddecontinuar .Elbuclefor que
controlalaentradadedatosterminacuandosehacefalsalacondición (resp == 'S') && (total < max).Lafunción
escribir_inventario, seencargadevisualizarlainformaciónalmacenadaenelarr aya querecibecomoparámetro.El
númerodedatosquecontieneelin ventariolorecibelafunciónenelparámetroporvalor total.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
8.1.
Diseñarunaestructuraderegistroparaunabasedeempleadosquecontengacamposquecodif iquenelestado
civildelempleado, else xoyeltipodecontratoutilizandolamenorcantidaddememoriaposible, esdecir,
utilizandocamposdebits.
8.3.
Diseñarunaestructuraquecontengainformaciónde
operacionesfinancieras.Estaestructuradebeconstarde
unnúmerodecuenta, unacantidaddedinero, eltipode
operación(depósitooretiradadefondos)ylafechay
horaenquelaoperaciónseharealizado.
8.2.
Enlabasededatosanteriorcrearuncampodetipoenumeradoquepermitadeterminareldepartamentoalque
perteneceunempleado, utilizandounnombresimbólico.
8.4.
Escribirunenumeradopararepresentarlossignosdel
zodíaco.Escribirfuncionesquepermitanasignarv aloresaltipoenumeradoye xtraervalores(lecturayescrituradevaloresdeltipoenumerado).
8.5.
Suponerquesetieneunarrayquealmacenalainformacióndelosempleadosdeunagranempresa.Decada
empleadoseguardaelnombre, losdosapellidos, elnúmerodelaSeguridadSocial, elNIF, laedad, eldepartamentoenelquetrabajaylaantigüedadenlaempresa.
Escribirunprogramaenelqueseordeneelarrayporel
campoprimerapellidoyencasodequeelprimerapellidocoincidaporelse gundoapellido.Siambosapellidoscoincidenparaalgúnregistro, ordenarentoncespor
elnombre.Notavercapítulodeordenación.
8.6.
UtilizandoelarraydelProblema8.5escribirunprogramaquepermitaaunusuariopormediodeunmenúelegirunodeloscampospararealizarunabúsquedapordichocampoenelarraydere gistros.
8.7.
Escribirunprogramaauxiliarquepermitaañadirnuevos
camposalatabladeempleados,
comoporejemplo,
sueldoanualyporcentajederetencionesdeimpuestos.
Unavezmodificadoelarraydeestructuras, escribirun
programaquepermitaaunusuarioele girunrangode
registrosdeempleadosespecificandounapellidoinicial
PROBLEMAS PROPUESTOS
8.1.
Escribirunprogramaparacalcularelnúmerodedías
quehayentredosfechas;declararfechacomounaestructura.
8.2.
Unnúmeroracional secaracterizaporelnumeradory
denominador.Escribirunprogramaparaoperarconnúmerosracionales.Lasoperacionesadefinirsonlasuma,
resta, multiplicaciónydivisión;ademásdeunafunción
parasimplificarcadanúmeroracional.
8.3.
Escribirunprogramaquegestioneunaagendadedirecciones.Losdatosdelaagendasealmacenanenmemoriaenunarraydeestructuras, cadaunadelascualestienelossiguientescampos: nombre, dirección, teléfono
fijo, teléfonomóvil, direccióndecorreoelectrónico.El
programadebepermitirañadirunanue vaentradaala
agenda, borrarunaentrada, buscarpornombreyeliminarunaentradadeterminadaporelnombre.
8.4.
Suponerquesetienendosarraysdeltipodescritoenel
problemapropuesto8.1.CodificarunprogramaenC++
quelosunaenunosolo, eliminandolosduplicadosque
puedanexistirentrelosdos.
CAPÍTULO 8 Registros (estr ucturas y uniones)
182
yotrofinal, oundepartamentoconcreto, yproduzcaen
lasalidalasumatotaldelossueldosqueselespagana
losempleadosseleccionados.
8.8.
Escribirunprogramaquepermitaelaboraruninformea
partirdelarraydeestructurasanteriorconelsiguiente
formato.Cadapáginacontendrálosempleadosdeun
solodepartamento.Alcomienzodecadapáginaseindicapormediodeunacabeceracadaunodeloscampos
queselistanyaldepartamentoquecorrespondeellistado.Loscamposaparecenjustif icadosaladerechaen
cadacolumna.
CAPÍTULO 9
Cadenas
Introducción
C++notienendatospredefinidostipocadena(string).Ensulugar, C++, manipulacadenasmediantearraysdecaracteresque
terminanconelcarácternulo ASCII ('\0').Unacadena seconsideracomounarrayunidimensionaldetipo char o unsigned char.Enestecapítuloseestudiantemastalescomo: cadenasenC++;lecturaysalidadecadenas;usodefuncionesdecadenadelabibliotecaestándar;asignacióndecadenas;operacionesdi versasdecadena(longitud, concatenación, comparación
yconversión);localizacióndecaracteresysubcadenas;in versióndeloscaracteresdeunacadena.
9.1. Concepto de cadena
Unacadena esuntipodedatocompuesto, unarraydecaracteres( char), terminadoporuncarácternulo ('\0'), NULL (Figura9.1).Unacadenaes "ABCD" (tambiénllamadaconstantedecadena oliteraldecadena).Enmemoriaestacadenaconstade
cincoelementos: 'A', 'B', 'C', 'D' y '\0', odeotramanera, seconsideraquelacadena "ABCD" esunarraydecincoelementosdetipo char.Elvalorrealdeunacadenaesladireccióndesuprimercarácterysutipoesunpunteroa char.
a
E
j
e
m
p
l
o
d
e
c
a
d
e
n
a
b
E
j
e
m
p
l
o
d
e
c
a
d
e
n
a
a
A
B
C
D
b
A
B
C
D
\0
\0
Figura 9.1. a) array de caracteres; b) cadena de caracteres.
Elnúmerototaldecaracteresdeunarrayessiempreigualalalongituddelacadena más1.Lasfuncionesdeclaradas
enelarchivodecabecera <iostring> seutilizanparamanipularcadenas.
183
CAPÍTULO 9 Cadenas
184
Declaración de cadenas. Lascadenassedeclarancomolosrestantestiposdearrays.Eloperadorpostf ijo [] contieneeltamañomáximodelobjeto.Eltipobase, naturalmente, eschar, obien unsigned char:
char texto[80];
char orden[40];
unsigned char datos;
//una línea de caracteres de texto
//cadena para recibir una orden del teclado
// activación de bit de orden alto
Eltipo unsigned char puedeserdeinterésenaquelloscasosenqueloscaracteresespecialespresentespuedantenerel
bitdeordenaltoactivado.
Aveces, sepuedeencontrarunadeclaracióncomoésta: char *s;.¿Esrealmenteunacadenas?No, noes.Esunpunteroauncarácter(elprimercarácterdeunacadena).Perolascadenaspuedengestionarsecomopunteros, yaqueun
punteroa char, puedeserunarraydecaracteres.
Inicialización de variables tipo cadena. Lascadenasdecaracterespuedeninicializarseenelmomentodeladeclaracióntal
ycomoindicanlossiguientesejemplos.
char alfa[81] = "Esto es una cadena de caracteres";
char cadenatest[] = "¿Cuál es la longitud de esta cadena?";
Lacadena alfa puedecontenerunmáximode80caracteresmáselcarácternulo.Lainicializaciónnopuederealizarse
conunacadenadelongitudsuperior.Lasegundacadena, cadenatest, sedeclaraconunaespecificacióndetipoincompletay
secompletasóloconelinicializador.Dadoqueenelliteralhay36caracteresyelcompiladorañadeelcarácter '\0', untotal
de37caracteresseasignarána cadenatest.Unacadenanosepuedeinicializarfueradeladeclaración.P araasignarunacadenaaotrahayqueutilizarlafunción strcpy( ).Lafunción strcpy( ) copialoscaracteresdelacadenafuentealacadenadestino.
EJEMPLO 9.1. Lascadenasterminanconelcarácternulo.Elsiguientepr ogramamuestraqueelcarácter NULL
('\0') seañadealacadenayqueesnoimprimible .
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char S[]="Lucas"; // cadena estática inicializada a 5 caracteres y nulo
char S1[12] = " nombre:";
cout << S1 << endl << endl;
for (int i = 0; i < 6; i++)
cout << " S[" << i << "] = " << S[i] << "\n";
system("PAUSE");
return EXIT_SUCCESS;
}
Enelresultadodeejecuciónaparece S[5] =carácternulo queesnoimprimible:
CAPÍTULO 9 Cadenas
185
9.2. Lectura de cadenas
Lalecturausualdedatosconelobjeto cin yeloperador >>, siseaplicaadatosdecadenaproduceanomalías, yaqueelobjetocin terminalaoperacióndelecturasiemprequeseencuentraunespacioenblanco.Elmétodorecomendadoparalalectura
decadenasesutilizarunafuncióndenominada getline(), enunióncon cin, enlugardel operador>>.Lafunción getline
permitea cin leerlacadenacompleta, incluyendocualquierespacioenblanco.
EJEMPLO 9.2. Esteprogramamuestracomo cin leedatosdetipocadena, ycómolohace cin.getline.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char Ejemplo[31];
// Definir array de caracteres
cout << " introduzca frase \n ";
cin.getline(Ejemplo,30);
// lectura de cadena completa
cout << "\t\"" << Ejemplo << "\"\n";
cout << " introduzca otra frase \n ";
cin >> Ejemplo;
// lectura de palabra hasta encontrar blanco
cout << "\t\"" << Ejemplo << "\"\n";
system("PAUSE");
return EXIT_SUCCESS;
}
Resultadodeejecución:
Elobjeto cin delflujodeentradaincluyeentreotraslasfuncionesdeentrada:
cin.getline( ),cin.get( ), cin.ignore( ), cin.putback( ).
cin.getline(). cin esunobjetodelaclase istream y getline() esunafunciónmiembrodelaclase iostream.La
sintaxisdelafunción getline() es:
istream& getline(signed char* buffer, int long, char separador = '\n' );
Lalecturadecadenascon cin serealizaconelsiguienteformato:
cin.getline(<var_cad>, <max_long_cadena+2>, <'separador'>);
Elprimerargumentode getline eselidentificadordelav ariablecadena.Else gundoargumentoeselnúmeromáximo
decaracteresqueseleeránydebeseralmenosdoscaracteresmayorquelacadenareal, parapermitirelcarácternulo '\0' y
el '\n'.Porúltimo, elcarácterseparadorseleeyalmacenacomoelsiguientealúltimocarácterdelacadenayeselúltimo
carácterqueselee.Lafunción getline() insertaautomáticamenteelcarácternulocomoelúltimocarácterdelacadena.
CAPÍTULO 9 Cadenas
186
Reglas:
• Lallamada cin.getline(cad, n, car) leetodaslasentradashastalaprimeraocurrenciadelcarácterseparador
car en cad.
• Sielcarácterespecif icado car eselcarácterdenue valínea '\n', lallamadaanterioresequi valentea cin.getline(cad, n).
Problemas con la función cingeline(). Lafunción getline() presentaproblemascuandoseintenteutilizarunav ariable
cadena, despuésdequesehautilizado cin paraleerunavariablecarácteronumérico.Larazónesquenoseleeelretornode
carro<INTRO>, porloquepermaneceenelb ufferdeentrada.Cuandosedalaorden getline(), seleeyalmacenaesteretornoquepordefectoeselcarácterseparador , porloquenoseleelacadenadecaracteresquesepretendeseaeldato.
EJEMPLO 9.3. Lecturayescrituradecadenasdecar acteres.Secodificandosfunciones, unaparaleerunregistro
yotraparaescribirlo.
#include <cstdlib>
#include <iostream>
using namespace std;
struct registro
{
char Nombre_y_apellidos[51];
char Calle[33], Poblacion[28];
char Provincia[28], Pais[21], Codigo_Postal[8];
}r;
void Leer_registro(registro &r)
{
cout << " Lectura de datos \n";
cout << " Nombre y apellidos: ";cin.getline(r.Nombre_y_apellidos, 50);
cout << " Calle: "; cin.getline(r.Calle, 32);
cout << " Poblacion: "; cin.getline(r.Poblacion,27);
cout << " Provincia: "; cin.getline(r.Provincia, 27);
cout << " Pais: "; cin.getline(r.Pais, 20);
cout << " Codigo Postal: "; cin.getline(r.Codigo_Postal, 7);
}
void Escribir_registro(registro r)
{
cout << " \n Visualizacion de datos \n \n";
cout << " " << r.Nombre_y_apellidos << endl;
cout << " " << r.Calle << endl;;
cout << " " << r.Poblacion << endl;
cout << " " << r.Provincia << endl;
cout << " " << r.Pais << endl;
cout << " " << r.Codigo_Postal << endl;
}
int main(int argc, char *argv[])
{
Leer_registro(r);
Escribir_registro(r);
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 9 Cadenas
187
cin.get(). Lafunción cin.get() seutilizaparaleercarácteracarácter.Lallamada cin.get(car) copiaelcaráctersiguientedelflujodeentrada cin enlavariable car ydevuelve 1, amenosquesedetecteelf inaldelarchivo, encuyocasose
devuelve0.
EJEMPLO 9.4. (Usodecingetc).Lafunciónesvocal decidesielcarácterquerecibecomoparámetroesunavocal.
Elprogramaprincipaliterahastaquesetecleeelf inaldelflujodeentrada, dadoporcontrol+Z.
#include <cstdlib>
#include <iostream>
using namespace std;
bool esvocal(char ch)
{
ch= toupper(ch);
return ( ch == 'A' || ch == 'E' ||ch == 'I' ||ch == 'O' ||ch == 'U');
}
int main(int argc, char *argv[])
{
char ch;
int cuenta = 0;
while (cin.get(ch))
if (esvocal(ch))
cuenta++;
cout << " numero de vocales leidas "<< cuenta << "\n";
system("PAUSE");
return EXIT_SUCCESS;
}
cout.put.Lafunciónopuestadeget esput.Lafuncióncout.put() seutilizaparaescribirenelflujodesalidacout carácteracarácter.
EJEMPLO 9.5. Elsiguienteprogramaleeunte xtoylovisualiza, escribiendotodaslasvocalesenminúsculaylas
consonantesenmayúsculas.
#include <cstdlib>
#include <iostream>
using namespace std;
bool esvocal(char ch)
{
ch= toupper(ch);
return ( ch == 'A' || ch == 'E' ||ch == 'I' ||ch == 'O' ||ch == 'U');
}
int main(int argc, char *argv[])
{
char ch;
while (cin.get(ch))
{
if (esvocal(ch))
cout.put(tolower(ch));
else if(isalpha(ch))
// es una vocal
// escribe en minúscula
// es letra
CAPÍTULO 9 Cadenas
188
cout.put(toupper(ch));
else cout.put(ch);
// escribe minúscula
// escribe como se lee
}
system("PAUSE");
return EXIT_SUCCESS;
}
Lafunción cin.putback() restauraelúltimocarácterleídopor cin.get() denuevoalflujodeentrada cin.Lafunción
leeunoomáscaracteresdelflujodeentrada cin sinprocesar.
cin.ignore()
EJEMPLO 9.6. ElsiguienteprogramaleelíneasdeltecladohastaqueseintroducecontrolmásZ.Encadalíneadebe
haberdosnúmerosreales.Elprogramapresentaporcadalínealeídaotr alíneaconlasumadelosdosnúmer os.
Laexpresióncin.get(ch) copiaelsiguientecarácterench ydevuelve1 sitieneéxito.Acontinuación, sich esundígito, elnúmerorealcompletoseleeen r ysedevuelve.Encasocontrario, elcarácterseeliminade cin ycontinúael
bucle.Siseencuentraelf inaldelarchivo, laexpresióncin.get(ch) devuelve0, ysedetieneelbucle.
#include <cstdlib>
#include <iostream>
using namespace std;
float siguienteReal()
{ // busca el primer caracter dígito y lee el número real
char ch;
float r;
while (cin.get(ch))
if (ch >= '0' && ch <= '9')
{
cin.putback(ch);
cin >> r;
break;
}
return r;
// restaura
// lee dato real
}
int main(int argc, char *argv[])
{
float r1, r2;
char ch;
cout <<"intoduzca linea con dos numeros a sumar control+z fin \n";
while(cin.get(ch))
{
cin.putback(ch);
// restaura para leer reales
r1 = siguienteReal(), r2 = siguienteReal();
cin.ignore(80,'\n');
// salta hasta fin línea
cout << r1 << " + " << r2 << " = " << r1 + r2 << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 9 Cadenas
189
EJEMPLO 9.7. Funciónqueobtieneunacadenadeldispositivodeentr ada, deigualformaquelafunciónmiembr o
getline de cin utilizandolafunciónmiembro getc de cin.
Lafuncióncin.getline() leecaracteresdelaentradaestándar, normalmenteelteclado, hastaqueseleintroduceun
saltodelínea, osellegaalmáximodecaracteresaleerobienhaleídouncarácterqueselepasacomoparámetro.Los
caracteresquerecibesoncolocadosenladireccióndondeindiqueelar gumentodelafunción, encasodequedispongadeuno.Seutilizalasobrecar gadefuncionese xplicadaenelCapítulo6paradef inirlafunción getline2.Laprimeracodificaciónvoid getline2 (char* cadena, int n) admitecomoparámetroslacadenaylalongitudmáxima, porloquelalecturayalmacenamientodecaracteresdeberealizarsehastaqueseaf indefichero, sehayaleídoel
findelínea '\n', y, además, nosehayaleídoelnúmeromáximodecaracteres.Lase
gundacodif icación void
getline2 (char* cadena, int n, char ch) esanálogaalaprimera, peroenestecasounodelosf inalesdela
lecturadedatos, enlugardeserelf indelínea '\n', eselcontenidode ch.
void getline2 (char* cadena, int n)
{
char c, *p = cadena;
int i = 0;
while (( cin.get(c)) && (c != '\n') && (i < n))
{
*p++ = c;
i++;
}
*p = '\0';
}
void getline2 (char* cadena, int n, char ch)
{
char c, *p = cadena;
int i = 0;
while (( cin.get(c)) && (c != ch) && (i < n))
{
*p++ = c;
i++;
}
*p = '\0';
}
9.3. La biblioteca string.h
LabibliotecaestándardeC++contienelabibliotecadecadena iostring, quecontienelasfuncionesdemanipulacióndecadenasutilizadasmásfrecuentemente.Elusodelasfuncionesdecadenatienenunav ariableparámetrodeclaradasimilara:
char *s1;. Cuandoseutilizalafunción, sepuedeusarunpunteroaunacadenaosepuedeespecif icarelnombredeunavariablearray char.Cuandosepasaunarrayaunafunción, C++pasaautomáticamenteladireccióndelarray char.Lasfuncionesqueincluyenlapalabrareserv ada const, loquepermiteverrápidamenteladiferenciaentrelosparámetrosdeentrada
(const)ysalida.LaTabla9.1resumealgunasdelasfuncionesdecadenamásusuales.
EJEMPLO 9.8. Ejemplodeprogramacióndelafunciónquerealizalamismaoperaciónquestrcpy.
char * strcpya( char * destino, const char* origen)
{
int lon = strlen(origen);
// se calcula longitud
CAPÍTULO 9 Cadenas
190
destino = new char [lon + 1];
for (int i = 0; i < lon; i++)
destino[i]= origen[i];
destino[lon] = '\0';
return destino;
// se reserva memoria
//se copia carácter a carácter
// se añade fin decadena
// retorno de la copia
}
Tabla 9.1. Funciones de <string.h>
Función
Cabecera de la función y pr ototipo
memcpy()
void* memcpy(void* s1, const void* s2, size_t n).Reemplazalosprimeros n bytesde *s1
conlosprimeros n bytesde *s2.Devuelves.
char *strcat(char *destino, const char *fuente).Añadelacadenafuente alfinaldedestino.
char* strchr(char* s1, const char* s2).Devuelveunpunteroalaprimeraocurrenciade c en
s.Devuelve NULL sic noestáen s.
int strcmp(const char *s1, const char *s2).Comparalacadena s1 as2 ydevuelve: 0 sis1 =
= s2, <0 si s1 < s2, >0 si s1 > s2.
int strcmpi(const char *s1, const char *s2).Igualquestrcmp(), perotrataloscaracterescomo
strcat
strchr()
strcmp
strcmpi
sifuerantodosdelmismotamaño.
strcpy
strcspn()
strlen
strncat()
strncmp()
strnset
strpbrk()
strrchr()
strspn()
strstr
strtok()
char *strcpy(char *dest, const char *fuente).Copialacadena fuente alacadena destino.
size_t strcspn(char* s1, const char* s2).Devuelvelalongituddelasubcadenamáslar gade
s1 quecomienzacon s1[10] ynocontieneningunodeloscaracteresencontradosen s2.
size_t strlen (const char *s).Devuelvelalongituddelacadena s.
char* strncat(char* s1, const char*s2, size_t n).Añadelosprimeros n caracteresde s2 a
s1.Devuelve s1.Si n >= strlen(s2), entonces strncat(s1, s2, n) tieneelmismoefectoque
strcat(s1, s2).
int strncmp(const char* s1, const char* s2, size_t n).Compara s1 conlasubcadena s de
losprimeros n caracteresde s2.Devuelveunenterone gativo, ceroounenteropositi vo, segúnque s1
lexicográficamenteseamenor, igualomayorque s.Si n ≈ strlen(s2), entonces strncmp(s1, s2,
n) y strcmp(s1, s2) tienenelmismoefecto.
char *strnset(char *s, int ch, size_t n).Utilizastrcmp()sobreunacadenae xistenteparafijarn bytesdelacadenaalcarácter ch.
char* strpbrk(const char* s1, cont char* s2).Devuelveladireccióndelaprimeraocurrencia
de s1 decualquieradeloscaracteresde s2.Devuelve NULL siningunodeloscaracteresde s2 aparece
ens1.
char* strrchr(const char* s, int c).Devuelveunpunteroalaúltimaocurrenciade c ens.DevuelveNULL sic noestáen s.
size_t strspn(char* s1, const char* s2).Devuelvelalongituddelasubcadenamáslargades1
quecomienzacon s2[0] ycontieneúnicamentecaracteresencontradoses s2.
char *strstr(const char *s1, const char *s2).Buscalacadena s2 en s1 ydevuelveunpunteroaloscaracteresdondeseencuentra s2.
char* strtok(char* s1, const char* s2).Analizalacadena s1 entokens (componentesléxicos)
delimitadosporloscaracteresencontradosenlacadenas2.Despuésdelallamadainicial strtok(s1,
s2), cadallamadasucesivaastrtok(NULL, s2) devuelveunpunteroalsiguientetoken encontradoen
s1.Estasllamadascambianlacadena s1, reemplazandocadaseparadorconelcarácter NUL ('\0').
EJEMPLO 9.9. Leeruntextocuyomáximonúmerodelíneassea60deunalongitudmáximade80caracteresporlínea, yescribirelmismotexto, perointercambiandoentresílaslíneasdemayorconlademenorlongitud.
Eltextosemanejaapartirdeunamatrizdecaracteresde60f ilaspor81columnas.Encadaunadelasf ilassealmacenaunalíneadeentrada.Medianteunb ucle while controladoporlavariableentera i, sevanleyendolaslíneasdel
textoyalmacenándolasenlamatrizporf ilas.Alavezquesealmacenasev acalculandolalongitudyposicióndelas
líneasmáscortaymáslar ga, paraquecuandoseterminaelb ucle, sepuedanintercambiarentresílaslíneasmáscor-
CAPÍTULO 9 Cadenas
191
taconlamáslarga.Elbuclewhile terminacuandosehanleídolas60líneas, obiencuandoseintroduceunalíneavacía, yaqueenesemomentoserompelaejecucióndeb ucle.
#include <cstdlib>
#include <iostream>
using namespace std;
#define max 60
int main(int argc, char *argv[])
{
char texto[max][81];
int i = 0, j, lon,
int longmax = 0, posmax, longmin = 81, posmin;
char linea [80];
while (i < max)
{
cin.getline(linea, 80);
lon = strlen(linea);
if ( lon == 0)
break;
if (lon < longmin)
{
posmin = i;
longmin = strlen(linea);
}
if (lon > longmax)
{
posmax = i;
longmax = strlen (linea);
}
strcpy (texto [i], linea);
i++;
}
strcpy (linea, texto[posmin]);
strcpy (texto[posmin], texto[posmax]);
strcpy (texto[posmax], linea);
cout << " texto intercambiado \n";
for (j = 0; j < i; j++)
cout << texto[j] << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
9.4. Conversión de cadenas a números
Lafunción atoi( ) convierteunacadenaaunvalorentero.Suprototipoes:
int atoi(const char*cad).
Lacadenadebetenerlarepresentacióndeunv alorentero.Silacadenanosepuedecon vertir, atoi( ) devuelvecero.
Lafunción atof( ) convierteunacadenaaunvalordecomaflotante.Suprototipoes:
double atof(const char*cad);
CAPÍTULO 9 Cadenas
192
Laconversiónterminacuandoseencuentreuncarácternoreconocido.Lacadenadecaracteresdebetenerunarepresentacióndecaracteresdeunnúmerodecomaflotante.
Lafunción atol( ) convierteunacadenaaunvalorlargo(long).Suprototipoes:
long atol(const char*cad);
EJEMPLO 9.10. Lecturadenúmerosenlíneas, yacumulacióndelosnúmeros.Sesabequelosvaloresnuméricosde
cadalíneaestánsepar adosporblancosoelcarácterf indelínea, yquerepresentankilogramosdeunpr oducto.En
laslíneaspuedehaber, además, cualquierotrocarácter.Elsiguienteprogramaleeeltextoyobtienelasumadelosvaloresnuméricosdecadaunadelaslíneasasícomoeltotaldelasumadetodoslosvalor esnuméricos.Elfindetexto
vienedadoporunalíneaenblanco.
Lafunción strtok(s1,s2) analizalacadenas1en tokens (componentesléxicos)delimitadosporloscaracteresencontradosenlacadena s2.Despuésdelallamadainicial strtok(s1, s2), cadallamadasucesi vaa strtok(NULL,
s2) devuelveunpunteroalsiguiente token encontradoen s1.Comolafunciónestándardecon versióndecadenasen
enteros, atoi, devuelve 0 sinoencuentradígitosenlacadenaqueselepasacomoar gumento.Utilizandoestacaracterísticasepuedesepararenpalabraslaslíneasdelte xtoyaplicaracadapalabralafunción atoi, siencuentraunnúmerodevolveráelnúmerodekilosquesenecesitasaber .Seprogramaunb ucleinfinito, cuyasalidavienedeterminadaconlaorden break, queseejecutacuandoseintroduceunalíneav acía.Losacumuladores sumalinea y suma, se
encargandesumarlosnúmerosintroducidosenunalíneayeneltotaldelaslíneasrespecti vamente.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char buffer [80], *ptr;
int kilos, suma = 0, sumalinea;
cout << " Introduzca el texto linea a linea. \n";
for (; ; )
{
sumalinea = 0;
cin.getline(buffer, 80);
if (strlen(buffer) == 0)
break;
// salida del bucle
ptr = strtok(buffer, " ");
while (ptr)
{
if ((kilos = atoi (ptr)) != 0)
sumalinea += kilos;
ptr = strtok(NULL, " ");
}
cout << " La suma de kg en linea es: " << sumalinea << endl;
suma += sumalinea;
}
cout << " La suma de kg de todas las lineas es: " << suma << endl;
system("PAUSE");
}
Lasfunciones strtol y strtoul conviertenlosdígitosdeunacadena, escritaencualquierbasedenumeraciónaunenterolargooaunenterolar gosinsigno.Elprototipodeambasfuncioneses:
long strtol(const char * c, char**pc, int base) y
unsigned long strtoul(const char c, char**pc, int base)
CAPÍTULO 9 Cadenas
193
transformaelnúmeroescritoenlacadenacenunaciertabaseennúmerosenterosoenteroslar gos, moviendo*pc alfinaldel
númeroleídodentrodelacadena c.Sielnúmeroestáincorrectamenteescritoenlabase.
EJEMPLO 9.11. Convertirunacadenanuméricaanúmerosenteroslargosyenterosinsignoenunabase .
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{ char *cadena= " 32 111";
char **pcadena = new(char*) ;
long numero1;
unsigned long numero2;
numero1 = strtol (cadena,pcadena,4);
// extrae numero en base 4
cout << " numero = "<< numero1 << endl;
cout << " cadena actual "<< *pcadena << endl;
cadena = *pcadena;
numero2 = strtoul (cadena, pcadena,2);
// extrae numero en base 2
cout << " n2 = "<< numero2 << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
EJERCICIOS
9.1.
¿Cuáldelassiguientesdeclaracionessonequivalentes?
char
char
char
char
char
9.2.
var_cad0[10] ="Hola";
var_cad1[10] = { 'H','o','l','a'};
var_cad2[10]= { 'H','o','l','a','\0'};
var_cad3[5]= "Hola";
var_cad4[]= "Hola";
¿Quéhaydeincorrecto(siexiste)enelsiguientecódigo?
char var_cad[]= "Hola";
strcat(var_cad, " y adios");
cout << var_cad<< endl;
9.3.
Supongaquenoexisteelcódigodelafunción strlen.Escribaelcódigodeunafunciónquer ealicelatareaindicada.
9.4.
¿Quédiferenciasyanalogíasexistenentrelasvariablesc1, c2, c3?Ladeclaraciónes:
char** c1;
char* c2[10];
char* c3[10][21];
CAPÍTULO 9 Cadenas
194
9.5.
Escribirunprogramaqueleadoscadenasdecar acteres, lasvisualicejuntoconsulongitud, lasconcateneyvisualicela
concatenaciónysulongitud.
9.6.
LacarreradesociologíatieneuntotaldeNasignatur as.Escribirunafunciónqueleadeldispositivoestándardeentr ada
lasNasignaturasconsuscorrespondientescódigos.
9.7.
AñadiralEjercicio9.6funcionesparavisualizarlasNasignaturasymodificarunaasignaturadeterminada.
9.8.
Escribaunprogramaqueleaunacadenadecar acteresdelaentradaylainvierta.
PROBLEMAS
9.1.
Lafunción atoi( ) transformaunacadenaformadapordígitosdecimalesenelequivalentenúmer oentero.Escribiruna
funciónquetransformeunacadenaformadapordígitoshe xadecimalesenunenterolargo.
9.2.
Definirunarraydecadenasdecaracteresparapoderleeruntextocompuestoporunmáximode80caracteresporlíneas.
Escribirunafunciónparaleereltexto, yotraparaescribirlo;lasfuncionesdebentenerdosar gumentos, unoeltextoyel
segundoelnúmerodelíneas.
9.3.
Sesabequeenlas100líneasqueformanunte xtohayvaloresnuméricosenteros, querepresentanloskgdepatatasr ecogidosenunafinca.Losvaloresnuméricosestánseparadosdelaspalabrasporunblanco, oelcarácterfindelínea.Escribirunprogramaqueleaeltextoyobtengalasumadetodoslosvalor esnuméricos.
9.4.
Escribirunafunciónquetengacomoentr adaunacadenaydevuelvaelnúmerodevocales, deconsonantesydedígitosde
lacadena.
9.5.
Escribirunprogramaqueencuentredoscadenasintroducidasportecladoqueseanana gramas.Seconsideraquedoscadenassonanagramassicontienene xactamentelosmismoscar acteresenelmismooendifer enteorden.Hayqueignor ar
losblancosyconsiderarquelasmayúsculasylasminúsculassoniguales.
9.6.
Escribirunprogramaparalaslíneasdeuntextosabiendoqueelmáximodecaracteresporlíneaes80caracteres.Contar
elnúmerodepalabrasquetienecadalínea, asícomoelnúmerototaldepalabrasleídas.
9.7.
Setieneunte xtoformadoporunmáximode30líneas, delcualsequieresaberelnúmerodeaparicionesdeunapalabr a
clave.Escribirunprogramaquelealapalabraclavedetermineelnúmerodeaparicionesenelte xto.
9.8.
Setieneunte xtode40líneas.Laslíneastienenunnúmer odecaracteresvariable.Escribirunprogramaparaalmacenar
eltextoenunamatrizdelíneas, ajustadalalongituddecadalíneaalnúmer odecaracteres.Elprogramadebeleereltexto, almacenarloenlaestructuramatricialyescribirporpantallalaslíneasenor dencrecientedesulongitud.
9.9.
Escribirunprogramaqueleaunacadenaclaveyunte xtode, comomáximo, 50líneas.Elprogramadebeeliminarlaslíneasquecontenganlaclave.
9.10. Escribirunafunciónquerecibacomoparámetrounacadenadecaracteresylainvierta, sinusarlafunción strrev.
9.11. Escribirunafunciónquer ecibaunacadenadecar acteres, unalongitudlon, yuncarácter ch.Lafuncióndeber etornar
otracadenadelongitud lon, quecontengalacadenadecar acteresysiesnecesario, elcarácter ch repetidoalfinaldela
cadenalasvecesqueseanecesario.
CAPÍTULO 9 Cadenas
195
9.12. Sequieresumarnúmerosgrandesquenopuedanalmacenarseenvariablesdetipo long.Porestarazónsehapensadoen
introducircadanúmerocomounacadenadecar acteresyrealizarlasumaextrayendolosdígitosdeambascadenas.Hay
quetenerencuentaquelacadenasumapuedeteneruncaráctermásquelamáximalongituddelossumandos.
9.13. Escribirunafunciónquer ecibacomoparámetrosunnúmerograndecomocadenadecar acteres, ylomultipliqueporun
dígito, querecibacomoparámetrodetipocarácter.
9.14. Escribirunafunciónquemultipliquedosnúmer osgrandes, recibidoscomocadenasdecaracteres.
9.15. Untextoestáformadoporlíneasdelongitudvariable .Lamáximalongitudesde80car acteres.Sequierequetodaslaslíneastenganlamismalongitud, ladelacadenamáslar ga.Paraellosedeberellenarconblancosporlader echalaslíneashastacompletarlalongitudr equerida.Escribirunprogramaparaleeruntextodelíneasdelongitudvariableyformateareltextoparaquetodaslaslíneastenganlalongituddelamáximalínea.
SOLUCIÓN DE LOS EJERCICIOS
9.1.
Todaslasdeclaracionesrealizaninicializacionesdearraydecaracteresacadenas, exceptoladeclaracióncorrespondientea var_cad1, queinicializaunarraydecaracteres, simplemente, yaquenoterminaenelcarácternulo '\0'.Sonequivalenteslasinicializacionesdelasvariables var_cad0 yvar_cad2 entresí, yaquelaprimeraseinicializaaunaconstantecadena, ylase gundaseinicializacadaposicióndelarr ayalosmismoscar acteresterminandoenelcarácternulo.
Tambiénsonequivalenteslasinicializacionesde var_cad3 y var_cad4, apesardequelase gundainicializaciónesdeun
arrayindeterminado.
9.2.
Laprimerasentenciainicializalavariable var_cad delongitudvariablealacadenadecar acteres "Hola".Lasiguiente
sentenciaconcatenalacadenadecaracteres, "y adios", ylasiguientesentenciavisualizaelresultado.Portanto, noexisteerrorenelcódigo.Siseejecutaelsiguientepr ogramasepuedecomprobarelresultado.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char var_cad[]= "Hola";
strcat(var_cad, " y adios");
cout << var_cad<< endl;
system("PAUSE");
return EXIT_SUCCESS;
}
9.3.
Seutiliza typedef paradefinir cadena80, comounarrayde80car acteres.Lafunción Longitud recibecomoparámetro
porreferenciaunacadenadecaracteres.Elcálculodelalongitudserealizaconunbuclewhile queiterahastaqueelcontenidodelaposicióndelarr ayalaqueseaccedeconcontadorsea NULL.Elprogramaprincipalrealizaunallamadaala
funciónparacomprobarresultados.
#include <cstdlib>
#include <iostream>
CAPÍTULO 9 Cadenas
196
using namespace std;
typedef char cadena80[80];
int Longitud(cadena80 &cad)
{
int contador = 0;
while (cad[contador] != '\0')
contador ++;
return contador;
}
int main(int argc, char *argv[])
{
cadena80 cad = "C++ es mejor que C";
cout << "longtud de " << cad<< " = " << Longitud(cad) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
9.4.
Lavariable c1 esunavariablepunteroqueapuntaaunpunter odecaracteres.Lavariable c2 esunarrayde10punteros
acaracteres.Lavariable c3 esunamatrizconespaciopar a210punterosacaracteresaccesiblessegúnunarreglode10
filasde21elementoscadaunadeellas.
9.5.
Sepresentalacodificaciónprogramaasícomounresultadodeejecución.Seutilizalafunción strcat queconcatenados
cadenasdecaracteres.
int main(int argc, char *argv[])
{
char s1[81], s2[81];
cout << " introduzca cadena :";
cin.getline(s1,80);
cout << " introduzca cadena :";
cin.getline(s2,80);
cout << " Antes de strcat(s1, s2): \n";
cout << " s1 = \"" << s1 << "\", longitud = "<<strlen(s1) << endl;
cout << " s2 = \"" << s2 << "\", longitud = "<<strlen(s2) << endl;
strcat(s1, s2);
cout << " Despues de strcat(s1, s2):\n";
cout <<" s1 = \"" << s1 << "\", longitud = " << strlen(s1) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
9.6.
SesuponequeelnúmerodeasignaturasN esconstanteyvale 50.Estevalorde N sedefineenelmacro#define N 50.Se
suponequelaasignaturatieneunnombredemenosde20 caracteresyquesucódigonosobrepasaloscincocaracteresalfanuméricos.Sedeclaradosarray asignatura y codigo quealmacenanlosnombr esycódigosdelas N asignatura.Medianteunbuclefor, sesolicitanalusuariolosdatos, realizandolalecturaconcin.getline.Lafunciónleer, laquerealizalatareasolicitada, devolviendolasasignaturasyloscódigosendosparámetr os.
CAPÍTULO 9 Cadenas
197
include <cstdlib>
#include <iostream>
using namespace std;
char asignatura [N][21], codigo [N][7];
void leer(char asignatura[][21], char codigo[][7], int n)
{
for (int i = 0; i <= n; i++)
{
cout << " Escriba el nombre de la asignatura: " << i + 1 << " ";
cin.getline (asignatura [i],20);
cout << " Escriba el código de la asignatura: " << i + 1 << " ";
cin.getline(codigo [i], 6);
}
}
#define N 50
int main(int argc, char *argv[])
{
.....
system("PAUSE");
return EXIT_SUCCESS;
}
9.7.
Lavisualizacióndelasasignaturasyloscódigosserealizaronporlafunción escribir, quepresentalosdatosquerecibe
ensusparámetros.Elnúmerototaldeasignatur asavisualizares n, quedebeestarenelr ango 0,...,N–1.Paramodificarlosdatosdeunaasignatur adeterminada i, bastaconsolicitarlosalusuario, yrotornarlos, enlaposicióncorrespondientedelosarrayqueserecibencomoparámetros.
void escribir(char asignatura[][21], char codigo[][7], int n)
{
for (int i = 0; i<= n; i++)
{
cout<< " nombre de la asignatura: " << i + 1<<asignatura[i]<< endl;
cout << " código de la asignatura: " << i << codigo[i]<< endl;
}
}
void modificar(char asignatura[][21], char codigo[][7], int i)
{
cout << " Escriba nuevo nombre de asignatura: " << i + 1 << " ";
cin.getline (asignatura [i],20);
cout << " Escriba nuevo código de asignatura: " << i + 1 << " ";
cin.getline(codigo [i], 6);
}
9.8.
Seusalafunción strrev querecibecomoentradaunacadenaylainvierte:
#include <cstdlib>
#include <iostream>
using namespace std;
CAPÍTULO 9 Cadenas
198
int main(int argc, char *argv[])
{
char cadena[41] ;
cout << "deme cadena ";
cin.getline(cadena,40);
strrev(cadena);
cout << "Cadena invertida \n" << cadena << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
SOLUCIÓN DE LOS PROBLEMAS
9.1.
Lafunción Hexadecimal_a_enterolargo recibecomoparámetrounacadenadecar acteres Hexa enlaqueseencuentr a
escritoelnúmeroenbasehexadecimal, ylotransformaaunenterolargoescritoenbase10 devolviéndoloenlapropiafunción, queesdeclaradacomodetipoenterolargo. Pararealizarlaoperaciónseusa, elmétododeHorner deevaluaciónde
unpolinomioescritoenunaciertabase:
"2345"16=( ( (0 * 16 + 2)* 16 + 3) * 16 + 4)* 16 + 5.
Seinicializaunavariable numero a0.Medianteunbuclefor serecorrentodaslasposicionesde Hexa, hastaquenoquedendatoscadena[c] == '\0'.Elcarácteralmacenadoenlaposición c setransformaenundatonuméricoconlaexpresión Valordigito = Hexa[c]-'0', siesundigito, ymediantelae xpresión Valordigito = Hexa[c] -'A'+ 10, enel
casodequeseauncarácterdeentr e' A','B','C','D','E','F'.Unavezobtenidoel ValordeldigitoserealizalatransformacióndeHorner numero = numero * base + Valordigito.
La codificación de este problema se encuentra en la página Web del libro.
9.2.
Sedeclarauna linea comounsinónimodeunacadenadecar acteresdelongitud 80.Eltextotext esunpunteroalaslíneas, queeselarraydondesealmacenaráeltexto.Aestetextoseleasignamemoriaenelprogramaprincipal, ysellama
alasfunciones Leer_Texto yEscribir_Texto, quesonlasencargadasdeleerlosdatosyvisualizarlosr esultados.
La codificación de este problema se encuentra en la página Web del libro.
9.3.
SedeclaralavariableTextoEntrada comounarrayde100 posicionesdepunterosachar, parapoderalmacenarlas100
líneasdeltextodeentrada.Acadaunadeestaslíneasdelte xtoseleasignamemoriadinámicamentemediantelasentencia new, unavezquesesabelalongituddelalínea.Estalongitudvienedeterminadaporlafunción strlen aplicadaala
linea deentradapreviamenteleídaconlaordencin.getline().Laentradadeinformacióndecadalinea serealizacon
unbuclefor queitera100 veces.Esmedianteotrobuclefor comosevisualizaalfinaldelprogramatodoeltextoleídodel
dispositivoestándardeentrada.Paraencontrarseparar, yacumularlosnúmerosdeltexto, seusanlasfunciones: atoi que
devuelveelnúmeroalmacenadoenlacadenaocer oencasoquenocomienceporunnúmer oentero, ylafunción strtok,
queseencargadeirdesplazandounpunteroptr alolargodelalíneadeentr ada, encadablancoqueencuentra.
La codificación de este problema se encuentra en la página Web del libro.
9.4.
Lafunciónquesepidedeberetornartresvalores, porellosedefinentresparámetrosporreferenciapararetornarlos.Para
averiguareltipodelcarácterquealmacenaencadaposiciónlacadena, serecorrelacadenaconunpunteroauxiliaryse
comparasucódigoASCIIconeldelosnúmer osylasletras, usandolasfunciones isupper, tolower yisdigit.Elbucle
CAPÍTULO 9 Cadenas
199
while quecontrolaelcarácterqueseestácompar andoterminacuandollegaalfinaldelacadena, detectadoporcoincidirelnúmeroASCIIdelcontenidodelpunteroconelnúmeroASCIIdelcarácternulo.
La codificación de este problema se encuentra en la página Web del libro.
9.5.
Secodificaenprimerlugarlafunción tolowercad querecibecomoparámetrounacadenadecaracteresdelongitudmáxima80ydevuelvelacadenaenlaquetodaslasletrasmayúsculassonconvertidasenminúsculas.Pararealizarloiterasobretodaslasposicionesdelacadenadecar acteresusandolafunción tolower.Paradecidirsidoscadenasdecar acteres
sonanagramasbastaconvertirtodosloscaracteresdelascadenasqueseanletrasmayúsculasenletrasminúsculasycontarelnúmerodeaparicionesdecadacarácterqueseaunaletr aminúscula.Paracontarelnúmer odevecesqueapar ece
cadaletraminúsculaenlasrespectivascadenas, seusandosarraysdeenterosletras1 yletras2, quealmacenanensus
28posiciones, lasaparicionesde 'a' enlaposición 0, 'b' enlaposición 1, etc.
La codificación de este problema se encuentra en la página Web del libro.
9.6.
Cadalíneaseleellamandoalafunción cin.getline, conunargumentoquepuedaalmacenarelmáximodecar acteres
deunalínea.Porconsiguiente, sedeclaralavariable: char cad[81], argumentode cin.getline.Lalongituddelacadenasedeterminaconunallamadaa strlen.Sedefinendosfunciones, laprimera saltablancos sirveparasaltarselos
blancosquehayentesdecualquierpalabra, ylasegundasaltapalabra seutilizaparasaltarseunapalabracompleta.Ambasfuncionesrecibencomoparámetrolacadenadecar acteres cad, asícomolaposición i porlaquedebecomenzarla
búsqueda, yretornanenelpropioparámetroporreferencia i laposicióndondehaconcluidosubúsqueda.Elnúmer ode
palabrasdecadalíneasedetermina, buscandoelcomienzodelaprimer apalabraconlafuncion saltablanco y, posteriormente, llamandoenunbuclealasfunciones saltapalabra y saltablanco.Laejecuciónterminacuandoseintr oduceunalíneasindatosobienelf indearchivo.Elcontador n cuentaelnúmerodepalabrasdecadalínea, yelacumulador
total, acumulalaspalabrastotalesleídas.
La codificación de este problema se encuentra en la página Web del libro.
9.7.
Setrataderealizarunabúsquedacon strstr( ) encadaunadelaslíneasdelte xto.Enprimerlugar, seleelapalabr a
clavequesesuponedelongitudmáxima, menoroigualque14.Eltextoserepresentaporunarraydeunmáximode30posicionesdepunterosacaracteres.Encadaunadeesasposicionesdelarr ay, sealmacenaunalíneaalaqueseleasigna
memoriamediantelaorden new dereservadeespacio.Cadavezqueseleeunalíneaysealmacenaenelte xto, sedeterminaelnúmerodevecesquelapalabraclave estáenlalínea.Nohayqueolvidarquelafuncion strstr retornaunpunteroL alaposicióndelaprimer aaparicióndelapalabr aclave, porloquesisequier eavanzarenlabúsquedahayque
incrementarlo.
La codificación de este problema se encuentra en la página Web del libro.
9.8.
Setratadeleeruntextoydemanipularlospunterosdeltexto, paranotenerquetrasladarlaspropiaslíneas.ComoenC++
lascadenasdecar acteresnoguar daninformaciónacer cadesupr opialongitud, ypuestoquelamar cadef inaldelínea,
'\0', essuficienteparadeterminarsue xtensión, seusaunarr ayauxiliar longitudlineas paraalmacenarlalongitudde
cadalíneaylaposicióninicialquetieneneneltexto(indexaciónparapoderordenarynomoverlíneasdeltexto).Eltextose
almacenaenunarrayde40posicionesconpunterosacaracteres(encadaunadeestasposicionesealmacenaráunalínea).
• Lafunción leer_texto recibecomoparámetroelarraydeltexto, elarrayparalaindexaciónyunparámetr oporreferenciai, queindicacuántaslíneasdeltextorealessehanleído.Estafunciónleeelte xtolíneaalínea, almacenadoenel
arraydeindexaciónsulongitudylaposiciónqueocupaenelte xto.Elbuclequecontrolalalecturaterminacuandose
leeunalíneaenblanco.
• Lafunción ordenar, ordenaporlongituddelíneaelarr aydeinde xaciónporelconocidométododelab urbuja(véase
métodosdeordenacióndelCapítulo12).
• Lafunción escribir_texto seencargadevisualizarelte xtoconlaslíneasdeloriginalenlasposicionesqueindicael
arraydeindexaciónquecontienelaslongitudesordenadasylasposicionesqueocupa.
• Elprogramaprincipalrealizalasllamadasalasfuncionespar aresolverelproblemaplanteado.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 9 Cadenas
200
9.9.
Sedeclara texto comounarraydecadenasdecar acteresdelongitudvariable .Asimismo, sedeclaraunpunteroacadenasdecaracteresptr usadoenlafunción strstr paradeterminarsila clave leídaseencuentraenlacadena.Esta clave sealmacenaenunacadenadecar acteresdelongitudmáxima15.Elb ucleserepitemedianteunavariableentera i un
totalde 50 vecesleyendolíneasyalmacenándolasenelte xtosinoapar ecelaclave.Pararealizarelalmacenamiento, se
disponedeunavariableenteraj queindicalaposicióndeltexto dondedebeseralmacenadalalíneaactualqueseleeen
casoquehayaquehacerlo.Unalíneasealmacenasinoseencuentr alaclaveenella.Encasodequeasísea(debequedarseenel texto), sereservaespacioenmemoriapar alalínea, secopiaconlaor den strcpy yseincrementaelcontadorj enunaunidad.Alfinaldelprogramasepresentaeltextosinlaslíneasquecontienenla clave enella.
La codificación de este problema se encuentra en la página Web del libro.
9.10. Lafunciónreverseresuelveelproblema.Paraellosecalculalalongituddelacadena, secreaespacioenmemoriapar a
ella, ymedianteunbuclefor serealizalaasignación rcadena[lon - i - 1] = cadena[i], quevacambiandolasposicionesdeloscaracteres.Recuerdequetodacadenaterminasiempreenelcarácternulo, porloqueesnecesarioañadirlo
despuésdelbuclefor.Elresultadodelacadenainvertidaseretornaenlafunción.
La codificación de este problema se encuentra en la página Web del libro.
9.11. Lafunciónrecibecomoparámetrounacadena yretornaunacadenadelongitud lon quecontienelosiguiente: silacadenadelparámetrodeentradatienelongitudmayorque lon tomalos lon primeroscaracteresdela cadena;enotrocasoa
lacadena delparámetrodeentradaseleañadeelcarácter ch hastaquetengalongitudlon.Pararealizarlobastaconcopiarla cadena yañadirelcarácter ch lasvecesqueseannecesarias. Antesderetornarla cadena, hayqueañadirelcarácternuloenlaposicióncorrespondiente.
La codificación de este problema se encuentra en la página Web del libro.
9.12. Pararesolverelproblema, sesigueelsiguienteesquema:
• Invertirlascadenasdecaracteresyconvertirlasencadenasdeiguallongitud, parapodersumaralrevésyasípoderrealizarlasumadeizquier daader echa.Parainvertirlascadenasycon vertirlasencadenasdelamismalongitud, rellenas concerosalader echa, seusanlasfunciones: reverse y ampliacaracter delosPr oblemas9.10y9.11r espectivamente.
487954558
235869
invertido
invertidoyrellenodeceros
855459784
000968532
• Sumarlascadenasdecaracteresconvirtiendocomopasointermedioloscaracteresendígitosyconvirtiendoelresultado
denuevoencadenas.
487954558
+ 235869
855459784
+ 000968532
488190427
724091884
Antesdecomenzarlasumadelascadenas, sereservamemoriaparael resultado delasuma.Setomanlascadenas
carácteracarácter, seconviertenendígitosysesumaelresultado, teniendocuidado, claroestá, quesielresultadoesmayorque9hadehaberarr astresobreeldígitosiguiente(enr ealidadelanteriorenlacadena), puestoqueencadacaráctersolamentesepuederepresentarundígitodel0al9.EslafunciónSumarGrandes, laquerealizaeltrabajodesumarlos
númerosgrandesquerecibecomoparámetroensendascadenasdecaracteres, devolviendoelresultadoenunacadenade
caracteres.Obsérvesequeunavezsumadoslosnúmer ossedebeinvertirdenuevolacadenadecaracteresresultado.
Seincluyelacodificacióndelasfuncionesreverse ampliacaracter, asícomounprogramaprincipalquerealizados
llamadasalafunción sumarGrandes paracomprobarlosresultados.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 9 Cadenas
201
9.13. Paramultiplicarunacadenaquealmacenaunnúmer oenteroporundígito, seinviertelacadenadecar acteres(34567se
convierteen76543), paraposteriormenteusarelalgoritmoclásicodemultiplicaciónporundígito, almacenandoelresultadoenotracadenadecar acteres.Unavezobtenidoelr esultado, hayqueretornarlacadenain vertida.Paramultiplicar
porundígito, seusacomopasointermediolaconversióndecaracteresendígitos, paravolverareconvertirelresultadode
nuevoencaracteres.Eslafunciónmultiplicadigito, laquemultiplicalacadenadecaracteresnúmeroporeldigitodig,
retornandoelresultadocomocadenadecaracteres.Seusalafunciónreversedelejercicioanterior.
La codificación de este problema se encuentra en la página Web del libro.
9.14. Elalgoritmoclásicodemultiplicaciónrealizalaoperacióndelasiguienteforma:
2457
x
956
-----------22113
12285
14742
-----------1619163
2457
x
956
-----------22113
122850
1474200
-----------1619163
Usandolasfuncionesdefinidasenlosdospr oblemasanteriores, resultasencillorealizarlamultiplicación, yaquesólose
necesitainicializarelresultado alacadenavacía, para, posteriormente, irmultiplicandoelprimernúmeroporcadauno
delosdígitosdelse gundonúmeroensentidoin verso, desplazándolounaposiciónhacialaizquier da, eiracumulandoel
valordelsumandoenelacumuladorresultado.Pararealizarestedesplazamientobastaconobservarquealaderechade
losnúmerosdesplazadosesmuyútilponerunceroparautilizarlafunciónSumarGrandes.Estedesplazamientopuederealizaseconlafunción ampliacaracter, queponeloscerosnecesariosparaeldesplazamiento.Unavezterminadoelpr oceso, seretornaelvalorde resultado.Enlacodif icaciónquesepr esenta, seincluyeunpr ogramaprincipalquer ealiza
unallamadaalafunciónquemultiplicalosnúmer osgrandes.
La codificación de este problema se encuentra en la página Web del libro.
9.15. Seleeeltextolíneaalínea, almacenadoenlavariablemayor, lalongitudmáximadelaslíneasleídas.Unavezterminada
lalecturaserellenandeblancoslaslíneaspar acovertirlastodasencadenasdecar acteresdelamismalongitud, paralo
cualserealizanlasllamadascorrespondientesalafunción ampliacaracter, peroconelcarácterblancoenlallamada.
Porúltimosevisualizaelte xtoleídoyatratado.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
9.1.
Escribirunafunciónparatransformarunnúmeroentero
enunacadenadecaracteresformadaporlosdígitosdel
númeroentero.
9.3.
EscribirunafuncióndeC++querealicelamismatarea
quelafunciónstrncat yconlosmismoparámetros.Es
decir, concatenardoscadenas.
9.2.
Escribirunafunciónparatransformarunnúmerorealen
unacadenadecaracteresquesealarepresentacióndecimaldelnúmeroreal.
9.4.
Escribirunafunciónquerecibacomoparámetrouna
cadenaeindiqueelnúmerodeletrasmayúsculasque
tiene.
CAPÍTULO 9 Cadenas
202
PROBLEMAS PROPUESTOS
9.1.
Escribirunprogramaquelealíneasdetextoobtengalas
palabrasdecadalíneaylasescribaenpantallaenorden
alfabético.Sepuedeconsiderarqueelmáximonúmero
depalabrasporlíneaes28.
9.2.
Escribirunprogramaqueleaunalíneadete xtoyescribaenpantallalaspalabrasdequeconstalalíneasinutilizarlasfuncionesdestring.h.yparticularmentesinusar
strtok().
9.3.
9.4.
9.5.
Unsistemadeencriptaciónsimpleconsisteensustituir
cadacarácterdeunmensajeporelcarácterqueestásituadoatresposicionesalfabéticaspordelantesuyo.Escribirunafunciónquetomecomoparámetrounacadenaydevuelvaotracifradacomosehae xplicado.
Escribirunprogramaqueleaunte
xto, ydospalabras claves, clave1 y clave2.Elprogramadebesustituirtodaslasaparicionesde clave1 por clave2, mostrarelnuevotexto, eindicarelnúmerodeintercambios
realizados.
Otrosistemadeencriptaciónconsisteensustituircada
carácterdelalf abetoporotrodecididodeantemano,
perosiempreelmismo.Utilizarestemétodoenunafunciónquetomecomoparámetroselmensajeacifrary
unacadenaconlascorrespondenciasordenadasdelos
caracteresalfabéticos.Lafuncióndevolveráunpuntero
alacadenacifradadelmensaje.
9.6.
Setratadeencriptarunte xtomedianteunafunciónde
cifrado.Elcifradoserealizacambiandotodaslasletras
minúsculasporotrasnue vasletrasquerecibeenun
arraycifradodecaracteres;esdecirdecambiar 'a' por
cifrado[0], 'b' por cifrado[1], etc.Escribiruna
funciónquerecibauntextoyloencripte.
9.7.
Escribirunafunciónquerecibaelte xtoqueretornala
funcióndelejercicioanterior , debidamenteencriptado,
ylotransformeenelte xtooriginal.Elarraydecifrado
esundato.
9.8.
Escribirunafunciónquegenereuncódigoalf anuméricodiferentecadavezqueseallamadadevolviéndoloen
formadecadena.Elar gumentodedichafunciónesel
númerodecaracteresquevaatenerelcódigogenerado.
9.9.
EscribirunprogramaquetomecomoentradaunprogramaescritoenlenguajeC++deunarchi vodetextoy
compruebesiloscomentariosestánbienescritos.Esdecir, setratadecomprobarsidespuésdecadasecuencia
'/*'existeotradeltipo'*/',peroteniendopresentequeno
sepuedenanidarcomentarios.
9.10. Escribirunafunciónquerecibaunapalabraygeneretodaslaspalabrasquesepuedenconstruirconsusletras.
9.11. Modificarlafunciónanteriorparaquesólogenerelas
palabrasquecomiencenporunaconsonante.
CAPÍTULO 10
Punteros (apuntadores)
Introducción
Elpuntero (apuntador), esunaherramientaquepuedeutilizarensusprogramasparahacerlosmáseficientesyflexibles.Los
punterosson, unadelasrazonesfundamentalesparaqueellenguajeC++seatanpotenteytanutilizado.
Unavariablepuntero (opuntero, comosellamanormalmente)esunavariablequecontienedireccionesdeotrasvariables.
Todaslasvariablesvistashastaestemomentocontienenvaloresdedatos, porelcontrario, lasvariablespunteroscontienenvaloresquesondireccionesdememoriadondesealmacenandatos.Utilizandopunterossuprogramapuederealizarmuchastareasquenoseríaposibleutilizandotiposdedatosestándar .
10.1. Concepto de puntero (apuntador)1
Cuandounavariablesedeclara, seasociantresatrib utosfundamentalesconlamisma: sunombre, sutipo ysu dirección en
memoria.Alvalor, ocontenidodeunavariableseaccedepormediodesunombre.Aladireccióndelavariableseaccedepor
mediodeloperadordedirección &.
Unareferencia esunaliasdeotrav ariable.Sedeclarautilizandoeloperadordereferencia( &)queseañadealtipodela
referencia.
EJEMPLO 10.1. Obtenerelvaloryladireccióndeunavariableyunar eferencia.
LosdosidentificadoresVariable yReferencia sonnombresdiferentesparalamismavariable, cuyocontenidoydirecciónsonrespectivamente75 y0x22ff74.
0x22ff74
Variable
Referencia
75
int
#include <cstdlib>
1
EnLatinoaméricaesusualempleareltérmino apuntador.
203
CAPÍTULO 10 Punteros (apuntadores)
204
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int Variable= 75;
int& Referencia = Variable;
// Declaración de variable
//Referencia e inicialización
cout << " Contenido de Variable = " << Variable << endl;
cout << " Direccio &Variable = " << &Variable << endl;
cout << " Contenido de Referencia = " << Referencia << endl;
cout << " Direccio &Referencia = " << &Referencia << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Reglas
&
serefierealadirecciónenquesealmacenaelv alor.Elcarácter & tienediferentesusosenC++:
1. Cuandoseutilizacomoprefijodeunnombredeunav ariable, devuelveladireccióndeesavariable.
2. Cuandoseutilizacomounsuf ijodeuntipoenunadeclaracióndeunav ariable, declaralavariablecomosinónimodelavariablequesehainicializado.
3. Cuandoseutilizacomosuf ijodeuntipoenunadeclaracióndeparámetrosdeunafunción, declaraelparámetroreferenciadelavariablequesepasaalafunción.
Unpunteroesunav ariablequecontieneunadireccióndeunaposicióndememoriaquepuedecorresponderonoauna
variabledeclaradaenelprograma.Ladeclaracióndeunavariablepunterodebeindicareltipodedatoalqueapunta;paraello
sehaceprecederasunombreconunasterisco(*):
<tipo de dato apuntado> *<identificador de puntero>
C++noinicializalospunteroscuandosedeclaranyesprecisoinicializarlosantesdesuuso.Despuésdelainicialización,
sepuedeutilizarelpunteroparareferenciarlosdatosdireccionados.P araasignarunadireccióndememoriaaunpunterose
utilizaeloperador &.Estemétododeinicialización, denominadoestático, requiere:
• Asignarmemoriaestáticamentedefiniendounavariabley, acontinuación, hacerqueelpunteroapuntealvalordelavariable.
• Asignarunvaloraladireccióndememoria.
Existeunse gundométodoparainicializarunpuntero: asignacióndinámicadememoria .Estemétodoutilizalosoperadores new y delete, yseanalizaráenelsiguientecapítulo, aunqueeloperador new dereservadememoriaseusayaeneste
capítulo.
Elusodeunpunteroparaobtenerelv aloralqueapunta, esdecir, sudatoapuntado, sedenominaindireccionarelpuntero (“desreferenciarelpuntero”);paraello, seutilizaeloperadordeindirección*.LaTabla10.1resumelosoperadoresdepunteros.
Tabla 10.1. Operadores de punteros
Operador
Propósito
&
*
*
Obtieneladireccióndeunavariable.
Defineunavariablecomopuntero.
Obtieneelcontenidodeunavariablepuntero.
CAPÍTULO 10 Punteros (apuntadores)
205
Siemprequeaparezcaunasterisco( *)enunadefinicióndevariable, éstaesunavariablepuntero.
Siemprequeaparezcaunasterisco( *)delantedeunav ariablepunteroseaccedealav ariablecontenidodelpuntero.
Eloperador & devuelveladireccióndelavariablealacualseaplica.
C++requierequelasv ariablespunterodireccionenrealmentev ariablesdelmismotipodedatoqueestáligadoalos
punterosensusdeclaraciones.
Unpunteropuedeapuntaraotrav ariablepuntero.Esteconceptoseutilizaconmuchafrecuenciaenprogramaslar gosy
complejosdeC++.Paradeclararunpunteroaunpunterosehaceprecederalavariablecondosasteriscos(**).Enelsiguiente
código, ptr5 esunpunteroaunpuntero.
int valor_e = 100;
int *ptr1 = &valor_e;
int **ptr5 = &ptr1;
EJEMPLO 10.2. Asignaraunavariablepunterounadirección, yasucontenidounvalor.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int var;
int *pun;
// define una variable entera var
//define un puntero a un entero pun
pun = &var;
//asigna la dirección de var a pun
*pun = 60;
// asigna al contenido de p 60
cout << " &var. Direccion de var = " << &var << endl;
cout << " pun. Contenido de pun es la misma direccion de var ";
cout << pun << endl;
cout <<" var. Contenido de var = " << var << endl;
cout << " *pun. El contenido de *pun es el mismo que el de var: ";
cout << *pun << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
NOTA: Sonvariablespunterosaquellasqueapuntanalaposiciónendondeotra/svariable/sdeprogramasealmacenan.
EJEMPLO 10.3. EscribalosnúmerosASCIIdeloscaracteresA, B, C, D, E, F.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char *punteroc;
char caracter;
// un puntero a una variable carácter
CAPÍTULO 10 Punteros (apuntadores)
206
punteroc = &caracter;
cout << " ASCII caracter" << endl;
for (caracter = 'A'; caracter <= 'F'; caracter++)
cout << " "<< (int) caracter << "
" << *punteroc << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
10.2. Punteros NULL y void
Unpunteronulo noapuntaaningúndatoválido, seutilizaparaproporcionaraunprogramaunmediodeconocercuandouna
variablepunteronodireccionaaundatoválido.P aradeclararunpunteronuloseutilizalamacro NULL.
EnC++sepuededeclararunpunterodemodoqueapunteacualquiertipodedato, esdecir, noseasignaauntipodedato
específico.Elmétodoes: declararelpunterocomounpunterovoid.Unpunterodetipovoid puededireccionarcualquierposiciónenmemoria, peroelpunteronoestáunidoauntipodedatoespecíf ico.
NOTA: Unpunteronulonodireccionaningúndatoválido.Unpuntero void direccionadatosdeuntiponoespecif icado.Unpunterovoid sepuedeigualaranulosinosedireccionaningúndatoválido.NULL esunvalor;void esuntipo
dedato.
EJEMPLO 10.4. Lospunterosvoid puedenapuntaracualquiertipodedato.
int x, *px = &x, &rx = x;
char* c = "Cadena larga";
float *z = NULL;
void *r = px, *s = c, *t = z;
x esunavariableentera; px esunpunteroaunavariableenterainicializadoaladirecciónde x;rx esunareferenciaa
unenteroinicializadaa x.
c (punteroacarácter)esunacadenadecaracteresdelongitud10.
z esunpunteroaunrealinicializadoa NULL.
r esunpunterovoid incializadoaunpunteroaentero;s esunpunterovoid, inicializadoaunpunteroachar;t esun
punterovoid inicializadoaunpunteroa float.
10.3. Punteros y arrays
LosarraysylospunterosestánfuertementerelacionadosenellenguajeC++.Elnombredeunarrayesunpunteroquecontieneladirecciónenmemoriadecomienzodelasecuenciadeelementosqueformanelarray.Estenombredelarrayesunpunteroconstanteyaquenosepuedemodif icar, sólosepuedeaccederparaindexaraloselementosdelarray.Paravisualizar, almacenarocalcularunelementodeunarray , sepuedeutilizarnotacióndesubíndicesonotacióndepunteros, yaqueaun
punterop selepuedesumarunentero n, desplazándoseelpunterotantosbytescomoocupeeltipodedato.
Sisetienelasiguientedeclaracióndearray int V[6] = {1, 11, 21, 31, 41, 51};, sualmacenamientoenmemoria
seráelsiguiente:
memoria
V[0]
V[1]
V[2]
V[3]
V[4]
V[5]
1
11
21
31
41
51
*V
*(V + 1)
*(V + 2)
*(V + 3)
*(V + 4)
*(V + 5)
CAPÍTULO 10 Punteros (apuntadores)
207
EJEMPLO 10.5. Inicializaciónyvisualizacióndeunarr ayconpunteros.
Elprogramainicializaunarrayderealesyvisualizalasdireccionesdecadaunadelasposicionesasícomosuscontenidos.Lasdireccionesconsecutivassediferencianen 4 unidadescorrespondientesalos 4 bytesqueocupaun float.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float V[6];
for (int j = 0; j < 6; j++)
*(V+j) = (j + 1) * 10 + 1;
cout << "
Direccion
Contenido" << endl;
for (int j= 0; j < 6; j++)
{
cout << " V+" << j << " = "<< V + j;
cout << "
V[" << j <<"] = " << *(V+j)<< "\n";
}
system("PAUSE");
return EXIT_SUCCESS;
}
Sepuededeclararun arraydepunter os, comounarrayquecontienepunteroscomoelementos, cadaunodeloscuales
apuntaráaotrodatoespecífico.
EJEMPLO 10.6. Inicializaciónyvisualizacióndeunarr aydepunteros.
Elsiguienteprogramainicializaelarraydereales V, asícomoelarrraydepunterosareales P, conlasdireccionesde
lassucesivasposicionesdelarray V.Posteriormente, visualizalasdireccionesyloscontenidosde V usandoelarrayde
punterosP.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float V[6], *P[6];
for (int j = 0; j < 6; j++)
{
*(V+j) = (5-j) * 10 + 1;
*(P+j) = V+j;
// inicialización de array de punteros
}
cout << "
Direccion
Contenido" << endl;
for (int j = 0; j<6; j++)
{
cout << " V+" << j << " = " << *(P+j) << " = *(P+" << j << ")";
cout << "
V[" << j <<"] = " << **(P+j) << "\n";
}
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 10 Punteros (apuntadores)
208
10.4. Punteros de cadenas
Considéreselasiguientedeclaracióndeunarraydecaracteresquecontienelasv eintiséisletrasdelalfabetointernacional.
char alfabeto[27] = "abcdefghijklmnopqrstuvwxyz";
Sip esunpunteroa char. Seestableceque p apuntaalprimercarácterdealf abetoescribiendo
p =
alfabeto;
// o bien p = &alfabeto[0];
Esposible, entonces, considerardostiposdedefinicionesdecadena
char cadena1[]="Las estaciones";
char *pCadena = "del anyo son:";
//array contiene una cadena
//puntero a cadena
Tambiénesposibledeclararunarraydecadenasdecaracteres:
char* Estaciones[4] ={"Primavera", "Verano", "Otonyo", "Invierno"};
// array de punteros a cadena
10.5. Aritmética de punteros
Aunpunteroselepuedesumarorestarunentero n;estohacequeapunte n posicionesadelante, oatrásdelaactual. Auna
variablepunteroselepuedeaplicareloperador++, oeloperador--.Estaoperaciónhacequeeloperadorcontengaladireccióndelsiguiente, oanteriorelemento.Sepuedensumarorestarunaconstantepunteroaodesdeunpunteroysumarorestar
unentero.Sinembargo, notienesentidosumarorestarunaconstantedecomaflotante.
Operaciones no válidas con punter os: nosepuedensumardospunteros;nosepuedenmultiplicardospunteros;no
sepuedendividirdospunteros.
EJEMPLO 10.7. Modificacióndeunacadenaconunpunter o.
Elprogramaleeunacadenadecaracteres, ymedianteunavariablepuntero, inicializadaalaprimeraposicióndelaray
decaracteres, sevancambiandolasletrasmayúsculasporminúsculasyrecíprocamente.Elbuclewhile iterahastaque
selleguealfinaldelacadenadecaracteres.Lasentencia *puntero++ = *puntero-32. Asignaalcontenidodelpunteroelcontenidodel puntero menoselnúmeroASCII32 paraqueelcarácterpasealetraminúscula.Posteriormente,
elpunteroavanzaunaposición(unbyteporserdetipo char).
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char *puntero;
char Cadena[81];
cout << "Introduzca cadena a convertir:\n\n";
cin.getline(Cadena, 80);
puntero = Cadena;
// puntero apunta al primer carácter de la cadena
CAPÍTULO 10 Punteros (apuntadores)
209
while (*puntero)
// mientras puntero no apunte a \0
if ((*puntero >= 'A') && (*puntero <= 'Z'))
*puntero++ = *puntero+32; // sumar 32, para convertir en minúscula
else if ((*puntero >= 'a') && (*puntero <= 'z'))
*puntero++ = *puntero-32; // restar 32, para convertir en mayúscula
else
puntero++;
cout << "La cadena convertida es:\n" << endl;
cout << Cadena << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Un puntero constante esunpunteroquenosepuedecambiar , peroquelosdatosapuntadosporelpunteropuedenser
cambiados.Paracrearunpunteroquenopuedasermodif icadoopunteroconstante sedebeutilizarelsiguienteformato:
<tipo de dato > *const <nombre puntero> = <dirección de variable >;
Nopuedecambiarseelvalordelpuntero, peropuedecambiarseelcontenidoalmacenadoenlaposicióndememoriaadondeapunta.
Un puntero a una constante sepuedemodificarparaapuntaraunaconstantediferente, perolosdatosapuntadosporel
punteronosepuedencambiar.Elformatoparadefinirunpunteroaunaconstantees:
const <tipo de dato elemento> *<nombre puntero> = <dirección de constante >;
Cualquierintentodecambiarelcontenidoalmacenadoenlaposicióndememoriaadondeapuntacrearáunerrordecompilación, peropuedecambiarseelvalordelpuntero.
Nota: Unadefinicióndeunpunteroconstantetienelapalabrareserv ada const delantedelnombredelpuntero, mientrasqueelpunteroaunadef iniciónconstanterequierequelapalabrareserv ada const sesitúeantesdeltipodedato.
Así, ladefiniciónenelprimercasosepuedeleercomo“punterosconstanteodeconstante”, mientrasqueenelsegundocasoladefiniciónselee“punteroatipoconstantededato ”.
Elúltimocasoaconsiderarescrearpunterosconstantesaconstantesutilizandoelformatosiguiente:
const <tipo de dato elemento> *const <nombre puntero> = <dirección de constante >;
Regla
• Sisabequeunpunterosiempreapuntaráalamismaposiciónynuncanecesitaserreubicado(recolocado), defínalocomounpunteroconstante.
• Sisabequeeldatoapuntadoporelpunteronuncanecesitarácambiar , definaelpunterocomounpunteroauna
constante.
EJEMPLO 10.8. Punteroconstanteypunteroaconstante.
Muestralasoperacionesválidasynoválidasdeunpunteroconstante puntero1, yunpunteroaconstante puntero2.
int x, y;
const int z = 25;
const int t = 50;
int *const puntero1 = &x;
const int *puntero2 = &z;
// constante entera
// constante entera
//puntero1 es un puntero constante
// puntero2 es un puntero a constante
CAPÍTULO 10 Punteros (apuntadores)
210
*puntero1 = y;
p1 = &y;
puntero2 = &t;
*puntero2 = 15;
// sentencia válida puede cambiarse su contenido
//sentencia ilegal no puede cambiarse el puntero
// sentencia válida puede cambiarse puntero2
// sentencia ilegal no puede cambiarse su contenido
Punteros en los array de dos dimensiones. Paraapuntaraunarraybidimensionalcomotal,oloqueeslomismo, paraapuntarasuinicio, elcompiladordeC++consideraqueunarraybidimensionalesenrealidadunarraydepunterosalosarraysque
formansusfilas.Portanto, seránecesariounpunterodobleopunteroapuntero, quecontendráladireccióndelprimerpunterodelarraydepunterosacadaunadelasf ilasdelarraybidimensionalomatriz.Si a sehadefinidocomounarraybidimensional, elnombredelarrayaes unpunteroconstante queapuntaalaprimeraf ila a[0].Elpuntero a+1 apuntaalase gunda
filaa[1], etc.Asuveza[0] esunpunteroqueapuntaalprimerelementodelaf ila0 quees a[0][0].Elpuntero a[1] esun
punteroqueapuntaalprimerelementodelaf ila1 quees a[1][0], etc.
EJEMPLO 10.9. Arraybidimensional, punterosyposicionesdememoria.
Dadaladeclaración float A[5][3] quedefineunarraybidimensionaldecincof ilasytrescolumnas, setienelasiguienteestructura:
Puntero a puntero fila
Puntero a fila
ARRAY BIDIMENSIONAL float A[4][3]
A
➔
A[0]
➔
A[0][0]
A[0][1]
A[0][2]
A+1
➔
A[1]
➔
A[1][0]
A[1][1]
A[1][2]
A+2
➔
A[2]
➔
A[2][0]
A[2][1]
A[2][2]
A+3
➔
A[3]
➔
A[3][0]
A[3][1]
A[3][2]
A+4
➔
A[5]
➔
A[4][0]
A[4][1]
A[4][2]
Aesunpunteroqueapuntaaunarrayde5punteros A[0], A[1], A[2], A[3], A[4].
esunpunteroqueapuntaaunarraydetreselementos A[0][0], A[0][1], A[0][2].
esunpunteroqueapuntaaunarraydetreselementos A[1][0], A[1][1], A[1][2].
esunpunteroqueapuntaaunarraydetreselementos A[2][0], A[2][1], A[2][2].
esunpunteroqueapuntaaunarraydetreselementos A[3][0], A[3][1], A[3][2].
esunpunteroqueapuntaaunarraydetreselementos A[4][0], A[4][1], A[4][2].
A[0]
A[1]
A[2]
A[3]
A[4]
A[i][j]
esequivalentealassiguientesexpresiones:
• *(A[i]+j) elcontenidodelpunteroalaf ilai máselnúmerodecolumna.
• *((*(A+i))+j).Sisecambia A[i] por*(A+i) setienelasiguienteexpresiónanterior.
• *(&A[0][0]+ 3*i+j).
A esunpunteroqueapuntaa A[0].
A[0] esunpunteroqueapuntaa A[0][0].
SiA[0][0] seencuentraenladireccióndememoria100yteniendoencuentaqueunfloat ocupa4bytes, lasiguiente
tablamuestraunesquemadelamemoria:
Contenido de
puntero a puntero
fila
Contenido de
puntero a fila
*A = A[0]
A[0] = 100
&A[0][0] = 100
&A[0][1] = 104
&A[0][2] = 108
*(A+1) = A[1]
A[1] =112
&A[1][0] = 112
&A[1][1] = 116
&A[1][2] = 120
*(A+2) = A[2]
A[2] =124
&A[2][0] = 124
&A[2][1] = 128
&A[2][2] = 132
*(A+3) = A[3]
A[3] =136
&A[3][0] = 136
&A[3][1] = 140
&A[3][2] = 144
*(A +4) = A[4]
A[5] =148
&A[4][0] = 148
&A[4][1] = 152
&A[4][2] = 156
Direciones del array bidimensional float A[4][3]
CAPÍTULO 10 Punteros (apuntadores)
211
EJEMPLO 10.10. Matrizder ealesyvectordepunter osar eales.Difer enciasquepuedenencontr arseentr elas
declaraciones: float A[10][10]; float *V[10];.¿Puedenr ealizarselassiguientesasignaciones?: A= V;
V[1] = A[1]; V[2] = &mt[2][0];.
esunamatrizderealesy V esunv ectordepunterosareales, porloquelasdeclaracionessonesencialmentediferentes.
EncuantoalaprimeaasignaciónA = V, ambasvariablesA yV sonpunterosqueapuntanapunterosareales(aunqueligeramentediferente)porloqueenprincipiopodríarealizarselaasignación, perodebidoaqueambasv ariables
sonpunterosconstantes(alsernombresdev ariablesdearrays), nopuederealizarse, yaquenopuedemodif icarsesu
contenido.
EnlasegundaasignaciónV[1] = A[1], elcompiladorinterpretalaexpresiónA[1] comoconteniendoladirección
delasegundafiladelamatriz, queesunpunteroaunv ectorde 10 reales, porloqueesunpunteroareales.Porotro
lado, paraelcompilador V[1], esunpunteroarealesy, portanto, suvaloresdelmismotipoque A[1].Todoloanteriormenteindicadopermiterealizarlaasignaciónindicada.
Laexpresióndeladerecha &mt[2][0], delaterceraasignación V[2] = &mt[2][0], proporcionaladireccióndel
primerelementodelaterceraf iladelamatiz, porconsiguienteestambiéndetipopunteroarealaligualqueellado
izquierdodelaasignación V[2], porloquelaasignaciónescorrecta.
A
EJEMPLO 10.11. Direccionesocupadasporpunterosasociadosaunamatriz.
Elprogramamuestralasdireccionesocupadasportodosloselementosdeunamatrizderealesdoblesde5filasy4columnas, asícomolasdireccionesdelosprimeroselementosdecadaunadelasf ilas, accedidosporunpunteroaf ila.
Observequelasalidaseproduceenhexadecimal.Ladireccióndeunelementodelamatrizseobtienedelanteriorsumándole8enhexadecimal.
include <cstdlib>
#include <iostream>
using namespace std;
#define N 5
#define M 4
double A[N][M];
int main(int argc, char *argv[])
{
int i,j;
cout <<" direciones de todos lo elementos de la matriz\n\n";
for (i = 0; i < N; i++)
{
for (j = 0; j < M; j++)
cout << " &A[" << i << "][" << j << "]=" << &A[i][j];
cout << "\n";
}
cout << " direcciones de comienzo de las filas de la matriz\n\n";
for (i = 0; i < N; i++)
cout << " A["<<i<<"] = " << A[i]
<< " contiene direccion de &A[" << i << "][" << 0 << "]" << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 10.12. Lecturayescrituradematricesmediantepunteros.Escribirunprogramaqueleayescribamatricesgenéricasmediantepunterosyfunciones.
Parapodertratarlalecturayescrituradematricesmediantefuncionesquerecibanpunteroscomoparámetros, basta
contrasmitirunpunteroapuntero.Además, sedebeinformaracadaunadelasfuncioneselnúmerodecolumnasyfi-
CAPÍTULO 10 Punteros (apuntadores)
212
lasquetiene(aunquesóloesnecesarioelnúmerodecolumnas), porloquelasfuncionespuedenserdeclaradasdela
siguienteforma: void escribir_matriz(int ** A, int f, int c) y void leer_matriz(int ** A, int f,
int c) donde f y c sonrespectivamenteelnúmerodef ilasyelnúmerodecolumnasdelamatriz.P aratratarposteriormentelalecturayescrituradedatosencadaunadelasfuncioneshayqueusar *(*A + c * i + j).Lasllamadasaambasfunciones, debenserconuntipodedatocompatibletalycomosehaceenelprogramaprincipal.Enel
programa, ademássedeclaranelnúmerodef ilasF, yelnúmerodecolumnas C comomacrosconstantes.
#include <cstdlib>
#include <iostream>
#define F 3
#define C 2
using namespace std;
int A[F][C];
void escribir_matriz(int ** A, int f, int c)
{
int i, j;
for (i = 0; i < f; i++)
{
for(j = 0; j < c ; j++)
cout << " " << *(*A + c*i+j);
cout << endl;
}
}
void leer_matriz(int** A, int f, int c)
{
int i, j;
for (i = 0; i < f; i++)
for(j = 0; j < c; j++)
cin >> *(*A + c*i+j);
}
int main(int argc, char *argv[])
{
int * a = &A[0][0];
leer_matriz(&a,F,C);
escribir_matriz(&a,F,C);
system("PAUSE");
return EXIT_SUCCESS;
}
10.6. Punteros como argumentos de funciones
Cuandosepasaunav ariableaunafunción( pasoporvalor)nosepuedecambiarelcontenidodeesav ariable.Sinembargo,
sisepasaunpunteroaunafunción(pasopordirección)sepuedecambiarelcontenidodelavariablealaqueelpunteroapunte.Elpasodeunnombredearrayaunafuncióneslomismoquepasarunpunteroalarray .Sepuedencambiarcualquierade
loselementosdelarray.Cuandosepasaunelementoaunafunción, sinembargo, elelementosepasaporvalor.
LosparámetrosdirecciónsonmáscomunesenC, dadoqueenC++e xistenlosparámetrosporreferenciaqueresuelvenmejorlamodificacióndelosparámetrosdentrodefunciones.
CAPÍTULO 10 Punteros (apuntadores)
213
EJEMPLO 10.13. PasoporreferenciaenCyenC++.
#include <cstdlib>
#include <iostream>
using namespace std;
struct datos
{
float mayor, menor;
};
void leer_registrodatosCmasmas(datos &t) // parámetro por referecia en C++
{
float actual;
cin >> actual;
if (actual > t.mayor)
t.mayor = actual;
else if (actual < t.menor)
t.menor = actual;
}
void leer_registrodatosC(datos *t)
{
float dat;
cin >> dat;
if (dat > t -> mayor)
t -> mayor = dat;
else if (dat < t -> menor)
t -> menor = dat;
}
int main(int argc, char *argv[])
{
datos dat;
.....
leer_registrodatosCmasmas(dat);
leer_registrodatosC(&dat);
system("PAUSE");
return EXIT_SUCCESS;
}
// parámetro dirección C, referencia
// llamada por referencia en C++
// llamada por dirección en C
10.7. Punteros a funciones
Esposiblecrearpunterosqueapuntenafunciones.Estospunterosdefuncionesapuntanacódigoejecutable, enlugardedireccionardatos.Unpunteroaunafunciónessimplementeunpunterocuyov aloresladireccióndelnombredelafunción.
Dadoqueelnombrees, ensímismounpuntero, unpunteroaunafunciónesunpunteroaunpunteroconstante.Medianteun
punterocuyov alorseaigualaladireccióninicialdeunafunciónsepuedellamaraunafuncióndeunaformaindirecta.La
sintaxisgeneralparaladeclaracióndeunpunteroaunafunciónes:
Tipo_de_retorno (*PunteroFuncion) (<lista de parámetros>);
Esteformatoindicaalcompiladorque PunteroFuncion esunpunteroaunafunciónquede vuelveeltipo Tipo_de_reytieneunalistadeparámetros.
torno
CAPÍTULO 10 Punteros (apuntadores)
214
pfunción
función
int funcion(int n)
{
...
...
}
Lafunciónasignadaaunpunteroafuncióndebetenerelmismotipoderetornoylistadeparámetrosqueelpunteroafunción;encasocontrario, seproduciráunerrordecompilación.Lasintaxisgeneraldeincializacióndeunpunteroafuncióny
eldellamadasonrespectivamente:
PunteroFuncion = una funcion
PunteroFuncion(lista de parametros);
Recuerde
•
•
•
•
•
func, nombredeunelemento.
func[] esunarray.
(*func[]) esunarraydepunteros.
(*func[])( ) esunarraydepunterosafunciones.
int (*func[])( ) esunarraydepunterosafuncionesquede vuelvenvalores int.
EJEMPLO 10.13. Arraydepunterosafunciones.Sequier eevaluarlasfuncionesf1(x), f2(x)yf3(x)par atodoslos
valoresdexenelintervalo0.3≤ x≤ 4.1con incrementode0.5.Escribirunprograma queevalúedichasfuncionesutilizandounarraydepunterosafunción.Lasfuncionessonlassiguientes:
f1(x)=3*sin(x)+2.5*cos(x);f2(x)=–x*sin(x)+x*x;f3(x)=x 2 –x+1
Setrata, comosehaceenlacodif icación, dedefinirlastresfunciones f1, f2 y f3 alestilodeC++ydespuésdef inir
unarraydepunterosalasfunciones, alosqueseasignancadaunadelasfuncionespréviamentedef inidas.Elaccesoadichasfuncionesparasuejecuciónessimilaralaccesoqueser ealizaconcualquierotrotipodedatocuandose
accedeconpunteros.
#include <cstdlib>
#include <iostream>
#include <math.h>
#define maxf 3
#define minx 0.3
#define maxx 4.1
#define incremento 0.5
using namespace std;
float f1 (float x)
{
return (3 * sin(x)+ 2.5*cos(x));
}
float f2(float x)
CAPÍTULO 10 Punteros (apuntadores)
215
{
return (-x * sin (x) + x*x);
}
float f3(float x)
{
return ( x * x
}
- x
+ 1);
int main(int argc, char *argv[])
{
float (*Array_de_Funciones[maxf]) (float);
// array de punteros a funciones que retornan reales
Array_de_Funciones [0] = f1;
Array_de_Funciones [1] = f2;
Array_de_Funciones [2] = f3;
for (int i = 0; i < maxf; i++)
{
cout << " funcion " << i +1 << endl;
for ( float x = minx; x < maxx; x += incremento)
cout << " x = "<<x<<" f = " << Array_de_Funciones [i](x) << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Lospunterosafuncionestambiénpermitenpasarunafuncióncomounar gumentoaotrafunción. Parapasarelnombre
deunafuncióncomounar gumentofunción, seespecificaelnombredelafuncióncomoar gumento.
EJEMPLO 10.14. Pasodefuncionescomoparámetrosaotrasfunciones.Cálculodelasumadelos n primerostérminosdeunaseriegenérica.
n
Setratadesumarlos n primerostérminosdeunaseriegenérica suma =Σ ti.Lafunción sumaterminos, recibecomo
i=1
parámetroelnúmerodetérminos n asumaryunafunción fun quecalculaeltérminogenérico.Paraprobarlafunción
seusanlostérminosdedosseries
3
i∗
i
i=1
n
serie1= Σ
1
i=1 i
n
serie2= Σ
Lasfunciones terminoserie1 yterminoserie2, calculanlostérminosdecadaunadelasseries.
#include <cstdlib>
#include <iostream>
using namespace std;
double Sumaterminos(int n, double (*fun) (int ))
{
double acu = 0;
for (int i = 1; i <= n; i++)
acu += fun(i);
return acu;
}
CAPÍTULO 10 Punteros (apuntadores)
216
double terminoserie1(int i)
{
return (double)3.0 / (i * i);
}
double terminoserie2(int i)
{
return (double)1.0 / i;
}
int main(int argc, char *argv[])
{
cout << "Suma de cinco elemento de serie1: "
<< Sumaterminos(5, terminoserie1) << endl;
cout << "Suma de cuatro terminos de serie2: "
<< Sumaterminos(3, terminoserie2) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
10.8. Punteros a estructuras
Sepuededeclararunpunteroaunaestructuratalcomosedeclaraunpunteroacualquierotroobjeto.Cuandosereferenciaun
miembrodeunaestructurausandoelnombredelaestructura, seempleaeloperadorpunto (.).Encambio, cuandosereferenciaunaestructurautilizandoelpunteroestructura, seempleaeloperadorflecha (->) paraaccederaunmiembrodeella.
EJEMPLO 10.15. Accesoamiembrosdeestructuras. Dadaslassiguientesdeclaracionesdeestructuras, setratade
escribircómoaccederalosatributosdat, dia ymes delavariableestructuraest detipodatos. ¿Quéproblemashabríaenlasiguientesentencia? cin.getline( est.nombre,40).
struct fechas
{
int dia, mes, anyo;
float dat;
};
struct datos
{
char* nombre;
fechas * fec;
} est;
Lavariableest esunavariabledetipoestructura, yporestarazónseusaeloperadorpuntoparaaccederalmiembro fec.
Desdeeldatomiembro fec esnecesariousareloperadorflecha -> paraaccederaloscampos dat, día, mes yanyo, alserun
punteroalaestructura fechas alaqueapunta.
est.fec->dat;
est.fec->dia;
est.fec->mes;
est.fec->anyo;
Elcampo nombre delaestructura fechas esunpunteroa char, porellosinosereservamemoriapreviamente, noapuntaaningúnsitio, ydaráproblemascuandolafuncióncin.getline( est.nombre,40) intentecolocarelresultadoenelpun-
CAPÍTULO 10 Punteros (apuntadores)
teroqueselepasacomoar gumento.P arae vitarestoseríanecesarioreserv armemoriaantesdellamara
ne(est.nombre,40), delasiguienteforma este.nombre = new char[41].
217
cin.getli-
EJEMPLO 10.16. Lecturadeunaestructur aconparámetrodetipopunteroaestructura, yvisualizaciónconparámetrodetipoestructura.
#include <cstdlib>
#include <iostream>
using namespace std;
struct articulo
{
char nombre[81];
int codigo;
};
void leerarticulo( articulo * particulo)
{
cout << "nombre del articulo :";
cin.getline(particulo->nombre, 80);
cout << "Codigo del artículo :";
cin >> particulo->codigo;
}
void mostrararticulo ( articulo articul)
{
cout << "nombre del articulo :" << articul.nombre << endl;
cout << "Codigo asociado al articulo : " << articul.codigo << endl;
}
int main(int argc, char *argv[])
{
articulo a;
leerarticulo(&a);
mostrararticulo(a);
system("PAUSE");
return EXIT_SUCCESS;
}
EJERCICIOS
10.1. Encontrarloserroresdelassiguientesdeclaracionesdepunteros:
int x, *p, &y;
char* b= “Cadena larga”;
char* c= ‘C’;
float x;
void* r = &x;
10.2. ¿Quédiferenciassepuedenencontrarentreunpunteroaconstanteyunaconstantepunter o?
CAPÍTULO 10 Punteros (apuntadores)
218
10.3. Unarrayunidimensionalsepuedeindexarconlaaritméticadepunteros.¿Quétipodepunterohabríaquedefinirparaindexarunarraybidimensional?
10.4. Elcódigosiguienteaccedealoselementosdeunamatriz. Accederalosmismoselementosconaritméticadepunter os.
#define N 4
#define M 5
int f,c;
double mt[N][M];
. . .
for (f = 0; f < N; f++)
{
for (c = 0; c < M; c++)
cout << mt[f][c];
cout << “\n”;
}
10.5. Escribirunafunciónconunar gumentodetipopunter oa double yotroargumentodetipo int.Elprimerar gumentose
debedecorresponderconunarrayyelsegundoconelnúmerodeelementosdelarray.Lafunciónhadeserdetipopunteroa double paradevolverladireccióndelelementomenor.
10.6. Dada lassiguientesdefinicionesylafunción gorta:
double W[15], x, z;
void *r;
double* gorta(double* v, int m, double k)
{
int j;
for (j = 0; j < m; j++)
if (*v == k)
return v;
return 0,
}
• ¿Hayerroresenlacodificación?¿Dequétipo?
• ¿Escorrectalasiguientellamadaalafunción?:
r = gorta(W,10,12.3);
• ¿Yestasotrasllamadas?:
cout << (*gorta(W,15,10.5));
z = gorta(w,15,12.3);
CAPÍTULO 10 Punteros (apuntadores)
219
PROBLEMAS
10.1. Sequierealmacenarlasiguienteinformacióndeunaper sona: nombre, edad, alturaypeso.Escribirunafunciónquelea
losdatosdeunapersona, recibiendocomoparámetrounpunteroyotrafunciónquelosvisualice.
10.2. Escribirunprogramaquedecidasiunamatrizdenúmerosrealesessimétrica.Utilizar: 1, unafuncióndetipobool que recibacomoentradaunamatrizdereales, asícomoelnúmerodefilasydecolumnas, ydecidasilamatrizessimétrica;2,otra
funciónquegenerelamatrizde10filasy10columnasdenúmerosaleatoriosde1a100;3, unprogramaprincipalquerealicellamadasalasdosfunciones.Nota: usarlatransmisióndematricescomoparámetrospunterosylaaritméticadepunterosparalacodificación.
10.3. Escribirunprogramaparagenerarunamatrizde4x5númer osreales, ymultipliquelaprimer acolumnaporotr acualquieradelamatrizymostrarlasumadelosproductos.Elprogramadebedescomponerseensubprogramasyutilizarpunterosparaaccederaloselementosdelamatriz.
10.4. Codificarfuncionesparasumaraunafiladeunamatrizotrafila;intercambiardosfilasdeunamatriz, ysumaraunafila
unacombinaciónlinealdeotras.Nota: deberealizarseconpunterosyaritméticadepunteros.
10.5. Codificarfuncionesquerealicenlassiguientesoperaciones: multiplicarunamatrizporunnúmero, yrellenardecerosuna
matriz.Nota: usarlaaritméticadepunteros.
10.6. Escribirunprogramaenelqueselea20líneasdete xto, cadalíneaconunmáximode80car acteres.Mostrarporpantallaelnúmerodevocalesquetienecadalínea, eltextoleído, yelnúmerototaldevocalesleídas.
10.7. Enunacompeticióndenataciónsepresentan16nadadores.Cadanadadorsecaracterizaporsunombre, edad, pruebaen
laqueparticipaytiempo(minutos, segundos)delaprueba.Escribirunprograma querealicelaentradadelosdatosycalculeladesviacióntípicarespectoaltiempo.
10.8. Escribirunprogramaquepermitacalculareláreadediversasfiguras: untriángulorectángulo, untriánguloisósceles, un
cuadrado, untrapecioyuncírculo.Nota: utilizarunarraydepunterosdefunciones, siendolasfuncioneslasquepermiten
calcularelárea.
10.9. DesarrolleunprogramaenC++queuseunaestructur aparalasiguienteinformaciónsobr eunpacientedeunhospital:
nombre, dirección, fechadenacimiento, sexo, díadevisitaypr oblemamédico.Elpr ogramadebetenerunafunciónpar a
entradadelosdatosdeunpaciente , guardarlosdiversospacientesenunarr ayymostrarlospacientescuyodíadevisita
seaunodeterminado.
10.10. Escribirunafunciónquetengacomoentradaunacadenaydevuelvaunnúmeroreal.Lacadenacontieneloscaracteresde
unnúmerorealenformatodecimal(porejemplo, lacadena“25.56” sehadeconvertirenelcorrespondientevalorreal).
10.11. Escribirunpr ogramapar asimularunapequeñacalculador aquepermitaleere xpresionesenter asterminadasenel
símbolo=ylase valúedeizquier daader echasintenerencuentalaprioridaddelosoper adores.Ejemplo4*5-8=12.
Nota: usarunarraydefuncionespararealizarlasdistintasoperaciones(suma, resta, producto, cocienteresto).
SOLUCIÓN DE LOS EJERCICIOS
10.1. Esincorrectasintácticamenteladeclaraciónint &y, yaqueesunareferenciaydebeserinicializadaaunavariable.(Una
referencia esunaliasdeotr avariable.)NotieneningúnsentidoenC++, deberíaser, porejemplo, int &y = x.Uncarácterqueestáentrecomillassimplesesconsideradocomounaconstantedetipo char nocomounacadena, paralocual
deberíaestarrodeadodedoblescomillas: char* c= "C".Ladeclaraciónvoid* r = &x; escorrecta.
CAPÍTULO 10 Punteros (apuntadores)
220
10.2. Pormediodeun punteroaconstante sepuedeaccederalaconstanteapuntada, peronoestápermitidocambiaromodif icarsuvalorpormediodelpunter o.Unpunterodeclaradocomoconstante nopuedemodificarelvalordelpunter o, esdecir, ladirecciónquecontieneyalaqueapunta;peropuedemodificarseelcontenidoalmacenadoenlaposicióndememoriaalaqueapunta.
10.3. Eltipodelpunteroqueseutilicepararecorrerunarrayunidimensionaltienequeserdelmismotipoqueeldeloselementosquecomponganelarray, puestoquevaairapuntandoacadaunodeellossegúnlosrecorra.Elaccesoyrecorridopuederealizarsedelasiguienteforma:
int *p, v[5];
p = v;
for (int i = 0; i < 5; i++, p++)
//
p apunta a v[i]
ElcompiladordeC++consideraqueunarraybidimensionalesenrealidadunarraydepunterosalosarraysqueforman
susfilas, porloquepar aapuntaraliniciodeunarr aybidimensionalesnecesariounpunter odobleopunteroapuntero,
quecontieneladir eccióndelprimerpunterodelarraydepunterosacadaunadelasf ilasdelarraybidimensionalomatriz.Comolosarr aysbidimensionalessealmacenanenmemorialinealmentef ilaafila, paraaccederaunelementoconcretodeunaf ilaycolumnadeterminadashayquecalcularprimer oenquef ilaestáydentr odeesaf ilaenquécolumna
parapodercalcularsuposicióndentrodelamemoria.Pararealizarestaoperaciónnoesnecesariosabercuántasfilascontienelamatrizbidimensionalperosícuántascolumnas, parasabercuántosbytesocupacadafila(conocidoeltipodedato).
Porejemplodadaladeclaración:
int v[10][5];
sonexpresionesequivalentes:
v[i][j];
*(v[i] +j );
// puntero de filas
*((*(v + i)) + j)
//puntero de columnas
(&v[0][0] + Numero_de_columnas * i + j)
10.4. Sedefineunpunteroapunteroqueapuntealaprimeraposicióndelamatrizysecalculanlasposicionesdememoriadondeseencuentrancadaunodeloselementosdelamatriz, abasedesumarlalongituddelasf ilasdesdeelcomienzodela
matrizyloselementosdesdeelcomienzodelaf iladondeestásituadoelelementoalquesedeseaacceder .Siunelemento estáenlafilai, habráquesaltar i filasenterasdeelementosdeltipodelamatriz, parasituarsealcomienzodesuf ila
enlamemoria.Sielelementoqueseb uscaestáenlacolumna j, hayqueavanzartresposicionesdesdeelcomienzodesu
filacalculadoanteriormente . Así, seaccedealadir eccióndondeseencuentr aelelementob uscado. V[i][j] está
*(&V[0][0] + i * (numero_de_columnas) + j) (Pararealizarloscálculosesimprescindibleconocerelnúmerodecolumnasdelamatriz, queesigualaltamañodecadafila).Elelementobuscadotambiénseencuentraen*(V[i]+j), obien
en*((*(mt+f))+c).Unadeestasexpresiones(normalmentelaprimera)eslamismaquesustituyeelcompiladordeC++,
cuandocompilalaindirecciónquerepresentanlosoperadorescorchetesdelosarrays.Enlacodificaciónquesepresenta,
seincluyencadaunadelase xpresionesanterioresparavisualizarlamatriz.
#include <cstdlib>
#include <iostream>
using namespace std;
#define N 2
#define M 3
double mt[N][M];
int main(int argc, char *argv[])
{
int f, c;
CAPÍTULO 10 Punteros (apuntadores)
221
for (f = 0; f < N; f++)
for (c = 0; c < M; c++)
cin >> mt[f][c];
cout << " mt[f][c]\n";
for (f = 0; f < N; f++)
{
for (c = 0; c < M; c++)
cout << mt[f][c] << " ";
cout << endl;
}
cout << " * ( ( * (mt + f) ) + c)\n";
for (f = 0; f < N; f++)
{
for (c = 0; c < M; c++)
cout << (* ( ( * (mt + f) ) + c)) << " ";
cout << endl;
}
cout << " * (mt[f]+c)\n";
for (f = 0; f< N; f++)
{
for (c = 0; c < M; c++)
cout << ( * (mt[f] + c)) << " ";
cout << endl;
}
cout << " * (&mt[0][0] + M * f + c)\n";
for (f = 0; f< N; f++)
{
for (c = 0; c < M; c++)
cout << (* (&mt[0][0] + M * f + c)) << " ";
cout << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
10.5. Alhacerlallamadaalafunciónsedebepasarelnombr edelarrayquesevaarecorrerounpunteroconladireccióndel
comienzodelarray.Elpunteroquerecibelafunción double *A puedesertratadodentrodesucódigocomosifuer aun
array, usandoeloperadorcorchete[], A[i], ocomounsimplepunteroquesevaamoverporlamemoria.Enestecasose
codificaconeloperadorcorchete.Pararesolverelproblemaplanteadoseusaunalgoritmovoraz, quetomacomo minimo
elprimerelementoA[0],ycomodireccióndelmínimodirminimo ladireccióndelprimerelementodelarray&A[0].Usandoelsegundoparámetrodelafunción int n, queesnecesariopar anomoversefueradelaregióndelamemoriadonde
estánlosdatosválidosdelarrayoriginalalmacenados, seiteraconunbuclefor, eligiendocomonuevominimo elqueya
seteníaoelqueseestátr atandoencasodequelosea.
double *minimo_de_Array (double *A, int n)
{
int i;
CAPÍTULO 10 Punteros (apuntadores)
222
double minimo = A[0];
double *dirminimo = & A[0];
for (i = 0; i < n; i++)
if (A[i] < minimo)
{
dirminimo = &A[i];
minimo = A[i];
}
return dirminimo;
}
10.6. Lafuncióntiene, enprimerlugar, unerrordesintaxisenlasentenciareturn, yaquedebeterminarnecesariamenteenpuntoycoma( ;) ynoencoma( ,) comoasílohace .Porotraparte, seobservaqueelb ucle for iteraperosiemprecompara
elmismovalor *v = = k, yparecequehayotroerrorsemánticoysintáctico, yaqueespocoprobablequeseprogrameun
bucleparacompararunsoloelemento. Talvez, loqueelpr ogramador, hayaqueridoprogramar, seaunafunciónquer etorneladireccióndelaprimeraocurrenciade k enelvector v, porellolacodificacióndeberíaserlasiguiente:
double* gorta(double* v, int m, double k)
{
int j;
for (j = 0; j < m; j++)
if (*v == k)
return v;
else
v++;
return 0;
}
// si no se encuentra retorna el valor de 0
• Laprimerallamada r = gorta(W,10,12.3);escorrectayaqueaunpunter o void selepuedeasignarcualquierotr o
tipodepunteros, yelvalorde m es12 queesmenoroigualque 15 queeseltamañodeclaradodelarray.
• Lase gundallamada cout << (*gorta(W,15,10.5) essintácticamentecorr ecta.Later cerallamada z = gorta
(W,15,12.3) esincorrectayaqueaunavariabledetipo double nopuedeasignárseleunpunteroauntipo double.
SOLUCIÓN DE LOS PROBLEMAS
10.1. Sedeclaralaestructura Persona conlosatributosindicados, yseprogramalasdosfuncionespedidas, ambasconparámetrostipopunteroa Persona, conloqueelaccesoalosmiembr osdebehacer secon -> Además, seprogramaunallamadaalafunción mostrar_Persona usandounArray_de_Personas, previamenteinicializadoconlainformacióndedos
personas, realizandolasllamadasconunpunterop quetomaantesdecomenzarelbucleelvalorde p = Array_de_Personas.
La codificación de este problema se encuentra en la página Web del libro.
10.2. Lafunciónsimetrica decidesiunamatrizm cuadradaquerecibecomoparámetroessimétrica, porloqueesdetipobool.
Estafunciónsecodificacontresparámetrosbool simetrica (float **mat, int f, int c).Elprimeroesunpunteroapunterodereales, m enelqueserecibelamatriz, elsegundo, f, yeltercero, c, sonrespectivamenteelnúmerodefilas
CAPÍTULO 10 Punteros (apuntadores)
223
ydecolumnas, queenelcasodeunamatrizcuadradadebecoincidir.Esbienconocidoqueunamatrizessimétricasicada
unodesuselementosesigualasusimétricoconr espectoaladiagonalprincipal.Pararesolverelproblemadedecidirsi
unamatrizessimétrica, sedefineunavariabledetipobool sime, inicializadaatrue.Estavariableseponeafalse cuandoseestásegurodequelamatriznocumplelacondicióndesimetría.Elr ecorridodelamatrizsehacemediantedosb ucles for anidadosqueavanzanporlasposiblesf ilasycolumnas, siemprequelacondicióndesimetríasigacumpliéndose
(sesaledecualquieradelosdosbuclessisime tomaelvalorde false).Sienunadelasiteracionessecompruebaqueno
secumplelacondición“cadaelementoesidénticoalqueseobtienecambiandosuf ilaporsucolumna” lavariable, ointerruptorsime cambiadevalorponiéndosea false.
Lafunción crearMatriz, generaaleatoriamentelosdatosdelamatrizcuadr adade f filasy c columnas.Parahacerlousalasfunciones randomize yrandom definidasensendosmacros, yqueseencargandegenerarlasemillaylossucesivosnúmerosaleatoriosenelrangode 1 ymax =100.
Elprogramaprincipalrealizalasllamadasalasfuncionese xplicadasanteriormente, paramostrarcómodeber ealizarseunainvocacióndelasmismas.Sehacealpropiotiempounallamadaalafunción escribir_matriz, cuyoprototipo
esincluidoenelcódigo, ycuyacodificación, puedeconsultarseenelEjemplo10.11. Anivelglobalsereferencianensentenciasdefine elnúmerodefilas, eldecolumnasyelvaloraleatoriomáximoquesepuedeg enerarenloscorrespondientesidentificadoresF, C, max.
La codificación de este problema se encuentra en la página Web del libro.
10.3. Lafunciónmultiplicacolumna recibecomoparámetroenformadepunteroapunteroderealeslamatriz m, elnúmerode
filaseldecolumnas, asícomolacolumna ncol quesemultiplicaporlacolumna 0, unvectordepunterosvp comopunteroareales, dondeseretornaelresultado.Lacodificaciónusaunbuclefor querecorrelassucesivasfilasdelamatriz, para
iralmacenandolosr esultadosdelospr oductosparcialesdelacolumna 0 porlacolumna ncol enlasposicionescorr espondientesdelvector vp.
Lafunción muestravector, seencargademostrarelvector v querecibecomoparámetro(punteroareales).
Lafunciónmuestra_suma realizalasumadelascorrespondientescomponentesdelvectorquerecibecomoparámetro
visualizandoelresultado.
Elprogramaprincipalrealizalassucesivasllamadasalasfunciones,usando, además, lasfuncionesescribir_matriz
ycrearMatriz cuyosprototipossonincluidos, ycuyacodificaciónpuedeconsultarseenelProblema10.2.
La codificación de este problema se encuentra en la página Web del libro.
10.4. Lafunción Intercambiafilas, recibelosnúmerosdelasfilasquedebeintercambiar, nf1, nf2, ymedianteunbucleitera
porcadaunadelascolumnasinter cambiandoloselementosunoauno.Lafunción Sumafilas eslaencargadadesumar
alafila nf1, lafila nf2, realizándolomediantesucorr espondientebucledecolumnascontr oladoporlavariable j.Para
sumaraunaf ila nf1, unacombinaciónlinealdef ilas, lafunción Sumacombinacion, recibeloscoeficientesdelacombinaciónenelvector vf (punteroareales)y, posteriormente, porcadaelemento j delafilanf1, selasumalacombinación
lineal
m(nf1,j)=
f–1
Σ m(i, j)∗vf(i)
i=0
La codificación de este problema se encuentra en la página Web del libro.
10.5. Lacodificacióndeambasfuncionesescasitrivial.Bastaconr ecorrertodosloselementosdelamatrizporf ilasycolumnas, efectuandoloscálculoscorrespondientes
La codificación de este problema se encuentra en la página Web del libro.
10.6. Paraalmacenareltextodeentradasedeclaraunsinónimodechar* queeslinea, paraquealdeclararentrada comoun
punteroalínea, setengaunpunteroqueapuntaaunpunterodecaracteres.Éstaesunaformadedeclararunamatrizbidimensionaldecaracteres, detalmaneraquecadaunadelasf ilascontengaunalíneadelaentr ada.Alnodeclararuna
matrizdecaracterescomotalenelpr ograma, esnecesariodisponerdememoriapar alamatriz, reservandoprimeramentememoriaparaunvectordepunter osa char conlaorden entrada = new linea [20] y, posteriormente, reservando
CAPÍTULO 10 Punteros (apuntadores)
224
memoriaparacadaunadelaslíneasmediantelaor den entrada[i] = new char[strlen(cad)+1].Estavariable cad,
esunacadenadecaracteres(punteroacarácter)alaqueselereservamemoriaparaalmacenarunalíneacompletade80
caracteres.Ahorabien, cuandosereservamemoriaa entrada[i], sólosehaceconlalongitudrealquetengalalínealeída, sindesperdiciarespaciodememoriasinserusadacomoocurriríasihubieradefinidounamatrizcontodaslasfilasde
lamismalongitud.Elpr ogramaquesepresenta, leelaslíneasdelte xtoenunbucleexternocontroladoporlavariable i,
almacenándolasenelarr aybidimensional entrada, para, posteriormente, enotrobucleinternocontroladoporlavariablej, irtratandocadaunodeloscaracteresdelalínea, paraacumularlasvocalesypodervisualizarelr esultadodelnúmerodevocalesleídasalfinaldelbucleinterno.Unvezterminadalalecturadedatos, sepresentaeltextoleído, asícomo
elnúmerototaldevocalesquetieneelte xto.
La codificación de este problema se encuentra en la página Web del libro.
10.7. Elprimerpasoconsisteendefinirunaestructuratiempos parapoderalmacenarlosminutosysegundos.Elsegundopaso
consisteendefinirlaestructura regnadador paraalmacenarlosdatosdecadanadador.Comolaestructura regnadador
tienemiembrosquesoncadenas, sedeclaranpunterosacarácter, parareservarsólolamemoriaquesenecesite , unavez
queseconozcalalongituddelacadenaqueseintr oduceenelcampo. Altenerquealmacenarunmáximode16nadadoressedefineunarrayVectorNadadores quealmacenalainformacióndecadaunodelosnadadores, comopunterosaestructurasde regnadador porloquealprincipiodelpr ogramasecreaunarr aydepunterossininicializar, loqueocupa
pocoespacioenmemoria.Se gúnseleacadaunodelosnadador essereservaráespacioenmemoriaajustadoalainformaciónquesealmacena.Elahorr oenespaciodememoriaessignif icativocuandoelnúmer oder egistros, comoeneste
caso, esgrande.Lasfunción leerregnadador seencargadelareservadememoriaparaunregistrodeunnadador, yleer
losdatosintroducidosporelusuario.Recibecomoparámetr oporreferenciaunpuntero reg a regnadador.Paravisualizarlosdatosdeunnadadorseemplealafunción escribirregnadador querecibecomoparámetrounpunteroaunaestructuraregnadador.Porúltimo, lafunción DesviaciónMedia, calculaladesviaciónmediaensegundosdelarraydenadadores, paraloquenecesitaunafunción MediaVector, encargadadecalcularlamediaense gundosdelosnadador es.
Lasexpresionesmatemáticasdeestasdosfuncionesson:
n–1
m =
Σ abs(a(i)–m)
dm = i=0
n
n–1
1Σ a(i)2@n
i=0
La codificación de este problema se encuentra en la página Web del libro.
10.8. Seprogramanenprimerlugarlasfuncionesquecalculanelár eadecadaunadelasf igurasdeacuer doconlascorr espondientesfórmulas:
Tri Rec=(c1 ∗ c2)/2
ŒW1 2
TriIsos =l1∗
l2
l12 – ___
2
2
Cuad =l2
Circ =p*r2
Elarrayareafigura[] contienelosnombresdecadaunadelasfunciones.Estearraydenombresdelasfuncioneses
llamadoenelprogramaprincipal, dentrodeunmenúdeopciones.
La codificación de este problema se encuentra en la página Web del libro.
10.9. Elprogramasehaestructur adodelasiguienteforma: Lafunción leer_registro, solicitaalusuariotodoslosdatosde
un registro, cuyosatributoshansidodeclar adosenlaestructur a registro, retornandolosresultadosenelparámetr o
porreferencia reg.Estafunciónpermitealusuariolaposibilidaddenocontinuarconlaentr adadenue vosregistrosde
pacientes.Lalecturadelainformacióndetodoslospacientesesrealizadaporlafunción leervector.Estafunciónretornalainformaciónenvector, queesunparámetrorecibidocomopunteroaregistro.Lafunciónmostrarlasconsultas,
estáencargadadevisualizarlosnombresdelospacientesquecumplanlacondicióndelafec ha.Porsuparteelprograma
principalrealizalasllamadasalasdistintasfunciones.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 10 Punteros (apuntadores)
225
10.10. PararesolverelproblemaseprogramalafunciónCadena_A_Numero querecibelacadenadecaracteresyloretornacomo
númeroreal.Elalgoritmotienelassiguientespartes: saltarselosblancos;decidirelsigno;extraerlaparteentera;añadir
lapartedecimal.Parahacerlo, bastaconrecorrerlacadenadecaracteresconunpunterocarácteracarácteryconvertir
loscaracteresadígitos, usandoelnúmeroASCIIasociado 9 = '9'–'0'.Seincluye, además, unprogramaprincipalque
efectúallamadasalafunción.
La codificación de este problema se encuentra en la página Web del libro.
10.11. Paraprogramarunapequeñacalculadora, sedefinenenprimerlugarlasfuncionesquesepuedenusarenella.Enestecaso
lasde sumar, restar, multiplicar, dividir y resto denúmerosenteros.Sedef ineunarr aydepunter osafunción,
arrayfunc[], inicializadoconcadaunadelasoper aciones.Asimismo, setratanlossímbolosdecadaunadelasfuncionesenotroarrayoperadores, inicializadoacadaunodeellos.Enestecasoestossímbolosson: +, –, *, /, %.Unavezdefinidosdosoperandoscomovariablesdetipo char denominadosoperando1, operando2, yunoperador, seleenenprimer
lugarunoperandoyunoperador, yseiterahastafindedatos(=), leyendoelsiguienteoperador, evaluandolaexpresión,
realizandolacorrespondientellamadaalafunciónalmacenadaen arrayfunc, yvolviendoasolicitarunnuevooperador.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
10.1. Dadalasiguientedeclaración, escribirunafunciónque
tengacomoar gumentounpunteroaltipodedatoy
muestreporpantallaloscampos.
struct boton
{
char* rotulo;
int codigo;
};
porcolumnas.Elprimerargumentosecorrespondecon
unamatrizentera, elsegundoyterceroeselnúmerode
filasycolumnasdelamatriz.Escribalaimplementacióndelafunciónaplicandolaaritméticadepunteros.
10.4. Escribirunafuncióncuyoprototiposeasimilaraldela
funcióndelejercicioanterior, cuyopropósitosealeerde
laentradalasfilaspares.Escribirlaimplementaciónde
lafunciónaplicandolaaritméticadepunteros.
10.2. Escribirunafunciónquetengacomoargumentounpunteroaltipodedato boton delejercicioanterioryleade
laentradalosdistintosdatos.
10.5. Escribirfuncionesqueusandolaaritméticadepunteros
ypunteroscomoparámetrosrealicenlasuma, restay
productodematrices.
10.3. Elprototipodeunafunciónes:
10.6. Escribirunafunciónquerecibacomoparámetrounvectoryundato, yretorneladireccióndelaposicióndel
vectordondeseencuentreeldato.
void
escribe_mat(int** t, int nf, int nc).Lafun-
cióntienecomopropósitomostrarporpantallalamatriz
CAPÍTULO 10 Punteros (apuntadores)
226
PROBLEMAS PROPUESTOS
10.1. Dadounarrayquecontieneunaseriedere gistroscon
losdatosdeclientesdeunestablecimiento, realizaruna
funciónenelquesedecómoentradaunpunteroaliniciodelarrayyelapellidodeuncliente.Lafuncióndebe
devolverladireccióndelregistroquecontienelosdatos
delclientebuscadoo NULL sinoloencuentra.Incluirla
funciónenunprogramaqueutiliceelpunteroresultado
paraimprimirlosdatosdelcliente.
10.2. Sequieree valuarlasfunciones f(x), g(x), h(x) y z(x)
paratodoslosvaloresdex enelintervalo0 ≤ x <3.5 con
incrementode0.2.Escribirunprograma queevalúedichasfunciones, utilizandounarraydepunterosafunción.Lasfuncionessonlassiguientes:
f(x)=3*e x –2x;g(x)=–x*sin(x)+1.5h(x)=
=cos(x)+tan(x);z(x)=x 3 –2x+1
10.3. Suponerquesetieneuncatálogodeunalmacénconlos
datosdecadaunodelosartículosen stock yquesedeseacambiarelordenenqueaparecenenlatablaperosin
modificar, enrealidad, elordenenquefueronalmacenadoslosregistrosenelarray.Escribirunprogramaque
añadauncampodetipopunteroalmismotipodeestructuraacadare gistro.Unav eztransformadoelarray
elprogramahadehacerqueelpunterodecadaestructuraapuntealaestructuraqueestaríaacontinuaciónsegúnunnuevoorden, porejemplo, enordencrecientede
númerodelartículo.
10.4. Utilizandoelarraydeestructurasdelejercicioanterior
escribirunafunciónquebusqueunartículoporsucódigoutilizandoelmétododebúsquedabinariaqueaprovechalaordenacióndelosre gistrospormediodelos
punteros.
10.5. Escribirunafunciónquetengacomoentradaunacadenadecaracteresenlaqueseintroducendistintosnúme-
rosrealesseparadosporblancosydevuelvaunarrayde
númerosreales(porejemplolacadena “25.56 23.4”
sehadeconvertirenloscorrespondientesv alorereales
yretornarlosenunvector).
10.6. Setienelaecuación 3*ex–7x=0 , paraencontraruna
raíz(unasolución)escribirtresfuncionesqueimplementenrespectivamenteelmétododeNe wton, RegulaFalsiyBisección.Mediantepunterodefunciónaplicar
unodeestosmétodosparaencontrarunaraízdedicha
ecuación.
10.7. Sepretendegestionarunvídeoclub;sedisponedelos
datosdetodaslaspelículasquesepuedenalquilaryde
losclientesabonados.Escribirunprogramaquecree
dosarraysdeestructurasunoparalaspelículasdevídeo
yotroparalosclientescontodossusdatos.Laestructuradecadapelículatendráunpunteroalaestructurade
latabladeclientesalregistrodelclientequehaalquilado.Tambiénalre vés, elregistrodecadaclientetendrá
unpunteroalregistrodelapelículaquetienealquilada.
Elprogramapedirácontinuamenteelnombredecada
cintayaquiénseprestaoquiénladevuelve, colocando
acontinuaciónlospunterosdeformaqueapuntenalos
registrosquecorrespondan.
10.8. Modificarelprogramaanteriorparasacarporpantalla uninformequeindiquelaspelículasalquiladasy
a quién, losclientesylaspelículasquetienenyque
permitatambiénpre guntarquéclientetieneunadeterminadacinta.
10.9. Escribirunafuncióngenéricaquerecibacomoparámetrounv ectoryelnombredelmétododeordenación, y
realicelaordenaciónporelmétodoindicado.
Nota:
úsenselosmétodosdeordenacióncodificadosenelCapítulo12.
CAPÍTULO 11
Gestión dinámica
de la memoria
Introducción
Losprogramaspuedencrearvariablesglobalesolocales.Estasclasesdev ariablessedefinencuandosecompilaelprograma
porloqueelcompiladorreserva(define)espacioparaalmacenarvaloresdelostiposdedatosdeclaradosenelmomentodela
compilación.Sinembar go, nosiempreesposibleconocerconantelaciónalaejecucióncuántamemoriasedebereserv aral
programa.
C++asignamemoriaenelmomentodelaejecuciónenel montículo omontón (heap), mediantelasfunciones malloc()
y free().C++ofreceunmétodomejorymásef icientequeCpararealizarlagestióndinámica(entiempodeejecución)de
lamemoria.Enlugardellamaraunafunciónparaasignaroliberarmemoria, C++proporcionadosoperadoresparalagestión
delamemoria: new() ydelete(), queasignanyliberanlamemoriadeunazonadememoriadenominadaalmacénlibre (free
store).
11.1. Gestión dinámica de la memoria
Ennumerosasocasiones, noseconocelamemorianecesariahastaelmomentodelaejecución.Porejemplo, sisedeseaalmacenarunacadenadecaracterestecleadaporelusuario, nosepuedeprever, apriori, eltamañodelarraynecesario, amenos
quesereserveunarraydegrandimensiónysemalgastememoriacuandonoseutilice.Elmétodopararesolv eresteinconvenienteesrecurrirapunterosyatécnicasde asignacióndinámicadememoria.
Unespaciodelav ariableasignadadinámicamentesecreadurantelaejecucióndelprograma, alcontrarioqueenelcaso
deunavariablelocalcuyoespacioseasignaentiempodecompilación.Elprogramapuedecrearodestruirlaasignacióndinámicaencualquiermomentodurantelaejecución.
Elcódigodelprogramacompiladosesitúaense gmentosdememoriadenominados segmentosdecódigo .Losdatosdel
programa, talescomovariablesglobales, sesitúanenunáreadenominadasegmentodedatos.Lasvariableslocalesylainformacióndecontroldelprogramasesitúanenunáreadenominadapila.Lamemoriaquequedasedenominamemoriadelmontículo oalmacénlibre.Cuandoelprogramasolicitamemoriaparaunavariabledinámica, seasignaelespaciodememoriadeseadodesdeelmontículo.
227
CAPÍTULO 11 Gestión dinámica de la memoria
228
ErrortípicodeprogramaciónenC++
Ladeclaracióndeunarraye xigeespecificarsulongitudcomounae xpresiónconstante, asísedeclaraunarrayde100
elementos: char cadena[100];
Siseutilizaunavariableounaexpresiónquecontienevariablesseproduciráunerror.
ElmapadememoriadelmodelodeunprogramagrandeesmuysimilaralmostradoenlaFigura11.1.Eldiseñoe xacto
dependerádelmodelodeprogramaqueseutilice.Elalmacénlibrees, esencialmente, todalamemoriaquequedalibredespuésdequesecargaelprograma.
Memoria alta
El montículo (almacén libre)
Toda la memoria que queda libre está disponib le
en asignaciones dinámicas de memor ia.
SP
Segmento de Pila
La pila crece hacia abajo en memor ia.
SS
Datos no inicializados.
DS
Datos inicializados.
Cada segmento dato, código
o pila se limita a 64K
Segmento de código #n.
CS
.
.
Segmento de código #2.
Memoria baja
Segmento de código #1.
Figura 11.1. Mapa de memoria de un programa
EnClasfuncionesmalloc() yfree() asignanyliberanmemoriadeunbloquedememoriadenominadoelmontículodel
sistema.C++ofreceunnue voymejormétodoparagestionarlaasignacióndinámicadememoria, losoperadores new y delete, queasignanyliberanlamemoriadeunazonadememoriallamada almacénlibre.
Losoperadores new y delete, sonversátilesyfiablesyaqueelcompiladorrealizav erificacióndetiposcadav ezqueun
programaasignamemoriacon new.Seimplementancomooperadoresporloquelosprogramaspuedenutilizarlossinincluir
ningúnarchivodecabecera.Nuncarequierenmoldeado (conversiónforzosadetipos)detiposyesohaceanew ydelete sean
fácilesdeusar.Losobjetoscreadoscon new residenenelalmacenamientolibre.Losobjetosdelalmacenamientolibreseeliminanconeloperador delete.
10.2. El operador new
Eloperador new asignaunbloquedememoriaqueeseltamañodeltipodedato.Eldatouobjetodatopuedeserun int, un
float, unaestructura, unarrayocualquierotrotipodedato.Eloperadornew devuelveunpuntero, queesladireccióndelbloqueasignadodememoria.Elformatodeloperador new es:
puntero = new nombreTipo (inicializador opcional)
obien
1. tipo *puntero = new tipo
2. tipo *puntero = new tipo[dimensiones]
// No arrays
// Arrays
Elformato1esparatiposdedatosbásicosyestructuras, yelsegundoesparaarrays.Cadavezqueseejecutaunaexpresiónqueinvocaaloperador new, elcompiladorrealizaunaverificacióndetipoparaasegurarqueeltipodelpunteroespecif i-
CAPÍTULO 11 Gestión dinámica de la memoria
229
cadoenelladoizquierdodeloperadoreseltipocorrectodelamemoriaqueseasignaenladerecha.Silostiposnocoinciden,
elcompiladorproduceunmensajedeerrorde volviendoNULL.
Sintaxis de los operadores new ydelete
puntero = new tipo;
delete puntero ;
Eloperadornew devuelveladireccióndelavariableasignadadinámicamente.Eloperador delete eliminalamemoria
asignadadinámicamentealaqueseaccedeporunpuntero.
Sintaxis de asignación-desasignación deunarraydinámico.
Puntero Array = new[tamaño Array]
delete[] Puntero Array ;
EJEMPLO 11.1. New ydelete detipobásicoycadena.
Seasignamemoriadinámicaaunacadenadecaracteresyaunenteroyseliberalamemoriaaasignada.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char *Cadena = " Montes de Toledo en Castilla la Mancha";
int * pEntero, lonCadena, Entero = 15, ;
char *pCadena;
lonCadena = strlen(Cadena);
pCadena = new char[lonCadena+1]; //Memoria con una posición fin cadena
strcpy(pCadena, Cadena);
//copia Cadena a nueva área de memoria
pEntero = new int;
//se reserva memoria para un entero
*pEntero = Entero;
// se almacena en contenido de pEntero 15
cout << " pCadena =" << pCadena << " longitud = "<< lonCadena<<endl;
delete pCadena;
// libera memoria de pCadena
cout << " *pEntero = " << *pEntero << endl ;
delete pEntero;
// libera memoria de pEntero
system("PAUSE");
return EXIT_SUCCESS;
}
Sepuedeinvocaraloperador new paraobtenermemoriaparaunarray, inclusosinoseconoceconantelacióncuántamemoriarequierenloselementosdelarray.Todoloquesehadehaceresinvocaraloperador new utilizandounpunteroalarray.
Sinew nopuedecalcularlacantidaddememoriaquesenecesitacuandosecompilesusentencia,new esperahastaelmomento
delaejecución, cuandoseconoceeltamañodelarray, yasigna, acontinuación, lamemorianecesaria.
Cuandoseasignamemoriaconeloperador new, sepuedesituarunvaloroexpresióndeinicializacióndentrodeparéntesisalfinaldelaexpresiónqueinvocaeloperador new.C++inicializaentonceslamemoriaquesehaasignadoalv alorquese
haespecificado.Sinembargo, nosepuedeinicializarcadaelementodeunarrayconlaorden new.
EJEMPLO 11.2. Reservadinámicadememoriaeinicialización.
Sereservaeinicializamemoriadinámicadeunenteroydeunv
nidos.
ectordeenterosdinámico, visualizandolosconte-
CAPÍTULO 11 Gestión dinámica de la memoria
230
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i, *v, n, *pEntero;
pEntero = new int(20);
//reserva e incialización de memoria
cout << " *pEntero incializado: " << *pEntero << endl;
cout << " introduzca dimension de v : ";
cin >> n;
v = new int[n];
// reserva dinámica no se puede inicializar
for( i = 0; i < n; i++)
v[i] = 10 * (i+1);
cout <<" vector :\n";
// rellenado del vector
for( i = 0; i < n; i++)
cout << " v[" << i << "]=" << *v++;//salida de datos con puntero
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Paraasignarmemoriadinámicaaunarraymultidimensional, seindicacadadimensióndelarraydeigualformaquesedeclaraunarraymultidimensional, haciendousodetipossinónimos, peronoesexactamenteelmismotipodedato.
typedef float * col;
float ** p;
float m[5][5];
p = new col[5];
// también col *p;
// m apunta a un array de punteros de 5 reales
// p apunta a un array de punteros reales
//de cualquier longitud
for(int i = 0; i < 5; i++)
p[i] = new int[5];
// p apunta a un array de punteros de 5 reales
perohayquetenerencuentaqueahorasone xpresionesequivalentesy, portanto, puedenmezclarseloscódigos:
p[i][j]
*(*(p+i)+j)
*(p[i]+j)
perolaexpresión *(&p[0][0] + i * 5 + j) esdistintaalasanterioresynodebemezclarseenloscódigos(lae xpresión
anteriorconlasotras), yaqueelcompiladordebealmacenarlainformación“p[i] esunpunteroqueapuntaaunarraydepunterosarealesdelongitudvariable”, adiferenciade m[i] queapuntaaunarraydee xactamente5reales.
EJEMPLO 11.3. Reservadinámicadememoriainter activaparamatrices. Tratamientocomopunteroapunterode
untipodado.
Seasignamemoriadinámicaaunamatrizcuadradadedimensión n*n, rellenandolamatrizcondatosf ijosyvisualizandolamatrizdelaformaestándaryconpunteros.
#include <cstdlib>
#include <iostream>
CAPÍTULO 11 Gestión dinámica de la memoria
231
using namespace std;
int main(int argc, char *argv[])
{
int i, j, n;
typedef int* col;
// col es un sinónimo de puntero a entero
int **m ;
//m es puntero que apuntan a punteros a enteros
cout << " introduzca dimension de m : ";
cin >> n;
m = new col[n];
// reserva de memoria para n punteros enteros
for( i = 0; i < n; i++)
{
m[i] = new int[n];
// m[i] puntero a vector de n enteros
//m puntero a puntero de enteros
for (j = 0; j < n; j++)
m[i][j] = 10 * (i + 1) + j;
}
cout << "\n visualizacion matriz con indexacion: \n";
for( i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
cout << " " << m[i][j];
// indexación tipo matriz
cout << endl;
}
cout << "\n visualizacion matriz con punteros: \n" ;
for( i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
cout<<" " << *(*(m+i)+j);
cout << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
// también válido con
*(m[i]+j)
}
EJEMPLO 11.4. Lecturayvisualizacióndematricescuadr adasconfuncionescuyamemoriaser eservadinámicamenteeinteractivamente.
Seescribenlasfuncionesdelecturayescrituradematricescuadradas, cuyamemoriasehareserv adodinámicamente
enunprogramaprincipal.
#include <cstdlib>
#include <iostream>
using namespace std;
typedef int* col;
void
{
leermatriz (int** m, int n)
int i, j;
CAPÍTULO 11 Gestión dinámica de la memoria
232
for( i = 0; i < n; i++)
for (j = 0; j < n; j++)
cin >> m[i][j] ;
}
void escribirmatriz (int** m, int n)
{
int i, j;
for( i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
cout << " " << m[i][j]
cout << endl;
}
;
}
int main(int argc, char *argv[])
{
int n;
int **m;
// válido con col *m;
cout << " introduzca dimension de m : ";
cin >> n;
m = new col[n];
for (int i = 0; i < n; i++)
m[i] = new int[n];
leermatriz(m,n);
escribirmatriz(m,n);
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 11.5. Lecturayvisualizacióndeunte xtoalmacenadoenmemoriadinámica.
Leeuntextode10líneas, ysevisualizanindicandolalongituddecadalínea.Lamemoriaseajustaalalongitudmínimadelaentradadedatos.Paraello, sereservamemoriainteractivamenteaunarraydepunterosacaracteres.Selee
unalíneaenun buffer delongitudconstante81, yseajustalalongituddelte xtodeentradaalvalorleído.
int main(int argc, char *argv[])
{
typedef char * columna;
columna * textoentrada;
int i, n = 10;
char buffer[81];
textoentrada = new columna[n];
// reserva de memoria
for (i = 0; i < n; i++)
{
cout << " Introduzca linea: ";
cin.getline(buffer,80);
textoentrada[i] = new char [strlen (buffer)+1];
//ajuste
strcpy (textoentrada[i], buffer);
}
CAPÍTULO 11 Gestión dinámica de la memoria
233
cout << "longitud
linea\n";
for (i = 0; i < n; i++)
// visualización con punteros
cout << " " << strlen(*(textoentrada + i)) << " :"
<< *(textoentrada + i) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
11.3. El operador delete
Cuandosehaterminadodeutilizarunbloquedememoriapre viamenteasignadopor new, sepuedeliberarelespaciodememoriaydejarlodisponibleparaotrosusos, medianteeloperador delete.Elbloquedememoriasuprimidosede vuelvealespaciodealmacenamientolibre, demodoquehabrámásmemoriadisponibleparaasignarotrosbloquesdememoria.Elformatoes:
delete puntero; silareservaes puntero = new tipo;
delete[] Puntero Array; silareservaes Puntero Array = new[tamaño Array]
EJEMPLO 11.6. Reservaespacioenmemoriaparaunarrayde5elementos, ylalibera.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
float *DatosI = new float[5];
int i;
for (i = 0; i< 5; i++)
DatosI[i] = 2 * i+1;;
cout << " los 5 primeros impares son \n" ;
for (i = 0; i < 5; i++)
cout << " " << DatosI[i];
cout << endl;
delete [] DatosI;
system("PAUSE");
return EXIT_SUCCESS;
// Libera memoria
}
EJEMPLO 11.7. Reservaespacioenmemoriaparaunarraydinámicodenelementosdeestructur as.
Seleenyvisualizanmediantefunciones, lascoordenadasden puntosdelplano, almacenadolosresultadosenunarray
dinámico.
#include <cstdlib>
#include <iostream>
using namespace std;
struct Punto
{
CAPÍTULO 11 Gestión dinámica de la memoria
234
float CoordX;
float CoordY;
};
Punto *Vector;
void Leer_Punto( Punto &p)
{
cout << " coordenada x e y :";
cin >> p.CoordX >> p.CoordY;
}
void Escribir_Punto( Punto p)
{
cout << " "<< p.CoordX <<" "<< p.CoordY << endl;
}
void LeerVectorPuntos( Punto *Vector, int n)
{
int i;
for (int i = 0; i < n; i++)
Leer_Punto(Vector[i]);
}
void EscribirVectorPuntos( Punto *Vector, int n)
{
int i;
for (int i = 0; i < n; i++)
Escribir_Punto(Vector[i]);
}
int main(int argc, char *argv[])
{
int n;
cout << " ¿cuantos puntos? : ";
do
cin >> n;
while (n <= 0);
Vector = new Punto[n];
LeerVectorPuntos(Vector, n);
EscribirVectorPuntos(Vector, n);
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 11 Gestión dinámica de la memoria
235
EJERCICIOS
11.1. ¿Cuáleslasalidadelsiguientepr ograma?
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int * p1, *p2;
p1= new int;
*p1 = 45;
p2 = p1;
cout << " *p1 == " << *p1 <<
cout << " *p2 == " << *p2 <<
*p2 = 54;
cout << " *p1 == " << *p1 <<
cout << " *p2 == " << *p2 <<
cout << " vivan los punteros
system("PAUSE");
return EXIT_SUCCESS;
endl;
endl;
endl;
endl;
\n";
}
11.2. ¿Cuáleslasalidadelsiguientecódigo?
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int * p1, *p2;
p1= new int;
p2= new int;
*p1 = 10;
*p2 = 20;
cout << *p1 << " " << *p2 << endl;
*p1 = *p2;
cout << *p1 << " " << *p2 << endl;
*p1 = 30;
cout << *p1 << " " << *p2 << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
11.3. Supongaqueunprogramacontieneelsiguientecódigopar acrearunarraydinámico.
int * entrada;
entrada = new int[10];
Sinoexistesuficientememoriaenelmontículo, lallamadaanteriora new fallará.Escribiruncódigoqueverif iquesiesa
llamadaa new fallaporfaltadealmacenamientosuf icienteenelmontículo(heap). Visualiceunmensajedeerrorenpantallaqueloadviertaexpresamente.
CAPÍTULO 11 Gestión dinámica de la memoria
236
11.4. Supongaqueunpr ogramacontienecódigopar acrearunarr aydinámicocomoenelEjer cicio11.3, demodoquelavariableentradaestáapuntadoaestearr aydinámico.Escribirelcódigoquer elleneestearrayde10númer osescritospor
teclado.
11.5. Dadalasiguientedeclaración, definirunpunterob alaestructura, reservarmemoriadinámicamenteparaunaestructura
asignandosudireccióna b.
struct boton
{
char* rotulo;
int codigo;
};
11.6. Unavezasignadamemoriaalpunterob delEjercicio10.5escribirsentenciasparaleerloscampos rotulo ycodigo.
11.7. Declararunaestructurapararepresentarun punto enelespaciotridimensionalconunnombre.Declararunpunteroala
estructuraquetengaladireccióndeunarraydinámicodenestructuraspunto.Asignarmemoriaalarrayycomprobarque
sehapodidoasignarlamemoriar equerida.
PROBLEMAS
11.1. DadaladeclaracióndelaestructurapuntodelEjercicio11.7, escribirunafunciónquede vuelvaladireccióndeunarray
dinámicodenpuntosenelespaciotridimensional.Losvalor esdelosdatosseleendeldispositivodeentr ada(teclado).
11.2. Añadiralproblemaanteriorunafunciónquemuestr elospuntosdeunvectordinámicocuyater ceracoordenadaseamayorqueunparámetroquerecibecomodato.
11.3. Añadiralproblemaanteriorelpuntomásalejadodelorig endecoordenadas.
11.4. Sepretenderepresentarenelespaciotridimensionaltriángulos, perominimizandoelespacionecesariopar aalmacenarlos.Teniendoencuentaqueuntriánguloenelespaciotridimensionalvienedeterminadoporlascoor denadasdesustr es
vértices, escribirunaestructurapararepresentaruntriánguloqueusandoelvectordinámicodelosproblemasanteriores,
almaceneelíndicedelostr esvérticesasícomosuperímetr oyárea(deestaformasealmacenalostr esvérticescontr es
enterosenlugardecon9r eales, ahorrandomemoria).Elperímetroyeláreadebensercalculadosmedianteunafunción
apartirdelíndicedelostr esvértices, yelvectordinámicodepuntosdelespaciotridimensional.
11.5. Añadiralproblemaanteriorunafunciónqueleayalmaceneenunvectorlosmtriángulosdelespaciotridimensionalcuyosvérticesseencuentrenenelarraydinámicodepuntos.Usarlasfuncionesyestructurasdefinidasenlosproblemasanteriores.
11.6. Añadiralproblemaanteriorunafunciónquevisualicelostriángulosdelvectordetriángulos.
11.7. Dadaladeclaracióndelarraydepunteros:
#define N 4
char *linea[N];
Escribirlassentenciasdecódigopar aleerNlíneasdecar acteresyasignarcadalíneaaunelementodelarr ay.
CAPÍTULO 11 Gestión dinámica de la memoria
237
11.8. EscribiruncódigodeprogramaqueeliminedelarraydeNlíneasdelProblema11.7todasaquellaslíneasdelongitudmenorque20.
11.9. Escribirunafunciónqueutilicepunterosparacopiarunarraydeelementos double.
11.10. Escribirunprogramaqueleaunnúmer odeterminadodeenter os(1000comomáximo)delterminalylosvisualiceenel
mismoordenyconlacondicióndequecadaenter osóloseescribaunavez.Sielenter oyasehaimpr eso, nosedebevisualizardenuevo.Porejemplo, silosnúmerossiguientesseleendesdeelterminal 55 78 –25 55 24 –3 7 elprograma
debevisualizarlosiguiente: 55 78 –25 55 24 –3 7.Sedebetr atarconpunterosparatratarconelarr ayenelquese
hayanalmacenadolosnúmeros.
11.11. Escribirunprogramaparaleerncadenasdecaracteres.Cadacadenatieneunalongitudvariableyestáformadaporcualquiercarácter.Lamemoriaqueocupacadacadenasehadeajustaraltamañoquetiene .Unavezleídaslascadenasse
deberealizarunprocesoqueconsisteeneliminartodoslosblancos, siempremanteniendoelespacioocupadoajustadoal
númerodecaracteres.Elprogramadebemostrarlascadenasleídasylascadenastr ansformadas.
11.12. Escribirelcódigodelasiguientefunciónquedevuelvelasumadeloselementos float apuntadosporlos n primerospunterosdelarrayp.
11.13. Escribaunamatrizquer ecibacomoparámetrounpunterodoblea float, asícomosudimensión, yretornememoriadinámicaparaunamatrizcuadrada.
11.14. Escribaunafunciónquegenerealeatoriamenteunamatrizcuadradasimétrica, yquepuedaserllamadadesdeunprogramaprincipalquegenerealeatoriamentelamatrizconlafuncióndelProblema11.13.Eltratamientodelamatrizdebehacerseconpunteros.
11.15. Escribirunafunciónquedecidasiunamatrizcuadr adadeorden n esmayoritaria.“unamatrizcuadr adadeorden n se
dicequeesmayoritaria, siexisteunelementoenlamatrizcuyonúmeroderepeticionessobrepasaalamitadden*n.Eltratamientodebehacerseconpunteros.
11.16. Unamalladenúmerosenterosrepresentaimágenes, cadaenteroexpresalaintensidadluminosadeunpunto.Unpuntoes
unelemento“ruido” cuandosuvalorsedifer enciaendosomásunidadesdelvalormediodelosoc hopuntosqueler odean.Escribirunpr ogramaquetengacomoentr adalasdimensionesdelamalla, reservememoriadinámicamentepar a
unamatrizenlaqueseleanlosvaloresdelamalla.Diseñarunafunciónquerecibaunamalla, devuelvaotramalladelas
mismasdimensionesdondeloselementos“ruido” tenganelvalor1ylosquenolosonvalor0.
SOLUCIÓN DE LOS EJERCICIOS
11.1. Laprimerasentenciap1= new int;reservamemoriaparaelpunterop1.Lasegundasentenciaasignaap2 elvalordep1,
porloquelosdospunter osapuntanalamismadir eccióndememoriaylasdossentenciasdesalida, mostraránelcontenidodeladireccióndememoriaquees45, asignadoporlasentencia *p1 = 45;.Cuandoseejecutalasiguientesentencia *p2 = 54;secambiaelcontenidodelamemoriaapuntadapor p1 y p2 alvalorde54, porloqueésaserálasalida
quemuestrenlasdossentenciassiguientes.
11.2. Lasdosprimerassentencia p1= new int; p2 = new int;reservanmemoriaparalospunteros p1 y p2.Lasdossentenciassiguientesasignanvaloresaloscontenidosdelosdospunteros, porloquelasalidadelasentencia cout serálosvaloresasignadosqueson 20 y30.Lasentencia *p1 = *p2;asignaalcontenidodelpunterop1 elcontenidodelpunterop2,
porloquelasalidaserá 20 20.Lasiguientesentenciacambiaelcontenidodelpunter op1 a30, porloquelanuevasalidaserá 30 20.
CAPÍTULO 11 Gestión dinámica de la memoria
238
11.3. Teniendoencuentaquelaor den new devuelve NULL sinosepuedeasignarmemoria, pararesolverelproblemabastacon
interrogarporelvalorr etornandoporlaor den new ydarelmensajecorr espondiente.Elsiguientefr agmentodeprograma, ademásdedarelmensajedeerrorpedido, informaaproximadamentedelamemoriadisponibleenelmontículo(heap).
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int *entrada;
for (int i = 0; ; i++)
// bucle infinito
{
entrada = new int[5012];
if (entrada == NULL)
{ cout << " memoria agotada ";
break;
}
cout<< " asignado " << i* 10 << "K bytes" << endl;
}
system("PAUSE");
return EXIT_SUCCESS
}
11.4. Unavezreservadamemoriadinámicaalvector, lavariableentrada secomportacomoelidentificadordeunavariableque
esunarrayunidimensional, porloquelalecturaserealizadelaformaestándar.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int *entrada;
entrada = new int[10];
for (int i = 0; i < 10; i++)
cin >> entrada[i];
system("PAUSE");
return EXIT_SUCCESS;
}
11.5. Lasoluciónvienedadaporlasiguientesentencia.
boton * b;
b = new boton;
11.6. Lassentenciassolicitadasusaneloper adordeindir ecciónflecha -> paraaccederdesdeelpunter o b acadaunodelos
camposdelaestructura.Además, comoelatributorotulo esunpunteroaunacadena, esnecesarioasignar, previamente,
memoriaalacadena, obienqueapunteaunacadenadecar acteresleídaconanterioridad.
boton * b;
b = new boton;
cin >> b->codigo;
CAPÍTULO 11 Gestión dinámica de la memoria
b->rotulo = new char [21];
cin.getline(b->rotulo,20);
239
// por ejemplo cadena de 20 caracteres
11.7. Seasignamemoriadinámicamentemedianteelusodelavariableenter a n, cuyovalorhasidosolicitadoalusuario.Después, secompruebasihahabidoerrorenlaasignación, analizandosi Vector3D contieneNULL.
struct Punto3D
{
char *Nombre;
float CoordX;
float CoordY;
float CoordZ;
};
Punto3D
int n;
*Vector3D;
cout << "introduzca n :";
cin >> n;
if ((Vector3D = new Punto3D[n]) == NULL)
{
cout <<" Error de asignación de memoria dinámica \n";
exit(1);
}
SOLUCIÓN DE LOS PROBLEMAS
11.1. Lafunción Leer_Punto3D devuelvecomoparámetroporreferencialascoordenadasdeunpuntodetr escoordenadas, así
comoelNombre.Elnombre, alserunpunteroachar, seleasignamemoriadinámicamente, mediantelalongituddelacadenadeentradarealqueintroduzcaelusuario, paraoptimizarlamemoria.LafunciónLeer_Vector_Puntos3D retornaen
elvectorquer ecibecomoparámetr olosdatossolicitados, realizandountotaldenllamadasalafunciónqueleelaestructuraquedefineunpuntoendimensión 3.
La codificación de este problema se encuentra en la página Web del libro.
11.2. Laprogramacióndelafunciónpedidaessimilaralar ealizadaenelproblemaanterior, exceptoqueenestecasosellama
aunafunciónquevisualizalosdatosdelascoordenadasdeunpuntoendimensión3cuyaordenadaseamayorquelaque
recibeensuparámetro.
La codificación de este problema se encuentra en la página Web del libro.
11.3. Paraencontrarelpuntomáscer canoalorigendecoordenadas, esnecesariodefinirlafunción distancia_Origen deun
puntocualquieraxque, enestecaso, seráladistanciaeuclídead = œw
x2 +y2 +z 2.Medianteelusodeestafunciónpuede
calcularseelpunto Mas_Cercano_Orignen medianteunalgoritmovor azquetomainicialmentecomopuntomáscer cano
elprimero, yposteriormentemedianteunbuclefor, eligecomomáscercanoelqueyateníaobienelqueseestátratando.
Lafunción Escribe_Mas_Cercan_Origen visualizaelcontenidodelpunter odelpuntomáscer canoquerecibedelafunciónquelocalcula.
La codificación de este problema se encuentra en la página Web del libro.
240
CAPÍTULO 11 Gestión dinámica de la memoria
11.4. Untriánguloestácompletamentedeterminadomedianteelíndicedelostrespuntosdelespaciotridimensionalquelodefinen, porloqueparaalmacenarlos, bastaconincluirlosíndicesdelostr espuntosenunarraydeenteros.
Elperímetrodeuntriángulovienedadoporlasumadelaslongitudesdesustr eslados, a, b, c.Eláreadeuntriána +b +c
gulodeladosa, byces= œw
p(p –a)(p –w
b)(p –c) siendopelsemiperímetrop=
.Laslongitudesdecadauno
2
delosladosdeltriángulo, estándeterminadasporlosmódulosdelosvectoresformadosporlospuntosquedeterminanlos
vérticesdeltriángulo.Enconcr etovector1=p 1–p0;vector2=p 2–p0 yvector3=p 2–p1, siendop 0, p1, yp 2 lascoordenadas desustrespuntos.Exactamentelascoordenadasdeunvectorv =p1–p0 sonv =(v1,v2,v3)=(x1,y1,z1)–(x0,y0,z0),siendo
p1 =(x1,y1,z1) yp 0 =(x0,y0,z0).Yelmódulodelvectorvvienedadoporlae xpresión: módulo(v)= œw
v12 +v22 +v22.Paracalcularladistanciaentredospuntossedefinelafuncióndistancia_puntos querecibecomoparámetroslosdospuntos.El
cálculodelperímetr oyelár eadeuntriánguloser ealiza, encontrandoladistanciaentr ecadapardepuntos, yobteniendo losvalorescorrespondientesmediantelase xpresionesquelodeterminan.P arapoderr ealizarlohayqueteneren
cuentaqueesnecesariodisponerentodomomentodelvectordepuntosquecontienelascoor denadasdelespaciotridimensional, yaqueeltriángulo, sóloalmacenalosíndicesdelospuntos.Estoobligaaquelafunción Calcula_perimetro_Area_Triangulo tengacomoparámetroselvectordinámicodepuntosdelespacio, asícomoeltriángulo.
La codificación de este problema se encuentra en la página Web del libro.
11.5. Lalecturadelostriángulosserealizaleyendolostresvérticesdecadaunodeellos, yalmacenandoeláreayperímetro.La
función leer_triangulos realizalalecturadelosvérticesdelos m triángulos, ylosalmacenaenunvectordetriángulos
VT, medianteunbuclefor queiteradesde0 hastam – 1.Encadaiteración, solicitalosíndicesdelostres, puntosdeltriángulocomprobandoquesondistintos, yseencuentrandentrodelrangodepuntosdelespaciodisponible(0,1,..., n) con
ayudadelafunción corecto.
La codificación de este problema se encuentra en la página Web del libro.
11.6. LavisualizacióndeuntriánguloserealizapresentandolosvérticesqueloformanconayudadelafunciónEscribir_Punto3D, asícomosuperímetroyárea.Hayquetenerencuenta, queentodomomentosenecesitaelvectordinámicodepuntosdelespacioparapodervisualizarlo, yaquesólosealmacenanlosíndicesdelosvértices.Lapr esentacióndetodoslos
puntosserealizaporlafunción Escribir_triangulos.
La codificación de este problema se encuentra en la página Web del libro.
11.7. Enestecaso, ladeclaracióndadanoesmásqueunarraydeN punterosacaractereslinea.Es, portanto, unpunteroaun
char.Éstaesunaformabastanteeficientedeminimizarelespaciodememoriareservadoparatodoeltexto, yaquesepuedeajustarlalongituddecadalíneaaltamañorealdeldatodeentrada.Parapoderrealizarlo, hayqueusarunbuffertemporal(arraydelongitudfijadecaracteres)declaradodeunaciertalongitudparaleercadalínea, yunavezsehayaleído,
reservarmemoriadinámicaconuncaráctermásquelalongitudr ealdelacadenaleída(estecaráctermásespar aelfin
decadena '\0').Elprogramaquesecodificasolicitaeltexto, ylovisualiza.
La codificación de este problema se encuentra en la página Web del libro.
11.8. Sielarraylíneas contienelíneasválidas, seprocedealaeliminacióndelaslíneasdelasiguienteforma: unavariablen1,
indicaencadamomentolaslíneasválidasquehayenelte xto.Cuandounalíneaessuprimidasedecr ementa n1 enuna
unidad.Siunalíneacualquier a i cumplelacondicióndesereliminada, seliberalamemoriadelalínea, ysemuevenlas
líneasqueocupanposicionessuperior esenelte xtounaposiciónhaciaatrás(enlaposiciónactual, seponelasiguiente ,
realizadoconelbucle for j).Siunalíneacualquier a i nocumplelacondicióndesereliminadaseincr ementaelcontadordelíneasi enunaunidad.Estecontadordelíneasi seinicializaa0;terminacuandoi tomaelvalorden1.Comoademásencadaiteraciónoseincrementai, osedecrementan1, elbuclewhile siempretermina.
La codificación de este problema se encuentra en la página Web del libro.
11.9. Lafuncióncopiar, recibeelvector v comopunteroadouble, yCopia comopunteroadouble.Sereservaespaciodememoria, paraelvectorquecontendrálacopia, paraposteriormenteiterarcopiandoloselementosunoaunomediantelos
punterosquesevandesplazandoalolar godecadaunodelosvector es.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 11 Gestión dinámica de la memoria
241
11.10. Lafunciónleer recibeunpunteroaun float v porreferenciaparaquepuedaasignarsememoriadinámicamentedentro
delafunciónalvector v yseretornelosvaloresalafuncióndellamada. Tambiéntieneporreferenciaelparámetron que
eselnúmerodeelementosleídosdelvectormenoroigualque 1000.Hayqueobservarquelalectur aserealizadedatos
delvector v yserealizaconunpunteroauxiliara float, p, previamenteinicializadoa v yqueavanzaencadaiter ación
delbucledelecturaunaposiciónenelvector v (nopuederealizarseestamismaoperacióncon v yaqueenesecasocambiadeposiciónelcomienzodelarrayylosresultadosseríanincorrectos).Lafunción repe, recibecomoparámetroelvector v yunaposición i, retornando true sielelementoqueseencuentr aenlaposición i aparecealmacenadoenalguna
posiciónanteriordelarr ay.Deestaforma, enunbuclesepueder ecorrertodaslasposicionesdelvectordedatos, ysiel
elementoqueseestátratando, noestárepetidoenalgunaposiciónanteriordelarr ayentoncessevisualiza.
La codificación de este problema se encuentra en la página Web del libro.
11.11. Sedeclara, enprimerlugar, unsinónimodepunteroacarácterquees linea.Posteriormente, lasvariables texto y texto1, comopunterosa linea, dondeseleeráelte xtooriginal, yseharálacopiadelte xtosinblancos.Esdecir , punteros
doblesquesonarraydepunterosacaracteres, obienunarraybidimensionaldecaracteres.Sereservaespacioenmemoriaparacadaunodeloste xtos, parallamaralasfuncionesencargadasdeleereltextotransformarloyvisualizarlo.
Lafunciónquer ealizalalectur adelaslíneadelte xto Leer_Texto, asignadinámicamentelalongituddecadalínea
deltexto, unavezconocidasulongitudrealdadaporelusuario.
Lafunciónquetr ansformaelte xto, enotrotextosinblancos, Transformar_Texto, copialíneaalínealosdatosdel
textooriginalenunacadenadecar acteres buffer, paraireliminandolosblancosunoauno.P ararealizarlo, seinicializandosvariables j, y lon apuntandoalprimeryúltimocarácterdelarr aydecaracteres(carácterfindecadena).Estas
dosvariablescontrolanelbuclequeeliminalosblancos.Sielcarácteratr ataresunblanco, seelimina, haciendoretrocedertodosloscaracteresdelacadenaunaposición, yhaciendoquelacadenatermineenelcarácteranterior( lon --;
buffer[lon]= '\0';).Sielcarácteratr atarnoesunblancoseavanzalavariable j.
Lavisualizacióndeltextoesrealizadaporlafunción Mostrar_Texto, quelomuestracarácteracarácterenlugarde
utilizarlascadenasdecaracteres, paraquesirvadeejemplodeotr aformadevisualizarlascadenas.
La codificación de este problema se encuentra en la página Web del libro.
11.12. Lafunciónseescribecontr atamientodepunteros.Como p esunvectordepunter osareales, setieneque * (p + i) es
unpunteroareal, porloque * ( * (p + í)) contieneelnúmerorealquehayquesumar.
La codificación de este problema se encuentra en la página Web del libro.
11.13. Lafunción generamatriz tienecomoparámetroporreferenciaunpunterodoblea float, pararetornarlamemoriayun
enteron queindicaladimensióndelamatrizcuadrada, ygeneradinámicamenteen, primerlugar, losn punterosalascolumnasy, posteriormente, losn punterosacadaunodelosr ealesdelacolumnas.
#include <cstdlib>
#include <iostream>
using namespace std;
typedef float* col;
void generamatriz( float ** &m, int n)
{
m = new col[n];
for (int i = 0; i < n; i++)
m[i] = new float[n];
}
int main(int argc, char *argv[])
{
int n;
//col es un sinónimo de un puntero a float
CAPÍTULO 11 Gestión dinámica de la memoria
242
float **m;
.....
generamatriz(m,n);
.....
}
11.14. Lafunciónrecibecomoparámetrolamatrizyasignaaleatoriamenteelmismovaloralasposiciones m[i][j] ym[j][i].
Usadosmacrosparadefinirlasfuncionesestándardeg eneracióndenúmerosaleatorios.
La codificación de este problema se encuentra en la página Web del libro.
11.15. Seprogramaenprimerlugarlafunciónel_mas_repe queencuentraelelementoquemásvecesserepiteenunamatrizasí
comoelnúmerodevecesquelohace.Estaoperaciónesrealizadamedianteunbuclevoraz.Setieneenunavariablenmasrepe elnúmerodevecesqueseharepetidoelnúmeromasrepe hastaelmomento.Unavezcontadoelnúmerodevecesque
seencuentraelnúmeroactualenlamatriz, elnuevomásrepetido, eselqueteníaoelnue vo.Pararealizarelbuclevoraz
seexplorantodosloselementosdelamatrizmediantedosb ucle for anidadoscontroladosporlasvariables i y j respectivamente.Paracadaposiciónactual m[i][j], delamatrizsecuentaelnúmer odevecesqueapar ecerepetidoenlamatrizeldato, ysiesmayorqueelqueteníaelnuevonúmeromásrepetidoseactualiza, asícomosunúmerodeveces.Enotro
casonohacenada.
Lamatrizserámayoritariasielnúmer odevecesqueser epiteelelementoquemásseencuentr aalmacenadosobrepasaelnúmerototaldeelementosdelamatrizqueesn*n.
La codificación de este problema se encuentra en la página Web del libro.
11.16. Sedefineunamatrizdinámicadeenterosde F filasy C columnasdondeseleenlosdatosdelamalladenúmer osmediante
unafunción LeerMatriz.Lafunción EscribeMatriz porsupartevisualizalosdatosdelamatrizmediantepunter os.
Dadounpuntocuyaposiciónenlamatrizes i, j, (m[i][j]) lamediadelosvalor esdelospuntosquelor odeanse
obtienesumandotodoslosvalor esydividiendoelr esultadoentreelnúmerodepuntos.Hayquetenerencuentaquenoa
todoslospuntoslorodeanlamismacantidad.Casitodostienenochopuntos, pero, porejemplo, losdelascuatroesquinas
delamatriz (m[0][0], m[0][C], m[F][0]y m[F][C]) sólotienen3puntosquelorodean.Tampocotienen8puntosrodeándolosaquellosqueseencuentranenlafila0, columna0, filaF ocolumna C.Lafunción Valormedio eslaencargada
derealizarloscálculosnecesariospar acadapuntocondosb ucles for, querecorrenenprincipiolos9candidatos, avecinosysólotratalosquerealmenteloson.
Paradecidirlospuntosdelamatrizquetienenruido, bastaconcomprobarlacondiciónparacadaunodeellos.Siun
puntotieneruido, entoncesseponeenlaposición i, j delamatrizderuido( ruido[i][j])elvalorde1y0enotrocaso.
LafunciónEncontrarRuido recorretodoslospuntosdelamatrizoriginalcondosbuclesfor anidadosasignandoacada
posicióndelamatrizde ruido elvalorcorrespondiente.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
11.1. Unarrayunidimensionalpuedeconsiderarseunaconstantepuntero.¿Cómopuedeconsiderarseunarraybidimensional?, ¿yunarraydetresdimensiones?
11.3. Escribiruna funciónquerecibaelarraydinámicoden
elementosyamplíeelarrayenotros m puntosdelespacio.
11.2. Dadaladeclaracióndelarraydepunteros:
11.4. ¿Quédiferenciase xisteentrelassiguientesdeclaraciones?
#define N 4
char *l[N];
Escribirlassentenciasdecódigoparaleer N líneasde
caracteresyasignarcadalíneaaunelementodelarray .
char *c[15];
char **c,
char c[15][12];
CAPÍTULO 11 Gestión dinámica de la memoria
243
PROBLEMAS PROPUESTOS
11.1. Enunacompeticióndeciclismosepresentann ciclistas.
Cadaparticipanteserepresentaporelnombre, club, los
puntosobtenidosypruebaenqueparticiparáenlacompetición.Lacompeticiónesporeliminación.Haypruebasdedostipos, persecuciónyvelocidad.Enladepersecuciónparticipantresciclistas, elprimerorecibe3
puntosyelterceroseelimina.Enladev elocidadparticipan4ciclistas, elmásrápidoobtiene4puntosel
segundo1yelcuartoseelimina.Laspruebassevanalternando, empezandoporvelocidad.Losciclistasparticipantesenunapruebaseeligenalazarentreaquellos
quehanparticipadoenmenospruebas.Eljue goterminacuandonoquedanciclistasparaalgunadelasdos
pruebas.Sehandemantenerarraysdinámicosconlos
ciclistasparticipantesyloseliminados.Elciclistaganadorseráelquemáspuntostenga.
11.2. Sequiereescribirunprogramaparaleernúmerosgrandes(detantosdígitosquenoentranenv ariables long)
yobtenerlasumadeellos.Elalmacenamientodeunnúmerograndesehadehacerenunaestructuraquetenga
unarraydinámicodeenterosyotrocampoconelnúmerodedígitos.Lasumadedosnúmerosgrandesdará
comoresultadootronúmerogranderepresentadoensu
correspondienteestructura.
11.3. Unpolinomio, P(x), puederepresentarseconunarray
detantoselementoscomoelgradodelpolinomiomas
uno.Escribirunprogramaquetengacomoentradael
gradon delpolinomio, reservememoriadinámicamenteparaunarrayden+1 elementos.Enunafunciónseintroducenportecladoloscoef icientesdelpolinomio, en
ordendecreciente.Elprogramatienequepermitire valuarelpolinomioparaunvalordadodex.
11.4. Escribirunprogramaquepermitasumar
, restar,
multiplicarydividirnúmerosrealesconsignorepresentadosconcadenasdecaracteresconunsolodígitopor
carácter.
11.5. Escribirunafunciónquetomecomoentradaunnúmero
enteroyproduzcaunacadenaconlosdígitosdesue xpresiónenbasedos.
11.6. Escribirfuncionesparasumarrestarymultiplicarnúmerosenterospositivosenbinario.
11.7. Construirunprogramaquesimuleelcomportamiento
delosclientesenlasalidadeungranalmacén.Separte
deunarraydecajasalasquesev anañadiendoalazar
losclientesparapagarsuscompras.Losclientesestán
representadosporcadenasdeasteriscosenlazadascon
lascajas, contantosasteriscoscomoclientes.Elprogramadebepoderpermitirañadirclientesalascajassegún
diferentesvelocidadesysimulandodiversasvelocidades
enelserviciodecadacaja.Laevolucióndetodaslascolassecompruebavisualmenteimprimiendolascadenas
deasteriscosquerepresentanlosclientesdecadacola
delantedecadacaja.
11.8. Dadalasiguientedefiniciónderegistro:
struct reg
{
char *autor;
char *título;
char *editorial;
int anno;
char *ISBN;
char** coemtnarios;
};
Realizarunprogramaquegeneredinámicamenteuna
tablaapartirdeunarraydepunterosaestructurasdel
tipoanteriorapuntadosporelsiguientepunterodoble:
reg **tabla;
Unavezgeneradalatabladeltamañoindicadopor
elusuario, rellenaradecuadamenteloscamposconla
memoriae xactaquecadare gistronecesite.Elcampo
comentariospermiteanotarvarioscomentariosrespecto
decadaobra.
11.9. Añadiralprogramaanteriorunmenúquepermitaal
usuarioañadirelementosalatabla, eliminarregistrosy
modificarsucontenido.
11.10. Conlosdatosintroducidosenlosdosejemplosanterioresenelarraydepunterostabla, creartresarraysdel
mismotipoqueapuntenalosregistrosdetablaenelordenenelqueestaríansiestuviesenordenadosrespectivamenteporautor , títulooeditorial.Construirunprogramaque, ademásderealizarloanterior , permita
imprimirelcontenidodelosre gistros, segúnelorden
originalenquehansidointroducidoslosdatosyse gún
lostresórdenesdefinidos.
11.11. DelamismaformaquehaceelsistemaUNIXconlaslíneasdeórdenes, realizarunafunciónquetomecomo
entradaunacadenayseparesuscomponentesencadenasdiferentes.Cadaunadelascadenasresultanteshade
estarenlazadaconunelementodeunarraydepunteros
acarácter.
244
11.12. Setieneunamatrizde20 ×20elementosenteros.En
la matrizhayunelementorepetidomuchasv eces.Se
quieregenerarotramatrizde20f ilasyqueencadaf ila
esténsóloloselementosnorepetidos.Escribirunprogramaquetengacomoentradalamatrizde20
×20,
generelamatrizdinámicapedidaysemuestreenpantalla.
CAPÍTULO 11 Gestión dinámica de la memoria
11.13. Escribirunprogramaqueleaunaseriedecódigosdeartículosymuestrelasfrecuenciasdeaparicióndecada
unodeellosconstruyendounhistogramadefrecuencias.
Paraelloelprogramaestablececuántoscódigosdistintos
selehanintroducidoyvisualizacadacódigoenunalíneadelapantallase guidadetantosasteriscoscomov eceshayaaparecidodichocódigoenlosdatosdeentrada.
CAPÍTULO 12
Ordenación y búsqueda
Introducción
Unadelastareasquerealizanmásfrecuentementelascomputadorasenelprocesamientodedatosesla ordenación.Elestudiodediferentesmétodosdeordenaciónesmuyimportantedesdeunpuntodevistateóricoy , naturalmente, práctico.ElcapítuloestudialosalgoritmosytécnicasdeordenaciónmásusualesysuimplementaciónenC++.Deigualmodo, seestudiará
elanálisisdelosdiferentesmétodosdeordenaciónconelobjetodeconse guirlamáximaeficienciaensuusoreal.
12.1. Búsqueda
Elprocesodeencontrarunelementoespecíficodeunarraysedenominabúsqueda.Esteprocesopermitedeterminarsiunarray
contieneunvalorquecoincidaconuncierto valorclave.Labúsquedapermitelarecuperacióndedatospre viamentealmacenados.Sielalmacenamientoserealizaenmemoria, labúsquedasedenominainterna.Lasbúsquedasmásusadasenlistasson:
secuencial(lineal)ybinaria.
12.1.1. BÚSQUEDA SECUENCIAL
Labúsquedasecuencialb uscaunelementodeunalistautilizandounv alordestinollamado clave.Enunabúsquedasecuencial(avecesllamadabúsquedalineal), loselementosdeunalistaov ectorseexploran(seexaminan)ensecuencia, unodespuésdeotro(deizquierdaaderechaovice versa).Labúsquedalinealconsisteenrecorrercadaunodeloselementoshastaalcanzarelfinaldelalistadedatos.Sienalgúnlugardelalistaseencontraraelelementobuscado, elalgoritmodeberáinformar
sobrelaolasposicionesdondehasidolocalizado.
EJEMPLO 12.1. Búsquedasecuencialdeunaclaveenunvectordendatosdeizquier daaderechacomenzandoen
laposición0.
Retorna–1 silaclavenoestáenelv ectorV ylaposicióndelaprimeraapariciónsíseencuentraenelv ectorV.
int busquedaLinealID (int V [], int n, int clave)
{
int i;
245
CAPÍTULO 12 Ordenación y búsqueda
246
for (i = 0 ; i < n; i++)
if (V[i] == clave)
return i;
return –1;
}
EJEMPLO 12.2. Búsquedasecuencialdeunaclaveenunvectordendatosdeder echaaizquierdacomenzandoen
laúltimaposición.
Retorna–1 silaclavenoestáenelv ectorV ylaposicióndelaúltimaapariciónsíseencuentraenelv ectorV.
int busquedaLinealDI (int V [], int n, int clave)
{
int i;
for (i = n – 1; i >= 0; i--)
if (V[i] == clave)
return i;
return –1;
}
Silalistaseencuentraordenadayeldatoabuscarnoestáenlalista, labúsquedaterminacuandoelelementoaencontrar
seamenorqueelelementoencursoenunalistaordenadaascendentemente, ocuandoseamayorsiseb uscaenunalistaordenadadescendentemente.
EJEMPLO 12.3. Búsquedasecuencialdeunaclaveenunvectordendatosor denadocrecientementedeizquierdaa
derechacomenzandoenlaprimeraposición.
Labúsquedasecuencialseprogramadeformaascendente(elbucleterminacuandohaencontradoelelemento, seestá
seguroquenoseencuentraocuandonohaymáselementosenelv ector)suponiendoqueelv ectorestáordenado.La
variableencontrada seponeatrue cuandoseterminalabúsquedadelaclave, obienporquenopuedeestarlaclave enelvector, obienporqueyasehaencontrado.
int BsecorAscendente(int V[], int n, int clave)
{
int i = 0;
bool encontrada = false;
while ((!encontrada) && (i < n))
// Búsqueda secuencial ascendente
{
encontrada = (V[i] >= clave);
//encontrada true fin de búsqueda
if (! encontrada)
// avanzar en la búsqueda
i++;
}
if (i < n)
encontrada = V[i] = = clave ;
return encontrada ? i : –1;
//i si calve encontrada –1 otro caso
}
Estudio de la complejidad
Elmejorcaso, seproducecuandoelelementobuscadoseaelprimeroqueseexamina, demodoquesólosenecesitaunacomparación.Enelpeorcaso, elelementodeseadoeselúltimoquesee xamina, demodoquesenecesitan n comparaciones.En
elcasomedio, seencontraráelelementodeseadoaproximadamenteenelcentrodelacoleccióndedatos, haciendoaproximadamenten/2 comparaciones.Porestarazón, sedicequelaprestaciónmediadelabúsquedasecuenciales O(n).
CAPÍTULO 12 Ordenación y búsqueda
247
12.1.2. BÚSQUEDA BINARIA
Estemétododebúsquedarequierequeloselementosseencuentrenalmacenadosenunaestructuradeaccesoaleatoriodeformaordenada, esdecirclasificados, conarregloalvalordeundeterminadocampo.Engeneral, silalistaestáordenadasepuedeacortareltiempodebúsqueda.Labúsquedabinariaconsisteencompararelelementob uscadoconelqueocupaenlalista
laposicióncentraly, segúnseaigual, mayoromenorqueelcentral, pararlabúsquedaconéxito, obien, repetirlaoperación
considerandounasublistaformadaporloselementossituadosentreelqueocupalaposición central+1 yelúltimo, ambos
inclusive, oporlosqueseencuentranentreelprimeroyelcolocadoen central–1, tambiénambosinclusive.Elprocesoterminaconbúsquedaenfracasocuandolasublistadebúsquedasequedesinelementos.
EJEMPLO 12.4. Búsquedabinariadeunaclaveenunvectordendatosor denadocrecientemente.
Labúsquedabinariaseprograma, tomandoencadaparticiónelelemento central.Decidiendosielelementob uscadoseencuentraenesaposición, obiensihayquemoverelíndice izquierda oderecha delapartición.Seinicializa
izquierda a 0, derecha a n – 1 y central es, enelcomienzodecualquieriteracióndelb ucle, laposicióndelelementoqueocupaelcentro.Elbuclequerealizalabúsquedaterminacuandosehaencontradoelelementoobiencuandolosíndicesdelaparticiónsehancruzado.
int BusquedaBinaria(float V[], int n, float clave)
{
int izquierda = 0, derecha = n – 1, central;
bool encontrado = false;
while((izquierda <= derecha) && (!encontrado))
{
central = (izquierda + derecha) / 2;
if (V[central] == clave)
encontrado = true;
else if (clave < V[central])
//a
derecha = central – 1 ;
else
//
izquierda = central + 1;
}
return encontrado ? central:–1;
//central si
// éxito en la búsqueda
la izquierda de central
a la derecha de central
encontrado –1 otro caso
}
EJEMPLO 12.5. Seguimientodelabúsquedabinariaanteriordelaclave40enelvector V{–8, 4, 5, 9, 12, 18, 25,
40, 60}.
Clave = Cl =40, I = izquierda, C = central, D = derecha
V[0]
V[1]
V[2]
V[3]
V[4]
V[5]
V[6]
V[7]
V[8]
CL
I
C
D
–8
4
5
9
12
18
25
40
60
40
0
4
8
–8
4
5
9
12
18
25
40
60
40
5
6
8
–8
4
5
9
12
18
25
40
60
40
7
7
8
EJEMPLO 12.6. Búsquedabinariadeunaclaveenunvectordendatosor denadodecrecientemente.
Bastaconcambiar
clave < V[central]
lacondicióndebúsquedadelEjemplo12.4
por
clave > V[central]
CAPÍTULO 12 Ordenación y búsqueda
248
int BusquedaBinaria(float V[], int n, float clave)
{
int izquierda = 0, derecha = n – 1, central;
bool encontrado = false;
while((izquierda <= derecha) && (!encontrado))
{
central = (izquierda + derecha) / 2;
if (V[central] == clave)
encontrado = true;
else if (clave > V[central])
//a
derecha = central – 1 ;
else
//
izquierda = central + 1;
}
return encontrado? central:–1;
//central si
// éxito en la búsqueda
la izquierda de central
a la derecha de central
encontrado –1 otro caso
}
Estudio de la complejidad
Elalgoritmodeterminaenquémitadestáelelemento, ydescartalaotramitad.Encadadi visión, elalgoritmohaceunacomparación.Elnúmerodecomparacionesesigualalnúmerodev ecesqueelalgoritmodividelalistaenlamitad.Eltamañode
lassublistasenlassucesi vasiteracioneses: n, n/2, n/4, n/8, ...., 1.Sisesuponeque n esaproximadamenteiguala 2k entoncesk ok+1eselnúmerodevecesquen sepuededividirhastatenerunelementoencuadrado( k=log2 n).Porconsiguiente,
elalgoritmoes0(log2 n) enelpeordeloscasos.Enelcasomedio 0(log2 n) yO(1) enelmejordeloscasos.
12.2. Ordenación
Laordenación oclasificación dedatoseslaoperaciónconsistenteendisponerunconjuntodedatosenalgúnordendeterminadoconrespectoaunodelos campos deelementosdelconjunto.Laclasif icacióninternaeslaordenacióndedatosquese
encuentranenlamemoriaprincipaldelordenador.Unalista dicequeestáordenadaporlaclavek silalistaestáenordenascendenteodescendenteconrespectoaestacla ve.Lalistasedicequeestáen ordenascendentesi:
i < j
implicaque lista[i] <= lista[j]
ysedicequeestáen ordendescendentesi:
i > j
implicaque
lista[i] <= lista[j].
Entodoslosmétodosdeestecapítulo, seutilizaelordenascendente sobrevectoresolistas(arraysunidimensionales).Los
métodosdeclasificacióninternasedividenendostiposfundamentalesale valuarsucomplejidadencuantoaltiempodeejecución:
Directos.
DecomplejidadO(n2)comoburbuja(intercambiodirecto), seleccióneinserción.
Avanzados. Decomplejidadinferior O(n2) comoShell, yotrosdecomplejidad O(nlogn), comoelmétododelmontículo,
ordenaciónpormezclao radixSort.
EnestecapítuloseestudianlosmétodosdirectosyelmétodoShell.
12.3. Ordenación por burbuja
Laordenaciónporburbuja(“bublesort”)sebasaencompararelementosadyacentesdelalista(vector)eintercambiarsusvaloressiestándesordenados.Deestemodo, sedicequelosv aloresmásgrandes burbujean hacialapartesuperiordelalista
(haciaelúltimoelemento), mientrasquelosvaloresmáspequeñossehunden haciaelfondodelalista.Enelcasodeunarray
(lista)conn elementos, laordenaciónporburbujarequierehasta n – 1 pasadas.
CAPÍTULO 12 Ordenación y búsqueda
249
Laprimerapasadarealizalossiguientespasos: elvectortieneloselementos A[0], A[1], ..., A[n – 1].Elmétodo
comienzacomparando A[0] conA[1];siestándesordenados, seintercambianentresí.Acontinuación, secompara A[1] con
A[2], realizandoelintercambioentreellossiestándesordenados.Secontinuacomparando A[2] con A[3], intercambiándolossiestándesordenados..., hastacomparar A[n – 2] con A[n – 1] intercambiándolossiestándesordenados. Alterminar
estapasadaelelementomayorestáenlapartesuperiordelalista.
Lasegundapasadarealizaunprocesoparecidoalanterior , perolaúltimacomparacióny , portanto, elúltimoposibleintercambioesrealizadoconloselementos A[n – 3] y A[n – 2] y, portanto, colocaelsegundoelementomayorenlaposiciónA[n – 2].
Elprocesodescritoserepiteduranten – 1 pasadasteniendoencuentaqueenlapasadai sehacolocadoelelementomayordelasposiciones 0, ..., n – i enlaposición n – i.Deestaforma, cuandoi tomaelvalorn – 2, elvectorestáordenado.
EJEMPLO 12.7. Codificacióndelmétododelab urbuja.
Serealizalaordenaciónponiendoenprimerlugarelelementomayorenlaúltimaposicióndelarray .Posteriormente,
secolocaelsiguientemayorenlapenúltimaposición, yasísucesi vamente.Pararealizarelprocesosóloseutilizan
comparacionesdeelementosconsecutivos, intercambiándolosenelcasodequenoesténcolocadosenorden.
void Burbuja(float
{
int i, j;
float auxiliar;
A[], int n)
for (i = 0; i < n – 1; i++)
for (j = 0; j < n – 1 – i; j++)
if (A[j] > A[j + 1])
{
auxiliar = A[j];
A[j] = A[j + 1];
A[j + 1] = auxiliar;
}
// n–1 pasadas
// burbujeo de datos
//comparación de elementos contiguos
// mal colocados intercambio
}
Estudio de la complejidad
Enestemétododeordenación, losdosbuclescomienzanenceroyterminanen n – 2 y n – i – 1.Elmétododeordenaciónrequierecomomáximo n – 1 pasadasatravésdelalistaoelarray.Durantelapasada 1, sehacenn – 1 comparaciones
ycomomáximo n – 1 intercambios, durantelapasada 2, sehacen n – 2 comparacionesycomomáximo n – 2 intercambios.Engeneral, durantelapasada i, sehacen n – i comparacionesyalomás n – i intercambios.Porconsiguiente, enel
peorcaso, habráuntotalde (n – 1) + (n – 2) + ... + 1 = n*(n – 1) / 2 = O(n2) comparacionesyelmismonúmerodeintercambios.Porconsiguiente, laeficienciadelalgoritmodeburbujaenelpeordeloscasoses O(n2).
EJEMPLO 12.8. Seguimientodelmétododeordenacióndeburbujaparalosdatos8, 3, 8, 7, 14, 6.
SiseejecutaelcódigodelEjemplo12.7escribiendoelcontenidodelvectorcadavezqueserealizaunintercambiode
datos, asícomolosdatosintercambiadosyelíndicedelapasadaseobtieneelsiguienteresultado:
CAPÍTULO 12 Ordenación y búsqueda
250
12.4. Ordenación por selección
Elmétododeordenaciónsebasaenseleccionarlaposicióndelelementomáspequeñodelarrayysucolocaciónenlaposiciónquelecorresponde.Elalgoritmodeselecciónseapo yaensucesivaspasadasqueintercambianelelementomáspequeño
sucesivamenteconelprimerelementodelalista.Elalgoritmodeordenaciónporseleccióndeunalista(v ector)de n elementosserealizadelasiguienteforma: seencuentraelelementomenordelalistayseintercambiaelelementomenorconelelementodesubíndice0.Acontinuación, sebuscaelelementomenorenlasublistadesubíndices 1 .. n – 1, yseintercambia
conelelementodesubíndice 1.Después, sebuscaelelementomenorenlasublista 2 .. n – 1 yseintercambiaconlaposición2.Elprocesocontinúasucesivamente, duranten–1 pasadas.Unavezterminadaslaspasadaslalistadesordenadasereduceaunelemento(elmayordelalista)yelarraycompletohaquedadoordenado.
EJEMPLO 12.9. Codificacióndelmétododeordenaciónporselección.
void seleccion(float A[], int n)
{
int i, j, indicemin;
float auxiliar;
for (i = 0; i < n – 1; i++)
{
indicemin = i;
for(j = i + 1; j < n; j++)
if(A[j] < A[indicemin])
indicemin = j;
auxiliar = A[indicemin];
A[indicemin] = A[i];
A[i] = auxiliar;
// posición del menor
// nueva posición del menor
// intercambia posiciones
}
}
Estudio de la complejidad
Comoprimeraetapaenelanálisisdelalgoritmosedebecontarelnúmerodecomparacioneseintercambiosquerequierela
ordenaciónde n elementos.Lafunciónsiemprerealiza n – 1 intercambios( n, númerodeelementosdelarray), yaquehay
n – 1 llamadasaintercambio).Elbucleinternohacen – 1 – i comparacionescadavez;elbucleexternovadesde0 an – 2
demodoqueelnúmerototaldecomparacionesCes O(n2), porloqueelnúmerodecomparacionesdecla veescuadrático.
Ha deobservarsequeelalgoritmonodependedeladisposicióninicialdelosdatos, loquesuponeunav entajadeunalgoritmodeselecciónyaqueelnúmerodeintercambiosdedatosenelarrayeslineal. O(n).
EJEMPLO 12.10. Seguimientodelmétododeordenacióndeselecciónparalosdatos8, 6, 5, 7, 18, 7.
AlrealizarunseguimientodelmétododeordenacióndeseleccióncodificadoenelEjemplo12.9yescribirelcontenidodelvectorcadavezqueserealizaunintercambiodedatos, asícomolosdatosintercambiadosyelíndicedelapasadaseobtienelossiguiente:
CAPÍTULO 12 Ordenación y búsqueda
251
12.5. Ordenación por inserción
Estemétodoconsisteentomarunasublistainicialconunúnicoelementoquesepodráconsiderarsiempreordenada.Enlasublistaordenadaseiráninsertandosucesi vamentelosrestanteselementosdelalistainicial, enellugaradecuadoparaquedichasublistanopierdalaordenación.Elalgoritmoconsideraquelasublista A[0], A[1], ..., A[i–1] estáordenada, posteriormenteinsertaelelemento A[i] enlaposiciónquelecorrespondaparaquelasublista A[0], A[1], ...A[i–1], A[i] esté
ordenada, moviendohacialaderechaloselementosqueseannecesarios.Lasublistaordenadaaumentarásutamañocadav ez
queseinsertaunelementohastalle garaalcanzareldelalistaoriginal, momentoenelquehabráterminadoelproceso.Los
métodosdeordenaciónporinserciónpuedenserdirectoobinario, dependiendodequelabúsquedaserealicedeformasecuencialobinaria.
EJEMPLO 12.11. Codificación del método de ordenación por inserción lineal.
Lasublista 0 .. i – 1 estáordenada, ysecolocaelelementoqueocupalaposición i delalistaenlaposiciónque
lecorrespondemedianteunabúsquedalineal.Deestaforma, lasublistaseordenaentrelasposición 0 .. i.Si i varíadesde 1 hastan – 1 seordenalalistadedatos.
void Insercionlineal(float
{
int i,j;
bool encontrado;
float auxiliar;
A[], int n)
for (i = 1; i < n; i++)
{
// A[0], A[1], ..., A[i–1] está ordenado
auxiliar = A[i];
j = i – 1;
encontrado = false;
while (( j >= 0 ) && ! encontrado)
if (A[j] > auxiliar)
{
// se mueve dato hacia la derecha para la inserción
A[j + 1] = A[j];
j--;
}
else
encontrado = true;
A[j + 1] = auxiliar;
}
}
Estudio de la complejidad de la inser ción lineal
Elbucle for delafunciónseejecuta n – 1 veces.Dentrodeesteb ucleexisteunbucle while queseejecutaalomáselv alordei vecesparavaloresdei queestánenelrango 1 an – 1.Porconsiguiente, enelpeordeloscasos, lascomparaciones
delalgoritmovienendadaspor 1 + 2 +... + (n – 1) =
n(n – 1)
2
.Porotraparte, elalgoritmomuevelosdatoscomo
máximoelmismonúmerodev eces.Existenportanto, enelpeordeloscasos,
algoritmodeordenaciónporinserciónes O(n2) enelcasopeor.
n(n – 1)
2
movimientos. Porconsiguiente, el
EJEMPLO 12.12. Seguimientodelmétododeordenacióndeinserciónlinealparalosdatos14, 9, 16, 1, 13, 17.
AlejecutarelcódigodelEjemplo12.11, yescribirelcontenidodelv ectoralfinaldecadapasadaseobtienelasalida
siguiente:
CAPÍTULO 12 Ordenación y búsqueda
252
EJEMPLO 12.13. Codificación del método de ordenación por inserción binaria.
Laúnicadiferenciadelosdosmétodosdeordenaciónporinserción, radicaenelmétododerealizarlabúsqueda.En
estecasoesunabúsquedabinaria, porloqueeldesplazamientodedatoshacialaderechadebehacersedespuésdehaberencontradolaposicióndondesedebeinsertarelelemento, queenestacodificaciónessiempre izquierda.
void Insercionbinaria(float
A[], int n )
{
int
i, j, izquierda, derecha, centro;
float auxiliar;
for(i = 1; i < n; i++)
{
auxiliar = A[i];
izquierda = 0;
derecha = i – 1;
while (izquierda <= derecha)
//búsqueda binaria sin interruptor
{
centro = ( izquierda +derecha) / 2;
if(A[centro] >
auxiliar)
derecha = centro – 1;
else
izquierda = centro + 1;
}
// desplazar datos hacia la derecha
for(j = i – 1; j >= izquierda; j--)
A[j + 1] = A[j];
A[izquierda] = auxiliar;
}
}
Estudio de la complejidad de la inser ción binaria
Losmétodosdeordenaciónporinserciónlinealeinserciónbinaria, sólosediferencianentresí, conceptualmente, enelméton(n –1)
dodelabúsqueda.Portanto, elnúmerodemo vimientosdeclavesseráelmismoenamboscasoses
.Encuantoal
2
númerodecomparaciones, cuandoelintervalotieneielementos, serealizan log2(i) comparaciones.Portanto, elnúmerode
comparacioneses:
C=
n −1
n −1
i =1
1
∑ log2 (i) =
∫
log2 ( x )dx ≈ n log 2 (n)
Esdecirelnúmerodecomparacioneses O(nlog2 (n)), yelnúmerodemovimientoses O(n2).
CAPÍTULO 12 Ordenación y búsqueda
253
12.6. Ordenación Shell
LaordenaciónShellsesueledenominartambiénordenaciónporinserciónconincrementosdecrecientes.Esunamejoradelos
métodosdeinsercióndirectayburbuja, enelquesecomparanelementosquepuedensernocontiguos.Laideageneraldealgoritmoeslasiguiente.Sedi videlalistaoriginal( n elementos)en n/2 gruposdedoselementos, conuninterv aloentrelos
elementosdecadagrupoden/2 yseclasificacadagrupoporseparado(secomparanlasparejasdeelementosysinoestánordenadosseintercambianentresídeposiciones).Sedi videahoralalistaen n/4 gruposdecuatroconuninterv aloosaltode
n/4 y, denuevo, seclasificacadagrupoporseparado.Serepiteelprocesohastaque, enunúltimopaso, seclasificaelgrupo
den elementos.EnelúltimopasoelmétodoShellcoincideconelmétododelab urbuja.
EJEMPLO 12.14. CodificacióndelmétododeordenaciónShell.
void shell(float A[], int n)
{
int i, j, k, salto = n/2;
float auxiliar;
while (salto > 0)
// ordenación de salto listas
{
for (i = salto; i < n; i++)
// ordenación parcial de lista i
{
// los elementos de cada lista están a distancia salto
j = i – salto;
while(j >= 0)
{
k = j + salto;
if (A[j] <= A[k])
// elementos contiguos de la lista
j = –1;
// fin bucle par ordenado
else
{
auxiliar = A[j];
A[j] = A[k];
A[k] = auxiliar;
j = j – salto;
}
}
}
salto = salto / 2;
}
}
EJEMPLO 12.15. Seguimientodelmétododeor denacióndeshellpar alasiguientelistadedatos9, 18, 7, 9, 1, 7.
Elresultadodeejecucióndelafunciónanterior , escribiendolosintercambiosrealizadosasícomoelv alordesaltoen
cadaunodeelloses:
CAPÍTULO 12 Ordenación y búsqueda
254
EJERCICIOS
12.1. ¿Cuálesladiferenciaentrebúsquedayordenación?
12.2. Unvectorcontieneloselementosmostradosacontinuación.Losprimerosdoselementossehanordenadoutilizandounalgoritmodeinser ción.¿Cómoestaráncolocadosloselementosdelvectordespuésdecuatr opasadasmásdelalgoritmo?
3, 13, 8, 25, 45, 23, 98, 58.
12.3. ¿Cuálesladiferenciaentreordenación porselecciónyordenaciónporinserción?
12.4. Dadalasiguientelista47, 321, 32, 56, 92.Despuésdedospasadasdeunalgoritmodeor denación, elarraysehaquedadodispuestoasí: 3, 21, 47, 32, 56, 92.¿Quéalgoritmodeordenaciónseestáutilizando(selección, burbujaoinserción)?
Justifiquelarespuesta.
12.5. Unarraycontieneloselementosindicadosmásabajo.Utilizandoelalgoritmodebúsquedabinaria, trazarlasetapasnecesariasparaencontrarelnúmero88yelnúmero20.
8, 13, 17, 26, 44, 56, 88, 97.
PROBLEMAS
12.1. Modificarelalgoritmodeordenaciónporselecciónparaqueordeneunvectordeenterosenordendescendente.
12.2. Escribirunprogramaquecreeunarrayde100enterosaleatoriosenelrangode1a200y, acontinuación, utilizandouna
búsquedasecuencial, realizarlabúsquedade50enterosseleccionadosaleatoriamente(igualesodistintos).Alfinaldelprogramasedebenvisualizarlassiguientesestadísticas:
• Númerodebúsquedasconéxito.
• Númerodebúsquedasfallidas.
• Porcentajesdeéxitoydefallo.
12.3. Escribirunamejoradelmétododeordenacióndeburbuja, consistenteennorealizarmásiteracionescuandosedetecteque
elvectoryaestáordenado.
12.4. Modificarelmétododeor denaciónporselección, paraqueenlugardecolocarelelementomenorenellugarquelecorresponde, lohagaconelelementomayor.
12.5. Escribirunafunciónqueaceptecomoparámetrounvectorquepuedecontenerelementosduplicados.Lafuncióndebesustituircadavalorrepetidopor–1yde volveralpuntodondefuellamadoelvectormodif icadoyelnúmerodeentradasmodificadas(puedesuponerqueelvectordedatosnocontieneelvalor–1cuandosellamaalafunción).
12.6. Escribirunprogramaquegenereunvectorde1000númerosenterosaleatoriospositivosymenoresque100, yhagalosiguiente:
1. Visualizarlosnúmerosdelalistaenordencreciente.
2. Calculareimprimirlamediana(valorcentr al).
3. Determinarelnúmeroqueocurreconmayorfrecuencia.
CAPÍTULO 12 Ordenación y búsqueda
255
4. Imprimirunalistaquecontenga
a) númerosmenoresde30,
b) númerosmayoresde70,
c) númerosquenopertenezcanalosdosgruposanterior es.
12.7. Construirunafunciónquepermitaordenarporfechasydemayoramenorunvectordenelementosquecontienedatosde
contratos(n<=50).Cadaelementodelvectordebeserunaestructur aconloscampos(entero)día, mes, añoynúmerode
contrato.
12.8. Escribirunprogramaparaleerunte xtodedatosformadoporncadenasdecar acteres, siendonunavariableenter a.La
memoriaqueocupaeltextosehadeajustaraltamañoreal.Unavezleídoeltextosedebeordenareltextooriginalporla
longituddelaslíneas.Elprogramadebemostrareltextoleídoyeltextoordenado.
SOLUCIÓN DE LOS EJERCICIOS
12.1. Laordenacióndeunalistaeselprocesoporelcual, losdatosquesealmacenanenellasereestructurandetalmaneraque
quedanenordencrecienteodecrecienterespectodeunaclave.Labúsquedadeunelementoenunalistadeterminadaconsisteendecidirsielelementoseencuentr aonoenlalista, dandoalgunaposicióndondeseencuentr e, todaslasposiciones, osimplementeinformandodecuantasvecesapar eceenlalista.
12.2. Despuésdelaprimerapasada:
Despuésdelasegundapasada:
Despuésdelatercerapasada:
Despuésdelacuartapasada:
3, 8, 13, 25, 45, 23, 98, 58.
3, 8, 13, 25, 45, 23, 98, 58.
3, 8, 13, 25, 45, 23, 98, 58.
3, 8, 13, 23, 25, 45, 98, 58.
12.3. Elmétododeordenaciónporselección, seleccionalaposicióndelelementomáspequeño(oelmayor)ylocolocaenellugarquelecorr esponde.Porconsiguiente, eligelaposicióndelelementomáspequeñodelvectorylointer cambiaconla
posición 0.Posteriormente, eligelaposicióndelsiguientemáspequeñoylointer cambiaconelqueocupalaposición 1,
etc.Elmétododeordenaciónporinserción, partedeunvectorparcialmenteordenado(hastalaposición i – 1)ydecide
cualeslaposicióndondedebecolocarelsiguienteelementodelvector(elqueocupalaposición i)paraampliarlaordenaciónparcial(elvectorquedeordenadohastalaposicióni).Siserealizaniteracionesincrementandoencadaunadeellas
elvectorparcialmenteordenadoenunelemento, alfinalelvectorquedaráordenado.
12.4. Despuésderealizarlaprimerapasada, elmétododelaburbujadejaríaelvectorordenado, porloqueestemétodonopuedehaberseusado: 3, 21, 32, 47, 56, 92.
Pasadasdelmétododeselección:
primera: 3, 47, 21, 32, 46, 92.
segunda: 3, 21, 47, 32, 56, 92.
Pasadasdelmétododeordenaciónporinserción:
primera: 3, 47, 21, 32, 56, 92.
segunda: 3, 21, 47, 32, 56, 92.
Enconsecuencia, puedehabersidousadotantoelmétododeordenaciónporseleccióncomoeldeinserción, peronuncael
deburbuja.
CAPÍTULO 12 Ordenación y búsqueda
256
12.5. Búsquedadelaclave88.Enlaprimer aiteracióndelb uclelaclavecentr alsería26, ycomonocoincideconlaclavea
buscarquees88, entonceshabríaquer ealizarlabúsquedaen: 44, 56, 88, 97.Enlase gundaiteracióndelbucle, laclave centralsería56, ycomotampococoincideconlaclaveab uscarquees88, entonceshabríaquer ealizarlabúsqueda
en: 88, 97.Enlaterceraiteración, laclavecentrales88quecoincideconlaclavequeseb usca, portanto, seterminaría
elbucleconéxito.
Búsquedadelaclave20.Como20esmenorquelaclavecentral26, hayquebuscarenelsubarray8, 13, 17.Enlasegundaiteraciónlaclavecentr ales13queesmenorque20porloquehayquecontinuarlabúsquedaenelsubarr ay17.
Ahoralaclavecentrales17ycomoesmenorque20hayqueb uscarenelsubarraydeladerechaquenoexiste, ylabúsquedaconcluyeenfracaso.
SOLUCIÓN DE LOS PROBLEMAS
12.1. Paraordenardecrecientementeelvectorbastaconcambiarelsentidodelacompar acióndecontenidosqueser ealizaen
elmétododeordenación A[j] > A[indicemax].Enlacodif icaciónsehacambiadoademáselnombr edelíndicequese
intercambia.
La codificación de este problema se encuentra en la página Web del libro.
12.2. Lafunciónaleatorio rellenaelarraydennúmerosenterosaleatoriamenteenelrangosolicitado, usandolasmacrosrandomize yrandom previamentedefinidasensendasmacros.Lafunciónquerealizalabúsquedasecuencialdeuna clave en
unvector V den datos.Lafunción ejercicio resuelveelproblema, presentandolasestadísticassolicitadas.Almacenaen
lavariable exitos elnúmerodeéxitos, yenlavariable fallos elnúmerodefallosqueocurren.
La codificación de este problema se encuentra en la página Web del libro.
12.3. Encadapasadadelmétododelab urbuja, elmétodocomparaelementosconsecutivosintercambiándolossinoestánenel
ordencorrespondiente.Cuandoser ealizaunapasada, ynoseconsiguemo verningúndatoelvectorestáor denado.Este
hechopuedeaprovecharse, paracambiarelprimerbucle for delapasada, porunbulewhile quefinalicetambiéncuandonosemue vandatos. Deestaforma, semejoraelmétododeor denacióndeburbuja.Lavariable ordenado controlaen
cadapasadaestehecho.
La codificación de este problema se encuentra en la página Web del libro.
12.4. Seutilizalaideadequeencadaiteraciónsebuscalaposicióndelelementomayordelarray(quenohasidoyacolocado)
ylocolocaenlaposiciónquelecorr esponde.Enprimerlugar, secolocaelmayordetodosenlaposición n – 1, acontinuación, elsiguientemayorenlaposición n – 2, continuandohastalaposición 1.
La codificación de este problema se encuentra en la página Web del libro.
12.5. Lafunciónduplicadosrecibecomoparámetroelvector A, yelnúmerodeelementosquealmacenan.Elcontador ntotal
cuentaelnúmerodevecesquesecambiaunvalorpor –1.Elcontador ntotal1, cuentaelnúmerodeelementosqueson
cambiadospor –1 enlaiteracióni.Elproblemaseharesueltodelasiguienteforma: unbuclecontroladoporlavariable
i, recorreelvector.Paracadaposición i cuyocontenidoseadistintodelamarca–1 secomprueba, secuentaysecambia
porelvalorpredeterminado –1 medianteotrobuclecontroladoporlavariableenter a j, aquellosvaloresquecumplenla
condiciónA[i]==A[j] (siemprequeA[i]<>–1).Alfinaldelbuclej, sisehacambiadoalgúnelementoporelvalorpredeterminado, secambiatambiénelvalordelaposición i, y, porsupuesto, secuenta.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 12 Ordenación y búsqueda
257
12.6. Seusanlasfunciones Burbuja, paraordenarelvectory aleatorio, paragenerarloaleatoriamente.Lafunción mostrar
seencargadevisualizarelcontenidodeunvectordetamaño n queselepasacomoparámetr o.Enelarr ay repeticiones, sealmacenaelnúmerodevecesqueser epitecadanúmero.Lamedianaseencuentr asiempreenlaposicióncentr al
delarrayunavezordenado.
La codificación de este problema se encuentra en la página Web del libro.
12.7. Hayquetenerencuentaquesepideunaor denaciónportresclaves, siendolaclaveprimaria, anio, lasecundaria mes, y
laterciaria día.Siemprequehayaqueor denarporestetipodeclavesesnecesariodef inirunafunción mayor quereciba
dosdatosdetipoestructuraydecidacuándolaprimeraestructuraesmayorquelasegunda, deacuerdoconlosdatosdel
problema.Enestecaso, laestructuratieneelcontrato quesedefinecomounpunteroachar ylafechaconsustresmiembros, definidosenelenunciado.Elmétododeordenaciónqueseempleaeseldeburbuja, peropuedesercualquierotro.En
todosellossólohayquecambiareloper ador>porlafunción mayor.
La codificación de este problema se encuentra en la página Web del libro.
12.8. Sedeclara, enprimerlugar, unsinónimodepunteroacarácterquees cadena.Posteriormente, lasvariablesTexto yTextoaux, comopunterosa cadena, dondeseleeelte xtooriginal, ysehacelacopiadelte xtoparaordenarlo.Sereservaespacioenmemoriadinámicamentepar acadaunodeloste xtosajustadosalalongitudr ealdecadalínea, paraposteriormentellamaralasfuncionesencargadasdeleereltextotransformarloyvisualizarlo.
Lafunciónquer ealizalalectur adelaslíneadelte xto Leer_Texto, asignadinámicamentelalongituddecadalínea
deltexto, unavezconocidasulongitudrealdadaporelusuario, paraminimizarelespacioenmemoriadealmacenamientodedatos.
Lafunciónquetransformaeltexto, enotrotextoordenado, Transformar_Texto_en_Ordenado, copialíneaalínealos
datosdeltextooriginalenelte xtoauxiliar, asícomoenelvector longitud, lalongituddecadaunadelaslíneas. Aeste
vectordeenterosseleasignamemoriadinámicamente, antesdelproceso.Posteriormente, seusaunmétododeordenación
(inserciónlineal)paraordenarlosarraysparaleloslongitud yTextoaux.
Lavisualizacióndelostextosdeentradaytextoordenadoesrealizadoporlafunción Mostrar_Texto, quelomuestra
líneaalínea.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
12.1. Eliminartodoslosnúmerosduplicadosdeunalistao
vector.Porejemplo, sielv ectortomalosv alores4, 7,
11, 4, 9, 5, 11, 7, 35 hadecambiarsea 4, 7, 11, 9, 5, 3.
12.2. Escribirlafuncióndeordenacióncorrespondienteal
métodoShell paraponerenordenalfabéticounalistade
n nombres.
12.3. Realizarunprogramaquecompareeltiempodecálculodelasbúsquedassecuencialybinaria.
12.4. Realizarunse guimientodelosdistintosmétododeordenación: inserción, shell, burbujayselecciónparaun
vectorquealmacenalossiguientesdatos: 7, 4, 13, 11, 3,
2, 7, 9.
12.5. Realizarunse guimientodelmétododeordenaciónpor
selecciónparalosdatosdeentrada 3, 7, 10, 1, 6, 4, 0.
CAPÍTULO 12 Ordenación y búsqueda
258
PROBLEMAS PROPUESTOS
12.1. Supongaquesetieneunasecuenciade n númerosque
debenserclasificados:
Escribirunprogramaquerealiceestatarea. Nota: utilizarcomoalgoritmodeordenaciónelmétodoselección.
1. Siseutilizaelmétodode Shell, ¿cuántascomparacionesycuántosintercambiosserequierenparaclasificarlasecuencia si: yaestáclasif icado;estáen
ordeninverso?
2 Realizarlosmismoscálculossiseutilizaelalgoritmoburbuja.
12.5. Cadalíneadeunarchivodedatoscontieneinformación
sobreunacompañíadeinformática.Lalíneacontieneel
nombredelempleado, lasventasefectuadasporelmismoyelnúmerodeañosdeantigüedaddelempleadoen
lacompañía.Escribirunprogramaquelealainformacióndelarchivodedatosy, acontinuación, lavisualice.
Lainformacióndebeserordenadaporv entasdemayor
amenoryvisualizadadenuevo.
12.2. Setrataderesolverelsiguienteproblemaescolar.Dadas
lasnotas(1a10)delosalumnosdeuncolegioenelprimercursodebachillerato, enlasdiferentesasignaturas
(5, porcomodidad), setratadecalcularlamediadecada
alumno, lamediadecadaasignatura, lamediatotalde
laclaseyordenarlosalumnosporordendecrecientede
notasmediasindi viduales. Nota: utilizarcomoalgoritmodeordenaciónelmétodoinserciónbinaria.
12.3. Escribirunprogramadeconsultadeteléfonos.Elprocesoleeráunconjuntodedatosde1000nombresy
númerosdeteléfonodeunarchivoquecontienelosnúmerosenordenaleatorioylasconsultashandepoder
realizarsepornombreypornúmerodeteléfono.
12.4. Sedisponededosv ectores, Maestro y Esclavo, del
mismotipoynúmerodeelementos.Sedebenimprimir
endoscolumnasadyacentes.SeordenaelvectorMaestro, perosiemprequeunelementodeMaestro semueva, elelementocorrespondientede Esclavo debemoversetambién;esdecir , cualquieracciónhechacon
Maestro[i] debehacersea Esclavo[i].Despuésde
realizarlaordenaciónsevisualizadenuevolosvectores.
12.6. Sedesearealizarunprogramaquerealicelassiguientes
tareas
a) Generar, aleatoriamente, unalistade999números
realesenelrangode0a2000.
b) Ordenarenmodocrecienteporelmétododelaburbuja.
c) Ordenarenmodocrecienteporelmétodo Shell.
d) Buscarsiexisteelnúmerox (leídodelteclado)enla
lista.Aplicarlabúsquedabinaria.
12.6. Ampliarelprogramaanteriordemodoquepuedaobteneryvisualizarenelprogramaprincipallossiguientes
tiempos:
t1. Tiempoempleadoen ordenar lalistaporcadauno
delosmétodos.
t2. Tiempoqueseemplearíaen ordenar lalistayaordenada.
t3. Tiempoempleadoen ordenar lalistaordenadaen
ordeninverso.
CAPÍTULO 13
Clases y objetos
Introducción
Unaclase esuntipodedatoquecontienecódigo(funciones)ydatos.Unaclasepermiteencapsulartodoelcódigoylosdatosnecesariosparagestionaruntipoespecíf icodeunelementodeprograma.Enestecapítulosetrataránlasclases, unnuevo
tipodedatocuyasv ariablesseránobjetos.Enlaprogramaciónorientadaaobjetos, losobjetossonloselementosprincipales
deconstrucción.Sinembargo, lasimplecomprensióndeloqueesunobjeto, obien, elusodeobjetosenunprograma, nosignificaqueesténprogramandoenunmodoorientadoaobjetos.Unsistemaorientadoaobjetosesaquelenelcuallosobjetos
seinterconectanycomunicanentresí.
13.1. Clases y objetos
Laideafundamentalenloslenguajesorientadosaobjetosescombinarenunasolaunidad datosyfuncionesqueoper ansobreesosdatos.Talunidadsedenominaobjeto.Elconceptodeobjeto, aligualquelostiposabstractosdedatosotiposdef inidosporelusuario, esunacoleccióndeelementosdedatos, juntoconlasfuncionesasociadasparaoperarsobreesosdatos.
Lasclasessonsimilaresalostiposdedatosyequi valenamodelosoplantillasquedescribencómoseconstruyenciertos
tiposdeobjetos.Unaclasecontienelaespecif icacióndelosdatosquedescribenunobjetojuntoconladescripcióndelasaccionesqueunobjetoconocecómohadeejecutar .Estasaccionesseconocencomo servicios, métodoso funcionesmiembro.
Eltérminofunciónmiembro seutiliza, específicamente, enC++.
13.2. Definición de una clase
Unaclase esladescripcióndeunconjuntodeobjetos;constade métodos (ofuncionesmiembro)ydatoso atributos queresumencaracterísticascomunesdeunconjuntodeobjetos.Generalmente,unaclasesepuededefinircomounadescripciónabstractadeungrupodeobjetos, cadaunodeloscualessediferenciaporunestado específicoyescapazderealizarunaseriede
operaciones.
Unaclasees, enesencia, ladeclaracióndeuntipoobjeto.Lasclasessonsimilaresalostiposdedatosyequi valenamodelosoplantillasquedescribencómoseconstruyenciertostiposdeobjetos.Definirunaclasesignificadaralamismaunnombre, asícomodarnombrealoselementosquealmacenansusdatosydescribirlasfuncionesquerealizaránlasaccionesconsideradasenlosobjetos.
259
CAPÍTULO 13 Clases y objetos
260
Unadeclaración deunaclaseconstadeunapalabrareserv ada class yelnombredelaclase.Seutilizantresdiferentes
especificadoresdeacceso paracontrolarelaccesoalosmiembrosdelaclase.Estosaccesosson: public, private y protected.
Sintaxis
class nombre_clase {
public:
// miembros públicos
protected:
// miembros protegidos
private:
// miembros privados
};
Elespecificadorpublic definemiembrospúblicos, quesonaquéllosalosquesepuedeaccederporcualquierfunción. A
losmiembrosprivadosquesiguenalespecif icador private sólosepuedeaccederporfuncionesmiembrodelamismaclase
oporfuncionesyclasesamigas.Alosmiembrosquesiguenalespecificadorprotected sepuedeaccederporfuncionesmiembrodelamismaclaseodeclasesderi vadas1 delamisma, asícomoporsusamigas.Losespecif icadores public, protected
yprivate puedenaparecerencualquierorden.Siseomiteelespecificadordeacceso, elaccesopordefectoesprivado.Enla
Tabla 13.1cada “x” indicaqueelaccesoestápermitidoaltipodelmiembrodelaclaselistadoenlacolumnadelaizquierda.
Tabla 13.1. Visibilidad.
Tipo de miembro
private
protected
public
Miembro de la
misma clase
Amiga
Miembro de una
clase derivada
Función
no miembro
x
x
x
x
x
x
x
x
x
Elusodelosespecif icadoresdeaccesoesimplementarlaocultacióndelainformación.Elprincipiodeocultacióndela
informaciónindicaquetodalainteracciónconunobjetosedeberestringirautilizarunainterf azbiendefinidaparapermitir
quelosdetallesdeimplementacióndelosobjetosseanignorados.
Elprincipiodeencapsulamiento significaquelasestructurasdedatosinternasutilizadasenlaimplementacióndeuna
clasenopuedenseraccesiblesdirectamentealusuariodelaclase.
Lasfuncionesmiembroylosmiembrosdatosdelasecciónpública formanlainterfazexternadelobjeto, mientrasquelos
elementosdela secciónprivada sonlosaspectosinternosdelobjetoquenonecesitanseraccesiblesparausarelobjeto.La
secciónprotegidanecesitaparasucomprensiónelconceptodeherenciaquesee xplicaráposteriormente.
C++soportalascaracterísticasdeocultacióndedatosconlaspalabrasreserv adaspublic, private yprotected.
Lasfunciones miembro (o métodos) sonfuncionesqueseincluyendentrodeladefinicióndeunaclase, ypuedenserde
lossiguientestipos:
• Constructoresy destructores: funcionesmiembroalasquesellamaautomáticamentecuandounoperadorsecreaose
destruye.
1
LasclasesderivadasseestudianenelCapítulo14.
CAPÍTULO 13 Clases y objetos
•
•
•
•
261
Selectores: devuelvenlosvaloresdelosmiembrosdato.
Modificadores omutadores: permitenaunprogramaclientecambiarloscontenidosdelosmiembrosdato.
Operadores: permitendefiniroperadoresestándarC++paralosobjetosdelasclases.
Iteradores: procesancoleccionesdeobjetos, talescomoarraysylistas.
EJEMPLO 13.1. Declaracióndelaclase Punto delespaciotridimensionalquecontienelascoordenadasx, y, z del
espacioyfuncionesmiembroparaobteneryponercadaunadelascoor denadas.
class Punto
// nombre de la clase
{
public:
// zona pública con declaración de funciones miembro
float ObtenerX() { return x; }
//selector x
float ObtenerY() { return y;}
//selector y
float ObtenerZ() { return z;}
//selector z
void PonerX (float valx) { x = valx; }
//modificador x
void PonerY (float valy) { y = valy; }
//modificador y
void PonerZ (float valz) { z = valz;}
//modificador z
private:
// zona privada con declaración de atribitos.
float x, y, z;
};
13.3. Objetos
Unaclase esladeclaracióndeuntipoobjeto, yunavariabledetipoclaseesunobjeto.Cadav ezqueseconstruyeunobjeto
apartirdeunaclasesecrea unainstancia (ejemplar)deesaclase.Porconsiguiente, losobjetosnosonmásqueinstanciasde
unaclase.Unainstanciaesunavariabledetipoobjeto .
Engeneral, instanciadeunaclaseyobjetosontérminosintercambiables.Lostiposobjetosdef inidosporelusuariose
comportancomotiposincorporadosquetienendatosinternosyoperacionesinternasyexternas.Lasintaxisdedeclaraciónde
unobjetoes:
Sintaxis
nombre_clase identificador;
Así, ladefinicióndeunobjeto Punto es: Punto p;
Eloperadordeacceso aunmiembro(.)seleccionaunmiembroindi vidualdeunobjetodelaclase.
Ejemplo: Crearunpunto p, fijarsucoordenadax yvisualizardichacoordenada.
Punto p;
p.PonerX (100);
cout << " coordenada
//pone la coordenada x a 100
x es " << p.ObtenerX();
Cadaobjetoconstade:
• Estado (atributos)determinadosporsusdatosinternos.Elestadodeunobjetoessimplementeelconjuntodevaloresde
todaslasvariablescontenidasdentrodelobjetoenuninstantedado.Unatributoconstadedospartes: unnombredeatributoyunvalordeatributo.
• Métodos, funciones miembro, operacionesocomportamiento(métodosinvocadospormensajes).Estasoperacionesse
dividenentresgrandesgrupos: operacionesquemanipulan losdatosdealgunaformaespecífica(añadir, borrar, cambiar
formato...);operacionesquerealizanuncálculo oproceso;yoperacionesquecomprueban(monitorizan)unobjetofrentealaocurrenciadealgúnsucesodecontrol.Cadamétodotieneunnombreyuncuerpoquerealizalaacciónocomportamientoasociadoconelnombredelmétodo.
CAPÍTULO 13 Clases y objetos
262
Losobjetosocupanespacioenmemoriay, enconsecuencia, existeneneltiempo, ydeberáncrearseoinstanciarse.Porla
mismarazón, sedebeliberarelespacioenmemoriaocupadoporlosobjetos.
Unmensaje eslaacciónquerealizaunobjetoElconjuntodemensajesaloscualespuederesponderunobjetosedenominaprotocolo delobjeto.Unmensajeconstadetrespartes:
• Identidad delreceptor.
• Elmétodo quesehadeejecutar.
• Informaciónespecial necesariapararealizarelmétodoinvocado(argumentosoparámetrosrequeridos).
Dosoperacionescomunestípicasencualquierobjetoson:
• Constructor: unaoperaciónquecreaunobjetoy/oinicializasuestado.
• Destructor: unaoperaciónqueliberaelestadodeunobjetoy/odestruyeelpropioobjeto.
Estasoperacionesseejecutaránimplícitamenteporelcompiladoroexplícitamenteporelprogramador, medianteinvocaciónaloscitadosconstructores.
Losobjetostienenlassiguientescaracterísticas:
•
•
•
•
•
•
Seagrupanentiposllamados clases.
Tienendatosinternos quedefinensuestadoactual.
Soportanocultacióndedatos.
Puedenheredar propiedadesdeotrosobjetos.
Puedencomunicarseconotrosobjetospasando mensajes.
Tienenmétodos quedefinensucomportamiento.
EJEMPLO 13.2. Declararlaclasepuntocondistintasfuncionesmiembros: modificadores, selectores, yvariostipos
deconstructores(seexplicanposteriormente).Losobjetosdeclaradosseinicializanyvisualizan.
Elprogramaprincipaldeclaracuatroobjetosqueseinicializandedistintaformaysevisualizandatos.
#include <cstdlib>
#include <iostream>
using namespace std;
class Punto
// nombre de la clase
{
public:
// zona pública con declaración de funciones miembro
float ObtenerX() { return x; }
//selector x
float ObtenerY() { return y;}
//selector y
float ObtenerZ() { return z;}
//selector z
void PonerX (float valx) { x = valx; }
//modificador x
void PonerY (float valy) { y = valy; }
//modificador y
void PonerZ (float valz) { z = valz;}
//modificador z
Punto( float valx): x(valx), y(0.0), z(0.0){}
//constructor
// constructor que inicializa miembros
//Las declaraciones anteriores son definiciones de métodos, ya que
//incluyen el cuerpo de cada función. Son funciones en línea, inline
Punto();
Punto(float , float, float);
Punto( const Punto &p);
void EscribirPunto();
void AsignarPunto(float , float, float);
//constructor por defecto
//constructor alternativo
// constructor de copia
// selector
// modificador
CAPÍTULO 13 Clases y objetos
263
//Las declaraciones anteriores no incluyen el cuerpo de cada función
//Son funciones fuera de línea. El cuerpo de la función se declara
//independientemente
private:
// zona privada con declaración de atribitos.
float x, y, z;
};
Punto::Punto()
{
x = 0;
y = 0;
z = 0;
}
//cuerpo constructor por defecto
Punto::Punto(float valx, float valy, float valz)
{
//cuerpo constructor alternativo
x = valx;
y = valy;
z = valz;
}
Punto::Punto ( const Punto &p)
{
x = p.x;
y = p.y;
z = p.z;
}
// cuerpo del constructor de copia
void Punto::EscribirPunto()
{
cout << " " << ObtenerX() << " " << ObtenerY()
<< " " << ObtenerZ() << endl;
}
void
{
x
y
z
}
// cuerpo
Punto::AsignarPunto(float valx, float valy, float valz)
//Cuerpo. El nombre de los parámetros puede omitirse en declaración
= valx;
= valy;
= valz;
int main(int argc, char *argv[])
{
Punto p, p1;
// p, y p1 son objetos de la clase Punto
Punto p2 = Punto(5.0, 6.0, 7.0);
//p2 objeto de la clase Punto
Punto p3(8.0);
//p3 objeto de la clase Punto
p.AsignarPunto(2.0,3.0,4.0);
// llamada a función miembro;
p.EscribirPunto();
// llamada a función miembro
p1.EscribirPunto();
//Escribe valores constructor por defecto
p2.EscribirPunto(); //Escribe valores constructor alternativo
p3.EscribirPunto();
//Escribe valores constructor lista
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 13 Clases y objetos
264
Observaciones
• LosmétodosObtenerX, ObtenerY, ObtenerZ PonerX, PonerY, PonerZ, sonfuncionesmiembroenlínea, ysedeclaran
enunasolalínea.
• Losmétodos Punto, EscribirPunto, yAsignarPunto, tienensuprototipoenladeclaracióndelaclase, peroladeclaracióndesucuerposerealizafueradelínea.Ladeclaracióndesuprototipoterminaenpuntoycoma ;.
• Loscuerposdelasfunciones Punto, EscribirPunto, y AsignarPunto serealizanfueradelínea.Estasdeclaraciones
vanprecedidasdeloperadorderesolucióndeámbitocuatropuntos(::).Lasfuncionesmiembrodeunaclasesedefinen
deigualmodoquecualquierotrafuncióne xceptoquesenecesitaincluireloperadorderesolucióndeámbito :: enla
definicióndelafunción(ensucabecera).
Formato
Tipo_devuelto Nombre_clase ::Nombre_función (Lista_parámetros)
{
sentencias del cuerpo de la función
}
Elsímbolo :: (operadorderesolucióndeámbito)seutilizaensentenciasdeejecuciónparaaccederalosmiembrosde
laclase.Porejemplo, laexpresiónPunto::X serefierealmiembrodato X delaclase Punto.
• Lasllamadasalasfuncionesmiembrodelosobjetos p, p1, p2, p3 fueradelaclase(enelprogramaprincipal)tienenel
formatop.funcionmiembro.
• Lasllamadasalasfuncionesmiembrodeunaclasedentrodelapropiaclasenov anprecedidasdepunto, comosehace
porejemploenelmétodo EscribirPunto.
• Haytrestiposdeconstructoresquesee xplicanposteriormente.
• UnaclasedeC++esunageneralizacióndeunaestructuradeC.Unaclasequesólotienemiembrospúblicosysinfuncionesesunaestructura.
• Cadaclasecontieneunpunteroimplícito this queapuntaasímisma.Elpuntero this esladireccióndelainstanciade
unaclase. *this eselobjetoreal.
13.4. Constructores
Unconstructor esunafunciónmiembroqueseejecutaautomáticamentecuandosecreaelobjetodeunaclase.Losc onstructores tienensiempreelmismonombrequelapropiaclase.Cuandosedef ineunconstructornosepuedeespecif icarunvalor
deretorno, niincluso void.Unconstructorpuede, sinembargo, tomarcualquiernúmerodeparámetros(ceroomás).
Constructor por defecto. Unconstructorquenotieneparámetrossellamaconstructorpordefecto.Normalmente, inicializa
losmiembrosdatoasignándolesvalorespordefecto.Así, porejemplo, enelcasodeladeclaracióndelaclase Punto, elconstructor Punto(), esllamadoenelmomentodeladeclaracióndecadaobjeto, yejecutándoseenelmismomomentosussentenciadeinicialización:
Punto p1;
// p1.x = 0 p1.y = 0 p1.z = 0
Regla: C++creaautomáticamenteunconstructorpordefectocuandonoe xistenotrosconstructores.Sinembar go, tal
constructornoinicializalosmiembrosdatodelaclaseaunv alorpre visible, demodoquesiempreescon veniente
al crearsupropioconstructorpordefecto, darlelaopcióndeinicializarlosmiembrosdatoconv aloresprevisibles.
Precaución: Tengacuidadoconlaescrituradelasiguientesentencia: Punto p();
Aunqueparecequeserealizaunallamadaalconstructorpordefectoloquesehaceesdeclararunafuncióndenombrep quenotieneparámetrosydevuelveunresultadodetipo Punto.
CAPÍTULO 13 Clases y objetos
265
Constructores alternativos. Esposiblepasarargumentosaunconstructorasignandovaloresespecíficosacadamiembrodato
delosobjetosdelaclase.Unconstructorconparámetrossedenominaconstructoralternativo. Estosconstructoressonllamadosensentenciasdeltipo
Punto p2 = Punto( 5.0, 6.0, 7.0);
// p2.x = 5.0
p2.y = 6.0
p3.z = 7.0
Constructor de copia. Existeuntipoespecializadodeconstructordenominado constructordecopia, quesecreaautomáticamenteporelcompilador.Elconstructordecopiasellamaautomáticamentecuandounobjetosepasaporv alor: seconstruyeunacopialocaldelobjetoqueseconstruye.Elconstructordecopiasellamatambiéncuandounobjetosedeclaraeinicializaconotroobjetodelmismotipo.Porejemploelcódigosiguienteasignaalosatrib utosdelobjetoactuallosatrib utosdel
objetop.
Punto::Punto ( const Punto &p)
{
x = p.x;
y = p.y;
z = p.z;
}
Constructor lista inicializadora. Inicialización de miembr os. Noestápermitidoinicializarunmiembrodatodeunaclase
cuandosedefine.Lainicializacióndelosmiembrosdatodeunaclaseserealizaenel constructorespeciallista inicializadora demiembrosquepermite inicializar (enlugardeasignar)aunoomásmiembrosdato.Unalistainicializadorademiembrossesitúainmediatamentedespuésdelalistadeparámetrosenladefinicióndelconstructor.Constadeuncarácterdospuntos, seguidoporunoomásinicializadoresdemiembro, separadosporcomas.Uninicializadordemiembrosconstadelnombre
deunmiembrodatoseguidoporunvalorinicialentreparéntesis.Porejemplolasdeclaracióndeconstructorsiguiente, inicializax avalx, y a0.0 asícomo z a0.0.
Punto( float valx): x(valx), y(0.0), z(0.0){}
// constructor
Sobrecarga de funciones miembr o.Aligualquesepuedesobrecar garunafunciónglobal, sepuedetambiénsobrecar garel
constructordelaclaseocualquierotrafunciónmiembrodeunaclasee xceptoeldestructor(posteriormentesedescribiráel
conceptodedestructor, peronosepuedesobrecargar).Dehecholosconstructoressobrecargadossonbastantefrecuentes;proporcionanmediosalternativosparainicializarobjetosnue vosdeunaclase.Sólounconstructorseejecutacuandosecreaun
objeto, conindependenciadecuántosconstructoreshayansidodef inidos.
13.5. Destructrores
Enunaclasesepuededefinirtambiénunafunciónmiembroespecialconocidacomodestructor, quesellamaautomáticamente
siemprequesedestruyeunobjetodelaclase.Elnombredeldestructoreselmismoqueelnombredelaclase, precedidacon
elcarácter~.Aligualqueunconstructor, undestructorsedebedefinirsinningúntipoderetorno(niincluso void);alcontrarioqueunconstructornopuedeaceptarparámetros, yademáscadaclasetienesóloundestructor.Elusomásfrecuentedeun
destructoresliberarmemoriaquefueasignadaporelconstructor .Siundestructornosedeclarae xplícitamente, C++creaun
vacíoautomáticamente.
EJEMPLO 13.3. ObjetoContadorcondestructor.
Lasentencia c = Contador();asignaa c elvalordelconstructorpordefectoqueenestecasoes0.Cadav ezquese
produzcaunsucesoelcontadorseincrementaen1.Elcontadorpuedeserconsultadoparaencontrarlacuentaactual.
#include <cstdlib>
#include <iostream>
using namespace std;
class Contador
CAPÍTULO 13 Clases y objetos
266
{
private:
unsigned int cuenta;
public:
Contador() {cuenta = 0;}
void incrementa() {cuenta++;}
int valor()
{return cuenta;}
~Contador() { }
};
int main(int argc, char *argv[])
{
Contador c;
// contar
// constructor
// Iterador
//devuelve cuenta
// destructor
// define e inicializa a cero
for (int i = 0; i < 6; i++)
{
cout << " c = " << c.valor() << endl;
c.incrementa();
if(i = = 2)
c = Contador();
}
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 13.4. Clasepiladerealesconfuncionesmiembroparaponerunelementoysacarunelementodelapila.
Unapilaesuntipodedato“enelcualelúltimoenentrareselprimeroensalir”.Lasprimiti vas(operaciones)básicas
tradicionalesdegestióndeunapilason poner ysacar.Laprimeraañadeunelementoalapilaylasegundaextraeun
elementoborrándolo.Enelejemplosiguiente, lapilaseimplementaenunarray a delongitudmáximade 100 reales.
Lazonaprivadadelaclasepilacontiene: la cima queapuntaalasiguienteposiciónlibredelapila, enconsecuencia
lapilaestarávacíacuando cima apunteacero, yestarállenasilacimaapuntaaunnúmeromayoroigualque 100;y
elarraya de100 reales.Lazonapúblicacontieneelconstructor, eldestructorylasdosfuncionesmiembrodegestión
básica.Paraponerunelementoenlapila, secolocaenlaposición a[cima] yseincrementa cima.Parasacarunelementodelapila, sedecrementa cima enunaunidadyseretornaelv alorde a[cima].
#include <cstdlib>
#include <iostream>
#include <string.h>
using namespace std;
#define max 100
class pila
{
private:
int cima;
float a[max];
public:
pila(){cima = 0;};
float sacar();
void poner(float x);
~pila(){};
};
CAPÍTULO 13 Clases y objetos
267
float pila::sacar()
{
if(cima <= 0)
cout << " error pila vacía ";
else
return a[--cima];
}
void pila::poner(float x)
{
if(cima >= max)
cout << " error pila llena";
else
a[cima++]= x;
}
int main(int argc, char *argv[])
{
pila p;
p.poner(6.0);
p.poner(5.0);
cout << p.sacar()<< endl;
cout << p.sacar()<< endl;
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 13.5. Laclase empleado quecontienecomomiembrosel nombre, la dirección yel sueldo; comofuncionesmiembroponer yobtener cadaunodesusatributosasícomo Leerdatos() yverdatos() queleenlosdatos
deltecladoylosvisualizanenpantalla, respectivamente.
Elnombreyladirecciónsedeclarancomopunterosa char, porloquelaasignacióndememoriaalosatributosserealizadinámicamente, enlafunciónmiembro Leerdatos().Seescribeunprogramaqueutilicelaclase, creandoun
arraydetipo empleado yluegollenándolocondatoscorrespondientesa50empleados.Unav ezrellenadoelarray, se
visualizanlosdatosdetodoslosempleados.
#include <cstdlib>
#include <iostream>
using namespace std;
class empleado
{
char *nombre;
char *direccion;
float sueldo;
public:
empleado(){
nombre = new char[0]; nombre = "";
direccion = new char[0]; direccion ="";
sueldo = 0;
}
~empleado(){}
void Pnombre( char*s){ nombre = s; }
CAPÍTULO 13 Clases y objetos
268
void Pdireccion(char*s){direccion = s;}
void Psueldo(float s){sueldo = s;}
char * Onombre() { return nombre;}
char* Odireccion(){ return direccion;}
float Osueldo(){ return sueldo;}
void leerdatos();
void visualizardatos();
};
void empleado::leerdatos()
{
char nombre[50], *s;
float su;
cout << " introduzca nombre : ";
cin.getline(nombre,49);
s = new char(strlen(nombre)+1);
strcpy(s,nombre);
Pnombre(s);
cout << " introduzca ndirecion : ";
cin.getline(nombre,49);
s = new char(strlen(nombre)+1);
strcpy(s,nombre);
Pdireccion(s);
cout << " introduzca sueldo : ";
cin >> su;
cin.getline(nombre,2);
Psueldo(su);
// memoria dinámica
// limpiar buffer de entrada
}
void empleado::visualizardatos()
{
cout << " Nombre = " << Onombre() << endl;
cout << " Direccion = " << Odireccion() << endl;
cout << " sueldo = " << Osueldo() << endl << endl;
}
int main(int argc, char *argv[])
{
empleado Empleados[50];
int i;
for (i = 0; i < 50; i++)
Empleados[i].leerdatos();
for (i = 0; i < 50; i++)
Empleados[i].visualizardatos();
system("PAUSE");
return EXIT_SUCCESS;
}
13.6. Clase compuesta
Unaclasecompuesta esaquellaclasequecontienemiembrosdatoquesonasímismoobjetosdeclases.Antesdecrearelcuerpodeunconstructordeunaclasecompuesta, sedebenconstruirlosmiembrosdatoindi vidualesensuordendedeclaración.
CAPÍTULO 13 Clases y objetos
269
EJEMPLO 13.6. Clasecompuesta.
Laclase Estudiante contienemiembrosdatodetipo Expediente yDirección:
class Expediente {// ...}
class Direccion {// ...};
class Estudiante
{
public :
Estudiante()
{
PonerId(0);
PonerNotaMedia(0.0);
}
void PonerId(long);
void PonerNotaMedia(float);
private:
long id;
Expediente exp;
Direccion dir;
float NotMedia;
};
Aunque Estudiante contiene Expediente y Direccion, elconstructorde Estudiante notieneaccesoalosmiembros
privadosoprotegidosde Expediente o Direccion.Cuandounobjeto Estudiante salefueradealcance, sellamaasudestructor.Elcuerpode~Estudiante seejecutaantesquelosdestructoresdeExpediente yDireccion.Enotraspalabras, elordendelasllamadasadestructoresaclasescompuestasese xactamenteelopuestoalordendellamadasdeconstructores.
13.7. Errores de programación
1. Mal uso de palabras r eservadas. Esunerrordeclararunaclasesinutilizarf ielmenteunadelaspalabrasreserv adas
class, struct o union enladeclaración
2. Uso de constructores y destructores.Nosepuedeespecificaruntipoderetornoenunconstructorodestructor, nien
sudeclaraciónniensudefinición.Tampocosepuedenespecificarargumentos, inclusovoid, enladeclaraciónodefinicióndeldestructordeunaclase.Unconstructordeunaclase C++ nopuedeesperarunargumentodetipo C.
3. Inicializadores de miembros.
class C {
// ERROR
int x = 5;
};
class C {
int x;
...
public:
C() = {x = 5;}
};
// CORRECTO
4. Nosepuedeutilizarthis comoparámetro, yaqueesunapalabrareservada(this esunpunteroalpropioobjeto).Tampocosepuedeutilizarenunasentenciadeasignacióntalcomo:
this = ...;
// this es constante; ERROR
CAPÍTULO 13 Clases y objetos
270
5. Olvido de puntos y coma en definición de clases.Lasllaves{} sonfrecuentesencódigoC++, ynormalmentenose
sitúaunpuntoycomadespuésdelalla vedecierre.Sinembar goladef iniciónde class siempreterminaen };.Un
errortípicoesolvidaresepuntoycoma.
6. Olvido de punto y coma en prototipos y cabeceras de funciones.Laomisióndeunpuntoycomaalfinaldelprototipodeunafunciónpuedeproducirelmensajedeerror .
EJERCICIOS
13.1. ¿Cuáleselerrordelasiguientedeclaracióndeclase?
union float_bytes
{
private:
char mantisa[3], char exponente ;
public:
float num;
char exp(void);
char mank(void);
};
13.2. Examinelasiguientedeclaracióndeclaseyveasie xistenerrores.
class punto {
int x, y;
void punto(int x1, int y1) {x = x1 ; y = y1;}
};
13.3. Dadoelsiguienteprograma, ¿eslegallasentenciademain()?
class punto {
public:
int x;
int y;
punto(int x1, int y1) {x = x1 ; y = y1;}
};
main()
{
punto(25, 15);
}
//¿es legal esta sentencia?
13.4. Dadaslassiguientesdeclaracionesdeclaseyarray.¿Porquénosepuedeconstruirelarr ay?
class punto {
public:
int x, y;
punto(int a, int b) {x = a ; y = b;}
};
punto poligono[5];
CAPÍTULO 13 Clases y objetos
271
13.5. Secambiaelconstructordelejercicioanteriorporunconstructorpordefecto.¿Sepuedeconstruir, enestecaso, elarray?
13.6. ¿Cuáleselconstructorquesellamaenlassiguientesdeclar aciones?
class prueba_total
{
private:
int num;
public:
prueba_total(void)
prueba_total(int n )
int valor(void)
};
prueba_total prueba
{num = 0;}
{num = n;}
{return num;}
13.7. ¿Cuálesladiferenciadesignificadoentrelaestructura?
struct a
{
int i, j, k;
};
ylaclase
class
{
int i, j, k;
};
Expliquelarazónporlacualladeclar acióndelaclasenoesútil.¿Cómosepuedeutilizarlapalabr areservada public
paracambiarladeclaracióndelaclaseenunadeclar aciónequivalentea struct?
PROBLEMAS
13.1. Crearunaclasellamada hora quetengamiembrosdatosseparadosdetipo int parahoras, minutosysegundos.Unconstructorinicializaráestedatoa0, yotroloinicializaráavalor esfijos.Unafunciónmiembr odeberávisualizarlahor aen
formato11:59:59.Otrafunciónmiembrosumarádosobjetosdetipohor apasadoscomoargumentos.Unafunciónprincipalmain() creadosobjetosinicializadosyunoquenoestáinicializado.Sumarlosdosvalor esinicializadosydejarelresultadoenelobjetonoinicializado.Porúltimo, visualizarelvalorresultante.
13.2. Unnúmerocomplejotienedospartes: unaparterealyunaparteima ginaria;porejemplo, en(4.5+3.0i), 4.5eslaparte
realy3.0eslaparteima ginaria.Realizarunaclase Complejo quepermitalag estióndenúmeroscomplejos(unnúmer o
complejo=dosnúmerosreales).Lasoperacionesaimplementarsonlassiguientes:
• Unafunción leerComplejo() permiteleerunobjetodetipo Complejo.
• Unafunción escribirComplejo() realizalavisualizaciónformateadadeun Complejo.
CAPÍTULO 13 Clases y objetos
272
13.3. Supongaque a = (A, Bi) yc = (C, Di).Sedeseaañadiralaclase complejo lasoperaciones:
•
•
•
•
•
Suma: a + c = (A + C, (B + D)i).
Resta: a – c = (A – C, (B – D)i).
Multiplicación: a * c=(A * C – B * D, (A * D + B * C)i).
Multiplicación: x * c = (x * C, x * Di), dondex esreal.
Conjugado: ~a = (A. –Bi).
13.4. Escribirunaclase Conjunto quegestioneunconjuntodeenter os( int)conayudadeunatabladetamañof ino(un conjunto contieneunalistaordenadadeelementosysecaracterizaporelhechodequecadaelementoesúnico: nosedebeencontrardosveceselmismovalorenlatabla).Lasoper acionesaimplementarsonlassiguientes:
•
•
•
•
•
•
•
Lafunción vacía() vacíaelconjunto.
Lafunción agregar() añadeunenteroalconjunto.
Lafunción eliminar() retiraunenterodelconjunto.
Lafunción copiar() recopilaunconjuntoenotro.
Lafunción es_miembro() reenvíaunvalorbooleano(valorlógicoqueindicasielconjuntocontieneunenter odado).
Lafunción es_igual() reenvíaunvalorbooleanoqueindicasiunconjuntoesigualaotr o.
Lafunción imprimir() realizalavisualización“formateada” delconjunto.
13.5. Añadiralaclase Conjunto delejercicioanteriorlasfunciones es vacio, ycardinal deunconjunto, asícomo, launión,
intersección, diferenciaydiferenciasimétricadeconjuntos.
SOLUCIÓN DE LOS EJERCICIOS
13.1. Esunerrordeclararunaclasesinutilizarfielmenteunadelaspalabrasreservadasclass, struct ounion enladeclaración.Enestecasosehautilizadolapalabr aunion, porloquenoesunerr or, perosíqueesunerrorladeclaraciónchar
mantisa[3], char exponente yaqueobiensehacambiadolacomaporunpuntoycoma, obiensobrelapalabrareservadachar segunda.
Unadeclaracióncorrectapuedeser:
union float_bytes
{
private:
char mantisa[3];
char exponente;
public:
float num;
char exp(void);
char mank(void);
};
13.2. Estadeclaracióntienevarioserrores.Elprimeroesdeclararunconstructorconuntipo void.Losconstructoresnotienen
tipo.Elsegundoesquelosconstructoresdebenestarenlazonapúblicadeunaclase , ynoenlaprivada.Undeclar ación
correctaes, porejemplo, lasiguiente:
class punto
{
CAPÍTULO 13 Clases y objetos
273
int x, y;
public:
punto(int x1, int y1) {x = x1 ; y = y1;}
};
13.3. Lasentenciaessintácticamentecorr ecta, yaqueser ealizaunallamadaalconstructorde punto, perohayqueteneren
cuentaqueelconstructor, retornaunobjetodeltipo punto ynoesrecogidoporningunainstanciadelaclase .Seríaconveniente, haberrealizadounasentenciadeltiposiguiente: punto p = punto(25, 15);
13.4. Elarraynopuedeconstruirse, porquealhacerladeclaración, necesariamentesellamaalconstructorqueenestecasotienedosparámetrosdetipoentero, yenladeclaraciónnopuederealizarse.Pararesolverelproblema, puedeoptarsepordeclararexplícitamenteelconstructorde punto sinningúnparámetro.Porejemplopodríaserdelasiguienteforma:
class punto
{
public:
int x, y;
punto(int a, int b) {x = a ; y = b;}
punto(){}
};
punto poligono[5];
13.5. Aldesaparecerelconstructorcondosparámetros, elconstructorpordefectoentraenaccióny, portanto, síqueescorrecto,
tantosiseincluyecomosinosehaceenladeclar acióndelaclase.
13.6. Elconstructorllamadoeseldefinidopordefecto, queenestecasoeselquenotieneparámetr o: prueba_total(void).
13.7. Laúnicadiferenciaesque i, j, k sonpúblicosenlaestructura, yprivadosenlaclase, porloqueladeclaracióndelaclasenoesútil, yaquesólopuedeacceder sealosatrib utos i, j, k, mediantefuncionesmiembrosquenotiene .Parahacer
equivalentesambasdeclar acionesbastaconañadirlapalabr areservada public talycomosee xpresaacontinuación:
struct a
{
int i, j, k;
};
class
{
public:
int i, j, k;
};
SOLUCIÓN DE LOS PROBLEMAS
13.1. La codificación de este problema se encuentra en la página Web del libro.
13.2. Laclase Complejo esimplementadaconsusdosatrib utos, partereal r, yparteimaginaria i.Tienedosconstrutores, uno
pordefectoqueinicializaacer otantolaparter ealcomolaima ginaria, yotroqueinicializaelnúmer ocomplejoconsus
dosparámetroscorrespondientes.Lasfuncionesmiembro, Or yPr, seencargandeobteneryponerrespectivamentelapar-
CAPÍTULO 13 Clases y objetos
274
terealdeunnúmerocomplejo.Porsupartelasfunciones Oi, yPi, obtienenyponenlaparteimaginaria.Lasfuncionesde
yescribirComplejo, usanlasfuncionesmiembroanterioresparatratarlosatributosqueimplementanla
parterealylaparteimaginariadelnúmerocomplejo.
leerComplejo
La codificación de este problema se encuentra en la página Web del libro.
13.3. Alaclasedelproblemaanteriorseleañadenlasfuncionesmiembroindicadas.Observarlasobrecargadelafunciónmultiplicación.
La codificación de este problema se encuentra en la página Web del libro.
13.4. SerepresentaelConjunto conatributosNumelementos, queindicaelnúmerodeelementosquetieneelconjunto, asícomo
conunarrayL, deenterosquealmacenahastaunvalormáximode512 númerosenteros, declaradoenunamacro.Losdatossealmacenanenelarr ayenordencreciente.Parafacilitarlainser ciónyeliminacióndeelementosenelconjunto, se
programaunafunciónmiembronopública Buscar encargadadebuscarsiunelementoqueselepasacomoparámetr ose
encuentraenelconjuntoactual, indicandoademásencasodequeseencuentr elaposiciónenlaquesehallapar apoder
borrarlo, yencasodequenoseencuentrelaposicióndondehabríaqueañadirlo, encasodequefueranecesario.Estafunciónseprogramaentiempologarítmico, medianteunabúsquedabinariaclásica, talycomosehae xplicadoenelcapítulodeordenación.Elrestodelasfuncionesmiembr osseprogramandeformanatural.Tambiénseincluyenunconstructor
yundestructor.
La codificación de este problema se encuentra en la página Web del libro.
13.5. Seañadenalaclase Conjunto lasfuncionessolicitadas, incluyendosolamentelacodificación.
• Unconjuntoestávacíosinotieneelementos, yelnúmerodeelementosdeunconjuntovienedadoporelvalordesuatributoNumelementos.
• Lafunción union seimplementabasándoseenlamezclaor denadadedosarraysdenúmerosenteros, teniendoencuentaquedebenapar ecerloselementosdelosdosarr ays, yquesólopuedeapar ecerelelementounavez.Siempr equese
añadeunnuevoelementoalauniónsecompruebaquenosesobr epasalacapacidaddelconjunto .
• Lafunción interseccion queseimplementasebasaenr ealizarlamezcladedoslistasor denadasincluyendoloselementosqueestánenlasdoslistas.
• Lafunción Diferencia añadealconjuntoloselementosqueesténenelconjunto c1 ynoesténenelconjunto c2, realizandounrecorridodelconjunto c1.
• Lafunción diferenciaSimetrica, seimplementanusandolaspropiedadesdelosconjuntos.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
13.1. Considerarunapilacomountipoabstractodedatos.Se
tratadedef inirunaclasequeimplementaunapilade
100caracteresmedianteunarray.Lasfuncionesmiembrodelaclasedebenser: meter, sacar, pilavacia y
pilallena.
13.2. Clasificarlossiguientesconstructorescuyosprototipos
son:
a. rect::rect(int a, int h);
b. nodo::nodo(void);
c. calculadora::calculadora
(float *val i = 0.0);
d. cadena::cadena(cadena &c);
e. abc::abc(float f);
13.3. Crearunaclasellamada empleado quecontengacomo
miembrodatoelnombreyelnúmerodeempleado, y
comofuncionesmiembro Leerdatos() y verdatos()
queleanlosdatosdeltecladoylosvisualiceenpantalla, respectivamente.Escribirunprogramaqueutilicela
clase, creandounarraydetipoempleadoylue gollenándolocondatoscorrespondientesa50empleados.
Unavezrellenadoelarray, visualizarlosdatosdetodos
losempleados.
CAPÍTULO 13 Clases y objetos
275
PROBLEMAS PROPUESTOS
13.1. Sedesearealizarunaclase vector3d quepermitamanipularv ectoresdetrescomponentes(coordenadas x,
y, z)deacuerdoalassiguientesnormas:
• Sóloposeeunafunciónconstructoryesenlínea.
• Tieneunafunciónmiembroigualquepermitesabersi
dosv ectorestienensuscomponentesocoordenadas
iguales(ladeclaracióndeigualserealizaráutilizando:
a)transmisiónporv alor; b)transmisiónpordirección; c)transmisiónporreferencia).
13.2. Incluirenlaclase vector3d delejercicioanterioruna
funciónmiembrodenominada normamax quepermita
obtenerlanormamayordedosv ectores(Nota: Lanormadeunvector v = (x, y, z) esœw
x2+y2+z2 ).
13.3. Añadiralaclase vector3d lasfuncionesmiembros
suma (sumadedosv ectores), productoescalar (productoescalardedosvectores: v1= (x1, y1, z1); v2
= (x2, y2, z2 ); v1 * v2 = x1 * x2 + y1 * y2
+ z1 * z2).
13.4. Crearunaclase lista querealicelassiguientestareas:
• Unalistasimplequecontengaceroomáselementos
dealgúntipoespecífico.
• Crearunalistavacía.
• Añadirelementosalalista.
• Determinarsilalistaestávacía.
• Determinarsilalistaestállena.
• Accederacadaelementodelalistayrealizaralguna
acciónsobreella.
13.5. Implementarunaclase Random (aleatoria)paragenerar
númerospseudoaleatorios.
13.6. Implementarunaclase Fecha conmiembrosdatopara
elmes, díayaño.Cadaobjetodeestaclaserepresenta
unafecha, quealmacenaeldía, mesyañocomoenteros.
Sedebeincluirunconstructorpordefecto, unconstructordecopia, funcionesdeacceso, unafunción reiniciar (int d, int m, int a) parareiniciarlafecha
deunobjetoexistente, unafunciónadelantar(int d,
int m, int a) paraavanzaraunafechaexistente(dia,
d, mes, m, yañoa)yunafunción imprimir().Emplear
unafuncióndeutilidad normalizar() paraase gurar
quelosmiembrosdatoestánenelrangocorrecto
1 ≤ año, 1 ≤ mes ≤ 12, día ≤ días(Mes), donde
dias(Mes) esasegurarotrafunciónquedevuelveelnúmerodedíasdecadames.
13.7. Ampliarelprogramaanteriordemodoquepuedaaceptarañosbisiestos.(Nota: unañoesbisiestosiesdi visiblepor400, osiesdivisiblepor4peronopor100.Por
ejemploelaño1992y2000sonañosbisiestosy1997y
1900nosonbisiestos.)
CAPÍTULO 14
Herencia y polimorfismo
Introducción
Enestecapítuloseintroduceelconceptodeherencia ysemuestracómocrearclasesderivadas.Laherenciahaceposiblecrear
jerarquíasdeclasesrelacionadasyreducelacantidaddecódigoredundanteencomponentesdeclases.Elsoportedelaherenciaesunadelaspropiedadesquediferencialoslenguajes orientadosaobjetos deloslenguajesbasadosenobjetos ylenguajesestructurados.
Laherencia eslapropiedadquepermitedef inirnuevasclasesusandocomobaselasclasesyae xistentes.Lanuevaclase
(clasederivada)heredalosatributosycomportamientoquesonespecíf icosdeella.Laherenciaesunaherramientapoderosa
queproporcionaunmarcoadecuadoparaproducirsoftw arefiable, comprensible, bajocoste, adaptableyreutilizable.
Elpolimorfismo permitequediferentesobjetosrespondandemododiferentealmismomensaje;adquieresumáximapotenciacuandoseutilizaenunióndeherenciayhacelossistemamásfle xibles, sinperderningunadelasv entajasdelacompilaciónestáticadetiposquetienenlugarentiempodecompilación.
14.1. Herencia
Lapropiedadquepermitealosobjetosserconstruidosapartirdeotrosobjetossedenomina herencia.Dichodeotromodo,
lacapacidaddeunobjetoparautilizarlasestructurasdedatosylosmétodospre vistosenantepasadosoascendientes.Elobjetivofinaleslareutilización, esdecir, reutilizarcódigoanteriormenteyadesarrollado.
Laherenciasuponeunaclasebase yunajerarquíadeclases quecontienenlasclasesderivadas delaclasebase.Lasclasesderivadaspuedenheredarelcódigoylosdatosdesuclasebase,añadiendosupropiocódigoespecialydatosaellas,incluso
cambiaraquelloselementosdelaclasebasequenecesitanseandiferentes.
Lasclasesderivadasheredancaracterísticasdesuclasebase, peroañadenotrascaracterísticaspropiasnue vas.Enlasjerarquíasdegeneralización/especializaciónlaclasemásaltaconstituyelageneralización, mientrasquelaclasedemásbajonivelconstituyeunaespecialización.Laimplementacióndeestasjerarquíasgeneralización/especializacióndalugaralaherencia
(véaselaFigura14.1).
Unaclasehereda suscaracterísticas(datosyfunciones)deotraclase.
277
CAPÍTULO 14 Herencia y polimorfismo
278
Clase base
Característica A
Característica B
Característica A
Característica A
Característica A
Característica B
Característica B
Característica B
Característica X
Característica Y
Característica W
Característica Z
Clase derivada
Clase derivada
Clase derivada
Figura 14.1. Jerarquía de clases.
Lasclasesderivadaspuedenheredarelcódigoylosdatosdesuclasebase, añadiendocaracterísticaspropiasnuevas.Las
jerarquíasdeclasesseor ganizanenformadeárbolin vertido.Así, sepuededecirqueunaclasedeobjetosesunconjuntode
objetosquecompartencaracterísticasycomportamientoscomunes.Estascaracterísticasycomportamientossedefinenenuna
clasebase.Lasclasesderi vadassecreanenunprocesodedef inicióndenuevostiposyreutilizacióndelcódigoanteriormentedesarrolladoenladef inicióndesusclasesbase.Esteprocesosedenomina programaciónporherencia.Lasclasesqueheredanpropiedadesdeunaclasebasepueden, asuvez, servircomodefinicionesbasedeotrasclases.Lasjerarquíasdeclases
seorganizanenformadeárbol.
Ladeclaracióndederivacióndeclasesdebeincluirelnombredelaclasebasedelaquesederivayelespecificadordeaccesoqueindicaeltipodeherencia( pública, privadayprotegida).
Nombre de la clase derivada
Especificador de acceso
Normalmente público
Herencia
Nombre de la clase base
class ClaseDerivada : public ClaseBase {
public:
Símbolo de derivación o herencia
// sección privada
...
private:
// sección privada
...
};
Especificadordeacceso public, significaquelosmiembrospúblicosdelaclasebasesonmiembrospúblicosdelaclase
derivada.
Herenciapública esaquéllaenqueelespecif icadordeaccesoes public (público).Engeneral, herenciapública significaqueunaclasederi vadatieneaccesoaloselementospúblicosypri vadosdesuclasebase.Loselementospúblicosseheredancomoelementospúblicos;loselementosprote gidospermanecenprotegidos.
CAPÍTULO 14 Herencia y polimorfismo
279
Herenciaprotegida esaquéllaenqueelespecif icadordeaccesoes protected (protegido).Conherenciaprote gida, los
miembrospúblicosyprote gidosdelaclasebasesecon viertenenmiembrosprote gidosdelaclasederi vadaylosmiembros
privadosdelaclasebasesevuelv eninaccesibles.
Herenciaprivada esaquéllaenqueelespecificadordeaccesoes private (privado).Conherenciaprivada, losmiembros
públicosyprotegidosdelaclasebasesevuelv enmiembrosprivadosdelaclasederivada
Elespecificadordeaccesoquedeclaraeltipodeherenciaesopcional( public, private oprotected);siseomiteelespecificadordeacceso, seconsiderapordefecto private.Laclasebase (ClaseBase)eselnombredelaclasedelaquesederivalanuevaclase.Lalistademiembros constadedatosyfuncionesmiembro:
class nombre_clase: especificador de acceso opcional ClaseBase {
lista de miembros;
};
Tabla 14.1. Tipos de herencia y acceso que per miten
Tipo de herencia
Acceso a miembro clase base
Acceso a miembro a clase derivada
public
public
protected
private
public
protected
inaccesible
protected
public
protected
private
protected
protected
inaccesible
private
public
protected
private
private
private
inaccesible
EJEMPLO 14.1. Representarlajer arquíadeclasesdepublicacionesquesedistrib uyenenunalibr ería: revistasy
libros.
Publicación
Revista
Libro
Todaslaspublicacionestienenencomúnunaeditorialyunafechadepublicación.Lasre vistastienenunadeterminadaperiodicidadloqueimplicaelnúmerodeejemplaresquesepublicanalañoy , porejemplo, elnúmerodeejemplaresqueseponenencirculacióncontroladosof icialmente.Loslibros, porelcontrariotienenuncódigodeISBNyel
nombredelautor.
#include <cstdlib>
#include <iostream>
using namespace std;
class Publicacion
{
public:
void NombrarEditor(const char *s){strcpy (editor,s);}
void PonerFecha(unsigned long fe){ fecha = fe;}
void EscribirEditor(){ cout << editor << endl;}
void EscribirEditro(){ cout << fecha << endl;}
CAPÍTULO 14 Herencia y polimorfismo
280
private:
char editor[50];
unsigned long fecha;
};
class Revista :public Publicacion
{
public:
void NumerosPorAnyo(unsigned n){ numerosPorAnyo = n;}
void FijarCirculacion(unsigned long n){ circulacion = n;}
void EscribirNumerosPorAnyo(){ cout << numerosPorAnyo << endl;}
void EscribirCirculacion(){ cout << circulacion << endl;}
private:
unsigned numerosPorAnyo;
unsigned long circulacion;
};
class Libro :public Publicacion
{
public:
void PonerISBN(const char *s){ strcpy(ISBN,s);}
void PonerAutor(const char *s){ strcpy(autor,s);}
void EscribirISBN(){ cout << ISBN << endl;}
void EscribirAutor(){ cout << autor << endl;}
private:
char ISBN[20];
char autor[40];
};
int main(int argc, char *argv[])
{
Libro L;
Revista R;
L.NombrarEditor("McGraw-Hill serie Schaum");
L.PonerFecha(23052005);
L.PonerISBN("84-481-4514-3");
L.PonerAutor("Sanchez, García Lucas");
R.NombrarEditor("McGraw-Hill");
R.PonerFecha(1106005);
R.NumerosPorAnyo(12);
R.FijarCirculacion(20000);
system("PAUSE");
return EXIT_SUCCESS;
}
14.1.1. TIPOS DE HERENCIA
Existendosmecanismosdeherenciautilizadoscomúnmenteenprogramaciónorientadaaobjetos: herenciasimple yherencia
múltiple.EnC++laherenciaseconocecomoderi vación.
LaFigura14.2representalosgráf icosdeherenciasimpleyherenciamúltipledelaclase figura y persona, respectivamente.
En herencia simple, unobjeto(clase)puedetenersólounascendiente, ounsolopadre.Laherenciasimplepermiteque
unaclaseheredelaspropiedadessesusuperclaseenunacadenadejerarquía.Lasintaxisdelaherenciasimple:
CAPÍTULO 14 Herencia y polimorfismo
281
Figura
Círculo
Persona
Rectángulo
Triángulo
Profesor
Rectángulo
redondeado
Investigador
Profesor
universitario
Figura 14.2. Tipos de herencia.
class Base { ... }
class Derivada : [acceso] Base { ... }
elmodificadordeaccesoindicaeltipodevisibilidad, sibienelmásusadoessiempre public, utilizándoseotrostiposdeaccesoparaelcasodelareutilizacióndel software.
EJEMPLO 14.2. Herenciasimple.
Laclase estudiante heredadelaclase persona elatributo nombre, yañadeelatrib uto estudios, pudiendoutilizar
lasfuncionesmiembro ponernombre y obtenernombre.Laclase empleado heredadelaclasepersonael nombre y
añadeelatributosueldo.
Persona
Estudiante
#include <cstdlib>
#include <iostream>
using namespace std;
class persona
{
protected:
char nombre[40];
public:
persona(){}
void ponernombre(char *s ){strcpy(nombre,s);}
char * obtenernombre() {return nombre;}
};
class estudiante: public persona
Empleado
CAPÍTULO 14 Herencia y polimorfismo
282
{
protected:
char estudios[30] ;
public:
estudiante(){}
void ponerestudios( char *c){strcpy(estudios,c);}
char *obtenerestudios() {return estudios;}
};
class empleado : public persona
{
private:
float sueldo;
public:
empleado(){}
void ponersueldo( float r) { sueldo = r;}
float obtensueldo(){return sueldo;};
};
int main(int argc, char *argv[])
{
system("PAUSE");
return EXIT_SUCCESS;
}
La herencia múltiple eslapropiedaddeunaclasedepodertenermásdeunascendienteinmediato, omásdeunsolopadre.Unaherenciamúltipleesaquéllaenlaquecadaclasepuedeheredarmétodosyv ariablesdecualquiernúmerodesuperclases.Laherenciamúltipleesenesencialatransmisióndemétodosydatosdemásdeunaclasebasealaclasederi vada.La
sintaxisdelaherenciamúltipleesigualalaempleadaenlaherenciasimple, conlaúnicadiferenciadequeseenumeranlas
diferentesclasesbasedelasquedepende, enlugardeunasola.Laherenciamúltipleplanteadiferentesproblemastalescomo
laambigüedad porelusodenombresidénticosendiferentesclasesbase, yla dominación opreponderancia defuncioneso
datos
Problemasquesepuedenpresentarcuandosediseñanclasesconherenciamúltipleson:
• colisiones de nombres dediferentesclasesbase(dosomásclasesbasetieneelmismoidentificadorparaalgúnelemento
desuinterfaz.Seresuelveconeloperadordeámbito ::);
• herencia repetida deunamismaclasebase(unaclasepuedeheredarindirectamentedoscopiasdeunaclasebase.Se
resuelveconeloperadordeámbito ::);
EJEMPLO 14.3. Herenciamúltiplesinproblemasdecolisióndenombresodeherenciarepetida.
LaclaseC heredadedosclasesA yB, losatributosylosmétodos.Enconcreto, losatributosentero delaclaseA yletra delaclase B.Paraactivarelconstructordelaclase A y B enelmomentodecrearelobjetodelaclasederi vada C,
seincluyeexpresamenteelconstructordelaclasebaseA yB enlalistadeinicializacióndelconstructordelaclasederivadaC.
A
B
C
CAPÍTULO 14 Herencia y polimorfismo
283
#include <cstdlib>
#include <iostream>
using namespace std;
class A
{
protected:
int entero;
public:
A(){}
A(int i){entero = i;}
void ponerentero( int i){ entero = i;}
int obtenerentero() {return entero;}
};
class B
{
protected:
char letra;
public:
B(){}
B(char c){letra = c;}
void ponerletra( char c){ letra = c;}
char obtenerletra() {return letra;}
};
// constructor por defecto
// constructor alternativo
// constructor por defecto
// constructor alternativo
//La Clase C hereda de las dos clases anteriores A y B
class C : public A, public B
{
private:
float real;
public:
C(){}
C(int, char, float);
void ponerreal( float r) { real = r;}
float obtenerreal(){return real;};
};
C::C(int i, char c, float f) : A(i), B(c)
{
real = f;
}
int main(int argc, char *argv[])
{
C c1( 23,'C',24.5);
cout << c1.obtenerentero()<<endl;
cout << c1.obtenerletra()<<endl;
cout << c1.obtenerreal()<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}
// constructor por defecto
// constructor alternativo
CAPÍTULO 14 Herencia y polimorfismo
284
EJEMPLO 14.4. Herenciamúltipleconcolisióndenombre.Repeticióndeunatributoenlasclasesbaseyderivada.
Lasclases B1 y B2 tienenunatributoentero x.Laclasederi vada C esderivadadelasclases B1 y B2, porloquetiene
dosatributosx asociadosalasclases: C heredadeB1;yC heredadeB2.Laclase C heredapúblicamentedelaclase B1
y B2, porloquepuedeaccederalostresatrib utosconelmismonombre x.Estosatributosson: unolocala C, yotros
dosde B1 y B2.Lafunciónmiembro verx puederetornaelv alorde x, peropuedeserelde B1, B2, C resueltoconel
operadordeámbito ::.Lafunciónmiembro probar espúblicayamigadelaclase c, porloquepuedemodif icarlos
tresdistintosatributos x decadaunadelasclases.P araresolverelproblemadelaccesoacadaunodeellosseusael
operadorderesolucióndeámbito ::
B1
B2
C
#inlude <cstdlib>
#include <iostream>
class B1
{
protected:
int x;
};
class B2
{
protected:
int x;
};
class C: public B1,B2
{
protected:
int x;
public:
friend void probar();
int verx()
{
return x;
return B1::x;
return B2::x;
}
};
void probar()
{
C c1;
c1.x = 12;
c1.B1::x = 123;
c1.B2::x = 143;
}
// es amiga y tiene acceso a x
// x de C
// x de B1
// x de B2
// atributo x de C
// atributo x de B1 resolución de colisión
// atributo x de B2 resolución de colisión
CAPÍTULO 14 Herencia y polimorfismo
285
EJEMPLO 14.5. Herenciamúltiplerepetida.Repeticióndeunaclaseatr avésdedosclasesderivadas.
LasclasesB1 yB2 tienenunmismoatributoenterox.LaclasederivadaC tambiéntieneelmismoatributoenterox.La
claseC heredapúblicamentedelaclase B1 yB2, porloquepuedeaccederalostresatrib utosconelmismonombre x.
Lafunciónmiembro fijarx fijalosdosatributosx resolviendoelproblemaconeloperadordeámbito ::.
B
B1
B2
C
#include <cstdlib>
#include <iostream>
class B
{
protected:
int x;
};
class B1: public B
{
protected:
float y;
};
class B2: public B
{
protected:
float z;
};
class C: public B1,B2
{
protected:
int t;
public:
void fijax( int xx1, int xx2)
{
B1::x=xx1;
B2::x=xx2;
}
};
CAPÍTULO 14 Herencia y polimorfismo
286
14.1.2. CLASES ABSTRACTAS
Unaclaseabstractanormalmenteocupaunaposiciónadecuadaenlajerarquíadeclasesquelepermiteactuarcomoundepósitodemétodosyatrib utoscompartidosparalassubclasesdeni velinmediatamenteinferior.Lasclasesabstractasdef inenun
tipogeneralizadoysirvensolamenteparadescribirnuevasclases.
Lasclasesabstractasnotieneninstanciasdirectamente.Seutilizanparaagruparotrasclasesycapturarinformaciónque
escomúnalgrupo.Sinembar go, lassubclasesdeclasesabstractasquecorrespondenaobjetosdelmundorealpuedentener
instancias.Lassuperclasescreadasapartirdesubclasesconatrib utosycomportamientoscomunes, yempleadasparaderivar
otrasclasesquecompartensuscaracterísticas, sonclases abstractas.
EnC++, unaclaseabstractatienealmenosunafunciónmiembroquesedeclaraperonosedef ine;sudefiniciónserealizaenlaclasederivada.Estasfuncionesmiembrosedenominanfuncionesvirtualespuras, cuyadefiniciónformales:
virtual tipo nombrefuncion(argumentos) = 0;
Lassiguientesreglasseaplicanalasclasesabstractas:
• Unaclaseabstractadebeteneralmenosunafunciónvirtualpura.
• Unaclaseabstractanosepuedeutilizarcomountipodeargumentoocomountipoderetornodeunafunciónaunquesí
unpunteroaella.
• Nosepuededeclararunainstanciadeunaclaseabstracta.
• Sepuedeutilizarunpunterooreferenciaaunaclaseabstracta.
• Unaclasederivadaquenoproporcioneunadef inicióndeunafunciónvirtualpura, tambiénesunaclaseabstracta
• Cadaclase(derivadadeunaclaseabstracta)queproporcionaunadefinicióndetodassusfuncionesvirtualesesunaclaseconcreta.
• Sóloestápermitidocrearpunterosalasclasesabstractaypasárselosafunciones.
EJEMPLO 14.6. Unaclaseabstractapuedeserunaimpresora.
Impresora
+ inyectores
Impresora
chorro de tinta
#include <cstdlib>
#include <iostream>
using namespace std;
class impresora
{
public:
virtual int arrancar() = 0;
};
class ChorroTinta: public impresora
{
protected:
float chorro;
public:
int arrancar( ) { return 100;}
};
+ agujas
Impresora
matricial
CAPÍTULO 14 Herencia y polimorfismo
287
class matricial: public impresora
{
protected:
int agujas;
public:
int arrancar( ) { return 10;}
};
int main(int argc, char *argv[])
{
//impresora im;
no puede declararse es abstracta
matricial m;
ChorroTinta ch;
system("PAUSE");
return EXIT_SUCCESS;
}
14.2. Ligadura
Laligadura representa, generalmente, unaconexiónentreunaentidadysuspropiedades.Desdeelpuntodevistadelosatributos, laligaduraeselprocesodeasociarunatrib utoasunombre.Enlasfunciones, laligaduraeslacone xiónentrelallamadaalafunciónyelcódigoqueseejecutatraslallamada.Elmomentoenqueseasociaesel tiempodeligadura.
Laligaduraseclasificasegúnseaeltiempodeligaduraen: estática ydinámica.
• Enunprogramaconligadura estática, todaslasreferenciasy, engeneralcualquierllamadaaunafunción, seresuelven
entiempodecompilación.Elcompiladordef inedirectamentelaposiciónf ijadelcódigoquesehadeejecutarencada
llamadaafunción.EnC++pordefectolaligaduraesestática.
• Laligadura dinámica suponequeelcódigoaejecutarenunallamadaaunfunciónnosedeterminaráhastaelmomentodeejecución.Normalmente, elvalordeunpuntero, ounareferencia, determinalaligaduraefectivaentrelasposibilidadesdecadaclasederivada.EnC++laligaduradinámicaseproduceconlasfuncionesvirtuales.
14.3. Funciones virtuales
Unafunciónmiembrodeunaclasesedicequeesvirtual, silapalabrareservadavirtual precedealadeclaracióndeunafunción.Estapalabrareservadaleindicaalcompiladorquelafunciónpuedeserredef inidaenunaclasederivada.
Losusoscomunesdelasfuncionesvirtualesson: declaracióndeunaclaseabstracta(funcionesvirtualespuras);implementacióndelpolimorfismo.
14.4. Polimorfismo
Elpolimorfismo permitequediferentesobjetosrespondandemododiferentealmismomensaje.Elpolimorf ismoadquieresu
máximapotenciacuandoseutilizaenunióndeherencia.Elpolimorf ismopermitereferirseaobjetosdediferentesclasespor
mediodelmismoelementoyrealizarlamismaoperacióndeformasdiferentes, deacuerdoalobjetoaquesehacereferencia
encadamomento.Unejemplotípicoeslaoperación arrancar cuandoseaplicaadiferentestiposdemotores.Encadacaso
laoperacióndearrancarserealizadeformadiferente.
EJEMPLO 14.7. Polimorfismoyfuncionesvirtuales.
SiPoligono esunaclasebasedelaquecadafigurageométricaheredacaracterísticascomunes, C++permitequecada
claseutilicefuncionesométodosArea, Visualizar, Perimetro, PuntoInterior comonombredeunafunciónmiembrodelasclasesderivadas.Enestasclasesderivadasdondesedefinenlasfuncionesmiembro.
CAPÍTULO 14 Herencia y polimorfismo
288
class Poligono
{
// superclase
public:
virtual float Perimetro();
virtual float Area();
virtual bool PuntoInterior();
virtual void Visualizar();
};
// la clase Rectángulo debe definir las funciones virtuales que use de
//la clase polígono
class Rectangulo : public Poligono
{
private:
float Alto, Bajo, Izquierdo, Derecho;
public:
float Perimetro();
float Area();
bool PuntoInterior();
void Visualizar();
void fijarRectangulo();
};
// la clase Triángulo debe definir las funciones virtuales que use de
//la clase polígono
class Triangulo : public Poligono{
float uno, dos, tres;
public:
float Area();
bool PuntoInterior();
void fijarTriangulo();
}
EJERCICIOS
14.1. ¿Cuáleslasalidadelsiguientepr ogramaquecontienefuncionesvirtualesynovirtualesenlaclasebase?
#include <cstdlib>
#include <iostream>
using namespace std;
class base
{
public:
virtual void f(){ cout << "f(): clase base " << endl;}
void g() {cout << "g(): clase base " << endl;}
};
CAPÍTULO 14 Herencia y polimorfismo
289
class Derivada1 : public base
{
public:
virtual void f(){cout << "f(): clase Derivada 1 " << endl;}
void g() {cout << "g(): clase Derivada 1!" << endl;}
};
class Derivada2 : public Derivada1
{
public:
void f() {cout << "f(): clase Derivada 2 !" <<endl;}
void g() {cout << "g(): clase Derivada 2 !" << endl;}
};
int main(int argc, char *argv[])
{
base b;
Derivada1 d1;
Derivada2 d2;
base *p;
p = &b;
p ->f();
p = &d1;
p ->f();
p=&d2;
p ->f();
system("PAUSE");
return EXIT_SUCCESS;
p -> g();
p ->g();
p ->g();
}
14.2. Declararlasclases Punto unidimensional, Punto bidimensional ypuntotridimensional, quepermitantratarpuntos
enelespaciodedimensiónuno, dosytresrespectivamente, medianteunajerarquíadeclases.
14.3. Declararlaclaseabstr acta Figura conlasfuncionesvirtuales Área y perímetro yquetengacomoclasesderivadaslas
figurasgeométricascirculo, cuadrado yrectangulo.
14.4. Diseñarunajer arquíadeclasesconlaclasebase Deportes, delaquesederivanlasclases Futbol, Baloncesto, Volley_Ball, quetengaunaligaduradinámica.
PROBLEMAS
14.1. Definirlaclaseobjetogeométricoylasclasescírculoycuadradoqueheredenpúblicamentelascoordenadasdelcentrode
uncírculoydeuncuadradorespectivamente.Laclasecirculo deberápermitircalcularlalongituddelacircunferenciay
eláreadelcírculoderadiodado.Laclase cuadrado debepermitircalcularelperímetroyeláreadelcuadradoconocido
ademásunvérticedelcuadrado.
14.2. Definirlaclase persona conlosatrib utos EdadPersona, estado_civil, sexo, NombrePersona, direccion ylasclases
alumno y profesor derivadasdelaanterioryqueañadanelatrib uto departamento paraelcasodelpr ofesorylosatributos curso y Num_asignaturas paralaclasealumno. Añadirlosconstructoresdecadaunadelasclasesyunafunción
miembrovisualizaracadaunadelasclases.
14.3. Escribirunprogramaquepermitaleermedianteunmenúunvectordepersonasquepuedanseralumnosoprofesores.Usar
elProblemaresuelto14.2.
CAPÍTULO 14 Herencia y polimorfismo
290
SOLUCIÓN DE LOS EJERCICIOS
14.1. Laclasebase tienedosfuncionesunavirtualf queesredefinidaenlasdosclasesderivadasyunanovirtualg quesevuelvearedefinirenlasclasesderivadas.Conlastr esprimerassentenciassellamaalasfuncionesdelaclasebase .Conlas
siguientestressentenciassellamaalafunción f virtualredefinidaenlaclase Derivada1 ylafuncióndelaclasebase g.
Enlastressiguientesllamadasseejecutalafunciónvirtual f definidaenlaclase Derivada2 yalafunción g delaclase
base.Elresultadodeejecucióndelpr ogramasemuestr aacontinuación.Sisequier equeseejecutenlafunción g delas
clasesDerivada1 yDerivada2, hayqueoptarescribir d1.g() od2.g(), yaqueenlaasignaciones p = &d1, op = &d2,
comop esunpunteroalaclase base, entonceslareferenciap->g() accedealafunciónnovirtualdelaclase base.
14.2. Lajerarquíadeclasesesprácticamenteobvia.Laclase Punto1D, sólotieneunatributoqueeslacoordenadax deunpuntounidimensional.Laclase Punto2D heredaelatributo x ylasfuncionesmiembrodelaclase Punto1D.Además, estaclaseañadeelatrib uto y, asícomolasfuncionesmiembr ocorrespondientes.Laclase Punto3D heredalosatributos x e y de
laclase Punto2D asícomotodassusfuncionesmiembro, yañadeelatributoz.
La codificación de este ejercicio se encuentra en la página Web del libro.
14.3. Laclaseabstractafigura sólotieneelconstructoryladeclaracióndelasfuncionesvirtuales perimetro yArea.Lasclasesderivadascirculo, cuadrado, yrectangulo añadenlosatributos, radio, lado, largo yancho acadaunadelasclases.Sedefinenlasfuncionesvirtualesperimetro yArea asícomolosconstructorescorrespondientesylascorrespondientesfuncionesmiembroparamanipularlosatributosdecadaunadelasclasesderivadas.Seincluyeademásunpr ograma
principalyunresultadodeejecucióndedichoprogramaprincipal.
La codificación de este ejercicio se encuentra en la página Web del libro.
14.4. SeconsideralaclaseDeportes comolaclasebasedelaquesederivanotrasclases, talescomoFutbol, Baloncesto, Voleibol. Cadatipodedeportetienelaposibilidaddehacerqueunaper sonajueguealdeportecorr espondiente.Eneste
casolaclase Deportes declaralafunciónvirtual jugar, ycadatipodedeportesedeclaracomounaclasederivadadela
clasebase Deportes ydefinelafunciónvirtual jugar.EnladeclaraciónDeportes *Dep[4] sedeclaraunarraydepunterosaDeportes.Posteriormente, seinicializa Dep alosdistintosdeportes.Enlallamada Dep[i]->jugar(" Lucas") se
produceunaligaduradinámica, yaqueelcompiladornopuededeterminarcuáleslaimplementaciónespecíficadelafunciónjugar() quesehadellamarhastaquenoseejecutaelpr ograma.
La codificación de este ejercicio se encuentra en la página Web del libro.
SOLUCIÓN DE LOS PROBLEMAS
14.1. SeconsideralajerarquíaObj_geometrico, Cuadrado yCirculo.
obj-geométrico
Círculo
Cuadrado
Uncírculosecaracterizaporsucentroysur adio.Uncuadradosepuederepresentartambiénporsucentr oyunodesus
cuatro vértices.Sedeclaranlasdosfigurasgeométricascomoclasesderivadas.Laclase obj_geom contienesolamenteel
centro.Lasclases circulo y cuadrado añadenrespectivamentelosatrib utosdel radio, ylascoor denadasdeunpunto
CAPÍTULO 14 Herencia y polimorfismo
291
cualquiera.Deestaformasepuedenobtenerelár eadelcírculoydelcuadr ado, asícomoelperímetr odelcuadradoyla
longituddelacircunferencia, mediantelassiguientesexpresiones:
Cuadrado
Círculo
2
Área=diámetro∗ diámetro/2
perímetro=4∗ lado
diámetro=2∗ œw
(a –x)2 w
+(b –y)2
Área=pi∗ r
Circunferencia=2∗ pi∗ r
lado=
1 2 2
!ß
2∗
diámetro
2
La codificación de este problema se encuentra en la página Web del libro.
Elcasodelprogramaanteriorserepresentaenelsiguientegráfico.
y
5
4
3, 3.5
3
2, 2.5
2
1
1
2
3
4
5
x
Figura 14.3. Círculo (centro: 2, 2.5), cuadrado (centro: 3, 3.5)
14.2. Lajerarquíadeclasesvienedef inidaporelgráf icoadjunto.Sedeclar anlasclasesdeacuer doconloindicado, asícomo
losconstructorescorrespondientes.LafunciónmiembroVisualizar delaClasePersona sedeclaravirtual, yvuelveadefinirseenlasclases Alumno y Profesor añadiendosimplementelassentenciascorr espondientesquepermitemostr arlos
datos.ElconstructorPersona inicializalosatributosdeunapersona, independientementedequeseaunalumnoounprofesor.Elconstructor Alumno llamaalconstructorde Persona einicializaelrestodelosatributosdeunalumno.Estemismotrabajoesrealizadoporelconstructor Profesor paralaclase Profesor.
Persona
Alumno
Profesor
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 14 Herencia y polimorfismo
292
14.3. Sedeclaraenelprogramaprincipalunvectordepunterosalaclasepersona.Cadavezqueseleelosdatosdeunalumno
odeunprofesorsecreaelobjetocorrespondientemedianteunaordendebúsquedadememorialibr eysealmacenaenel
vector.Elprogramaquesepresentatieneunmenúdeopcionesquepermiteelegirentrealumno, profesor, visualizarlosdatosdelvectoroterminar.Enesteúltimocaso, seliberalamemoriamediantelascorr espondientesórdenesdeliberación.
Secodificaademásunafunción leerdatosP queleelosdatosdeunaper sona.
La codificación de este problema se encuentra en la página Web del libro.
PROBLEMAS PROPUESTOS
14.1. Definirunaclasebase persona quecontengainformacióndepropósitogeneralcomúnatodaslaspersonas
(nombre, dirección, fechadenacimiento, sexo, etc.)Diseñarunajerarquíadeclasesquecontemplelasclases
siguientes: estudiante, empleado, estudiante_empleado.Escribirunprogramaqueleadelaentradade
datosycreeunalistadepersonas: a)general; b)estudiantes;c)empleados;d)estudiantesempleados.Elprogramadeberpermitirordenaralfabéticamenteporelprimerapellido.
14.2. Implementarunajerarquía Librería quetengaalmenosunadocenadeclases.Considéreseuna librería que
tengacoleccionesdelibrosdeliteratura, humanidades,
tecnología, etc.
14.3. Implementarunajerarquía Empleado decualquiertipo
deempresaqueleseaf amiliar.Lajerarquíadebetener
almenoscuatroniveles, conherenciademiembrosdato,
ymétodos.Losmétodosdebenpodercalcularsalarios,
despidos, promoción, dardealta, jubilación, etc.Los
métodosdebenpermitirtambiéncalcularaumentossalarialesyprimaspara Empleados deacuerdoconsucategoríayproducti vidad.Lajerarquíadeherenciadebe
poderserutilizadaparaproporcionardiferentestiposde
accesoa Empleados.
14.4. Implementarunaclase Automovil (Carro)dentrode
unajerarquíadeherenciamúltiple.Considereque, ademásdeserunvehículo, unautomóvilestambiénunacomodidad, unsímbolodeestadosocial,
unmodode
transporte, etc.
14.5. Implementarunajerarquíadetiposdatosnuméricosque
extiendalostiposdedatosfundamentalestalescomo
int, y float, disponiblesenC++.Lasclasesadiseñar
puedenser Complejo, Fracción, Vector, Matriz, etc.
14.6. Implementarunajerarquía empleado decualquier
tipo deempresaqueleresulteconocida.Lajerarquía
debeteneralmenos3ni veles, conherenciademiembros.Escribirunprogramaquecreeobjetosdelosdiferentestiposdeempleadosyrealiceoperacionespolimórficas.
14.7. Implementarunajerarquíadeherenciadeanimalestal
quecontengaalmenosseisnivelesdederivaciónydoce
clases.
CAPÍTULO 15
Plantillas, excepciones
y sobrecarga de operadores
Introducción
Paradefinirclasesyfuncionesqueoperansobretiposarbitrariossedefinenlostiposparametrizado otiposgenéricos.Lamayoríadeloslenguajesdeprogramaciónorientadosaobjetosproporcionansoporteparalagenericidad.C++proporcionalacaracterísticaplantilla (template), quepermitealostiposserparámetrosdeclasesyfunciones.C++soportaestapropiedada
partirdelaversión2.1deAT&T.Lasplantillas otiposparametrizado sepuedenutilizarparaimplementarestructurasyalgoritmosquesonensumayoríaindependientesdeltipodeobjetossobrelosqueoperan.
Unodelosproblemasmásimportanteseneldesarrollodesoftwareeslagestióndecondicionesdeerror.Las excepciones
son, normalmente, condicionesdeerroresimprevistos.Estascondicionessuelenterminarelprogramadelusuarioconunmensajedeerrorproporcionadoporelsistema. Elmanejodee xcepciones eselmecanismopre vistoporC++paraeltratamiento
deexcepciones.Normalmente, elsistemaabortalaejecucióndelprogramacuandoseproduceunae xcepciónyC++permite
alprogramadorintentarlarecuperacióndeestascondicionesycontinuarlaejecucióndelprograma.
LasobrecargadeoperadoresesunadelascaracterísticasdeC++y , naturalmentedelaprogramaciónorientadaaobjetos.
Lasobrecargadeoperadores haceposiblemanipularobjetosdeclasesconoperadoresestándartalescomo+, *, []y<<.Esta
propiedaddelosoperadorespermiteredefinirellenguajeC++, quepuedecrearnuevasdefinicionesdeoperadores.Enestecapítulo, semostrarálasobrecar gadeoperadoresunitariosybinarios, incluyendoeloperadordemoldeado( cast)paraconversióndetiposimplícitosye xplícitos, operadoresrelacionales, operadordeasignaciónyotrosoperadores.
15.1. Generecidad
Lagenericidad esunapropiedadquepermitedef inirunaclase(ounafunción)sinespecif icareltipodedatosdeunoomás
desusmiembros(parámetros).Deestaformasepuedecambiarlaclaseparaadaptarlaalosdiferentesusossintenerquerescribirla.Lasclasesgenéricasson, normalmente, clasescontenedorasqueguardanobjetosdeundeterminadotipo.Ejemplos
declasescontenedorassonpilas, colas, listas, conjuntos, diccionarios, arboles, etc.C++proponedostiposdeplantillas: las
plantillasdefuncionesylasplantillasdeclases.P aradefinirclasesyfuncionesqueoperansobretiposdedatosarbitrarios se
definenlostiposparametrizadosotiposgenéricos.
Unaplantilla de funciones especificaunconjuntoinfinitodefuncionessobrecargadas.Cadafuncióndeesteconjuntoes
unafunciónplantillayunainstanciadelaplantilladefunción.Lasintaxisdeunaplantilladefuncionestieneelformato:
template <argumentos genéricos> tipo nombreFunción(argtos función)
{ ...}
293
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
294
Ladeclaracióndelaplantilladefuncionescomienzacon template, seguidadeunalistaseparadaporcomasdeparámetrosformales, encerradosentrecorchetestipoángulo(«<»y«>»);estalistanopuedeserv acía.Cadaparámetroformalconstadelapalabrareserv ada class, seguidaporunidentif icador.Estapalabrareserv adaindicaalcompiladorqueelparámetro
representaunposibletipoincorporadodef inidoporelusuario.Senecesita, almenos, unparámetro T queproporcionedatos
sobrelosquepuedaoperarlafunción.Tambiénsepuedeespecificarunpuntero( T * parámetro)ounareferencia( T & parámetro).
Lasplantillas de clase permitendefinirclasesgenéricasquepuedenmanipulardiferentestiposdedatos.Unaaplicación
importanteeslaimplementacióndecontenedores, clasesquecontienenobjetosdeuntipodato, talescomovectores(arrays),
listas, secuenciasordenadas, tablasdedispersión(hash);enesencia, loscontenedoresmanejanestructurasdedatos.
Así, esposibleutilizarunaclaseplantillaparacrearunapilagenérica, porejemplo, quesepuedeinstanciarparadiversos
tiposdedatospredefinidosydefinidosporelusuario.Puedetenertambiénclasesplantillasparacolas, vectores(arrays), matrices, listas, árboles, tablas(hash), grafosycualquierotraestructuradedatosdepropósitogeneral.
Ladefinicióndeunaclasegenéricatienelasiguientesintaxis:
template <argumentos genéricos> class NombreClase { ... }
Losargumentosgenéricos, generalmente, representantiposdedatos;enesecasoseutilizalapalabrareservadaclass.Entonceslasintaxises:
template <class T> class NombreClase { ... }
Laimplementacióndeunafunciónmiembrodeclasegenéricafueradelaclase, exigeindicarqueesunafuncióngenéricaconelprefijotemplate <class T>.
Elidentificadoronombredeunaclasegenéricaeselnombredelaclasese guido, entrecorchetesangulares, delosargumentosgenéricos.
Losargumentosgenéricosdelasplantillaspuedenser , ademásdelostiposdedatos, cualquierotroquesedeseerealizar
como, porejemplo, paradimensionarunarrayunidimensionalgenérico.
template < class T, int n>
class ejemplo
{
T V[n]
..
}
Laplantilladeclasegenéricadebeserinstanciadaadecuadamenteenelmomentodedeclararunobjetodeunaclasegenérica, paralocualhadeindicarseeltipoentreángulo.Enelmomentoqueserealizaladeclaracióndeunainstanciadelaclasegenéricasepasanlosargumentoscorrespondientesdeladeclaraciónalosargumentosgenéricos, entrecorchetesangulares,
queaparecenacontinuacióndelnombredelaclase.P araelcasodeladeclaraciónanteriorunainstanciapuedeser:
ejemplo <int> instancia(4);
//el tipo de la instancia es entero y almacena un vector de 4 datos.
EJEMPLO 15.1. Pilagenéricaconvectordinámico.
Elprefijotemplate <class T> enladeclaracióndeclasesindicaquesedeclaraunaplantilladeclaseyqueseutilizaráT comoeltipogenérico.Porconsiguiente, PilaG esunaclaseparametrizadaconeltipo T comoparámetro.
template <class T>
class PilaG
{
private:
T* Vector;
int cima, maximo;
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
295
public:
PilaG(){ cima = –1;}
~PilaG(){}
PilaG(int n)
{ cima =–1;
maximo = n–1;
Vector = new T[n];
}
void Anade(T x);
T Borrar();
bool Vacia();
};
template <class T>
void PilaG<T>:: Anade( T x) {...}
// añadir codificación
template <class T>
void PilaG<T>:: Borrar( ) {...}
// añadir codificación
template <class T>
bool PilaG<T>:: Vacia {) {...}
// añadir codificación
..
PilaG < int > P(40);
PilaG < float > P(60);
// declara una pila de 40 enteros
// declara una pila de 60 reales.
EJEMPLO 15.2. Arraygenéricoconnúmerodedatosvariables.
Sedeclaraunaclasequedef ineunvectorde n datosvariablesycuyotipoesgenérico.
#include <cstdlib>
#include <iostream>
using namespace std;
template <class T, int n>
class Array
{
public:
T V[n];
};
int main(int argc, char *argv[])
{
Array < float, 20> A;
Array <char, 30> B;
Array <double, 40> C;
A.V[2]=6;
cout << A.V[2];
system("PAUSE");
return EXIT_SUCCESS;
}
// array real de 20 elementos
// array char de 30 elementos
// array double de 40 elementos
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
296
15.2. Excepciones
Las excepcionessonanomalías(condicionesdeerrornoesperadas)producidasdurantelaejecucióndeunprograma . Siocurreunaexcepciónyestáactivaunsegmentodecódigodenominado manejadordeexcepción paraesaexcepción, entoncesel
flujodecontrolsetransf ierealmanejador.Sienlugardeello, ocurreunaexcepciónynoexisteunmanejadorparalae xcepción, elprogramasetermina.
Elmodelodeunmecanismodee xcepcionesdeC++sebasaenelconceptodesaltonolocalyseimplementaconlaspalabrasreservadastry, throw ycatch.
• try, esunbloqueparadetectare xcepciones.
• catch, esunmanejadorparacapturare xcepcionesdelosbloques try.
• throw, esunaexpresiónparalevantar(raise)olanzarexcepciones.
Lospasosdelmodeloson:
1. Primeroprogramar“intentar” (try)unaoperaciónparaanticiparerrores.
2. Cuandoseencuentraunerror , se“lanza” (throws)unae xcepción.Ellanzamiento( throwing)deunae xcepciónesel
actodelevantarunaexcepción.
3. Porúltimo, alguieninteresadoenunacondicióndeerror(paralimpiezay/orecuperación)seanticipaalerrory“capturará” (catch)laexcepciónquesehalanzado.
EJEMPLO 15.3. Esquemadetratamientodeunaexcepción.
Elesquematienetrespartes: códigoqueproducelae xcepciónqueselanza;llamadaalcódigoquepuedetenererror;
capturadelaexcepción.
void f()
{
// código que produce una excepción que se lanza
throw (i);
//
...
}
int main()
{
try {
f();
// Llamada a f – preparada para cualquier error
// Código normal aquí
}
catch(...)
{
// capturar cualquier excepción lanzada por f()
// hacer algo
}
// Resto código normal de main()
}
15.2.1. LANZAMIENTO DE EXCEPCIONES
Lasexcepcionesselanzanutilizandolasentencia throw, cuyasintaxises:
throw (expresión);
obien
throw();
Elprimerformatoespecificaquelaexpresiónsepasanecesariamentealmanejador de excepciones(cath), queesquien
larecogeylatrata.Elsegundoformatonodevuelveningunaexpresióneindicaquesehaproducidounaexcepciónqueescap-
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
297
turadaporlafunción terminar().throw secomportacomoreturn.Loquesucedeeslosiguiente: elvalordevuelto porthrow seasignaalobjetodel catch adecuado.
Lasentencia throw levantaunaexcepción.CuandoseencuentraunaexcepciónenunprogramaC++, lapartedelprogramaquedetectalae xcepciónpuedecomunicarquelamismahaocurridoporle vantamiento, olanzamiento deunaexcepción.
Unodelosusosmáscorrientesdethrow eseldelasfunciones.Enefecto, estacláusulapuedeespecificarquétiposdeexcepcionespuedenocurrirenladeclaracióndeunafunción.Una especificacióndeexcepcionesproporcionaunasoluciónque
sepuedeutilizarparalistarlase xcepcionesqueunafunciónpuedelanzarconladeclaracióndefunción.Unaespecif icación
deexcepcionesseañadeaunadeclaraciónoaunadef inicióndeunafunción.Losformatosson:
tipo nombre_función(signatura) throw (e1, e2, eN);
tipo nombre_función(signatura) throw (e1, e2, eN)
{
cuerpo de la función
}
// prototipo
// definición
donde e1, e2, eN esunalistaseparadaporcomasdenombresdee xcepciones(lalistaespecif icaquelafunciónpuedelanzar
directaoindirectamente, incluyendoexcepcionesderivadaspúblicamentedeestosnombres).
15.2.2. MANEJADORES DE EXCEPCIONES
Lasexcepcioneslevantadasdentrodeunbloquesoncapturadasutilizandocláusulascatch asociadasconelbloque. Unacláusula catch constadetrespares: lapalabrareservada catch, ladeclaracióndeunsolotipoounsimpleobjetodentrodeparéntesis(referenciadocomodeclaracióndeexcepciones), yunconjuntodesentencias.Silacláusulacatch seseleccionapara
manejarunaexcepción, seejecutalasentenciacompuesta.
Laespecificacióndelmanejador catch seasemejaaunadefinicióndefunciónsintipoderetorno.
catch (TipoParámetro NombreParámetro)
{
CuerpoManejador
}
Aligualqueconfuncionessobrecar gadas, elmanejadordee xcepcionesseactivasólosielar gumentoquesepasa(o se
lanza “thrown”)secorrespondeconladeclaracióndelar gumentodelasentencia catch.
15.2.3. DISEÑO DE EXCEPCIONES
Lapalabrareservadatry designaunbloquetry, queesunáreadesuprogramaquedetectaexcepciones.Enelinteriordebloquestry, normalmentesellamanafuncionesquepuedenle vantarolanzar excepciones.Lapalabrareservadacatch designa
unmanejadordecapturasconunasignaturaquerepresentauntipodee xcepción.Losmanejadoresdecapturasigueninmediatamenteabloques try oaotromanejador catch conunasignaturadiferente.
Unmanipuladorconsisteenunbloque try, dondeseincluyeelcódigoquepuedeproducirlae xcepción.Unbloque try
eselcontextoparadecircuálessonlosmanipuladoresqueseinvocancuandoselevantaunaexcepción.Elordenenquesedefinenlosmanejadoresdeterminaelordenenquesepruebanlosmismosparaunae xcepciónlevantadacoincidenteentipos.
Unbloque try tienelasiguientesintaxis:
try
{
código del bloque try
}
catch (signatura)
{
código del bloque catch
}
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
298
EJEMPLO 15.4. Tratamientodelasexcepcionesparalaresolucióndeunaecuacióndesegundogrado.
Unaecuacióndesegundogradodelaforma ax2 +bx+c=0 tienelassiguientesraícesreales.
x1=
–b +œw
b2 –4ac
2a
x2=
–b +œw
b2 –4ac
2a
Loscasosenloscualeslase xpresionesanterioresnotienesentidoson: 1)a =0;2) b2 –4ac<0, quenoproduceraícesreales, sinoimaginarias.Enconsecuencia, seconsideranexcepcionesdetipoerrortalescomo:
enum error {no_raices_reales, coeficiente_a_cero};
Unacodificacióncompletaes:
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
enum error {no_raices_reales, Coeficiente_a_cero};
void raices(float a, float b, float c, float &r1, float &r2)
throw(error)
{
float discr;
if(b*b < 4 * a * c)
throw no_raices_reales;
if(a= =0)
throw Coeficiente_a_cero;
discr = sqrt(b * b – 4 * a * c);
r1 = (–b – discr) / (2 * a);
r2 = (–b + discr) / (2 * a);
}
int main(int argc, char *argv[])
{
float a, b, c, r1, r2;
cout << " introduzca coefiecientes de la ecuación de 2º grado :";
cin >> a >> b >> c;
try {
raices (a, b, c, r1, r2);
cout << " raices reales " << r1 << " " << r2 << endl;
}
catch (error e)
{
switch(e) {
case no_raices_reales :
cout << "Ninguna raíz real" << endl;
break;
case Coeficiente_a_cero :
cout << "Primer coeficiente cero" << endl;
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
299
15.3. Sobrecarga
EnC++hayunnúmerodeterminadodeoperadorespredef inidosquesepuedenaplicaratiposestándarincorporadosointegrados.Estosoperadorespredef inidos, realmente, estánsobrecargadosyaquecadaunodeellossepuedeutilizarparadiferentestiposdedatos.Casitodoslosoperadorespredef inidosparatiposestándarsepuedensobrecar gar.LaTabla15.1muestradichosoperadores
Tabla 15.1. Operadores que se pueden sobrecargar
New
delete
New[]
delete[]
+
!
^=
<=
()
–
=
&=
>=
[]
*
<
|=
&&
/
>
<<
||
%
+=
>>
++
^
–=
>>=
––
&
*=
<<=
,
|
/=
==
–>*
~
%=
!=
–>
Unoperadorunitario esunoperadorquetieneunúnicooperando.Un operadorbinario, porelcontrario, tienedosoperandos.Algunosoperadorestalescomo+sonunitariosybinarios, dependiendodesuuso.
Lossiguientesoperadoresnosepuedensobrecar gar:
.
::
accesoamiembro
resolucióndeámbitos
.x
?:
indireccióndeaccesoamiembro
aritmético
if
Unafunciónoperador esunafuncióncuyonombreconstadelapalabrareservadaoperator seguidaporunoperadorunitarioobinario.
Sintaxisfunción: tipo
operator operador(lista de parámetros)
Exceptoparaelcasodelosoperadores new, delete y–>, lasfuncionesoperadorpuedendevolvercualquiertipodedato.
Laprecedencia, agrupamientoynúmerodeoperandosnosepuedecambiar.Conexcepcióndeloperador(), lasfuncionesoperadornopuedentenerargumentospordefecto.Unafunciónoperadordebeserobienunafunciónmiembronoestáticaouna
funciónomiembroquetengaalmenosunparámetrocuyotipoesunaclase, referenciaounaclaseenumeración, oreferencia
aunaenumeración.Cuandosedeclarannuevosypropiosoperadoresparaclasesloquesehaceesescribirunafunciónconel
nombre operatorX endonde x eselsímbolodeunoperador .Existendosmediosdeconstruirnuestrospropiosoperadores,
bienformulándoloscomofuncionesamigas, obiencomofuncionesmiembro.
EJEMPLO 15.5. Operadoresunitariosbinariosyfuncionesoper ador.
n++;
x / y;
+x;
x + y;
// unitarios
// binarios
int operator *(int x, int y)
{// código no válido para definir una función operador + ya que no se
//define sobre una clase.
return x * y;
}
class Integer {
// ...
public:
int valor;
};
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
300
int operator * (const Integer &x, int y)
{ //función no miembro válida ya que al menos un parámetro es clase:
return x.valor * y;
}
15.3.1. SOBRECARGA DE OPERADORES UNITARIOS
Losoperadoresunitariossonaquellosqueactúansobreunúnicooperando.Estosoperadoressonlossiguientes:
new
++
()
+
*
!
,
delete
incremento
llamadaafunción
más
desreferencia(indirección)
NOTlógico
coma
new[] delete[]
-decremento
[]
subíndice
–
menos
&
direcciónde
~
NOTbitabit
Cuandosesobrecar ganoperadoresunitariosenunaclaseeloperandoeselpropioobjetodelaclasedondesedef ineel
operador.Portanto, losoperadoresunitariosdentrodelasclasesnorequierenoperandosexplícitos.Lasintaxisdedeclaración
eslasiguiente:
<tipo> operador <unitario>();
Sieloperadorunitario, tieneformapostfijayprefija, comoporejemplolosoperadores++o––entoncesseusalasiguiente
declaraciónparacadaunadelasformas:
prefija
postifija
<tipo> operador <unitario>();
<tipo> operador <unitario>(int);
Los operadoresunitariospuedensobrecar garsecomofuncionesmiembro ocomofuncionesamigas.Enelprimercasoel
sistemapasaelpuntero this implícitamente.Porconsiguiente, elobjetoquellamaalafunciónmiembrosecon vierteenel
operandodeesteoperador.Enelse gundocasoelsistemanopasaelpuntero this implícitamente.Porconsiguiente, sedebe
pasarexplícitamenteelobjetodelaclase.
EJEMPLO 15.6. Sobrecargadeoperadoresunitariocomofunciónmiembroycomofunciónamiga.
Lafunciónoperadorunitario --() estádeclarada, yyaqueesunafunciónmiembro, elsistemapasaelpuntero this
implícitamente.Porconsiguiente, elobjetoquellamaalafunciónmiembroseconvierteeneloperandodeestaoperador.Lafunciónoperador ++() estádefinida, comofunciónamiga, porloqueelsistemanopasaelpuntero this implícitamente.Porconsiguiente, sedebepasarexplícitamenteelobjetodelaclase Unitaria.
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
class Unitaria {
int x;
public:
Unitaria()
{x = 0;}
// constructor por defecto
Unitaria(int a)
{x = a;}
// constructor con un parámetro
friend Unitaria& operator++(Unitaria y) {++y.x; return y; }
Unitaria& operator-- () {--x ; return *this;}
void visualizar(void)
{cout << x << "\n";}
};
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
int main(int argc, char *argv[])
{
Unitaria ejemplo = 65;
for(int i = 5; i > 0; i--)
{
++ejemplo;
}
for(int i = 5; i > 0; i--)
{
--ejemplo;
}
system("PAUSE");
return EXIT_SUCCESS;
}
301
// operator++(ejemplo);
// ejemplo.operator--();
15.3.2. CONVERSIÓN DE DATOS Y OPERADORES
DE CONVERSIÓN FORZADA DE TIPOS
CuandoenC++unasentenciadeasignaciónasignaunvalordeuntipoestándaraunavariabledeotrotipoestándar, C++convierteautomáticamenteelvaloralmismotipoquelavariablereceptora, haciendoquelosdostiposseancompatibles.Elcompiladorfuncionarádemododiferentesegúnquelaconversiónseaentretiposbásicos, tiposbásicosyobjetos, obienentreobjetosdediferentesclasessilacon versiónautomáticafalla, sepuedeutilizarunaconversiónforzadadetipos( cast):
int *p =(int *) 50;
// p y (int *) 50 son punteros
varentera = int(varfloat);
Elmoldeado(casting)esunaconversiónexplícita yutilizalasmismasrutinasincorporadasalacon versiónimplícita.
Enlaconversiónentretiposdefinidosporelusuarioytiposbásicos(incorporados)nosepuedenutilizarlasrutinasdeconversiónimplícitas.Ensulugarsedebenescribirestasrutinas. Así, paraconvertiruntipoestándarobásico—porejemplo,
float—auntipodefinidoporelusuario, porejemplo, Distancia, seutilizaráunconstructorconunargumento.Porelcontrario, paraconvertiruntipodefinidoporelusuarioauntipobásicosehadeemplearun operadordeconversión.
Lasfuncionesdeconversión sonfuncionesoperador.Elargumentoenestasfuncioneseselargumentoimplícitothis.Para
convertirauntipo nombretipo seutilizaunafuncióndeconversiónconesteformato:
operator nombretipo();
ydebetenerpresentelossiguientespuntos:
•
•
•
•
Lafuncióndeconversióndebeserunmétododelaclaseacon vertir.
Lafuncióndeconversiónnodebeespecificaruntipoderetorno.
Lafuncióndeconversiónnodebetenerargumentos.
Elnombredelafuncióndebesereldeltipoalquesequierecon vertirelobjeto.
EJEMPLO 15.7. Conversióndecoordenadascartesianasapolares.
Sepresentaunafuncióndecon versióndiseñadaparacon vertirclasesdiferentes: Rect, querepresentalaposiciónde
unpuntoenelsistemadecoordenadasrectangularesy Polar querepresentalaposicióndelmismopuntoenelsistemadecoordenadaspolares.Lascoordenadasdeunpuntoenelplanosepuedenrepresentarporlascoordenadasrectangulares x e y, obienporlascoordenadaspolares Radio y Angulo.Lasclases Rec y Polar, sondeestructuradiferenteylasentenciadeasignación
rect = polar;
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
302
implicaunaconversiónqueserealizamediantelafuncióndecon versión.Lasfórmulasautilizarson:
x = radio*coseno(angulo)
y = radio*seno(angulo)
y
P(x, Y)
Radio
y
Ángulo
0
x
x
Figura 15.1. Coordenadas rectangulares de un punto.
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
class Rect
{
private:
double xco;
// coordenada x
double yco;
// coordenada y
public:
Rect()
{xco = 0.0; yco = 0.0;}
// constructor sin argumentos
Rect(double x, double y)// constructor con dos argumentos
{xco = x; yco = y;}
void visualizar()
{cout << " ( " << xco << " , " << yco << " ) ";}
};
class Polar
{
private:
double radio, angulo;
public:
Polar()
// constructor sin argumentos
{radio = 0.0; angulo = 0.0;}
Polar(double r, double a)
// constructor dos argumentos
{radio = r; angulo = a ;}
void visualizar()
{
cout << " ( " << radio << " , " << angulo << " ) ";
}
operator Rect()
// función de conversión
{
double x = radio * cos(angulo);
// calcular x
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
303
double y = radio * sin(angulo);
// calcular y
return Rect(x, y);
// invoca constructor de la clase Rect
}
};
int main(int argc, char *argv[])
{
Rect rec;
Polar pol(100.0,0.585398);
//rec = pol;
// Rect utiliza constructor
// Polar que utiliza constructor 2
// convierte Polar a Rect
// utilizando función de conversión
rec = Rect(pol);
cout << "\n polar="; pol.visualizar();
cout << "\n rectang="; rec.visualizar();
system("PAUSE");
return EXIT_SUCCESS;
// polar original
// rectangular equivalente
}
Resultadodeejecución:
15.3.3. SOBRECARGA DE OPERADORES BINARIOS
Losoperadoresbinariostomandosargumentos, unoacadaladodeloperador.LaTabla15.2listalosoperadoresbinariosque
sepuedensobrecargar.
Tabla 15.2. Operadores binarios que se pueden sobrecargar
Operador
Significado
Operador
Significado
+
–
*
/
%
=
+=
-=
*=
/=
%=
&
|
^
^=
%=
Adición(suma)
Resta
Multiplicación
División
Módulo
Asignación
Sumaconasignación
Restaconasignación
Multiplicaciónconasignación
Divisiónconasignación
Móduloconasignación
ANDbitabit
ORbitabit
ORexclusivobitabit
ORexclusivobitabitconasignación
ANDbitabitconasignación
|=
==
!=
>
<
>=
<=
||
&&
<<
<<=
>>
>>=
->
->*
Orbitabitconasignación
Igual
Noigual
Mayorque
Menorque
Mayoroigualque
Menoroigualque
ORlógico
ANDlógico
Desplazamientoaizquierda
Desplazamientoaizquierdaconasignación
Desplazamientoaderecha
Desplazamientoaderechaconasignación
Puntero
Punteroamiembro
Losoperadoresbinariospuedensersobrecargadospasandoalafuncióndosargumentos.Elprimerargumentoeseloperandoizquierdodeloperadorsobrecargadoyelsegundoargumentoeseloperandoderecho, silafunciónnoesmiembrodelaclase.Consideremosuntipodeclase t ydosobjetos x1 yx2 detipot.Definamosunoperadorbinario + sobrecargado.Entonces:
x1 + x2
seinterpretacomo
operator+(x1, x2)
ocomo
x1.operator+(x2)
304
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
Unoperadorbinariosobrecargadopuedeserdefinido:
• biencomounafunciónamiga dedosargumentos,
• biencomounafunciónmiembro deunargumento, yeselcasomásfrecuente.
EJEMPLO 15.8. Sobrecargadeoperadoresbinarioscomofunciónamigaycomofunciónmiembr o.
Lafunciónmiembro + sobrecargaeloperadorsumaporloquesóloselepasaunoperandocomoargumento.Elprimer
operandoeselpropioobjeto, yelsegundoeselquesepasacomoparámetro.Lafunciónoperadorbinario-()estádeclaradocomofunciónamiga porlocualelsistemanopasaelpunterothis implícitamentey, porconsiguiente, sedebe
pasarelobjeto Binario explícitamenteconambosar gumentos.Comoconsecuencia, elprimerar gumentodelafunciónmiembroseconvierteeneloperandoizquierdodeesteoperadoryelse gundoargumentosepasacomooperando
derecho.
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
class Binario
{
float x;
public:
Binario()
{x = 0;}
Binario(float a)
{ x = a;}
Binario operator + (Binario&);
friend Binario operator -(Binario&,Binario&);
void visualizar(void) {cout << x << "\n";}
};
Binario Binario::operator+(Binario& a)
{
Binario aux;
aux.x = x + a.x;
return aux;
}
Binario operator -(Binario& a, Binario& b)
{
Binario aux;
aux.x = a.x - b.x;
return aux;
}
int main(int argc, char *argv[])
{
Binario primero(2.8), segundo(4.5), tercero;
tercero = primero + segundo;
cout << " suma :";
tercero.visualizar();
tercero = primero – segundo;
cout << " resta :";
tercero.visualizar();
system("PAUSE");
return EXIT_SUCCESS;
}
// función miembro
// función amiga
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
305
Sobrecarga del operador de asignación
PordefectoC++sobrecar gaeloperadordeasignaciónparaobjetosdeclasesdef inidasporelusuario, copiandotodoslos
miembrosdelaclase.Cuandoseasignaunobjetoaotroobjeto, sehaceunacopiamiembroamiembrodeformaopuestaa
comosehacelacopiabitabit( bitwise).Laasignacióndeunobjetodeunaclaseaotroobjetodeesaclaseserealizautilizandoeloperadordeasignacióndecopia.Losmecanismossonesencialmentelosmismosqueloscitadosdeinicializaciónpor
defectomiembroamiembro, perohaceusodeunoperadordeasignacióndecopiaimplícitoenlugardelconstructordecopia.
Elformatogeneraldeloperadordeasignacióndecopiaeselsiguiente:
// formato general del operador de asignación de copia
nombreClase& nombreClase::operator=(const nombreClase&v)
{
// evita autoasignaciones
if (this != &v)
{
// semántica de la copia de clases
}
// devolver el objeto asignado
return *this;
}
Reglas1
Cuandounobjetodeunaclaseseasignaaotroobjetodesuclase, talcomonuevoObj = antiguoObj, sesiguenlossiguientespasos:
1. Seexaminalaclaseparadeterminarsiseproporcionaunoperadordeasignacióndecopiae xplícita.
2. Siesasí, suniveldeaccesosecompruebaparadeterminarsisepuedein vocarono, dentrodeunaporcióndel
programa.
3. Sinoesaccesible, segeneraunmensajedeerrorentiempodecompilación;encasocontrario, seinvocapara
ejecutarlaasignación.
4. Sinoseproporcionaunainstanciae xplícita, seejecutalaasignaciónmiembroamiembro.
5. Bajolaasignaciónmiembroamiembropordefecto, cadamiembrodatodeuntipocompuestooincorporadose
asignaalvalordesumiembrocorrespondiente.
Acadamiembrodelobjetodelaclaseseaplicarecursivamentelospasos1a6hastaqueseasignantodoslosmiembrosdatodelostiposcompuestosoincorporados.
1
Lipman, S.yLajoie, J.: C++Primer, 3.ªed., Reading, Masachussets: Addison-Wesley, 1998, p.730.
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
306
EJERCICIOS
15.1. Declararunaclasegenéricaparaunárbolbinario, quepermitatrabajarconunaimplementacióndepunteros.
15.2. Expliqueelfuncionamientodelafunción f definidaparaeltratamientodeexcepcionesdelaclase cadena enelsiguiente
fragmentodeprograma.
class cadena
{
char* s;
public:
enum {minLong = 1, maxLong = 1000};
cadena(){};
cadena(int);
};
cadena::cadena(int longitud)
{
if (longitud < minLong || longitud >= maxLong)
throw (longitud);
s = new char [longitud+1];
if (s == 0)
throw ("Fuera de memoria");
}
void f(int n)
{
try{
cadena cad (n);
}
catch (char* Msgerr)
{
cout << Msgerr << endl;
abort();
}
catch(int k)
{
cout << "Error de fuera de rango :" << k << endl;
}
}
PROBLEMAS
15.1. Diseñarunapiladetipog enéricoquepermitainserciónyborradodeelementos.
15.2. Escribirunprogramaquepermitageneraraleatoriamenteunvector, loordene, yposteriormentevisualiceelresultadodel
vectorordenado.Debenrealizarsetodaslasfuncionesmedianteelusodeplantillas.
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
307
15.3. Unapilaesuntipoestructuradodedatosquerecibedatosporunextremoylosretiraporelmismo, siguiendolaregla“últimoelementoenentrar, primeroensalir”. Diseñarunapilacontratamientodeexcepcionesquepermitacrearunapilade
enterosdelongitudvariableydetectarsisepr oduceundesbordamientoporquesequierenañadirmásdatosdelosquese
hanreservado, obiensequiereretirarundatoynolotiene .
15.4. Definirunaclasegenéricaparaarrays, conestosargumentosgenéricos: <class T, int n>.Elsegundoargumentoserá
lacapacidaddelarray.Lasoperacionesaimplementar: asignarElemento, devolverElement(index) yvisualizartodos
loselementosasignados.
15.5. Sobrecargareloperadorunitario++enformaprefijaypostfijaparalaclasetiempo quecontienelosatributoshoras, minutosysegundos, encargadadeincrementareltiempocadavezquesellameenunse gundo, realizandoloscambiosnecesariosenlosatributosminutosyhor assifueranecesario.Programar, además, lasfuncionesmiembroencargadasdeleer
unahoraydevisualizarla.
15.6. Declararlaclase vector quecontienecuatrocoordenadasx, y, z, t, ysobrecargaroperadoresbinariosquepermitanrealizarlasumaydiferenciadevectores, asícomoelproductoescalar.Sobrecargaroperadoresunitariosquepermitancambiardesignoaunvectorincrementarodecrementarenunaunidadtodaslascoordenadasdeunvector, asícomocalcular
lanormadeunvector.
15.7. Añadiralaclase vector delProblema15.6dosfuncionesamigasquesobrecarguenlosoperadores<<y>>parapermitirsobrecargarlosflujosdeentradaysalidaleeryescribirvector escon cin ycout respectivamente.
15.8. Definirunaclase Complejo paradescribirnúmeroscomplejos.Unnúmerocomplejoesunnúmerocuyoformatoes:
a +b ∗ i, dondeaybsonnúmerosdetipodoubleeiesunnúmeroquerepresentalacantidad œw
–1.Lasvariablesaybse
denominanrealeseima ginarias.Sobrecargarlossiguientesoper adoresdemodoqueseapliquencorr ectamentealtipo
Complejo: =, +, –, ∗, /, >>y <<.Paraañadiror estardosnúmeroscomplejos, sesumanor estanlasdosvariablesmiembrodetipodouble.Elproductodedosnúmeroscomplejosvienedadoporlafórmulasiguiente:
(a +b ∗ i)∗ (c +d ∗ i)=(a ∗ c –b ∗ d)+(a ∗ d +b ∗ c)∗ i
elcocientevienedadoporlafórmula:
(a +b ∗ i)/ (c +d ∗ i)=((a ∗ c +b ∗ d)+(–a ∗ d +b ∗ c))/(c ∗ c +d ∗ d)
SOLUCIÓN DE LOS EJERCICIOS
15.1. Unárbolbinarionovacío, tienealmacenadoensuzonaprotegidaunelemento e, detipogenéricoT, yademásunhijoizquierdo hi yunhijoder echo hd quesonpunterosalaclase Arbol.Paratratarconárbolhayquehacerlor ealmentecon
unpunteroalaclase Arbol, talycomopuedeobservar seenelpr ogramaprincipal.Sedeclar aenprimerlugar, laclase
genérica Arbol precedidadesucorrespondiente template.Estadeclaracióndeplantillaesválidapar atodaslasfuncionesmiembroquesedefinandentrodelapropiadeclaracióndelaclase.Todaslasfuncionesmiembroquesedefinanfuera
delaclase, debidoporejemploasugr anlongituddecódigo, debenserprecedidasdelacorrespondienteorden template, talycomoapareceenelejercicio.Lacodificacióndefuncionesmiembromuysimilaresalasaquídeclar adaspueden
consultarseenelcapítulodeárboles.
La codificación de este ejercicio se encuentra en la página Web del libro.
15.2. Laclasecadenacontieneunatrib utoqueesunpunter oa char;porellopar apoderalmacenarcadenasdecar acteresse
necesitareservarmemoria.Estaoperaciónesrealizadaconelconstructor cadena(int).Parapoderdeterminarlalongitudmáximaymínimadeunacadenadecar acteresseutilizauntipoenumer adoconvalores 1 y 1000.Medianteestosvaloressedeterminaelr angodentrodelcualpueder eservarsememoria, detalmaneraquesinosecumplelacondiciónde
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
308
estarenelrango, entonceslanzaunaexcepciónretornandolalongituddecadenaquenoesviabledebidoaladeclaración.
Siporalgunacir cunstancia, puedereservarsememoria, peroalhacerloelsistemanodisponedeella, entoncesselanza
otraexcepciónconelmensajedete xtofueradememoria.Lafunción f realizalareservadememoria, ysisepr oduceun
errorescapturadoconel catch einformadoelusuario.Lamismacodif icaciónconcomentariosadecuadosenlospuntos
másimportanteseslasiguiente:
La codificación de este ejercicio se encuentra en la página Web del libro.
15.3. EnelcapítulodePilasyColasseexplicacondetalleslaimplantacióndeunacolaenunarraydetamañofijo.Enesteejerciciosóloseincluyeelprototipodelasfuncionesmiembrodelaclase Cola, asícomoeltipoenumeradoerrores quesirveparacapturarlasexcepcionesypodertomardecisionesadecuadas.
La codificación de este ejercicio se encuentra en la página Web del libro.
SOLUCIÓN DE LOS PROBLEMAS
15.1. Seimplementalaclase Pila conarrayestático, ygenericidaddetiposusandolasplantillas.Sóloseincluyenlasfuncionesmiembro Pop, Push, elconstructoryeldestructor.Elrestodelasfuncionesmiembrosonomitidas, y, porello, losmétodos Push y Pop debenconsultarelatrib utoprotegido cima paracomprobarquenosee xcedeeltamañomáximodela
pila, yquehaydatosenlapilar espectivamente.
La codificación de este problema se encuentra en la página Web del libro.
15.2. Lasoluciónseharealizadousandolassiguientesfuncionesquetr atanvectoresdeuntipogenéricoT.
•
•
•
•
Aleatorio.Realizalageneraciónaleatoriadelvectordendatos.
intercambio.Realizaelintercambiodelosvaloresdedosvariablesdetipog enérico.
mayor.Recibecomoparámetrosdosvaloresgenéricosydecidesielprimeroesmayorqueelsegundo.
Burbuja.Realizalaor denacióndeunvectordendatosg enéricosporelconocidométododeor denaciónquelle vasu
nombre.
• Mostrar.Visualizalainformacióndeunvectorg enéricodendatos.
• Elprogramaprincipalrealizalasllamadascorrespondientes.
La codificación de este problema se encuentra en la página Web del libro.
15.3. Sedeclaralapilacomounaclasequetienecomozonaprivadaunatributolapila queespunteroaenteros(seráunarray
dinámico), yotrosdosenteros cima y tamapila queindicaránlaposicióndondeestáelúltimoelementoqueseañadióa
lapilaycuantosnúmerosenterospuedealmacenarcomomáximolapila.La pila tienedosconstructores, unopordefectoyotroquegeneraunapiladeltamañoquesepasecomoparámetro, mediantelacorrespondienteordendereservadeespaciodememoriaparaelarraydinámico.Lapilacontieneenlazonapúblicadosclasesanidadespar aeltratamientode
lasexcepcionesqueson: Desbordamiento y Subdesbordamiento.Enestazonapúblicacontiene , además, lasfunciones
miembro meter undatoenlapilay sacar undatodelapila, encargadasderealizarlascorrespondientesllamadasalos
objetosdedesbordamientoosubdesbordamintodelapila.Elprogramaprincipalfuerzaalapilaparaquesedesborde, haciendoqueseinvoquealmanejadordeexcepciones.
La codificación de este problema se encuentra en la página Web del libro.
15.4. Laclase array tieneunazonaprivadaconunatributoenterondatos queindicaelnúmerodeelementosquepuedealmacenarel array yunpunteroauntipog enérico T denominado Parray.Elconstructordelaclaser eservaespaciodememoriadeltipo T paraunacantidaddeelementosindicadaensuparámetr o n.Eldestructor, seencargadeliberarlamemoriadel array.Lafunciónmiembr o visualizar seencargadevisualizarelvectorcompletodedatos. Ademásdelas
funcionesmiembro AsignarElemento y DevolverElemento encargadasdeasignarenunaposición i del array unele-
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
309
mentooderecuperarelelementoqueseencuentr aalmacenadoenlaposición i, sesobrecarga2 eloperador [] parapodertrabajarconelarraycomosifueraunvectordefinidodelaformaestándarenC++.Sepr esenta, además, unprogramaprincipalenelquesedeclar aunobjeto array de5elementosdenominado tabla yserellenayvisualizalatablacon
eloperadorsobrecargado[].
La codificación de este problema se encuentra en la página Web del libro.
15.5. Laclasetiempo tienecomoatributosprivadoslashoraslosminutosylossegundos.Setratadehacerqueeltiemposeincrementeenunaunidadmedianteeloper adorsobrecargado++tantoenformapr efijacomoformapostf ija.Parasobrecargareloperador++, enformaprefijasedeclaralafunciónmiembrodelasiguienteforma: void operator ++ (void).
Parahacerloenformapostfijasedeclaralafunciónmiembroconint entreparéntesisvoid operator ++ (int).Elconstructortiempoinicializaeltiempoacer o.Lafunciónmiembr o verHora visualizalahor adelaclasetiempo.Lafunción
miembroleerTiempo, solicitalahoradelaentradaylaconvierteendatoscorrectos.Losminutosysegundosdebenestar
enelr ango0a59.Unavezdeclar adoelobjetotiempo t1, sepuedenr ealizarlasllamadasenformapr efijasiguientes:
++t1;o t1.operator++();.Lasllamadasenformapostf ijason t1++; ot1.operator++(0);.
La codificación de este problema se encuentra en la página Web del libro.
15.6. Laclase vector tienecomoatributosprivadoslascuatrocoordenadasx, y, z, t delvectordedimensión4.Sepr ograman
lassiguientesfuncionesmiembro:
• Constructorvector, encargadodeinicializarelvectoralascoordenadas0,0,0,0 obienconlosparámetrosquereciba.
• Operadorbinario + sobrecargadopararealizarlasumadedosvectorescomponenteacomponente:
a –b =a.x –b.x,
a.y –b.y,
a.z –b.z, a.t –b.t
• Operadorunitario–quecambiadesignotodaslascomponentesdeunvector:
–a =(–a.x, –a.y, –a.z, –a.t)
• Operadorbinario–cuyasobrecargapermiterealizarladiferenciadedosvectores, entendidacomodiferenciadelascorrespondientescomponentes:
a –b =(a.x –b.x,
a.y –b.y,
a.z –b.z,
a.t –b.t)
• Operadoresunitarios++ y–– querealizanelincrementoodecrementodeunaunidadentodaslascomponentesdelvector:
a ––=(a.x ––,
a.y ––,
a.z ––,
a.t ––)
a ––=(a.x ––,
a.y ––,
a.z ––,
a.t ––)
• Operadorbinario*encargadoderealizarelproductoescalardefinidocomolasumadelosproductosdelascomponentesdedosvectores:
a ∗ b =a.x ∗ b.x –a.y ∗ b.y –a.z ∗ b.z –a.t ∗ b.t
• Operadorunitario*sobrecargadoparacalcularlanormadeunvector:
a.x ∗ a.x +aw
.y ∗ b.y +aw
.z ∗ b.z +aw
.t ∗ b.t
norma(a) =sqrt(a ∗ a)= œw
La codificación de este problema se encuentra en la página Web del libro.
15.7. Lasobrecargadelflujodesalida << añadealaclase vector laposibilidaddevisualizarelvectorusandolasentenciadel
flujodesalida.Análogamente, ocurreconlasobrecargadeloperador>> paraelflujodeentrada, añadiendoalaclasepunto unoperadordeflujodesalida << sobrecargado, sepodránescribirobjetos punto ensentenciasdeflujodesalida.La
funciónamigaoperator<<() devuelveostream& ydeclaradosparámetrososdetipoostream yv, unareferenciaaunobjetovector.Análogamenteocurreconlafunciónamiga operador <<().
La codificación de este problema se encuentra en la página Web del libro.
2
Véaseelcapítulodesobrecargadeoperadores.Apartadodeoperadoresunitarios.
CAPÍTULO 15 Plantillas, excepciones y sobrecarga de operadores
310
15.8. Unnúmerocomplejotieneunaparter eal a yunaparteimaginaria b.Laformanormalder epresentarenmatemáticasun
númerocomplejoeslasiguiente: a + b * i (formabinómica).Dondeelsímbolo i sedenomina“unidadima ginaria” y
simbolizalaraízcuadradade–1(i = œw
–1).Debidoasunaturalezacompuesta, unnúmerocomplejoserepresentadeformanaturalporunaclasequecontengacomoatrib utoslaparterealaylaparteima ginariab.Lasobrecargadeoperadorespedidasedivideendosbloqueslosoper adoresbinarios+, –, *,/ quesecodificancomofuncionesmiembrodelaclase
complejoylosoperadoresunitarios<<y>>quesecodif icancomofuncionesamigasdelaclasecomplejo.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
15.1. Declararunaclasegenéricaparatrabajarconlistasenlazadasimplementadasconpunteros.
15.2. Diseñarunaclasegenéricaparapodertratarmatrices.
15.3. Definirunafunciónplantillaquede vuelvaelv alorabsolutodecualquiertipodedatoincorporadoopredef inidopasadoaella.
PROBLEMAS PROPUESTOS
15.1. EscribirelcódigodeunaclaseC++quelancee xcepcionesparacuantascondicionesestimecon venientes.
Utilizarunacláusula catch queutiliceunasentencia
switch paraseleccionarunmensajeapropiadoyterminarelcálculo.( Nota: Utiliceuntipoenumeradopara
listarlascondiciones enum error_pila {overflow,
underflow,...}.)
15.8. Escribirunaclase Racional paranúmerosracionales.
Unnúmeroracionalesunnúmeroquepuedeserrepresentadocomoelcocientededosenteros.Porejemplo,
1/2, 3/4, 64/2, etc.Sontodosnúmerosracionales.Sobrecargarlosrestantesdelossiguientesoperadoresde
modoqueseapliquenaltipo Racional :. ==, <,
<=, >,>=,+, –, * y /.
15.2. Escribirunaclaseplantillaquepuedaalmacenaruna
pequeñabasededatosdere gistros, yescribirunprogramaquepuedamanejarobjetosdelabasededatos.
15.9. Describirunaclase Punto quedefinalaposicióndeun
puntoenunplanocartesianodedosdimensiones.Diseñareimplementarunaclase Punto queincluyalafunciónoperador(–)paraencontrarladistanciaentredos
puntos.
15.3. Modificarelprogramadelproblemaanteriorparatratar
lasexcepcionesqueconsidereoportunas.
15.4. Escribirunaclasegenéricaparaeltratamientodeconjuntos.
15.5. Escribirunprogramaqueutilicelaclasegenéricadel
problemaanterioryquetrabajeconenteros, conreales
ycadenasdecaracteres.
15.6. Modificarlaclasegenéricadetratamientodeconjuntos
parapermitireltratamientodee xcepciones
15.7. Escribirunprogramaqueutilicelaclasegenéricadel
problemaanterioryrealiceuntratamientodelasexcepciones.
15.10. Crearlaclasematrizcuadradaycrearunoperadorfunciónquepermitasumar, restarymultiplicardosmatrices.
15.11. Definirlosoperadoresnecesariospararealizaroperacionesconcadenastalescomosumar(concatenar),
compararoextraercadenas.
15.12. Escribirunaclase Vector conncomponentesquepermitasumaryrestarv ectores, asícomocalcularel productoescalar dedosvectoresdeiguallongitud( u1, u2,
..., un)y(v1, v2, ...vn)sepuededefinircomolasuma.
n
Σu v
k=1
k k
CAPÍTULO 16
Flujos y archivos
Introducción
LabibliotecaestándardeC++proporcionanunconjuntoampliodecapacidadesdeentrada/salida.Elsoftw aredeC++incluyeunabibliotecaestándarquecontienefuncionesquesonutilizadasporlosprogramadoresdeC++.Sinembar go, C++introdujoelarchivoiostream 1 queimplementasuspropiascoleccionesdefuncionesdeentrada/salida.Enestecapítuloaprenderá
autilizarlascaracterísticastípicasdeE/S(Entrada/Salida)deC++yobtenerelmáximorendimientodelasmismas.
16.1. Flujos (streams)
LaentradasalidadeC++seproduceporflujosdebytes.Unflujoesunaabstracciónqueseref iereaunainterfazcomúnadiferentesdispositivosdeentradaysalidadeunacomputadora.Un flujo (stream)essimplemente, unasecuenciadebytes.En
lasoperacionesdeentrada, losbytesfluyendesdeundispositi voalamemoriaprincipal.Enoperacionesdesalida, losbytes
fluyendelamemoriaprincipalaundispositi vo.Existendosformasdeflujo: textoybinario.Losflujosdete xtoseusancon
caracteresASCII, mientrasquelosflujosbinariossepuedenutilizarconcualquiertipodedatos.
Elarchivoiostream declaratresclasesparalosflujosdeentradaysalidaestándar.Laclaseistreamesparaentradadedatosdesdeunflujodeentrada, laclase ostream esparalasalidadedatosaunflujodesalidaylaclase iostream esparaentradadedatosdentrodeunflujodedatos.Elarchi vofstream declaralasclases ifstream, ofstream yfstream paraoperacionesdeentradaysalidaporarchi vos.Estasclasesdeclarantambiénloscuatroobjetosyaconocidos.
cin
cout
cerr
clog
Unobjetodelaclase istream conectadoalaentradaestándar.
Unobjetodelaclase ostream conectadoalasalidaestándar.
Unobjetodelaclase ostream conectadoalerrorestándarparasalidasinbúfer .
Unobjetodelaclase ostream conectadoalerrorestándar, consalidaatravésdebúfer.
Elarchivodecabecera iostream seincluyeenlamayoríadelosprogramasdeC++ycontienelasfuncionalidadesrequeridasparatodaslasoperacionesdeentradaysalidabásicas.Elarchivodecabeceraiomanip contieneinformaciónútilpara
realizarlaentradaysalidaconformatoconmanipuladoresdeflujoparametrizados.La Tabla16.1muestralosobjetosdeflujosestándarenlabiblioteca iostream.
1
EnlasversionesanterioresalúltimoestándardeC++, elarchivodeCabeceraempleadosedenominaiostream.h(véaseCapítulo1) .
311
CAPÍTULO 16 Flujos y archivos
312
Tabla 16.1. Objetos estándar de flujo
Nombre
Operador
Clase de flujos
cin
cout
cerr
clog
>>
<<
<<
<<
istream
ostream
ostream
ostream
Significado
entradaestándar(conbúfer)
salidaestándar(conbúfer)
errorestándar(sinbúfer)
errorestándar(conbúfer)
16.2. Las clases istream y ostream
Lasclases istream yostream sederivandelaclasebase ios.
class istream:virtual public ios{//..}
class ostream:virtual public ios{//..}
Laclase istream permitedefinirunflujodeentradaysoportamétodosparaentradaformateadaynoformateada.Eloperadordeextracción>> estásobrecargadoparatodoslostiposdedatosintegralesdeC++, haciendoposiblelasoperacionesde
entradadealtonivel, aplicándoseaunobjeto istream yunobjetovariable.
objeto_istream >> objeto_variable;
cin >> precio >> cantidad;
// lee el precio
y la cantidad.
Eloperador>> extraeunasecuenciadecaracterescorrespondientesaunvalordeltipoobjeto_variable deobjeto_isporloquenormalmenteseconocecomo operadordeextracción, debidoaquesucomportamientoese xtraervalores
deunaclase istream.
Laclase ostream mantiene, esencialmentevariablesbooleanasdenominadaindicadoresparacadaunodelosestados
tream,
Tabla 16.2. Estado de errores en el flujo
Llamada a la función
Devuelve verdadero sí y sólo sí
cin.good()
cin.bad()
Cin.fail()
Todobienen istream
Algoincorrectoen istream
Laúltimaoperaciónnosehaterminado
Lafunciónmiembroclear() seutilizanormalmentepararestaurarunestadodeflujoa good demodoquelaE/Ssepuedaprocedereneseflujo.(Unavezqueeloperador good seponeafalso, ningunaoperacióndeentradaposteriorsepuedeejecutarhastaqueselimpiesuestado.)
Lafunciónmiembro ignore() reinicialosindicadoresdeestado.
cin.clear();
cin.ignore( 123, ' ')
//reinicializa good a verdadero; bad y fail a falso
// salta como máximo 123 caracteres, o hasta blanco
EJEMPLO 16.1. Funciónmiembroclear()ycontroldeerroresdeflujodeentrada.
Elsiguienteprogramaleedatosenterosdelaentradacontándolos, hastaquesepulsacontol+z encuyomomentoescribelamediaparcial.Posteriormente, limpialaentradayvuelv ealeerdatosdeentradahastaquesevuelv eapulsar
control+z.Porúltimoescribelamediatotal.
#include <cstdlib>
#include <iostream>
using namespace std;
CAPÍTULO 16 Flujos y archivos
313
int main(int argc, char *argv[])
{
int n, suma = 0, c = 0;
while(cin >> n)
{
suma+= n;
c++;
}
cout << " la media parcial es: " << (float)suma/c << endl;
cin.clear();
while(cin >> n)
{
suma+= n;
c++;
}
cout << " la media total es " << (float) suma/c << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Laclaseostream deC++proporcionalacapacidadderealizarsalidaformateadaysinformatear.Estaclasesirveparallevarelflujodecaracteresdesdeunprogramaenejecuciónaundispositi vodesalidaarbitrario.
cout, unostream paravisualizarlasalidanormal.
cerr unostream paravisualizarmensajesdeerrorodediagnóstico.
Eloperadordeinsercióndeflujoses <<, seaplicaaunobjeto ostream yunaexpresión:
objeto_ostream << expresión;
Esteoperadordeinserciónsepuedeponerencascada, demodoquepuedenaparecerv arioselementosenunasolasentenciadeC++, mezclandoexpresiones, numéricas, alfanuméricas, etc., perosinponerblancosdeseparación.
EJEMPLO 16.2. Usode cout.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
cout << " Mazarambroz se encuentra a " << 100;
cout << " km de Toledo. Tiene " << 1500 << " habitantes "<< endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Labibliotecaiostream, quecontieneentreotraslasclasesistream yostream, proporcionamanipuladoresquepermiten
formatearelflujodesalida.Laentradaysalidadedatosrealizadaconlosoperadoresdeinserciónye xtracciónpuedenformatearseajustándolaalaizquierdaoderecha, proporcionandounalongitudmínimaomáxima, precisión, etc.Normalmente,
losmanipuladoresseutilizanenelcentrodeunasecuenciadeinserciónoe xtraccióndeflujos.Casitodoslosmanipuladores
estánincluidosfundamentalmenteenelarchivodecabecera iomanip.h.LaTabla16.3recogelosmanipuladoresmásimportantesdeflujodeentradaysalida.
CAPÍTULO 16 Flujos y archivos
314
Tabla 16.3. Manipuladores de flujo
Manipulador
endl
ends
flush
dec
oct
hex
left
right
setbase(int b)
setw(arg)
setprecoson(arg)
setiosflags/fmtflags f)
resetiosflags/fmtflags f)
setfill(char car)
Descripición
Insertanuevalíneaylimpio ostream.
Insertaelbytenuloen ostream.
Limpiaostream.
Activaconversióndecimal.
Activaconversiónoctal.
Activaconversiónhexadecimal.
Justificasalidaalaizquierdadelcampo.
Justificasalidaaladerechadelcampo.
Establecebasea b.Pordefectoesdecimal.
Enlaentrada, limitalalecturaa arg caracteres;enlasalidautilizacampo arg como
mínimo.
Fijalaprecisióndecomaflotantea arg sitiosaladerechadelpuntodecimal.
Establecelosindicadoresde ios enf.
Borraindicadores ios enf.
Usacar pararellenarcaracteres(poromisiónblanco).
EJEMPLO 16.3. Usodealgunosmanipuladoresdeflujo.
#include <cstdlib>
#include <iostream>
#include <iomanip.h>
using namespace std;
int main(int argc, char *argv[])
{
const int n =15;
float dato = 123.4567;
cout << n << endl;
// salida en base diez
cout << oct << n<< endl;
// salida en base ocho
cout << hex<< n << endl;
// salida en base 16
cout << setw(8) << " hola" << endl;
// anchura de campo 8
cout << setw(10);
// anchura 10
cout.fill('#');
// rellena con #
cout << 34 << endl;
// escribe 34 en base 16 anchura 10 y relleno
cout<< setprecision(5) << dato << endl;
// precision 5 3 antes del
//punto y 2 después
system("PAUSE");
return EXIT_SUCCESS;
}
Lectura de datos tipo cadena
Cuandoseutilizaeloperadordee xtracciónparaleerdatostipocadena, seproducenanomalíassilascadenasconstandemás
deunapalabraseparadasporblancos, yaqueeloperador >> hacequeterminelaoperacióndelecturasiemprequeseencuentrecualquierespacioenblanco.P araresolveresteproblemasepuedeusarlafunción get() obienlafunción getline().
Lafunción miembro get() delobjeto cin delaclase istream, leeunsólocarácterdedatosdelteclado, obienunacadenadecaracteres.
Siestafunciónseusaconunparámetrocarácter , entoncesleeelsiguientecarácterdelflujodeentradaensuparámetro
quesepasaporreferencia.Lafunciónde vuelvefalsocuandosedetectaelf inaldearchivo.Suprototipoes:
istream&get(cahr &c)
CAPÍTULO 16 Flujos y archivos
315
EJEMPLO 16.4. Usodelafunciónget(), paraleercarácteracarácter.
Elprogramaleecaractereshastaqueseteclea control+z.Posteriormentelovisualiza.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char c;
cout << "comienza entrada de cadena\n";
while( cin.get(c))
cout << c;
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Lafunción get() tieneunformatoquepermiteleercadenasdecaracteres, cuyoprototipoes:
istream &get(char*bufer, int n char sep='\n')
Elprimerparámetroesunpunteroaunarraydecaracteres;else gundoparámetroeselnúmeromáximodecaracteresa
leermásuno;yeltercerparámetroeselcarácterdeterminación, sinoaparecees intro.
EJEMPLO 16.5. Usodelafunción get(), paraleercadenasdecaracteres.
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char cadena[20];
cout << " introduzca cadena de caracteres\n";
cin.get(cadena, 20);
cout << cadena<< endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Lafunciónmiembrodelaclase iostream getline().Tienelasiguientesintaxis:
istream& getline(signed char* buffer, int long, char separador = '\n' );
Elprimerargumentodelafunciónmiembro getline() eselidentificadordeunavariablecadena, enlaqueseretornala
cadenaqueselee.Else gundoargumentoeselnúmeromáximodecaracteresqueseleeránquedebeseralmenosdoscaracteresmayorquelacadenareal, parapermitirelcarácternulo '\0' yel '\n'.Porúltimo, elcarácterseparadorseleeyalmacenacomoelsiguientealúltimocarácterdelacadenayeselúltimocarácterqueselee.
Reglas
• Lallamada cin.getline(cad, n, car) leetodaslasentradashastalaprimeraocurrenciadelcarácterseparadorcar encad.
• Sielcarácterespecificadocar eselcarácterdenuevalínea '\n', lallamadaanterioresequivalentea cin.getline(cad, n).
CAPÍTULO 16 Flujos y archivos
316
Lafunción getline() presentaproblemascuandoseintenteutilizarunav ariablecadena, despuésdequesehautilizado
cin paraleerunavariablecarácteronumérico.Larazónesquenoseleeelretornodecarroporloquepermaneceenel
buffer
deentrada.Cuandosedalaorden getline(), seleeyalmacenaesteretornoquepordefectoeselcarácterseparador , porlo
quenoseleelacadenadecaracteresquesepretendeseaeldato.P araresolveresteproblemasepuededarunaordendelecturacon getline(cad,2) yselimpiaelbufferdeentrada.
EJEMPLO 16.6. Usodelafuncióngetline().
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char cadena[20];
int valor;
cout << " introduzca cadena \n";
cin.getline(cadena, 20);
cout << " cadena leida :"<< cadena << endl;
cout << " introduzca dato numerico:\n";
cin >> valor;
cout << " valor leido: " << valor << endl;
cin.getline(cadena, 2);
cout << " introduzca nueva cadena \n";
cin.getline(cadena, 20);
cout << " nueva cadena leida: "<< cadena << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
16.3. Las clases ifstream y ofstream
Lasclasesquemanejanlosarchi vosenC++son: ifstream paralaentrada(soloflujosdelectura), ofstream paralasalida
(sóloflujosdesalida)y fstream, paramanejartantolaentradacomolasalida(flujosdeentradaysalida).
Elaccesoalosarchi vossehaceconun buffer intermedio.Sepuedepensarenel buffer comounarraydondesev analmacenandolosdatosdirigidosalarchivo, odesdeelarchivo;elbuffersevuelcacuandodeunaformauotrasedalaordende
vaciarlo.Porejemplo, cuandosellamaaunafunciónparaleerdelarchi vounacadena, lafunciónleetantoscaracterescomo
quepanenel buffer.Luego, laprimeracadenadel buffer eslaqueseobtiene;unasiguientellamadaalafunciónobtendrála
siguientecadenadelbuffer, asíhastaquesequedevacíoyseallenadoconunaposteriorllamadaalafuncióndelectura.
16.3.1. APERTURA DE UN ARCHIVO
Paracomenzaraprocesarunarchi voenC++laprimeraoperaciónarealizares abrir elarchivo.Laaperturadelarchi vosuponeconectarelarchivoexternoconelprograma, eindicarcómovaasertratadoelarchivo: binario, texto.
Elmétodoparaabrirunarchivoes fopen( ), ysusintaxisdellamada:
void open(char *nombre_archivo, int modo);
nombre
modo
≡ cadena
Contieneelidentificadorexternodelarchivo.
Contieneelmodoenquesevaatratarelarchivo.Puedeserunoounacombinacióndeltipoenumeradoopen_mode, delaclase ios:: separadospor|.
CAPÍTULO 16 Flujos y archivos
317
fopen() esperacomose gundoargumentoelmododetratarelarchi vo.Fundamentalmente, seestablecesielarchi voes
paraleer, paraescribiroparaañadir;ysiesdete xtoobinario.Losmodosbásicossee xpresanenModo enlaTabla16.4.
Tabla 16.4. Modos de apertura de un archivo
Modo
Significado
ios::in
ios::out
ios::app
ios::ate
ios:trunc
ios:binary
Abreparalectura, situándosealprincipio.
Abreparacrearnuevoarchivo(siyaexistesepierdensusdatos).Sesitúaalprincipio.
Abreparaañadiralfinal.
Abrearchivoyaexistenteparamodificar(leer/escribir), situándosealfinal.
Creaunarchivoparaescribir/leer(siyae xistesepierdenlosdatos).
Archivobinario.
Paraabrirunarchi voenmodobinariohayqueespecif icarlaopción ios:binary enelmodo.Losarchi vosbinariosson
secuenciasdebytesyoptimizanelespacio, sobretodoconcamposnuméricos. Así, alalmacenarenmodobinariounentero
suponeunaocupaciónde2byteso4bytes(dependedelsistema), yunnúmeroreal4byteso8bytes;enmodote xtoprimero
seconvierteelvalornuméricoenunacadenadedígitosse gúnelformatoydespuésseescribeenelarchi vo.
Alterminarlaejecucióndelprogramapodráocurrirquee xistandatosenel buffer deentrada/salida;sinosev olcasenen
elarchivoquedaríaéstesinlasúltimasactualizaciones.Siemprequeseterminadeprocesarunarchi voysiemprequeseterminelaejecucióndelprogramalosarchi vosabiertoshayquecerrarlosparaqueentreotrasaccionessevuelqueel buffer.
Lafunciónmiembro fclose( ) cierraelarchivoasociadoaunaclase.Elprototipoes: void fclose();.
16.3.2. FUNCIONES DE LECTURA Y ESCRITURA EN FICHEROS
Eloperadordeflujodeentrada<< sepuedeusarconflujosdeentrada,aligualquesehaceconcin, cuandosetrabajeenmodo
texto(nobinario).
Eloperadordeflujodesalida >> puedeserusadoconflujosdesalidaaligualquesehacecon cout cuandosetrabajeen
modotexto.
Elmétododesalida fput() sirveparainsertaruncarácterencualquierdispositi vodesalida.Susintaxises ostream&
put(char c);.
Losmétodosdeentrada get() ygetline() paralalecturadedatosdetipocadenafuncionantalycomosehae xplicado
paraelcasodelalecturadelobjeto cin.
Elmétodo feof( ) verificasisehaalcanzadoelf inaldelarchivo, devuelveunvalornulosinoesasí.Elprototipodela
funcióneselsiguiente: int feof();.
Cadavezqueseproduzcaunacondicióndeerrorenunflujo esnecesarioeliminarla, yaqueencasocontrarioninguna
operaciónqueserealicesobreéltendráéxito.Lafunciónmiembro clear() seutilizanormalmentepararestaurarunestado
deflujoa good demodoquelaE/Ssepuedaprocedereneseflujo, talycomoapareceexpresadoenlaTabla16.2
EJEMPLO 16.7. Tratamientodearchivosdesecuencia.
Elprogramasolicitaalusuariounarchi vodetexto, loalmacenayposteriormentelovisualiza.
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
ofstream fichero;
ifstream fichero1;
char c;
fichero.open("datos.cpp", ios::out);
CAPÍTULO 16 Flujos y archivos
318
cout << " escriba fichero de texto: control+z para terminar\n";
while( cin.get(c))
fichero.put(c);
fichero.close();
cout
<< " lectura y escritura del fichero anterior\n";
fichero1.open("datos.cpp", ios::in);
while(fichero1.get(c))
cout.put(c);
fichero1.close();
system("PAUSE");
return EXIT_SUCCESS;
}
Elmétodo write( ) escribeelnúmerodecaracteresindicadoenelse gundotamañodesdecualquiertipodedatosuministradoporelprimero.Elprototipodelafunciónes:
ostream & write(const char *buffer, int
tamaño);
Elmétodoread() leeelnúmerodecaracteresindicadoenelparámetrotamañodentrodelbuffer decualquiertipodedato
suministradoporelprimerparámetro.Elprototipodelafunciónes:
ostream & read(char * buffer, int
tamaño);
Laextraccióndecaracterescontinúahastaquesehayanleídotamañocaracteresoseencuentreelf
indearchivodeentrada.
Parapoderleeryescribirregistrosoestructurasconlosmétodosread owrite seusaeloperadorreinterpret_cast.Su
sintaxises:
reinterpret_cast< Tipo > (arg)
Eloperando Tipo esenestecaso char * y arg es ®istro.donde registro es, normalmente, unavariabledeltipo
registroquesedesealeeroescribir.(VéaseelProblemaresuelto16.2.)
Losmétodosseekg( ) yseekp() permitentratarunarchivoenC++comounarrayqueesunaestructuradedatosdeaccesoaleatorio. seekg( ) y seekp() sitúanelpunterodelarchi vodeentradaosalidarespecti vamente, enunaposiciónaleatoria, dependiendodeldesplazamientoyelorigenrelati voquesepasancomoar gumentos.
Losprototiposdelosmétodosson:
istream & seekg (long desplazamiento);
istream & seekg (long desplazamiento, seek_dir origen);
ostream & seekp (long desplazamiento);
ostream & seekp (long desplazamiento, seek_dir origen);
Elprimerformatodeambosmétodoscambialaposicióndemodoabsoluto, yelse gundolohacedemodorelati vo, dependiendodetresvalores.
Elprimerparámetroindicaeldesplazamiento, absolutoorelativodependiendodelformato.
Elsegundoparámetrodelosdosmétodos eselorigendeldesplazamiento.Esteorigenpuedetomarlostressiguientesvalores:
beg
cur
end
Cuentadesdeeliniciodelarchivo.
Cuentadesdelaposiciónactualdelpunteroalarchi vo.
Cuentadesdeelfinaldelarchivo.
CAPÍTULO 16 Flujos y archivos
319
Laposiciónactualdelcursordeunarchi vosepuedeobtenerllamandoalosmétodo tellg() o tellp(). Elprimermétodolaobtiene paraarchivosdeentradaoelse gundoparasalida.Susprototiposson:
long int tellg();
long int tellp();
Elmétodogcount() retornaelnúmerodecaracteresobytesquesehanleídoenlaúltimalecturarealizadaenunflujode
entrada.Suformatoes
int gcount();
EJEMPLO 16.8. Tratamientodearchivosbinarioconlosmétodos read ywrite.
Elprogramaleeunarchi voaleatoriobinario datos.dat delquenosetieneningunainformación, ylocopiaenotro
archivobinarioaleatorio res.dat.
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
ifstream f;
ofstream g;
char cadena[81];
// archivo de entrada
// archivo de salida
// cadena de 81 bytes para leer de un fichero y
//escribir en el otro
// Abrir el archivo de f de lectura y binario
f.open("datos.dat", ios::binary);
if(!f.good())
{
cout <<"El archivo " << "datos.dat " << " no existe \n";
exit (1);
}
// Crear o sobreescribir el archivo g en binario
g.open("res.dat", ios::binary);
if(!g.good()) {
cout <<"El fichero " << "res.dat " << " no se puede crear\n";
f.close();
exit (1);
}
do
{
f.read(cadena, 81);
// lectura de f
g.write(cadena, f.gcount());
// escritura de los bytes leídos
} while(f.gcount() > 0);
// repetir hasta que no se leen datos
f.close();
g.close();
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 16 Flujos y archivos
320
EJERCICIOS
16.1. Escribirlassentenciasnecesariaspar aabrirunar chivodecaracterescuyonombreyaccesoseintr oduceportecladoen
modolectura.Enelcasodequeelr esultadodelaoperaciónseaerróneo, abrirelarchivoenmodoescritura.
16.2. Unarchivodetextocontieneenterospositivosynegativos.Utilizaoperadordeextracción>>paraleerelarchivo, visualizarloydeterminarelnúmerodeenterosnegativosypositivosquetiene.
16.3. Escribirunprogramaqueleauntextodeltecladoloalmaceneenunarchivobinarioyposteriormentevuelvaaleerelarchivobinarioyvisualicesucontenido.
16.4. Setieneunarchivodecaracteresdenombre“SALAS.DAT”.Escribirunprogramaparacrearelarchivo“SALAS.BIN” con
elcontenidodelprimerarchivoperoenmodobinario.
PROBLEMAS
16.1. Utilizarlosargumentosdelafunciónmain( ) paradarentradaadoscadenas;laprimerarepresentaunamáscara, lasegundaelnombredeunarchivodecaracteres.Elprogramatienequecontarlasvecesqueocurrelamáscaraenelarchivo.
16.2. Unatletautilizaunpulsómetr oparasusentrenamientos.Elpulsómetroalmacenalaspulsacionescada15se gundos, duranteuntiempomáximode2horas.Escribirunprogramaparaalmacenarenunarchivolosdatosdelpulsómetrodelatleta, detalformaqueelprimerr egistrocontengalafec ha, horaytiempoenminutosdeentr enamiento, acontinuación, los
datosdelpulsómetroporparejas: tiempo, pulsaciones.Losdatosdebenserleídosdelteclado.Unavezescritoenelar chivolosdatos, elprogramadebevisualizarelcontenidocompletodelar chivo.
SOLUCIÓN DE LOS EJERCICIOS
16.1. Éstassonlasoperacionesbásicaspararealizarlaaperturadeunarchivoquepuedeserdeentradaodesalida, luegodebe
serunobjetodelaclase fstream.Setratadedeclararunacadenadecaracteresparaleerelnombredelarchivo, yabrir
elarchivoenmodoentr ada.Encasodequenopuedaabrir sesedebecreardeescritura.Unaobservaciónimportantees
quesiempresehadecompr obarsilaapertur adelarchivohasidor ealizadaconéxito, puestoqueesunaoper aciónque
realizaelsistemaoperativoparaelprogramaquedafueradenuestrocontrolestaoperaciónserealizacomprobandoelvalordegood.
La codificación de este ejercicio se encuentra en la página Web del libro.
16.2. Unavezqueseconoceelfuncionamientodeloper adordeextracción >> paralaclase cout, esmuysencillosuusopar a
cualquierobjetodelaclase fstream, yaquesufuncionamientoeselmismo.Elarchivoabiertocontienenúmerosenteros,
peroalserunarchivodetextoesosnúmerosestánalmacenadosnodeformabinariasinocomounacadenadecar acteres
querepresentanlosdígitosyelsignodelnúmeroenformadesecuenciadesuscódigosASCIIbinarios.Estonoquieredecirquehayaqueleerlíneaalíneayencadaunadeellascon vertirlassecuenciasdecódigosdecar acteresalosnúmeros
enterosenbinariocorrespondiente, paraalmacenarlosasíenlamemoria.Estetrabajoeselquerealizaeloperadordeextracción>> cuandotieneunavariabledetipoenteroensupartederecha.Eslamismaoperacióndeconversiónquereali-
CAPÍTULO 16 Flujos y archivos
321
zaeloperadordeextraccióncuandoleesecuenciasdecódigosdeteclasdesdelaentradaestándar.Elprogramautilizados
contadoresparacontarlospositivosyne gativosyunavariablepar aleereldatodelar chivo.Elprogramavisualizaademáselarchivo.
La codificación de este ejercicio se encuentra en la página Web del libro.
16.3. Sedefineunobjetoar chivodeclase fstream quepuedeserabiertopar aleeropar aescribirenmodobinario.Seleeel
textodelapantallacarácteracarácter(elf inaldeltextodeentradavienedadopor control+z), yseescribeenelar chivobinariotambiéncarácteracarácter.Posteriormente, locierraelarchivobinario, sevuelveaabrirenmodolectura, para
leerlobyteabyteypresentarloenpantalla.
La codificación de este ejercicio se encuentra en la página Web del libro.
16.4. Observarqueladiferenciaexternaalusarunarchivobinarioyotrodetextoestásolamenteenelargumentoqueindicael
mododeapertura, porquelasoperacionesdelecturayescrituraseocupandeleeroescribirlamismavariablese gúnel
diferenteformato: enelarchivodetextobyteabytecon virtiéndoloasucódigo ASCIIyenelar chivobinariosevuelvea
escribirdelamemoriasinrealizarningunatransformación.Enelprogramacodificadosiseproduceunerrorenlaaperturadeunodelosdosar chivo, seretornaelcontrolalsistemaoperativo.
La codificación de este ejercicio se encuentra en la página Web del libro.
SOLUCIÓN DE LOS PROBLEMAS
16.1. Laorganizacióndeunar chivodetipote xtoeslasiguiente: unaseriedecadenasdecar acteresalmacenadassecuencialmenteyseparadasporcaracteresfinaldelíneaysaltodecarro, quecuandoseleenenmemoriaseconviertenencadenas
terminadasen '\0', comotodaslascadenasdellenguajeC++.Loscar acteresestánalmacenadosenunbytecuyocontenidoeselcódigoASCIIcorrespondiente.Lasfuncionesdeentradaysalida, esdecir, delecturayescrituraenarchivosde
modotextosondedostipos, oleenyescribenbyteabyte, carácteracarácter, oleenyescribenlíneaalínea.Enesteprogramaseleecadalíneadeunar chivodetextoenlavariabledetipocadena linea ybuscarenellalaocurrenciadeuna
subcadenaquesedenomina cadena_a_buscar, recibidaen arg[1], paralocualseutilizalafunciónestándardeC++
strstr detr atamientodecadenas.Elnombr edelar chivoesr ecibidoenelse gundoparámetrodelafunción main()
arg[2].
La codificación de este problema se encuentra en la página Web del libro.
16.2. Losdatosquehayquealmacenarsondefinidosporelusuarioporloquedebenserestructuras.Esdecir, debenserdetipo
struct;unadeellasdebedef inirelregistrodeentrenamiento, ylaotraelregistrodelpulsómentro.Seusaunarchivobinariof paraalmacenarlosdatos, porloquecomonosetieneningunamar caparadistinguirlainformaciónalmacenada
enellossonlosprogramaslosquedebenleerconlasmismasestructur asconqueseescribieron.Enestecaso, seescribe
enprimerlugarlaestructur adelr egistrodel entrenamiento y, posteriormente, enunb ucle for lasestructurasquealmacenanlosdistintosregistrosdelpulsómetro.Lalecturadelosdatosdelarchivo, esrealizadadelamismaformaqueha
sidocreadoparaquelosdatostenganelsentidoconelqueinicialmentefuer onescritos.
La codificación de este ejercicio se encuentra en la página Web del libro.
CAPÍTULO 16 Flujos y archivos
322
PROBLEMAS PROPUESTOS
16.1. Sequiereobtenerunaestadísticadeunarchi vodecaracteres.Escribirunprogramaparacontarelnúmerode
palabrasdequeconstaunarchi vo, asícomounaestadísticadecadalongituddepalabra .
16.2. Escribirunprogramaquevisualiceporpantallalaslíneasdete xtodeunarchi vo, numerandocadalíneadel
mismo.
16.3. Escribirunprogramaparalistarelcontenidodeundeterminadosubdirectorio, pasadocomoparámetroala
funciónmain( ).
16.4. Escribirunprogramaquegestioneunabasededatos
conlosregistrosdeunaagendadedireccionesyteléfonos.Cadaregistrodebetenerdatossobreelnombre, la
dirección, elteléfonofijo, elteléfonomóvil(celular), la
direccióndecorreoelectrónicodeunapersona.Elprogramadebemostrarunmenúparapoderañadirnue vas
entradas, modificar, borrarybuscarregistrosdepersonasapartirdelnombre.
16.5. Mezclardosarchi vosordenadosparaproducirotroarchivoordenadoconsisteenirle yendounre gistrode
cadaunodeellosyescribirenotroarchi vodesalidael
queseamenordelosdos, repitiendolaoperaciónconel
registronoescritoyotroleídodelotroarchi vo, hasta
quetodoslosre gistrosdelosdosarchi voshayansido
leídosyescritosenelarchi vodesalida.Éstetendráal
finallosregistrodelosdosarchivosdeentradaperoordenados.Suponerquelaestructuradelosre gistroses:
struct articulo
{
long clave;
char nombre [20];
int cantidad;
char origen[10];
};
Elcampo clave eslareferenciaparalaordenaciónde
losregistros.
16.6. Setienequeordenarunarchivocompuestoderegistros
conlasexistenciasdelosartículosdeunalmacén.Elarchivoesdemasiadograndecomoparaleerloenmemoriaenunarraydeestructuras, ordenarelarrayyescribirloalf inal, unavezordenado, eneldisco.Laúnica
maneraesleercadadoscientosre gistros, ordenarlosen
memoriayescribirlosenarchi vosdiferentes.Unav ez
setienentodoslosarchi vosparcialesordenadossev an
mezclando, comoseindicaenelejercicioanterior , sucesivamentehastatenerunarchi vocontodoslosre gistrosdeloriginal, peroordenados.Utilizarlaestructura
delejercicioanterior.
16.7. Unprofesortiene30estudiantesycadaestudiantetiene
trescalificacionesenelprimerparcial. Almacenarlos
datosenunarchivo, dejandoespacioparadosnotasmás
ylanotafinal.Incluirunmenúdeopciones, paraañadir
másestudiantes, visualizardatosdeunestudiante, introducirnuevasnotasycalcularlanotaf inalcomomediadelrestodelascalif icaciones.
16.8. Enunarchivodetextoseconservalasalidadelastransaccionesconlosproveedoresdeunacadenadetienda.
Sehaperdidoellistadooriginaldeproveedoresysedeseareconstruirapartirdelarchi vodetransacciones.Se
sabequecadalíneadelarchi vocomienzaconelnombredelproveedor.Sepideescribirunprogramaquelea
elarchivodetransacciones, obtengaelnombredelproveedorconloscaractereshastaelprimerespacioen
blancoymuestreunalistacontodoslosproveedoresdiferentesconlosquesetrabajaenlastiendas.
16.9. Unavezobtenidadelejercicioanteriorlalistadeproveedoresdesdeelarchivodetransacciones, sedeseasaberconquéproveedoressehatrabajadomás.P araello
sesabequeenelarchi vodete xtoseapuntabaencada
línealacantidadpagadaencadaoperación.Evidentemente, comohayv ariastransaccionesconunmismo
proveedoresnecesarioacumularlastodasparasaberel
montototaldelastransaccionesporproveedor.Unavez
quesetieneestacantidadhayqueescribirlaenunarchivodeproveedoresordenadosdescendentementepor
lacantidadtotalpagada.
16.10. Sequiereescribirunacartadefelicitaciónna videñaa
losempleadosdeuncentrosanitario.Eltextodelacartaseencuentraenelarchi vo CARTA.TXT.Elnombrey
direccióndelosempleadosseencuentraenelarchi vo
binario EMPLA.DAT, comounasecuenciadere gistros
conloscamposnombreydirección.Escribirunprogramaquegenereunarchi vodetextoporcadaempleado,
laprimeralíneacontienenelnombre, lasegundaestáen
blanco, latercera, ladirecciónyenlaquintaempiezael
textoCARTA.TXT.
CAPÍTULO 17
Listas enlazadas
Introducción
Enestecapítulosecomienzaelestudiodelasestructurasdedatosdinámicas. Alcontrarioquelasestructurasdedatosestáti cas(arrays —listas, vectoresytablas—y estructuras)enlasquesutamañoenmemoriaseestablecedurantelacompilación
ypermaneceinalterabledurantelaejecucióndelprograma, lasestructurasdedatosdinámicascrecenysecontraenamedida
queseejecutaelprograma.
Laestructuradedatosqueseestudiaráenestecapítuloeslalista enlazada (ligada oencadenada, “linkedlist”)queesuna
coleccióndeelementos(denominadosnodos)dispuestosunoacontinuacióndeotro, cadaunodeellosconectadoalsiguiente
elementoporun“enlace” o“puntero”.Laslistasenlazadassonestructurasmuyfle xiblesyconnumerosasaplicacionesenel
mundodelaprogramación.
17.1. Fundamentos teóricos
Unalista esunasecuenciade0omáselementos, deuntipodedatodeterminadoalmacenadosenmemoria.Sonestructuras
lineales, dondecadaelementodelalista, exceptoelprimero, tieneunúnicopredecesorycadaelementodelalista, exceptoel
último, tieneunúnicosucesor.Elnúmerodeelementosdeunalistasellamalongitud.Siunalistatiene0elementossedenominalistavacía.Esposibleconsiderardistintostiposdelistas, contiguasyenlazadas:
Contiguas. Loselementossonadyacentesenlamemoriadelacomputadoraytienenunoslímites, izquierdoyderecho, que
nopuedenserrebasadoscuandoseañadeunnue voelemento.Seimplementanatra vésdearrays.Lainserciónoeliminación
deunelementoenlalistasueleimplicarlatraslacióndeotroselementosdelamisma.
Enlazadas. Loselementossealmacenanenposicionesdememoriaquenosoncontiguasoadyacentes, porloquecadaelementonecesitaalmacenarlaposiciónodireccióndelsiguienteelementodelalista.Sonmuchomásfle xiblesypotentesque
laslistascontiguas.Lainserciónosupresióndeunelementodelalistanorequiereeldesplazamientodeotroselementosde
lamisma.Graciasalaasignacióndinámicadevariables, sepuedenimplementarlistasdemodoquelamemoriafísicautilizadasecorrespondaconelnúmerodeelementosdelatabla.P araelloserecurrealos punteros (apuntadores).Unalista enlazada esunasecuenciadeelementosdispuestosunodetrásdeotro, enlaquecadaelementoseconectaalsiguienteelemento
porun“enlace” o“puntero”.Laideaconsisteenconstruirunalistacuyoselementosllamadosnodos secomponendedospartesocampos: laprimeraparteocampocontienelainformaciónyes, porconsiguiente, unvalordeuntipogenérico(denominado Dato, TipoElemento, Info, etc.)ylase gundaparteo campo esunpuntero(denominado enlace osgt, sig, Sig, etc.)que
323
CAPÍTULO 17 Listas enlazadas
324
apuntaalsiguienteelementodelalista.Larepresentacióngráf icaeslasiguiente.Losenlacesserepresentanporflechaspar a
facilitarlacomprensióndelacone xiónentredosnodos.
e1
e2
e3
en
...
Figura 17.1. Lista enlazada (representación gráfica típica).
Elnodoúltimohadeserrepresentadodeformadiferenteparasignif icarqueestenodonoseenlazaaningúnotro.
en
en
NULL
Figura 17.2. Diferentes representaciones gráficas del nodo último.
17.2. Clasificación de las listas enlazadas
Laslistassepuedendividirencuatrocategorías:
• Listas simplemente enlazadas.Cadanodo(elemento)contieneunúnicoenlacequeconectaesenodoalnodosiguienteonodosucesor.
• Listas doblemente enlazadas.Cadanodocontienedosenlaces, unoasunodopredecesoryelotroasunodosucesor .
Surecorridopuederealizarsetantodefrenteaf inalcomodefinalafrente.
• Lista circular simplemente enlazada.Esunamodificacióndelalistaenlazadaenlacualelpunterodelúltimoelemento
apuntaalprimerodelalista.
• Lista circular doblemente enlazada .Unalistadoblementeenlazadaenlaqueelúltimoelementoseenlazaalprimer
elementoyviceversa.
Porcadaunodeestoscuatrotiposdeestructurasdelistas, sepuedeelegirunaimplementaciónbasadaenarraysounaimplementaciónbasadaenpunteros.
EJEMPLO 17.1. Listaenlazadaimplementadaconpunter osyconarr aysalaqueseleañadeunprimerelemento.
Implementación con punteros:
A
C
M
G
P
elemento a insertar
Implementación con arrays:
inicio = 3
elemento a insertar
P
Antes del “A”, es decir
antes del primero de
la lista
1
Info
Sig
C
4
inicio = 2
2
3
A
1
4
M
6
5
6
Nuevo elemento
Info
Sig
1
C
4
2
P
3
3
A
1
4
M
6
G
0
5
G
0
6
CAPÍTULO 17 Listas enlazadas
325
Comosepuedeobservar, tantocuandoseimplementaconpunteroscomocuandosehaceatra vésdearrays, lainsercióndeunnuevoelementonorequiereeldesplazamientodelosquelesiguen.P araobservarlaanalogíaentreambas
implementacionessepuederecurrirarepresentarlaimplementaciónconarraysdelasiguienteforma:
2
P
3
A
1
C
4
M
6
G
0
17.3. Operaciones en listas enlazadas
Lasoperacionessobrelistasenlazadasmásusualesson: Declaracióndelostiposnodo, punteroanodoyclasenodo ;Declaracióndeclaselista, inicializaciónocreación;insertarelementosenunalista;b uscarelementosdeunalista;eliminarelementosdeunalista;recorrerunalistaenlazada;comprobarsilalistaestávacía.
17.3.1. DECLARACIÓN DE LOS TIPOS NODO Y PUNTERO A NODO Y CLASE NODO
EnC++, sepuededefinirunnuevotipodedatoporunnodomediantelaspalabrasreserv adas struct o class quecontiene
lasdospartescitadas.
struct Nodo
{
int dato;
Nodo * enlace;
};
class Nodo {
public:
int dato;
Nodo *enlace;
// constructor
};
EJEMPLO 17.2. DeclaracióndeunnodoenC++.
EnC++, sepuededeclararunnue votipodedatoporunnodomediantelapalabrareserv ada class delasiguiente
forma:
class Nodo
{
public:
int info;
Nodo* sig:
};
typedef class Nodo
{
public:
int info;
Nodo *sig;
}NODO;
typedef double Elemento
class Nodo
{
public:
Elemento info;
Nodo *sig;
};
EJEMPLO 17.3. Declaracióneimplementacióndelaclasenodo quecontieneunainformacióndetipoelementoyel
siguientedetipopunteroa nodo.
Laclase Nodo tienedosatrib utosprotegidosquesonelelemento e, y Sig queesunpunteroalapropiaclase Nodo.
Ambosatributossirvenparaalmacenarlainformacióndelnodo, yladireccióndelsiguientenodo.Sedeclarancomo
funcionesmiembrotresconstructores.Estosconstructoresson: elconstructorpordefecto;elconstructorqueinicializaelatributox delNodo alvalordex, yponeelatributoSig aNULL;elconstructor, queinicializalosdosatributosdel
Nodo.Lasfuncionesmiembroencargadasde Obtener y Poner tanto elelemento e comoelpuntero Sig son: Telemento OE(); void PE(Telemento e); Nodo * OSig(); yvoid PSig(Nodo *p);.Porúltimo, lafunciónmiembro
destructor, sedeclarapordefecto.Eltipoelementodelaclase Nodo esunentero, peroalestardef inidoenun typedef, puedecambiarsedeunaformasencillayrápidaparaquealmacenecualquierotrotipodeinformación.
#include <cstdlib>
#include <iostream>
using namespace std;
CAPÍTULO 17 Listas enlazadas
326
typedef int Telemento;
class Nodo
{
protected:
Telemento e;
Nodo *Sig;
public:
Nodo(){}
Nodo (Telemento x);
Nodo(Telemento x, Nodo* s);
~Nodo(){}
Telemento OE();
void PE(Telemento e);
Nodo * OSig();
void PSig( Nodo *p);
};
Nodo::Nodo(Telemento x)
{
e = x;
Sig = NULL;
}
// constructor vacío
// constructor
// Constructor
// destructor por defecto
// Obtener elemento
// Poner elemento
// Obtener siguiente
// Poner siguiente
// constructor que inicializa e a x y Sig a Null
Nodo(Telemento x, Nodo* s)
{
e = x;
Sig = s;
}
Telemento Nodo::OE()
{
return e;
}
// constructor que inicializa e a x y Sig a s
//
void Nodo::PE(Telemento x)
{
e = x;
}
Nodo* Nodo::OSig()
{
return Sig;
}
void Nodo:: PSig(Nodo *p)
{
Sig = p;
}
obtiene una copia del atributo e
// pone el atributo e a x
//
obtiene una copia del atributo Sig
// Pone el atributo Sig a p
Puntero de cabecera y cola. Unpunteroalprimernododeunalistasellama puntero cabeza (Nodo *ptr _cabeza;).En
ocasiones, semantienetambiénunpunteroalúltimonododeunalistaenlazada.Elúltimonodoeslacola delalista, yunpunteroalúltimonodoesel puntero cola (Nodo *ptr_cola;).Cadapunteroaunnododebeserdeclaradocomounav ariable
puntero.
CAPÍTULO 17 Listas enlazadas
327
23.5
40.7
21.7
ptr_cabeza
ptr_cola
El Puntero nulo. LapalabraNULL representaelpuntero nulo NULL, queesunaconstantedelabibliotecaestándarstdlib.h
deC.Estepunteroseusa: enelcampo Sig delnodofinaldeunalistaenlazada;enunalistav acía.
4.15
5.25
71.5
10.5
null
ptr_cabeza
El operador -> de selección de un miembro. Sip esunpunteroaunaestructuray m esunmiembrodelaestructura, entonces p -> m accedealmiembro m delaestructuraapuntadapor P.Elsímbolo“ ->” esunoperadorsimple.Sedenomina operadordeseleccióndecomponente .
P -> m
significalomismoque (*p).m
17.3.2. DECLARACIÓN DE CLASE LISTA, INICIALIZACIÓN O CREACIÓN
Laclaselistasedeclaracomounaclasequecontieneunsoloatrib utoprotegidop queesunpunteroalaclase Nodo (Agregaciónlógica).Comomiembrosdelaclaselista, sedeclaranelconstructor , eldestructorydosfuncionesmiembrosparaobteneryponerelpunteroalalista.
EJEMPLO 17.4. Claselistasimpleconconstructor, destructor, yfuncionesmiembroparaponeryobtenerelpunteroalprimernododelalista.
#include <cstdlib>
#include <iostream>
using namespace std;
class ListaS
{
protected:
Nodo *p;
public:
ListaS();
~ListaS();
Nodo * Op();
void Pp( Nodo *p1);
};
ListaS::ListaS()
{
p = NULL;
}
ListaS::~ListaS(){};
//clase lista simplemente enlazada
// constructor
// destructor
// Obtener el puntero
// Poner el puntero
// otras funciones miembro
//......
CAPÍTULO 17 Listas enlazadas
328
Nodo * ListaS:: Op()
{
return p;
}
void ListaS:: Pp( Nodo *p1)
{
p = p1;
}
int main(int argc, char *argv[])
{
ListaS l1;
......
system("PAUSE");
return EXIT_SUCCESS;
}
17.3.3. INSERTAR ELEMENTOS EN UNA LISTA
Elalgoritmoempleadoparaañadiroinsertarunelementoenunalistaenlazadavaríadependiendodelaposiciónenquesedeseainsertarelelemento.Laposicióndeinserciónpuedeser: enlacabezadeunalista;noenlacabezadelista;alf inaldela
listaqueesuncasoparticulardelainserciónnoenlacabezadelalista.
Elprocesodeinserciónsepuederesumirenestealgoritmo:
• Asignarunnuevonodoaunpuntero aux queapuntealnuevonodoquesevaainsertarenlalista, ysituarelnuevoelementoenatributoe delnuevonodo.
• Hacerqueelcampoenlace Sig delnuevonodoapuntealprimernododelalistaapuntadopor p.
• Hacerqueelpuntero p queapuntaalprimerelementodelalistaapuntealnue vonodoquesehacreado aux.
EJEMPLO 17.5. Funciónmiembrodelaclase ListaS queañadeunnuevoelemento e alalista.
SesuponelasdeclaracionesdelosEjemplos17.3y17.4delasclases Nodo y ListaS.Enlazonapúblicadelaclase
sedebeincluirelprototipodelafunciónmiembro.
ListaS
void AnadePL(Telemento e);
void ListaS::AnadePL(Telemento e)
{
Nodo *aux;
aux = new Nodo(e);
aux->PSig(p);
p = aux;
}
// prototipo dentro de la clase ListaS
// código
// reserva de memoria, y asigna e
// poner p en el siguiente de aux
//Pp(aux); poner p a aux
Inserción de un nuevo nodo que no está en la cabeza de lista
Sepuedeinsertarenelcentrooalf inaldelalista.Elalgoritmodelanue vaoperacióninsertarrequierelospasossiguiente s:
• Asignarmemoriaalnuevonodoapuntadoporelpuntero insertar_ptr, ysituarelnuevoelementox comoatributodel
nuevonodo.
• Hacerqueelcampoenlace Sig delnuevonodo insertar_ptr apuntealnodoquevadespuésdelaposicióndelnue vo
nodo.
CAPÍTULO 17 Listas enlazadas
329
• Enlavariablepuntero anterior_ptr hayquetenerladireccióndelnodoqueestáantesdelaposicióndeseada(siempreexiste)paraelnue vonodo.Hacerque anterior_ptr->OSig() apuntealnue vonodoqueseacabadecrear insertar_ptr.
Inserción al final de la lista
Lainserciónalf inaldelalistaesuncasoparticulardelaanterior .Laúnicadiferenciaesqueelatrib uto Sig denuevonodo
apuntadoporelpuntero insertar_ptr siempreapuntaa NULL.
EJEMPLO 17.6. Segmentodecódigoqueañadeunnue voelemento e alalista, entrelasposiciones anterior_ptr
ypos.(Si pos esNULL, eselúltimodelalista.)
Sesuponedeclaradalaclase Nodo, yquepreviamente, sehacolocadoelpunteroa Nodo aux apuntadoalnodoanteriordondehayquecolocarlo(sesuponequealnoserelprimero, siempreexiste), yelpunteroa Nodo pos apuntando
alnodoquevadespués.
Nodo *anterior_ptr, *pos, *insertar_ptr;
// búsqueda omitida.
insertar_ptr = new Nodo(x);
insertar_ptr->PSig(pos);
anterior_ptr->PSig(aux);
EJEMPLO 17.7. Insertarunnuevoelemento35entreelelemento75yelelemento40enlalistaenlazada10, 25, 40.
ElsiguientegráficomuestraunseguimientodelcódigodelEjemplo17.6.
10
25
40
NULL
75
anterior_ptr
10
25
40
NULL
insertar_ptr = new Nodo (x);
no se utiliza
cabeza_ptr
75
insertar_ptr
anterior_ptr
10
insertar_ptr->PSig(pos);
anterior_ptr->PSig(aux);
25
75
insertar_ptr
40
NULL
CAPÍTULO 17 Listas enlazadas
330
17.3.4. BUSCAR ELEMENTOS DE UNA LISTA
DadoqueunafunciónenC++puededevolverunpuntero, elalgoritmoquesirvaparalocalizarunelementoenunalistaenlazadapuededevolverunpunteroaeseelemento.
5.75
41.25
101.43
0.25
NULL
EJEMPLO 17.8. Búsquedadeunelementoenunalistaenlazadaimplementadaconclases.
Lafunciónmiembro Buscar retornaunpunteroalnodoquecontienelaprimeraaparicióndeldato x, enlalistaenel
casodequeseencuentre, y NULL enotrocaso.Seusaunpunteroalnodo pos queseinicializaconelprimerpuntero
delalista p.Unbucle while, itera, mientrasquedendatosenlalistaynohayaencontradoelelementoqueseb usca.
Seincluye, además, lafunciónmiembroBuscar1, querealizalamismabúsquedasinutilizarinterruptorenc delabúsquedayconunbuclefor.
Nodo * ListaS::Buscar(Telemento x)
{
Nodo *pos = p;
bool enc = false;
while (!enc && pos)
if (pos->OE() != x)
pos = pos->OSig();
else enc = true;
if (enc)// Encontrado
return pos;
else
return NULL;
// es equivalente a poner return pos
}
Nodo* ListaS::Buscar1(Telemento x)
{
Nodo *pos = p;
for (; pos != NULL; pos = pos->OSig())
if (x == pos-> OE())
return pos;
return NULL;
}
EJEMPLO 17.9. FunciónmiembrodelaclaseListaS queañadeelelementox enlaposiciónposi querecibecomo
parámetro.
Serealizaunabúsquedaenlalistaenlazada, quedándoseademásdeconlaposición pos, conunpunteroalnodoanteriorant.Elbuclequerealizalabúsquedallevauncontadorquevacontandoelnúmerodeelementosqueserecorren,
paraquecuandoselle gueallímite pos, poderterminarlabúsqueda.Alahoradeañadirelnodoalalista, seobserva
lasdosposibilidadese xistentesenlainserciónenunalistaenlazada: primerodelalistaonoprimero(incluyealúltimo).
void ListaS::AnadeposL(Telemento x, int posi)
{
Nodo *ant = NULL, *pos = p, *aux = new Nodo(x);
int c = 0;
// contador de nodos de la lista
CAPÍTULO 17 Listas enlazadas
331
while (pos && c < posi)
{
ant = pos;
pos = pos->OSig();
c++;
}
if(c < posi)
// se va a insertar aunque no tenga menos elementos
{
aux->PSig(pos);
if( ant )
// centro o final de la lista
ant->PSig(aux);
else p = aux;
// primero de la lista.
}
}
17.3.5. ELIMINAR ELEMENTOS DE UNA LISTA
Elalgoritmoparaeliminarunnodoquecontieneundatosepuedee xpresarenestospasos:
• Buscarelnodoquecontieneeldatoyqueestéapuntadoporpos.Hayquetenerladireccióndelnodoaeliminaryladel
inmediatamenteanterior ant.
• Elpuntero Sig delnodoanterior ant hadeapuntaral Sig delnodoaeliminar.
• Sielnodoaeliminareselprimerodelalistasemodif icaelatributo p delaclaselistaqueapuntaalprimeroparaque
tengaladireccióndelnodo Sig delnodoaeliminar pos.
• Seliberalamemoriaocupadaporelnodo pos.
EJEMPLO 17.10. Eliminacióndeunnododeunalistaimplementadaconunclase ListaS.
Elcódigoquesepresenta, correspondealafunciónmiembro Borrar delaclase ListaS implementadaenejemplos
anteriores.void ListaS::Borrar(Telemento x)
{
Nodo *ant = NULL, *pos =p;
// búsqueda del nodo a borrar
......
// se va a borrar el nodo apuntado por pos
if(ant != NULL)
ant->PSig(pos->OSig());
else
p = pos->OSig();
pos->PSig(NULL);
delete pos;
// no es el primero
// es el primero
}
EJEMPLO 17.11. Funciónmiembrodelaclase ListaS queeliminalaprimeraaparicióndelelemento x delalista
siesqueseencuentra.
Primero, serealizalabúsquedadelaprimeraaparicióndelelemento x, quedándose, además, conunpuntero ant que
apuntaalnodoinmediatamenteanterior, encasodequeexista.Sisehaencontradoelelementoaborrarenlaposición
pos, sediferencianlasdosposibilidadesquehayenelborradoenunalistaenlazadasimple.Serelprimerelemento,
encuyocasoelpunteroanteriorapuntaa NULL, onoserlo.Sielelementoaborrareselprimerodelalista, hayque
moverelprimerpunterodelalista p alnodosiguientede p.Enotrocaso, hayqueponerelpunterosiguientedelnodo
anteriorenelpunterosiguientedelaposicióndondeseencuentre.
CAPÍTULO 17 Listas enlazadas
332
void ListaS::BorrarL(Telemento x)
{
Nodo *ant = NULL, *pos=p;
bool enc = false;
while (! enc && pos)
if (pos->OE()!= x)
{
ant = pos;
pos = pos->OSig();
}
else enc =true;
//búsqueda
if (enc)
{
if (ant)
ant->PSig(pos->OSig());
else
p= p->OSig();
pos->PSig(NULL);
delete pos;
}
// borrar la primera aparición
// no primero
// borrado del primero
}
17.4. Lista doblemente enlazada
Enunalista doblemente enlazada, cadaelementocontienedospunteros, apartedelvaloralmacenadoenelelemento;unpunteroapuntaalderechoosiguienteelementodelalista(sig)yelotropunteroapuntaalizquierdooelementoanteriordelalista(ant).LaFigura17.1muestraunalistadoblementeenlazadacircularyunnododedichalista.
cabeza
a)
Izquierdo
Dato
Derecho
b)
Figura 17.1. Lista doblemente enlazada circular y nodo.
Existeunaoperaciónde insertar yeliminar (borrar)encadadirección.
D
I
I
D
Inserción de un nodo en una lista dob lemente enlazada.
CAPÍTULO 17 Listas enlazadas
333
D
I
D
I
Eliminación de un nodo en una lista dob lemente enlazada.
EJEMPLO 17.12. Declaracióneimplementacióndelaclase NodoD quecontieneunainformacióndetipoelemento
yelsiguienteyelanteriordetipopunter oa NodoD.
Laclase NodoD esmuysimilaralaclase Nodo delEjemplo17.2.Dehecho, coincidecompletamente, exceptoenque
seañadeunnuevoatributoAnt, comounpunteroal NodoD ydosfuncionesmiembrosparaponerelanterioryobtener
elanterior.Hayquetenerencuenta, además, quesehacambiadoelnombredelnodo, porloquecambia Nodo por
NodoD.
#include <cstdlib>
#include <iostream>
using namespace std;
typedef int Telemento;
class NodoD {
protected:
Telemento e;
NodoD *Sig, *Ant ;
public:
NodoD (Telemento x);
Telemento OE();
void PE(Telemento e);
NodoD * OSig();
void PSig( NodoD *p);
NodoD * OAnt();
void PAnt( NodoD *p);
~NodoD(){};
NodoD(){}
};
NodoD::NodoD(Telemento x)
{
e = x;
Sig = NULL;
Ant = NULL;}
Telemento NodoD::OE()
{
return e;
}
void NodoD::PE(Telemento x)
{
e = x;
}
NodoD* NodoD::OSig()
{
// constructor
// Obtener elemento
// poner elemento
// Obtener siguiente
// poner siguiente
// Obtener anterior
// poner anterior
CAPÍTULO 17 Listas enlazadas
334
return Sig;
}
void NodoD:: PSig(NodoD *p)
{
Sig = p;
}
NodoD* NodoD::OAnt()
{
return Ant;
}
void NodoD:: PAnt(NodoD *p)
{
Ant = p;
}
EJEMPLO 17.13. Claselistadoblementeenlazadaconconstructor, destructor, yfuncionesmiembroparaponeryobtenerelpunteroalprimernododelalista.
class ListaD
//clase lista doblemente enlazada
{
protected:
NodoD *p;
// puntero al primer nodo protegido
public:
ListaD(){p = NULL;}
//constructor
NodoD *Op() { return p;}
//Obtener el puntero
void Pp(NodoD * p1) {p = p1;}
//Poner el puntero
~ListaD(){};
//destructor
};
17.4.1. INSERCIÓN DE UN ELEMENTO EN UNA LISTA DOBLEMENTE ENLAZADA
Elalgoritmoempleadoparaañadiroinsertarunelementoenunalistadoblevaríadependiendodelaposiciónenquesedesea
insertarelelemento.Laposicióndeinserciónpuedeser: enlacabeza(elementoprimero)delalista;enelfinaldelalista(elementoúltimo);antesdeunelementoespecif icado, obiendespuésdeunelementoespecif icado.
Inserción de un nuevo elemento en la cabeza de una lista doble
Elprocesodeinserciónsepuederesumirenestealgoritmo:
• Asignarmemoriaaunnuevonodoapuntadopor nuevo queesunavariablepunterolocalqueapuntaalnuevonodoque
sevaainsertarenlalistadobleysituarenelnodo nuevo elelemento e quesevaainsertardelnuevonodo nuevo.
• Hacerqueelcampoenlace Sig delnuevonodo nuevo apuntealacabeza(primernodo p)delalistaoriginal, yqueel
campoenlace Ant delnodocabeza p apuntealnue vonodo nuevo siesquee xiste.Encasodequenoe xistanohacer
nada.
• Hacerquecabeza(punterodelalista p)apuntealnuevonodoquesehacreado.
EJEMPLO 17.14. Funciónmiembrodelaclase ListaD queañadeunnue voelementoalalistadoblecomoprimer
elemento.
void ListaD::InsertaP(Telemento e)
{
NodoD *nuevo = new Nodo(el);
CAPÍTULO 17 Listas enlazadas
nuevo->Psig(p);
if(p)
p->Pant(nuevo);
p = nuevo;
335
// si existe p que apunte a un nodo
}
Inserción de un nuevo nodo que no está en la cabeza de lista
Lainsercióndeunnuevonodoenunalistadoblementeenlazadasepuederealizarenunnodointermediooalf inaldeella.El
algoritmodelanuevaoperacióninsertarrequiere lassiguientesetapas:
• Buscarlaposicióndondehayqueinsertareldato, dejandolospunterosa NodoD: ant apuntandoalnodoinmediatamenteanterior(siempreexiste), ypos alquedebeserelsiguienteencasodequeexista(NULL encasodequenoexista).
• Asignarmemoriaalnue vonodoapuntadoporelpuntero nuevo, ysituarelnue voelemento e comoatributodelnuevo
nodonuevo.
• Hacerqueelatrib uto Sig delnuevonodo nuevo apuntealnodo pos quevadespuésdelaposicióndelnue vonodo
ptrnodo (obienaNULL encasodequenohayaningúnnododespuésdelanuevaposición).ElatributoAnt delnodosiguienteptrnodo alqueocupalaposicióndelnuevonodo nuevo quees pos, tienequeapuntara nuevo siesqueexiste.
Encasodequenoe xistanohacernada.
• Hacerqueelatrib uto Sig delpuntero ant apuntealnuevonodo nuevo.Elatributo Ant delnuevonodo nuevo ponerlo
apuntandoa ant.
EJEMPLO 17.15. Segmentodecódigodeunafunciónmiembr odelaclase ListaD queañadeunnuevoelementoa
lalistadobleenunaposiciónquenoeslaprimer a.
void ListaD::InsertaListadoble(Telemento e)
{
NodoD *nuevo, *ant=NULL, *pos=p;
// búsqueda de la posición donde colocar el dato e
// se sabe que no es el primero de la lista doble
aux = new NodoD(x);
if (!pos)
{
ant->PSig(nuevo);
nuevo->PAnt(ant);
}
else
{
nuevo->PSig(pos);
nuevo->PAnt(ant);
ant->PSig(nuevo);
pos->PAnt(nuevo);
}
//último y no primero
//no primero y no último
}
17.4.2. ELIMINACIÓN DE UN ELEMENTO EN UNA LISTA DOBLEMENTE ENLAZADA
Elalgoritmoparaeliminarunnodoquecontieneundatoessimilaralalgoritmodeborradoparaunalistasimple.Ahoraladireccióndelnodoanteriorseencuentraenelpuntero ant delnodoaborrar.Lospasosaseguirson:
• Búsquedadelnodoquecontieneeldato.Sehadetenerladireccióndelnodoaeliminaryladireccióndelanterior(ant).
• ElatributoSig delnodoanterior( ant)tienequeapuntaralatributoSig delnodoaeliminar, pos (estoenelcasodeno
serelnodoprimerodelalista).Encasodequeseaelprimerodelalistaelatrib uto p delalistadebeapuntaralatrib utoSig delnodoaeliminar pos.
CAPÍTULO 17 Listas enlazadas
336
• Elatributo Ant delnodosiguienteaborrartienequeapuntaralatrib uto Ant delnodoaeliminar , estoenelcasodeno
serelnodoultimo.Enelcasodequeelpunteroaeliminarseaelúltimonohacernada
• Porúltimo, seliberalamemoriaocupadaporelnodoaeliminar pos.
EJEMPLO 17.16. SegmentodecódigodeunafunciónmiembrodelaclaseListaD queborraunelementoenunalistadoblementeenlazada.
void ListaD::Borrarelemento(Telemento x)
{
NodoD *ant = NULL, *pos = p;
if(!ant && ! pos->OSig())
{
p = NULL;
}
else if (!ant)
{
pos->OSig()->PAnt(NULL);
p = pos->OSig();
pos->PSig(NULL);
}
else if (!pos->OSig())
{
ant->PSig(NULL);
pos->PAnt(NULL);
}
else
{
ant->PSig(pos->OSig());
pos->OSig()->PAnt(ant);
pos->PAnt(NULL);
pos->PSig(NULL);
}
delete pos;
// búsqueda del nodo a borrar omitida
// NodoD a borrar en pos
// es el primero y último
//la lista doble se queda vacía
// primero y no último
//ultimo y no primero
// no primero y no último
}
17.5. Listas circulares
Enlaslistaslinealessimplesoenlasdoblessiemprehayunprimernodoyunúltimonodoquetieneelatrib utodeenlacea
nulo(NULL).Unalistacircular, porpropianaturalezanotieneniprincipionif in.Sinembargo, resultaútilestablecerunnodo
apartirdelcualseaccedaalalistayasípoderaccederasusnodosinsertar , borraretc.
–4.
5.0
Lc
Lista circular
7.5
1.5
CAPÍTULO 17 Listas enlazadas
337
Inserción de un elemento en una lista cir cular. Elalgoritmoempleadoparaañadiroinsertarunelementoenunalistacircularvaríadependiendodelaposiciónenquesedeseainsertarelelementoqueinsertaelnodoenlalistacircular.Entodocaso
hayqueseguirlossiguientespasos:
• Asignarmemoriaalnuevonodo nuevo yalmacenarelelementoenelatrib utoe.
• Silalistaestáv acíaenlazarelatributo Sig delnuevonodo nuevo conelpropionuevonodo, nuevo yponerelpuntero
delalistacircularenelnue vonodo nuevo.
• Silalistanoestáv acíasedebedecidirellugardondecolocarelnue vonodo nuevo, quedándoseconladireccióndel
nodoinmediatamenteanterior ant.Enlazarelatrib uto Sig denuevonodo nuevo conelatributo Sig delnodoanterior
ant.EnlazarelatributoSig delnodoanteriorant conelnuevonodonuevo.Sisepretendequeelnuevonodonuevo ya
insertadoseaelprimerodelalistacircular , moverelpunterodelalistacircularalnue vonodo nuevo.Enotrocasono
hacernada.
EJEMPLO 17.17. Segmentodecódigodeunafunciónmiembr odelaclase ListaS queinsertaunelementoenuna
listacircularsimplementeenlazada.
Paraimplementarunalistacircularsimplementeenlazada, sepuedeusarlaclase ListaS, ylaclase Nodo delaslistas
simplementeenlazadas.Elcódigoquesepresentacorrespondeaunafunciónmiembroqueañadeaunalistacircular
simplementeenlazadaunelemento e.
void ListaS::Insertar(Telemento e)
{
Nodo *ant = NULL, nuevo;
// Se busca dónde colocar el elemento x, dejando en ant la posición del
//
nodo inmediatamente anterior si es que existe.
nuevo = new NodoD(e);
if (p == NULL)
//la lista está vacía y sólo contiene el nuevo elemento
{
nuevo->PSig(nuevo);
p = nuevo;
}
else
// lista no vacía, no se inserta como primer elemento.
{
nuevo->PSig (ant);
ant->PSig(nuevo);
}
Eliminación de un elemento en una lista cir cular simplemente enlazada
Elalgoritmoparaeliminarunnododeunalistacirculareselsiguiente:
• Buscarelnodo ptrnodo quecontieneeldatoquedándoseconunpunteroalanterior ant.
• SeenlazaelatributoSig elnodoanteriorant conelatributosiguienteSig delnodoaborrar.Silalistaconteníaunsolo
nodoseponea NULL elatributop delalista.
• Encasodequeelnodoaeliminarseaelreferenciadoporelpunterodeaccesoalalista, p, ycontengamásdeunnodo
semodificap paraquetengalaelatrib utoSig dep (silalistasequedaravacíahacerque p tomeelvalorNULL).
• Porúltimo, seliberalamemoriaocupadaporelnodo.
EJEMPLO 17.18. SegmentodecódigodeunafunciónmiembrodelaclaseListaS queborraunelementoenunalistacircularsimplementeenlazada.
void ListaS::Borrar(Telemento e)
{
Nodo *ant = NULL, ptrnodo =p ;
CAPÍTULO 17 Listas enlazadas
338
// búsqueda del elemento a borrar con éxito que es omitida
ant->Psig(ptrnodo->OS());
if (p == p->OSig())
p = NULL;
else if (ptrnodo == p)
p = ant->Osig();
// la lista se queda vacía
//si es el primero mover p
}
EJERCICIOS
17.1. Escribirunafunciónmiembrodeunaclaselistasimplementeenlazadaquedevuelva“verdadero” siestávacíayfalso“false” enotrocaso;yotrafunciónmiembroquecreeunalistavacía.
17.2. Escribirunafunciónmiembroquedevuelvaelnúmerodenodosdeunalistasimplementeenlazada.
17.3. Escribirunafunciónmiembrodeunaclaselistasimplementeenlazadaqueborr eelprimernodo.
17.4. Escribirunafunciónmiembr odeunaclaselistasimplementeenlazadaquemuestr eloselementosenelor denqueseencuentran.
17.5. Escribirunafunciónmiembrodeunaclaselistasimplementeenlazadaquedevuelvaelprimerelementodelaclaselistasi
esquelotiene.
17.6. Escribirunafunciónmiembrodeunaclaselistadoblementeenlazadaqueañadaunelementocomoprimernododelalista.
17.7. Escribirunafunciónmiembrodeunaclaselistadoblementeenlazadaquede vuelvaelprimerelementodelalista.
17.8. Escribirunafunciónmiembrodeunaclaselistadoblementeenlazadaqueelimineelprimerelementodelalistasiesque
lotiene.
17.9. Escribirunafunciónmiembrodelaclaselistadoblementeenlazadaquedecidasiestávacía.
PROBLEMAS
17.1. Escribirelcódigodeunconstructordecopiadeunaclaselistasimplementeenlazada.
17.2. Escribirelcódigodeundestructorqueeliminetodoslosnodosdeunobjetodelaclaselistasimplementeenlazada.
17.3. Escribirunafunciónmiembrodelaclaselistasimplementeenlazada, queinserteenunalistaenlazadaordenadacrecientemente, unelementox.
17.4. Escribirunafunciónmiembrodeunalistasimplementeenlazada, queeliminetodaslasaparicionesdeunelementoxque
recibacomoparámetro.
17.5. Escribaunmétododelaclaselistasimplementeenlazadaqueelimineunelementoxquer ecibacomoparámetrodeuna
listaenlazadaordenada.
CAPÍTULO 17 Listas enlazadas
339
17.6. Escribirunafunciónmiembr odeunaclaselistasimplementeenlazadaqueor denelalistamo viendosolamentepunteros.
17.7. Escribirunafunciónquenoseamiembr odelaclaselistasimplementeenlazada, querecibacomoparámetrodosobjetos
detipolistaquecontengandoslistasor denadascrecientemente, ylasmezcleenotralistaquerecibacomoparámetro.
17.8. Escribirelcódigodeunconstructordecopiadeunaclaselistadoblementeenlazada.
17.9. Escribirunafunciónmiembrodeunaclaselistadoblementeenlazadaqueinserteunelementoxenlalistayquequedeordenada.
17.10. Escribirunafunciónmiembrodeunaclaselistadoblementeenlazadaqueborr eunelementoxenlalista.
17.11. Escribaunafunciónquenoseamiembr odelaclaselistadoblementeenlazadaquecopieunalistadobleenotr a.
17.12. Escribirunaclaselistasimplementeenlazadacircularquepermita, decidirsilalistaestávacía, vercuáleselprimerode
lalista, añadirunelementocomoprimer odelalista, borrarelprimerelementodelalistayborr arlaprimeraaparición
deunelementoxdelalista.
SOLUCIÓN DE LOS EJERCICIOS1
17.1. Sesuponedeclaradalaclase ListaS, ylaclase Nodo delosEjemplos17.3y17.4.Enestecasolacodif icacióndelasfuncionesmiembro, resultasencillayeslasiguiente:
void ListaS::VaciaL()
{
p = NULL;
}
bool ListaS::EsVaciaL()
{
return !p;
}
17.2. Paradecidirelnúmerodenodosdeunalista, bastaconrecorrerla, ycontarlosenuncontador.Unacodificacióneslasiguiente:
int ListaS::CuantosL()
{
Nodo *aux = p;
int c = 0;
while (aux)
{
c++;
// mientras queden datos en la lista.
1
Entodoslosejerciciossobrelistassimplementeenlazadas, seempleanlaclases Nodo ListaS, implementadasenlosEjemplo17 .3y17.4alaquesev anañadiendo
nuevasfuncionesmiembros.Enlosejerciciosdelistasdoblementeenlazadasseempleanlasclases NodoD yListaD implementadasenlosEjemplos17.11y17.12.
CAPÍTULO 17 Listas enlazadas
340
aux = aux->OSig();
}
return c;
}
17.3. Enestafunciónmiembrohayquepuentearelprimernododelalista, yposteriormenteborrarlo.
void ListaS::BorraPL()
{
Nodo *paux;
if( p )
{
paux = p;
p = p->OSig();
paux->PSig(NULL);
delete paux;
}
else;
}
// si tiene datos, borrar el primero
// nodo a borrar
// puentear el nodo a borrar
//poner el siguiente a NULL. No necesario hacerlo
// error
la lista esta vacía y no se puede borrar.
17.4. Serecorreloselementosdelalistaconunpunter o aux alaclase Nodo, inicializadoalprimerelementodelalista p, y se
muestransuscontenidos.
void ListaS::MostrarL()
{
Nodo *aux = p;
while (aux)
{
cout << aux->OE()<< endl;
aux = aux->OSig();
}
// mostrar el dato
// avanzar en la lista
}
17.5. Sielpunteroalprimernodonoes NULL entonesseretornaelelemento, yenotrocasonosehacenada.
Telemento ListaS::PrimeroPL()
{
if (p)
return p->OE();
else ; //error
}
17.6. SecreaunnuevonododetipoNodoD, yseponeelatributoSig ap.SilalistanoestávacíaseponeelatributoAnt delnodo
apuntadopor p aaux.Siempreelprimernododelalistaeselañadido.
void ListaD::AnadePLD(Telemento e)
{
NodoD *aux;
CAPÍTULO 17 Listas enlazadas
341
aux = new NodoD(e);
if(p)
{
aux->PSig(p);
p->PAnt(aux);
}
p = aux;
}
17.7. Silalistanoestávacíaelprimerelementoeselquesee xtraellamandoalafunciónmiembroOE delaclase NodoD.
Telemento ListaD::PrimeroLD()
{
if (p)
return p->OE();
else;// error
}
17.8. Sihaydatosenlalista, seavanzaelatrib utoqueapuntaalprimerelementodelalistadoble , yseborra.Silalistatiene
másdeundato, hayquehacerqueelatrib uto Ant delnodoapuntadopor p apuntea NULL.
void ListaD::BorraPLD()
{
NodoD *paux;
if(p)
{
paux = p;
p = p->OSig();
if (p)
p->PAnt(NULL);
delete paux;
}
else;
}
17.9. Unacodificacióneslasiguiente:
bool ListaD::EsVaciaLD()
{
return !p;
}
// error
CAPÍTULO 17 Listas enlazadas
342
SOLUCIÓN DE LOS PROBLEMAS2
17.1. Elconstructordecopiaseencar gadecopiarlalistaenlazadaqueser ecibecomoparámetroporvalorencualquierfunciónqueuseunobjetodelaclase ListaS.Lacodificaciónquesepresenta, añadeunnodoficticiocomoprimerelemento
delalistaenlazadaqueserálacopia(usalafunciónmiembrodefinidaenelEjemplo17.5), para, posteriormente, irrecorriendoycopiandoloselementosdelalistaquer ecibecomoparámetro p2.Unavezterminadalacopia, usalafunción
Borrar elprimerodelalistacodificadaenelEjercicioresuelto17.3paraeliminarelnodoficticioqueseañadió.
La codificación de este problema se encuentra en la página Web del libro.
17.2. Eldestructorvarecorriendotodoslosnodosdelalistayeliminándolosusandounpunter oa Nodo.
La codificación de este problema se encuentra en la página Web del libro.
17.3. LafunciónmiembroAnadeOI recibecomoparámetrounelemento x yloinsertadejándoladenuevoordenada.Pararealizarlo, primeramentecreaelnododondealmacenaráeldato, sieselprimerodelalistaloinserta, yenotrocasomedianteunbucle while recorrelalistahastaencontr ardóndecolocareldato.Unavezencontr adoelsitioser ealizalainsercióndeacuerdoconelalgoritmo.
La codificación de este problema se encuentra en la página Web del libro.
17.4. Paraborrartodaslasaparicionesdelelemento x enlalista, hayquerecorrerlalistahastaelfinal.Esterecorridoserealizaconunpunteroa Nodo pos, inicializadoalprimernododelalistaqueesapuntadoporelatrib utop, yseiteramientrasquedendatosenlalista( while (pos));ycadavezqueseencuentr aelelementoseelimina, teniendoencuentaque
seaonoelprimerelementodelalista.Unavezborr ado, comohayquese guirbuscandonuevasaparicionesparaeliminarlas, esnecesario, ponerelpunteroquerecorrelalistaenlazada pos enelnodosiguientealborr ado.
La codificación de este problema se encuentra en la página Web del libro.
17.5. LafunciónmiembroBorrarOI seencargadebuscarlaprimeraaparicióndedato x enunalistaenlazadaordenadayborrarlo.Paraello, realizalabúsquedadelaposicióndondeseencuentr alaprimeraaparicióndeldatoquedándoseconel
puntero pos yconelpuntero ant (anterior).Posteriormente, realizaelborradoteniendoencuentaqueseaelprimer ode
lalistaoquenolosea.
La codificación de este problema se encuentra en la página Web del libro.
17.6. Lafunciónmiembroordenar, realizalaordenacióndelalistaconlaayudadecuatr opunteros:
• pOrdenado esunpunteroqueapuntaaunnododelalistadetalmaner aquesi, porejemplo, hay3nodosenlalistaanterioresaélesostresnodosestánordenadosyademássuscontenidossonlosmáspequeñosdetodalalista.Estepunterocomienzaapuntandoalprimerodelalistaqueseencuentraenelatributop, yencadaiteración, avanzaunaposición
enlalista, porloquecuandolleguealfinaldelalista, éstaestaráordenada.
• pMenor esunpunteroquerecorreloselementosdelalistadeunoenunoycomenzandoporelnodosiguientealapuntadopor pOrdenado.Sielcontenidoapuntadopor pMenor esmáspequeñoqueelapuntadopor pOrdenado, entoncesmoviendopunteros, seeliminadelaposiciónqueocupaenlalista, ysecolocajustodelantedelnodoapuntadopor pOrdenado, recolocandoelpunteropOrdenado queahoraapuntapMenor, yelpunteropMenor queapuntaalsiguientededonde
estabapreviamente.
• pAantOrdenado, apuntaalnodoinmediatamenteanteriora pOrdenado, parapoderrealizarinserciones.
• AntpMenor, apuntaalnodoinmediatamenteanteriora pMenor, parapodereliminarlodelalista.
La codificación de este problema se encuentra en la página Web del libro.
2
Entodoslosproblemassobrelistassimplementeenlazadas, seempleanlaclases Nodo yListaS, implementadasenlosEjemplos17.3y17.4alaquesev anañadiendo
nuevasfuncionesmiembros.Enlosproblemasdelistasdoblementeenlazadasseempleanlasclases NodoD yListaD implementadasenlosEjemplos17.12y17.13.
CAPÍTULO 17 Listas enlazadas
343
17.7. Lafunción mezclar recibecomoparámetrosdosobjetos l1 y l2 detipo ListaS, ordenadoscrecientemente, ylosmezcla
ordenadosenelobjeto l3.Lamezclaserealizadelasiguienteforma:
• SeinicializanlospunterosaNodo, aux1 yaux2 alosdosprimerosnodosdelaslistasl1 yl2, parairavanzandocondos
punterosaux1 yaux2 porlaslistas l1 yl2.Unpunteroa Nodo aux3 apuntarásiemprealúltimonodoañadidoalalistamezcladelasdos l3.
• Unprimerbuclewhile avanzaráobienpor aux1 obienpor aux2 insertandoenlalistamezcla l3, dependiendodeque
eldatomáspequeñoestéen aux1 oen aux2, hastaqueunadelasdoslistasseterminen.
• Dosbucleswhile posterioresseencargandeterminardeañadiralalistamezcla l3 loselementosquequedenobiende
l1 obiende l2.
• Hayquetenerencuentaquelainser cióndeunnodoenlalista l3, puedeseralcomienzodelalistaobienalf inal.
La codificación de este problema se encuentra en la página Web del libro.
17.8. ElconstructordecopiaseencargadecopiarlalistadoblementequeserecibecomoparámetroporvalorencualquierfunciónqueuseunobjetodelaclaseListaD.Lacodificaciónquesepresenta, esmuysimilaraladelconstructordecopiade
ListaS.Sólosediferenciaenqueusalaclase NodoD, yque, además, trataelatributoAnt decadanododelalistadoblementeenalazada.Aligualquesusemejanteenlistas, añadeunnodoficticiocomoprimerelementodelalistadoblemente
enlazadaqueserálacopia(usalafunciónmiembr odefinidaenelEjer cicioresuelto17.6), paraposteriormenteirr ecorriendoycopiandoloselementosdelalistaquer ecibecomoparámetro p2.Unavezterminadalacopia, usalafunción
Borrar elprimerodelalistacodificadaenelEjercicioresuelto17.8paraeliminarelnodoficticioqueseañadió.
La codificación de este problema se encuentra en la página Web del libro.
17.9. LafunciónmiembrodelaclaseListaD InsertarOI insertaeldatox enunalistaenlazadaordenadacrecientemente, como
primerelemento, encasodeigualdaddeelementosalmacenados.Lainser ción, comienzaconunabúsqueda, quetermina,
cuandolalistasehaterminado, ocuandosehaencontr adolaposición.Enlospunter oa NodoD ant y pos setienenrespectivamenteladireccióndelnodoinmediatamenteanterioryelinmediatamenteposteriorencasodequee xistan, oNULL
enotrocaso.Unavezsituadoslosdospunteros, ycreadoelnuevonodo aux quealmacenaeldato x, lainsercióncontemplaloscuatrocasos:
•
•
•
•
Lalistaestávacía.Bastaconasignara p elpunteroaux.
Seinsertacomoprimerelementoynoúltimo.Hayqueponer: elsiguientedeaux enp;elanteriordep enaux;yp aaux.
Seinsertacomoúltimoynoprimer o.Hayqueponer: elsiguientede ant enaux;yelanteriorde aux enant.
Seinsertaenelcentrodelalista.Hayqueponer: elsiguientede aux en pos;elanteriorde aux en ant;elsiguientede
ant en aux;yelanteriorde pos en aux.
La codificación de este problema se encuentra en la página Web del libro.
17.10. Elborradodex, vaprecedidodelabúsquedaenunalistaordenadacrecientemente.Unavezterminadalabúsquedaycolocadodelaformaadecuadalospunter osa NodoD, ant y pos, sedecidesilapar adadelabúsquedadacomor esultado
quehayqueborr arelelemento.Estoocurr ecuando enc valeverdaderoyen pos seencuentraalmacenado x.Enelborradodelnodoapuntadopor pos, sedistinguencuatrocasosparaelmovimientodepunteros:
•
•
•
•
Eselprimeroyúltimodelalista: ponerp aNULL, yaquelalistasequedavacía.
Eselprimeroynoúltimo: ponerp alsiguientede pos;yelanteriorde p aNULL.
Eselúltimoynoprimero: ponerelsiguientede ant aNULL.
Noprimeroynoúltimo: ponerelsiguientede ant alsiguientede pos, yponerelanteriordelsiguientede pos aant.
Unavezquesehanrealizadolosenlaces, seprocedealaeliminacióndelnodoapuntadopor pos.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 17 Listas enlazadas
344
17.11. Paracopiarlalistadoblementeenlazadaapuntadapor ld, enlalistadoblementeenlazada ld1, seusanlasfunciones
miembrodelaclase ListaD, PrimeroLD, AnadePLD, EsVaciaLD, BorraPLD, codificadasenlosEjerciciosresueltos: 17.7,
17.8, 17.9, 17.10.Serealizadelasiguienteforma, secopiaenprimerlugarlalistadoblementeenlazada ld enuna ld2
auxiliarcomosifueraunapila.Esdecir, loselementosquedanjustoenelor deninversoalqueseencontr abanenlalista
original.Posteriormente, sevuelveacopiar, delamismaforma, lalistadoblementeenlazadald2 enld1, conloquelalistaquedaensuordennatural.
La codificación de este problema se encuentra en la página Web del libro.
17.12. Laclaselistasimplementeenlazadacir cularusalaclase Nodo definidoenelEjemplo17.3.Lasfuncionesmiembr
o:
ListaC();void VaciaL();ListaC (const ListaC &p2); ~ListaC();Nodo * Op();void Pp(Nodo *p1);y bool
EsVaciaL(); coincidenconlascodificadasenlaclase ListaS enlosejerciciosyproblemasdelpresentecapítulo, porlo
quesóloseincluyenelcódigodelasr estantesfuncionesmiembrospedidas.
Lalistacircularseimplementadetalmaneraqueelatributop delalista, siempreapuntaalúltimoelementodelalista, yelprimerodelalistasiempreseencuentraenelnodoapuntadoporelsiguientede p, encasodequelotenga.
• DeestaformalacodificacióndelafunciónmiembroPrimeroPl(), queretornaelprimerodelalistaestansencillacomo
return p->OSig()->OE();.
• AnadePL(), añadeunelementoxcomoprimer odelalista, esdecir, entreelnodoapuntadoporelatrib uto p, yelapuntadoporp->OSig().Enlacodificaciónhayquetenerencuentaquelalistaseencuentrevacíayaqueenestecasoelprimerelementosedebequedarapuntadoporelpr opioatributop->Osig() delalistacircular.
• Lafunciónmiembro BorraPL() eliminaelnodoapuntadopor p->Osig(), queeselprimerodelalista.Enlacodif icaciónsetieneencuentaquelalistasequedevacíaaleliminarlo(lalistateníaantesdelborr adounsolonodo).
• Paravisualizarelcontenidodelalistacircular, hayquetenerencuentaquelosnodosestánenunciclo, porloqueelbuclequecontrolalasalidadedatosdebepararcuando“sehayadadolavueltaalalistacir cular”.Estacondiciónsetraduceenelcontroldelbucledo while enlacondición( aux != p->OSig()).Hayqueobservarqueenelcuerpodelb ucle, aux esunpunter oqueapuntaalprimerelementoquedebeserescrito, portanto, hayquemostr alo, yavanzarel
punteroaux alsiguientedelalista.
• Elborradodelaprimer aaparicióndeunelementoesr ealizadoporlafunciónmiembr o BorrarL.Elcódigodelafunciónbuscalaprimeraaparicióndelelemento, yunavezencontrado, loelimina, teniendoencuentaquelalistasepuede
quedarvacía, oqueelelementoqueseelimineseaelúltimodelalista, queeselapuntadoporelatrib utop.
• Ademásdelasmacrosdelasfuncionesdeg eneracióndenúmerosaleatoriossepr esentaunafunciónnomiembr odela
claseListaC, quegeneraaleatoriamenteunalista, yunprogramaprincipalquellamaalafuncióndeg eneraciónaleatoriadeloselementosdelalista, ylafunciónmiembroquevisualizalalistacircular.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
17.1. Enunalistaenlazadadenúmerosenterossedeseaañadirunnodoentredosnodosconsecuti vosconcampos
datodedistintosigno;elv alordelcampodatodelnuevonodoquesealadiferenciaenv alorabsoluto.
17.2. Setieneunalistadesimpleenlace, elcampodatoesun
registro(estructura)conloscamposdeunalumno:
nombre, edad, sexo.Escribirunafunciónparatransformarla listadetalformaquesielprimernodoesdeun
alumnodese xomasculinoelsiguienteseadese xofemenino.
17.3. Escribirunalgoritmoqueleaunalistadeenterosdelteclado, creeunalisaenlazadaconelloseimprimaelresultado.
17.4. Escribirunalgoritmoqueacepteunalistaenlazada, la
recorraydevuelvaeldatodelnodoconelv alormenor.
17.5. Escribirunalgoritmoqueacepteunalistaenlazada, la
recorraydevuelvaeldatodelnodoconelv alormayor.
17.6. Escribirunafunciónquegenereunalistacircularcon
losdatos1, 2, 3, ..., 20.
CAPÍTULO 17 Listas enlazadas
345
PROBLEMAS PROPUESTOS
17.1. Escribirunafunciónmiembrodelaclase Listadoblementeenlazada quecreeunalistadoblementeenlazada
depalabrasintroducidasporteclado.Lafuncióndebe
tenerunar gumento, unpunteroal Nodo delalistadoblePLd enelquesedevuelvaladireccióndelnodoque
estáenlaposiciónintermedia.
17.5. Setieneunarchi vodete xtodepalabrasseparadaspor
unblancooelcarácterdef indelínea.Escribirunprogramaparaformarunalistaenlazadaconlaspalabras
delarchivo.Unav ezformadalalistasepuedenañadir
nuevaspalabrasoborraralgunadeellas. Alfinalizarel
programaescribirlaspalabrasdelalistaenelarchi vo.
17.2. Escribirunprogramaquecreeunarraydelistasenlazadas.
17.6. Escribirunprogramaqueleaunalistadeestudiantesde
unarchivoycreeunalistaenlazada.Cadaentradadela
listaenlazadahadetenerelnombredelestudiante, un
punteroalsiguienteestudianteyunpunteroaunalista
enlazadadecalificaciones.
17.3. Unalistacirculardecadenasestáordenadaalf abéticamente.Elatributop delobjetoListacircular tieneladireccióndelnodoalf abéticamentemayor, queasuv ez
apuntaalnodoalfabéticamentemenor.Escribirunafunciónparaañadirunanue vapalabra, enelordenquele
corresponda, alalista.
17.4. Sedisponedeunalistaenlazadaconlaquelosdatosde
cadaelementocontieneunentero.Escribirunafunción
quedecidasilalistaestáordenada.
17.7. Unpolinomiosepuederepresentarcomounalistaenlazada.Elprimernododelalistarepresentaelprimertérminodelpolinomio, elsegundonodoalsegundotérminodelpolinomioyasísucesi vamente.Cadanodotiene
comoatributoselcoeficientedeltérminoyelexponente.Porejemplo, elpolinomio3 x4 –4x2 +11serepresentaenlasiguientefigura:
3
17.8. Escribirunprogramaquepermitadarentradaapolinomiosenx, representándolosconunalistaenlazadasimple.Acontinuación, obtenerunatabladevaloresdelpolinomioparav aloresde x =0.0, 0.5, 1.0, 1.5, …, 5.0.
17.9. Teniendoencuentalarepresentacióndeunpolinomio
propuestaenelproblemaanteriorhacerloscambiosnecesariosparaquelalistaenlazadaseacircular .Elpunterodeaccesodebetenerladireccióndelúltimotérminodelpolinomio, elcuálapuntaráalprimertérmino.
17.10. Escribirunafunciónquetomeunalistaenlazadadeenteroseinviertaelordendesusnodos.
17.11. Escribirunprogramaparaobtenerunalistadoblemente
enlazadaconloscaracteresdeunacadenaleídadesdeel
teclado.Cadanododelalistatendráuncarácter .Una
vezquesetienelalista, ordenarlaalfabéticamenteyescribirlaporpantalla.
17.12. Escribirunprogramaenelquedadosdosarchi vosF1,
F2formadosporpalabrasseparadasporunblancoofin
delínea, secreendosconjuntosconlaspalabrasdeF1
yF2respectivamente, implementadosconlistassimplementeenlazadas.Posteriormente, encontrarlaspalabras
comunesymostrarlasporpantalla.
4
-4
2
11
0
17.13. Sedisponedeunalistadoblementeenlazadaordenada
crecientementeconcla vesrepetidas.Realizarunafuncióndeinsercióndeunacla veenlalistadeformatal
quesilaclaveyaseencuentraenlalistaseinsertealfinaldetodaslasquetienenlamismacla ve.
17.14. Utilizarunalistadoblementeenlazadaparacontrolar
unalistadepasajerosdeunalíneaaérea.Elprograma
principaldebesercontroladopormenúypermitiral
usuariovisualizarlosdatosdeunpasajerodeterminado,
insertarunnodo(siempreporelf inal), eliminarunpasajerodelalista. Alalistaseaccedeporunpunteroal
primernodoyotroalúltimonodo.
17.15. Escribirunprogramaqueleauntextodelongitudindeterminadayqueproduzcacomoresultadolalistadetodaslaspalabrasdiferentescontenidasenelte xtoasí
comosufrecuenciadeaparición.
17.16. Pararepresentarunenterolar go, demásde30dígitos,
utilizarunalistacircularteniendoelcampodatode
cadanodoundígitodelenterolar go.Escribirunprogramaenelqueseintroduzcandosenteroslar gosyse
obtengasusuma.
17.17. Unvectordispersoesaquelquetienemuchoselemen-
CAPÍTULO 17 Listas enlazadas
346
tosquesoncero.Escribirunprogramaquepermitarepresentarmediantelistasenlazadasunv ectordisperso.
Losnodosdelalistasonloselementosdelalistadistintosdecero;encadanodoserepresentaelv alordel
elementoyelíndice(posicióndelv ector).Elprograma
haderealizarlasoperaciones: sumardosv ectoresde
igualdimensiónyhallarelproductoescalar.
17.18. Escribirunafunciónquepermitainsertarunelemento
enunaposicióndeterminadadeunalistadoblemente
enlazada.
17.19. Escribaunafunciónquetengacomoargumentounalistacirculardenúmerosenteros.Lafuncióndebede volvereldatodelnodoconmayorv alor.
CAPÍTULO 18
Pilas y colas
Introducción
Enestecapítuloseestudianendetallelasestructurasdedatospilasycolasqueson, probablemente, lasutilizadasmásfrecuentementeenlosprogramasmásusuales.Sonestructurasdedatosquealmacenanyrecuperansuselementosatendiendoa
unestrictoorden.Laspilasseconocentambiéncomoestructuras LIFO (Last-in, first-out, últimoenentrar-primeroensalir)
ylascolascomoestructuras FIFO (First-in, First-out, primeroenentrar-primeroensalir).Entrelasnumerosasaplicaciones
delaspilasdestacalae valuacióndeexpresionesalgebraicas, asícomolaorganizacióndelamemoria.
18.1. Concepto de pila
Unapila (stack)esunaestructuradedatosquecumplelacondición: “loselementosseañadenoquitan(borran)delamisma
sóloporsupartesuperior(cima)delapila”.Debidoasupropiedadespecíf ica“últimoenentrar, primeroensalir” seconocea
laspilascomoestructuradedatos LIFO (last-in, first-out).Lasoperacionesusualesenlapilason Insertar yQuitar.Laoperación Insertar (push)añadeunelementoenlacimadelapilaylaoperaciónQuitar (pop)eliminaosacaunelementodelapila.
Cima
Insertar
Quitar
Fondo
Operaciones básicas de una pila
347
CAPÍTULO 18 Pilas y colas
348
Lapilasepuedeimplementarmediantearraysencuyocasosudimensiónolongitudesf ija, ymediantepunterosolistas
enlazadasencuyocasoseutilizamemoriadinámicaynoe xistelimitaciónensutamaño.Unapilapuedeestar vacía (notieneelementos)o llena (enelcasodetenertamañof ijo, sinocabemáselementosenlapila).OtrométododediseñoyconstruccióndepilaspuederealizarsemedianteplantillasconlabibliotecaSTL.Elmejorsistemaparadefinirunapilaesconuna
clase(class)obienconunaplantilla( template).
Especificación de una pila
Lasoperacionesquesirvenparadefinirunapilaypodermanipularsucontenidosonlassiguientes:
AnadeP (push)
BorrarP (pop)
EsVaciaP
VaciaP
EstallenaP
PrimeroP
Insertarundatoenlapila.
Sacar(quitar)undatodelapila.
Comprobarsilapilanotieneelementos.
CrealaPilavacía.
Comprobarsilapilaestállenadeelementos.
Extraeelprimerelementodelapilasinborrarlo.
La clase pila implementado con arrays (arr eglos)
EnC++paradefinirunapilaconarraysseutilizaunaclase.Losatrib utosdelaclase Pila incluyenunalista(array)yuníndiceopunteroalacimadelapila;además, unaconstanteconelmáximonúmerodeelementoslimitalalongituddelapila.
Elmétodousualdeintroducirelementosenunapilaesdef inirelfondo delapilaenlaposición0delarray , esdecir, definir
unapilavacíacuandosucimavale–1(elpunterodelapila almacenaelíndicedelarrayqueseestáutilizandocomocimade
lapila).Lacimadelapilasev aincrementandoenunocadav ezqueseañadeunnue voelemento, ysevadecrementandoen
unocadavezqueseborraunelemento.Losalgoritmosdeintroducir“insertar” (push)yquitar“sacar” (pop)datosdelapila
utilizanelíndicedelarraycomopunterodelapilason:
Insertar (push). Verificarsilapilanoestállena.Incrementarenunoelpunterodelapila.Almacenarelelementoenlaposicióndelpunterodelapila.
Quitar (pop). Verificarsilapilanoestáv acía.Leerelelementodelaposicióndelpunterodelapila.Decrementarenunoel
punterodelapila.
Enelcasodequeelarrayquedef inelapilatenga MaxTamaPila elementos, elíndiceopunterodelapila, estarán
comprendidosenelrango 0 a MaxTamaPila–1 elementos, demodoque enunapilallena elpunterodelapilaapuntaa
MaxTamaPila–1 yenunapilavacía elpunterodelapilaapuntaa –1, yaque 0, teóricamente, esíndicedelprimerelemento.
EJEMPLO 18.1. Clasepilaimplementadaconarray.
SedefineunaconstanteMaxTamaPila cuyovalores100queseráelvalormáximodeelementosquepodrácontenerla
pila.Sedefineenun typedef eltipodedatosquealmacenará Pila, queenestecasoseránenteros. Pila esunaclase
cuyosatributossonla cima queapuntasiemprealúltimoelementoañadidoalapilayunarray A cuyosíndicesvariaránentre 0 y MaxTamaPila–1.Todaslafuncionesmiembrodelaclase, sonpúblicas, excepto EstallenaP queesprivada.
•
•
•
•
•
•
VaciaP.Crealapilavacíaponiendolacimaenelv alor –1.
Pila.Eselconstructordela Pila.Coincidecon VaciaP.
EsvaciaP.Decidesilapilavacía.Ocurrecuandosu cima valga–1.
EstallenaP.Enlaimplementacióndeunapilaconarray , hayquetenerladeclaradacomoprivadaparaprevenirposibleserrores.Enestecasolapilaestarállenacuandolacima apuntealvalorMaxTamaPila–1.
AnadeP.Añadeunelementoalapila.Parahacerlocompruebaenprimerlugarquelapilanoestéllena,yencasoafirmativo, incrementala cima enunaunidad, paraposteriormenteponerenelarray A enlaposición cima elelemento.
PrimeroP.Compruebaquelapilanoestévacía, yencasodequeasíseadaráelelementodelarray A almacenadoen
laposiciónapuntadaporla cima.
CAPÍTULO 18 Pilas y colas
349
• BorrarP. Seencargadeeliminarelúltimoelementoqueentróenlapila.Primeramentecompruebaquelapilano
estévacíaencuyocaso, disminuyela cima enunaunidad.
• Pop.Estaoperaciónextraeelprimerelementodelapilayloborra.Puedeserimplementadadirectamente, obienllamandoalasprimitivasPrimeroP yposteriormentea BorrarP.
• Push.Estaprimitivacoincidecon AnadeP.
#include <cstdlib>
#include <iostream>
using namespace std;
#define MaxTamaPila 100
typedef int TipoDato;
class Pila
{
protected:
TipoDato A[MaxTamaPila];
int cima;
public:
Pila(){ cima = -1;}
~Pila(){}
void VaciaP();
void AnadeP(TipoDato elemento);
void BorrarP();
TipoDato PrimeroP();
bool EsVaciaP();
void Push(TipoDato elemento);
TipoDato Pop();
private:
bool EstallenaP();
};
void Pila:: VaciaP()
{
cima = -1;
}
void Pila::AnadeP(TipoDato elemento)
{
if (EstallenaP())
{
cout << " Desbordamiento pila";
exit (1);
}
cima++;
A[cima] = elemento;
}
void Pila::Push (TipoDato elemento)
{
AnadeP (elemento);
}
//constructor
//destructor
CAPÍTULO 18 Pilas y colas
350
TipoDato Pila::Pop()
{
TipoDato Aux;
if (EsVaciaP())
{
cout <<"Se intenta sacar un elemento en pila vacía";
exit (1);
}
Aux = A[cima];
cima--;
return Aux;
}
TipoDato Pila::PrimeroP()
{
if (EsVaciaP())
{
cout <<"Se intenta sacar un elemento en pila vacía";
exit (1);
}
return A[cima];
}
void Pila::BorrarP()
{
if (EsVaciaP())
{
cout <<"Se intenta sacar un elemento en pila vacía";
exit (1);
}
cima--;
}
bool Pila::EsVaciaP()
{
return cima == -1;
}
bool Pila::EstallenaP()
{
return cima == MaxTamaPila-1;
}
int main(int argc, char *argv[])
{
Pila P;
P.AnadeP(5);
P.AnadeP(6);
cout << P.Pop() << endl;;
cout << P.Pop() << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
CAPÍTULO 18 Pilas y colas
351
La clase pila implementada con punter os
Paraimplementarunapilaconpunterosbastaconusarunalistasimplementeenlazada, conloquelapilaestarávacíasilalistaapuntaa NULL.Lapilateóricamentenuncaestarállena.Lapilasedeclaracomounaclasequetieneunatrib utoprotegido
queesunpunteroanodo, estepunteroseñalaele xtremodelalistaenlazadaporelqueseefectúanlasoperaciones.Siempre
quesequieraponerunelementosehaceporelmismoe xtremoqueseextrae.
Losalgoritmosdeintroducir“insertar” (push)yquitar“sacar” (pop)datosdelapilason:
Insertar (push). Bastaconañadirunnue vonodoconeldatoquesequiereinsertarcomoprimerelementodelalista(pila).
Quitar (pop). Verificarsilalista(pila)noestávacía.Extraerelvalordelprimernododelalista(pila).Borrarelprimernodo
delalista(pila).
EJEMPLO 18.2. ClasePila implementadaconpunteros.
Sedefineenprimerlugarlaclase Nodo, yaimplementadaenelEjercicioresuelto17.3yutilizadaenlaslistassimplementeenlazadas.Laclase Pila tieneporatributoprotegidounpunteroalaclase Nodo.Lasfuncionesmiembrosque
seimplementandelaclase Pila son:
•
•
•
•
•
•
•
•
•
•
ConstructorPila.Crealapilavacíaponiendoelatributop aNULL.
Constructordecopia Pila utilizadoparalatransmisióndeparámetrosporv alordeunapilaaunafunción.
Destructor~Pila, cuyocódigoeliminatodoslosnodosdelalista.
VaciaP.Crealapilavacíaponiendoelatributo p a NULL.
EsvaciaP.Decidesilapilaestáv acía.Estoocurrecuandoelatrib uto p valgaNULL.
AnadeP.Añadeunelementoalapila.Parahacerloesprecisoañadirunnuevonodoquecontengacomoinformación
elelementoquesequieraañadiryponerlocomoprimerodelalistaenlazada.
PrimeroP.Enprimerlugarsecomprobaráquelapila(lista)noestév acía, yencasodequeasísea, daráelcampoel
almacenadoenelprimernododelalistaenlazada.
BorrarP.Seencargadeeliminarelúltimoelementoqueentróenlapila.Primeramentecompruebaquelapilanoesté
vacía, encuyocaso, seborraelprimernododelapila(listaenlazada).
Pop.Estaoperaciónextraeelprimerelementodelapilayloborra.Puedeserimplementadadirectamente, obienllamandoalasprimitivasPrimeroP y, posteriormente, aBorrarP.
Push.Estaprimitivacoincidecon AnadeP.
#include <cstdlib>
#include <iostream>
using namespace std;
typedef int Telemento;
class Nodo {
protected:
Telemento e;
Nodo *Sig;
public:
Nodo(){}
~Nodo(){}
Nodo (Telemento x){ e = x; Sig = NULL;}
Telemento OE(){ return e;}
void PE(Telemento x){ e = x;}
Nodo * OSig(){ return Sig;}
void PSig( Nodo *p){ Sig = p;}
};
class Pila
// constructor
// Obtener elemento
// poner elemento
// Obtener siguiente
// poner siguiente
CAPÍTULO 18 Pilas y colas
352
{
protected:
Nodo *p;
public:
Pila(){p = NULL;}
void VaciaP(){ p = NULL;}
bool EsvaciaP(){ return !p;}
Telemento PrimeroP(){ if (p) return p->OE();}
void AnadeP( Telemento e);
void Push(Telemento e){ AnadeP(e);}
void BorrarP();
Pila::Pila (const Pila &p2);
~Pila();
Telemento Pop();
};
void Pila::AnadeP(Telemento e)
{
Nodo *aux;
aux = new Nodo(e);
if( p )
aux->PSig(p);
p = aux;
}
void Pila::BorrarP()
{
Nodo *paux;
if(p)
{
paux = p;
p = p->OSig();
delete paux;
}
else;
// error
}
Pila::Pila (const Pila &p2)
{
Nodo* a = p2.p, *af, *aux;
p = NULL;
AnadeP(-1);
af = p;
while ( a != NULL)
{
aux = new Nodo(a->OE());
af->PSig(aux);
af = aux;
a = a->OSig();
}
// Se añade Nodo Cabecera
CAPÍTULO 18 Pilas y colas
BorrarP();
353
// Se borra nodo Cabecera
}
Pila:: ~Pila()
{
Nodo *paux;
while(p != 0)
{
paux = p;
p = p->OSig();
delete paux;
}
}
Telemento Pila::Pop()
{
Telemento e;
e = PrimeroP();
BorrarP();
return e;
}
int main(int argc, char *argv[])
{
Pila p;
p.VaciaP();
p.AnadeP(4);
p.AnadeP(5);
while (!p.EsvaciaP())
{
cout << p.PrimeroP() << endl;
p.BorrarP();
}
system("PAUSE");
return EXIT_SUCCESS;
}
18.2. Concepto de cola
Unacola esunaestructuradedatoslinealdondeloselementosseeliminan(sequitan)delacolaenelmismoordenenquese
almacenany, porconsiguiente, unacolaesunaestructuradetipo FIFO (first-in/first-out, primeroenentrar/primeroensalir
obienprimeroenllegar/primeroenserservido).
Lasaccionesqueestánpermitidasenunacolason: creacióndeunacolav acía;verificacióndequeunacolaestáv acía;
añadirundatoalfinaldeunacola;eliminacióndeundatodelacabezadelacola.
La clase cola implementada con arrays
Ladefinicióndeunaclase Cola hadecontenerunarrayparaalmacenarloselementosdelacola, ydosmarcadoresopunteros(variables)quemantienenlasposiciones frente yfinal delacola.Cuandounelementoseañadealacola, severificasi
elmarcador final apuntaaunaposiciónválida, entoncesseañadeelelementoalacolayseincrementaelmarcadorf inal
CAPÍTULO 18 Pilas y colas
354
en 1.Cuandounelementoseeliminadelacola, sehaceunapruebaparaversilacolaestávacíay, sinoesasí, serecuperael
elementodelaposiciónapuntadaporelmarcador(puntero) frente yésteseincrementaen 1.Esteprocedimientofunciona
bienhastalaprimeravezqueelpuntero frente alcanzaelextremodelarray, quedandoobienvacíoobienlleno.
Definición de la especificación de una cola
Sedefineenprimerlugareltipogenérico TipoDato.ElTDA Cola contieneunalistacuyomáximotamañosedeterminapor
laconstanteMaxTamC.Sedefinendostiposdevariablespunteroomarcadores, frente yfinal.Éstossonlospunterosdecabeceraycolaofinalrespectivamente.Lasoperacionestípicasdelacolason
AnadeC
BorrarC
VaciaC
EsvaciaC
EstallenaC
PrimeroC
Añadeunelementoalacola.
Borraelprimerelementodelacola.
Dejalacolasinningúnelemento.
Decidesiunacolaestávacía.
Decidesiunacolaestállena.
Extraeelprimerelementodelacola.
Lasimplementacionesclásicasdeunacolason:
Retroceso. Consisteenmantenerfijoaunoelvalorde frente, realizandoundesplazamientodeunaposiciónparatodaslas
componentesocupadascadavezqueseefectúaunasupresión.
Reestructuración. Cuandofinal llegaalmáximodeelementos, sedesplazanlascomponentesocupadashaciaatráslasposicionesnecesariasparaqueelprincipiocoincidaconlaprimeraposicióndelarray .
Mediante un array circular. Unarraycircularesaquélenelqueseconsideraquelaprimeraposiciónsiguealaúltima.
n–1
Cabeza
0
n–1
1
Final
0
1
...
.
.
.
2
...
Cola circular
Cola circular vacía
Lavariablefrente essiemprelaposicióndelelementoqueprecedealprimerodelacolaysea vanzaenelsentidodelas
agujasdelreloj.Lav ariable final eslaposiciónendondesehizolaúltimainserción.Despuésquesehaproducidounainserción, final semuevecircularmentealaderecha.Laimplementacióndelmo vimientocircularcalcularsiguienteserealiza
utilizandolateoríadelosrestos:
Mover final adelante
Mover frente adelante
=
=
(final+1)%MaxTamC
(frente+1) % MaxTamC
Siguiente de final
Siguiente de frente
EJEMPLO 18.3. ImplementacióndelaclaseColaconunarr aycircular.
Laclase Cola contienelosatributosprotegidos frente, final yelarray A declaradodeunalongitudmáxima. Todas
lasfuncionesmiembroseránpúblicas, exceptoelmétodoEstallenaC queseráprivadodelaclase.Enlaimplementacióndelaclase Cola conunarraycircularhayquetenerencuentaque frente vaaapuntarsiempreaunaposición
CAPÍTULO 18 Pilas y colas
355
anteriordondeseencuentraelprimerelementodelacolay final vaaapuntarsiemprealaposicióndondeseencuentraelúltimodelacola.Portanto, laparteesencialdelastareasdegestióndeunacolason:
Creacióndeunacolavacía: hacerfrente = final = 0.
Comprobarsiunacolaestávacía: ¿esfrente = = final?
Comprobarsiunacolaestállena: ¿es(final+1)% MaxTamC = = frente?Noseconfundaconcolav acía.
Añadirunelementoalacola: silacolanoestállena, añadirunelementoenlaposiciónsiguientea final yseestablece: final = (final+1)%MaxTamC.
• Eliminacióndeunelementodeunacola: silacolanoestáv acía, eliminarlodelaposiciónsiguientea frente yestablecerfrente = (frente+1) % MaxTamC.
•
•
•
•
#include <cstdlib>
#include <iostream>
#define MaxTamC 100
using namespace std;
typedef int TipoDato;
class Cola
{
protected:
int frente, final;
TipoDato A[MaxTamC];
public:
Cola();
~Cola();
void VaciaC();
void AnadeC(TipoDato e);
void BorrarC();
TipoDato PrimeroC();
bool EsVaciaC();
private:
bool EstallenaC();
};
Cola::Cola()
{
frente = 0;
final = 0;
}
Cola::~Cola(){}
void Cola::VaciaC()
{
frente = 0;
final = 0;
}
void Cola::AnadeC(TipoDato e)
{
if (EstallenaC( ))
{
//constructor
//destructor
CAPÍTULO 18 Pilas y colas
356
cout << "desbordamiento cola";
exit (1);
}
final = (final + 1) % MaxTamC;
A[final] = e;
}
TipoDato Cola::PrimeroC()
{
if (EsVaciaC())
{
cout << "Elemento frente de una cola vacía";
exit (1);
}
return (A[(frente+1) % MaxTamC]);
}
bool Cola::EsVaciaC()
{
return (frente == final);
}
bool Cola::EstallenaC()
{
return (frente == (final+1) % MaxTamC);
}
void Cola::BorrarC()
{
if (EsVaciaC())
{
cout << "Eliminación de una cola vacía";
exit (1);
}
frente = (frente + 1) % MaxTamC;
}
La clase cola implementada con una lista enlazada
Cuandolacolaseimplementautilizandov ariablesdinámicas, lamemoriautilizadaseajustaentodomomentoalnúmerode
elementosdelacola, peroseconsumealgodememoriae xtrapararealizarelencadenamientoentreloselementosdelacola.
Seutilizandospunterosparaaccederalacola, frente y final, quesonlose xtremospordondesalenloselementosypor
dondeseinsertanrespectivamente.
frente
e1
final
e2
e3
...
en
EJEMPLO 18.4. ImplementacióndelaclaseColaconununalistaenlazadaconfr enteyfinal.
Seusalaclase Nodo implementadayexplicadaenelEjemploresuelto 17.3yutilizadaenlaslistassimplementeenlazadas.Estaclase Nodo esincluidaenlaimplementación.Laclase Cola tienedostiposatributosprotegidos Frente y
CAPÍTULO 18 Pilas y colas
357
Final quesonpunterosalaclase Nodo yqueapuntaránalprimernododela Cola yalúltimonododela Cola respectivamente.Lasfuncionesmiembrodelaclaseson:
• Cola.Eselconstructorpordefectoqueponelosatrib utosFrente yFinal aNULL.
• Cola (const Cola &p2).Seencargadehacerunacopiadela Cola p2;paraellocrealacola p2 vacía, yposteriormenterecorretodoslosnodosdelacola p2 yselosañadealaactual.Eselconstructordecopiayseacti vacadavez
quehayunatransmisióndeparámetrosporv alor.
• ~Cola().Eseldestructordela Cola.Seencargademandaralamemoriadisponibletodoslosnodosdela Cola.
• VaciaC.Creaunacolavacía, paralocualbastaconponerelFrente yelFinal aNULL.Realizaelmismotrabajoque
elconstructorpordefecto.
• EsVacíaC. Decidesiunacolaestávacía.Esdecirsi Frente yFinal valenNULL.
• PrimeroC. Extraeelprimerelementodelacolaqueseencuentraenelnodo Frente.Previamenteaestaoperación
hadecomprobarsequelacolanoestév acía.
• AnadeC. Añadeunelementoalacola.Esteelementoseañadeenunnuevonodoqueseráelsiguientede Final enel
casodequelacolanoestév acía.Silacolaestáv acíael Frente debeapuntaraestenue vonodo.Entodocasoel
final siempredebemoversealnuevonodo.
• BorrarC.Eliminaelprimerelementodelacola.P arahacerestaoperaciónlacolanodebeestarv acía.Elborradose
realizaavanzandoFrente alnodosiguiente, yliberandolamemoriacorrespondiente.
#include <cstdlib>
#include <iostream>
using namespace std;
typedef int Telemento;
class Nodo {
protected:
Telemento e;
Nodo *Sig;
public:
Nodo(){}
~Nodo(){}
Nodo (Telemento x){ e = x; Sig = NULL;}
Telemento OE(){ return e;}
void PE(Telemento x){ e = x;}
Nodo * OSig(){ return Sig;}
void PSig( Nodo *p){ Sig = p;}
};
// constructor
// Obtener elemento
// poner elemento
// Obtener siguiente
// poner siguiente
class Cola
{
protected:
Nodo *Frente, *Final;
public:
Cola();
Cola (const Cola &p2);
~Cola();
void VaciaC();
void AnadeC( Telemento e);
Telemento PrimeroC();
void BorrarC();
bool EsvaciaC();
};
// constructor por defecto
// para los de parámetros por valor
//destructor
CAPÍTULO 18 Pilas y colas
358
Cola::Cola()
{
Frente = NULL;
Final = NULL;
}
Cola::Cola (const Cola &p2)
{
Telemento e;
Nodo* a = p2.Frente;
Frente = NULL;
Final = NULL;
while ( a != NULL)
{
AnadeC ( a -> OE());
a = a->OSig();
}
}
Cola:: ~Cola()
{
Nodo *paux;
while(Frente != 0)
{
paux = Frente;
Frente = Frente->OSig();
delete paux;
}
}
void Cola::VaciaC()
{
Frente = NULL;
Final = NULL;
}
void Cola::AnadeC(Telemento e)
{
Nodo *aux;
aux = new Nodo(e);
if( Final)
// nuevo nodo
// cola no vacía se coloca después de Final
Final->PSig(aux);
Else
Frente = aux;
Final = aux;
}
Telemento Cola::PrimeroC()
{
if (Frente)
return Frente->OE();
}
// la cola está vacía es Frente y Final
CAPÍTULO 18 Pilas y colas
359
bool Cola::EsvaciaC()
{
return !Frente;
}
void Cola::BorrarC()
{
Nodo *paux;
if(Frente)
{
paux = Frente;
Frente = Frente->OSig();
delete paux;
}
else;
if (! Frente )
Final = NULL;
// nodo a borrar
// error
// se queda vacía
}
EJERCICIOS
18.1. Escribirunprogramaqueusandolaclase Pila, leadatosdelaentrada(–1findedatos), losalmaceneenunapilayposteriormentevisualicelapila.
18.2. ¿Cuáleslasalidadeestese gmentodecódigo, teniendoencuentaqueeltipodedatodelapilaes int?
Pila *P;
int x = 4, y;
P.VaciaP();
P.AnadeP(x);
P.BorrarP();
P.AnadeP(32);
y = P.PrimeroP();
P.BorrarP();
P.AnadeP(y);
do
{
cout <<" "<< P.PrimeroP()<< endl;
P.BorrarP();
}
while (!P.EsvaciaP());
18.3. Codificareldestructordelaclase Pila implementadaconpunter osdelEjemplo18.2, paraqueliber etodalamemoria
apuntadaporlapila.
18.4. Escribirunafunciónquenoseamiembr odelaclase Pila, quecopieunapilaenotr a.
18.5. Escribirunafunciónquenoseamiembr odelaclase Pila, quemuestreelcontenidodeunapilaquer ecibacomoparámetro.
CAPÍTULO 18 Pilas y colas
360
18.6. Considerarunacoladenombr esrepresentadaporunaarr aycircularcon6posiciones, yloselementosdelaCola: Mar,
Sella, Centurión.Escribirloselementosdelacolaylosvalor esdelosnodossiguientedeFrenteyFinalsegúnserealizan
estasoperaciones:
•
•
•
•
•
AñadirGloriayGenerosaalacola.
Eliminardelacola.
AñadirPositivo.
AñadirHorchealacola.
Eliminartodosloselementosdelacola.
18.7. Escribirunafunciónnomiembrodelaclase Cola quevisualiceloselementosdeunacola.
18.8. Escribirunafunciónquerecibaunacolacomoparámetro, einformedelnúmerodeelementosquecontienelacola.
PROBLEMAS
18.1. Implementarunaclasepilaconunarr aydinámico.
18.2. Implementarunaclasepilaconlasfuncionesmiembr o“pop” y“push”.Éstallenaconsuconstructorydestructor , usandounarraydinámicoytiposgenéricos.
18.3. EscribirlasfuncionesnomiembrodelaclasePilaMayorPilayMenorPila, quecalculanelelementomayor, menordeuna
piladeenteros.
18.4. Escribirlafunciónnomiembrodelaclasepila, MediaPilaquecalculelamediadeunapiladeenter os.
18.5. EscribirunafunciónnomiembrodelaclasePila, quedecidasidospilassoniguales.
18.6. Escribirunafunciónparadeterminarsiunasecuenciadecaracteresdeentradaesdelaforma: X&Y.DondeXesunacadenadecar actereseYeslacadenain versa.Elcarácter&eselsepar adorysiempresesuponequee xiste.Porejemplo,
ab&basíesdelaformaindicada, peronolosonab&abnioab&xba.
18.7. Implementarlaclase Cola conunalistacircularsimplementeenlazada.
18.8. Implementarunafunciónnomiembr odelaclase Cola deenterosquer ecibaunacolacomoparámetr oyr etorneelelementomayoryelmenordeunainstanciadelaclase Cola.
18.9. Escribirunafunciónquerecibadosobjetosdelaclase Cola comoparámetrosydecidasisoniguales.
18.10. Escribirunafunciónquer ecibacomoparámetr ounainstanciadelaclase Cola yunelemento, yeliminetodosloselementosdelainstanciaqueseanmayor esqueelquerecibecomoparámetro.
18.11. Escribirunprogramaqueleaunafr aseydecidasiespalíndr oma.Unafr aseespalíndromasisepuedeleerigualdeizquierdaaderechaydederechaaizquierda.Ejemplo“para” noespalíndroma, pero“alila” síqueloes.
18.12. Escribirunprogramaparagestionarunacolagenéricaimplentadaconunarr aydinámicocircularconcontroldeexcepciones.
CAPÍTULO 18 Pilas y colas
361
SOLUCIÓN DE LOS EJERCICIOS
18.1. Seusalaimplementacióndelaclasepilar ealizadaenlosEjemplos18.1o18.2.Medianteunb ucle do while seleenlos
datosyenotrobuclewhile sevisualizanlosresultados.
La codificación de este ejercicio se encuentra en la página Web del libro.
18.2. Sevacíalapilayposteriormenteseañadeeldato 4.SeEscribeelprimerodelapilaquees 4.Seborraelprimerelementodelapilaconloquesevuelveaquedarvacía.Seañadeelnúmer o32 alapila, paradespuésborrarlo, yluegoañadirlo.Elúltimob ucleextraeelnúmero 32 delapila, loescribeydespuésdeborr arlo, lapilasequedavacíaconloquese
saledelbucle.Esdecir, lasoluciónes:
4
32
18.3. Eldestructorrecorretodoslosnodosdelapilaliber andolamemoriaaltiempoquemue veelatributoqueapuntaalprimernodo.
La codificación de este ejercicio se encuentra en la página Web del libro.
18.4. Lafunciónnomiembrodelaclase Pila, Copiar recibelapila p comoparámetroporvalor, yretornacomoresultadouna
copiadelapilaenelparámetroporreferenciap1.Sevuelca, enprimerlugar, elcontenidodelapila p enlapilaauxiliar
p2, paraposteriormentehacerlomismoconlapila p2 sobrelapila p1.
La codificación de este ejercicio se encuentra en la página Web del libro.
18.5. Medianteunbucle while seiteramientrasquedendatosenlapila, extrayendoelprimerelemento, borrándoloyvisualizándolo.Comoelparámetroesporvalor, laPila P nosedestruyenfueradelafunciónnomiembrodelaclase Pila.
La codificación de este ejercicio se encuentra en la página Web del libro.
18.6. Traslaprimeraoperaciónseescribirá Mar y Generosa, quedandolacolacon Mar, Sella, Centurión Gloria, Generosa.Despuésder ealizarlase gundaoperaciónseescribirá Sella y Generosa, quedandolacolacon Sella, Centurión
Gloria, Generosa.Despuésdeañadir Positivo seescribirá Sella y Positivo ylacolacontendrálossiguienteselementosSella, Centurión Gloria, Generosa, Positivo. AlañadirHorche alacolaseproduciráunerroryaquelacola
estállenainterrumpiéndoselaejecucióndelpr ograma.
18.7. Lafunciónrecibecomoparámetrounacolaylapresentaenpantalla.Paraellomedianteunbuclewhile extraeelementos
delacolaylosescribe .Elcódigoincluyeuncontador, paraquecadavezquesehayanescrito10elementossaltardelínea, yfavorecerdeestaformalavisualizacióndelosdatos.
La codificación de este ejercicio se encuentra en la página Web del libro.
18.8. Pararesolverelproblema, usauncontadorqueseinicializaacero, yseincrementeenunaunidad, cadavezqueunbucle
while extraeunelementodelacola.
La codificación de este ejercicio se encuentra en la página Web del libro.
CAPÍTULO 18 Pilas y colas
362
SOLUCIÓN DE LOS PROBLEMAS
18.1. Unapilapuedeimplementar seconunarr aydinámico, simplementecambiadoelatrib uto A delarray, porunpunter oal
tipodedato.Ahorabien, paraquelapilafuncione, eltamañomáximodelapiladebeserdefinidoaldeclararlo, porloque
elconstructordelaPila, debehacerlareservadememoriacorrespondiente.LaclasePila, seimplementacomoelEjemplo 18.1, perocambiansolamente, eltipodelatributoA, yelconstructorPila, porloquesóloseincluyeladeclaraciónde
laclaseylaimplementacióndelconstructor.
La codificación de este problema se encuentra en la página Web del libro.
18.2. Laimplementaciónconarr aydinámicoessimilaralar ealizadaenelpr oblemaanterior.Parapermitirlag eneredicidad
detipos, hayqueañadir template.Seincluyeademásunprogramaprincipalcomoejemplodellamada.
La codificación de este problema se encuentra en la página Web del libro.
18.3. Lafunciónnomiembrodelaclase Pila MayorPila calculaelelementomayor, inicializandolavariable Mayor aunnúmeromuypequeño, ymedianteunb uclevorazcontroladoporservacíalapilasee xtraenloselementosdelapilar eteniendoelmayordetodos. MenorPila calculaelelemento Menor.Serealizademaneraanálogaalafunción MayorPila.
La codificación de este problema se encuentra en la página Web del libro.
18.4. LafunciónnomiembrodelaclasepilaMediaPila calculalamediadeunapila, paralocualbastaacumularlosdatosque
contienelapilaenunacumuladorTotal yconcontadork contarloselementosquehay, paradevolverelcocienterealentreTotal yk, convirtiendopreviamenteTotal afloat, paraobligaraqueelcocientesear eal.
La codificación de este problema se encuentra en la página Web del libro.
18.5. Dospilassonigualessitienenelmismonúmer odeelementosyademáscoincidenenelor dendecolocación.P ortanto,
bastaconunbuclemientras controladoporlaexistenciadedatosenlasdospilasyhabersidotodosloselementosextraídosanteriormenteiguales, extraerunelementodecadaunadelaspilasyseguirdecidiendosobresuigualdad.Alfinaldel
bucledebeocurrirquelasdospilasesténvacíasyademásquelavariablelógicaquecontr olaelbucleseaverdadera.
La codificación de este problema se encuentra en la página Web del libro.
18.6. Seusantrespilas.Enlaprimer a, seintroducentodosloscar acteresqueesténantesqueelcarácter &.Enlase gunda, se
introducentodosloscaracteresqueesténdespuésde &.Seguidamente, sedalavueltaalaprimer apilaparadejarloscaracteresenelmismoor denenelquesele yeron.Porúltimo, seretornaelvalordesonigualeslasdospilas.Lafunción
SonIgualesPilas sehacodif icadoenelPr oblema18.5.Secodif icanademáslafunción DaVueltaPila, querecibeuna
pilacomoparámetroyladalavuelta.
La codificación de este problema se encuentra en la página Web del libro.
18.7. Paracomprobarelequilibriodeparéntesisycor chetes, hayquedecidirsitienenelmismonúmer odeabiertosquecerr adosyademássiaparecenenelordencorrespondiente.Seusaunapilaporlaquepasansólolosparéntesisabiertosylos
corchetesabiertosenelor denenqueaparecen.Cadavezquenosapar ezcaunparéntesiscerradoouncorchetecerrado,
seextraeunelementodelapila, comprobandosuigualdadconelúltimoquesehaleídoalmacenadoenunavariablelógicasw elvalorverdaderoofalsodependiendodequesesatisfagalaigualdad.Portanto, siconunbuclewhile controladoporelfindelíneayporelvalorverdaderodeunavariable sw detipológico(previamenteinicializadaaverdadero), se
leenloscaracteresyrealizaloindicadocuandotermineelb uclepuedeserque sw seafalso, encuyocasolaexpresiónno
escorrecta, oqueseseaverdadero, encuyocasolaexpresiónserácorrectasilapilaestávacía.
La codificación de este problema se encuentra en la página Web del libro.
18.8. Una Cola esunaclasequecontieneunatrib utoqueesunpunter oalnododelalistasimplementeenlazadadenominado
Nodo.TodaslasfuncionesmiembrotienenlamismaestructuraqueenelEjemplo18.4.Laclase Cola tieneunsoloatribu-
CAPÍTULO 18 Pilas y colas
363
toprotegidoC queesunpunteroalaclase Nodo.Laimplementaciónserealizadetalmaneraquesila Cola noestávacía
elatributoC apuntaalúltimonododelacolayelsiguientede C apuntasiemprealprimerelementodelacola.Losmétodosdelaclase Cola son:
• Cola.Eselconstructorpordefectoqueponeeltrib utoC NULL.
• Cola (const Cola &p2).Seencargadehacerunacopiadela p2 enla Cola, paraellocrealacolavacía, yposteriormenterecorretodoslosnodosdelacola p2 yselosañadea p2.
• ~Cola().Eseldestructordela Cola.Seencargadeenviaralamemoriadisponibletodoslosnodosdela Cola.
• VaciaC.Creaunacolavacía, paralocualbastaconponerC aNULL.Realizaelmismotrabajoqueelconstructorpordefecto.
• EsVacíaC.Decidesiunacolaestávacía.Esdecirsi C valeNULL.
• PrimeroC.Extraeelprimerelementodelacolaqueseencuentr aenelatributocorrespondientedelpunteroC->OSig().
Previamenteaestaoperaciónhadecomprobarsequelacolanoestévacía.
• AnadeC.Añadeunelementoalacola.EsteelementoseañadeenunnuevonodoqueseráelsiguientedeC.Silacolaestá
vacíaantesdeañadir, hayquehacerqueelnue vonodoseapunteasímismoy C apuntealnuevonodo.Encasodeque
lacolanoestévacía, elnuevonododebeañadirse, entrelospunterossiguientede C yelsiguientedelsiguientede C.En
todocasosiempreC debeapuntaralnuevonodo.
• BorrarC.Eliminaelprimerelementodelacola.P arahacerestaoper aciónlacolanodebeestarvacía.Elborr adose
realizaeliminadoelnodoapuntadoporelsiguientede C yestableciendolosenlacescorrespondientes.Siemprehayque
considerarquelacolasequedavacía.
La codificación de este problema se encuentra en la página Web del libro.
18.9. Siseusanlosmétodosdeg estiónde colas, loúnicoquehayquehaceresinicializar Mayor y menor alprimerelemento
delacola, ymedianteunbuclevorazcontroladoporsevacíalacolairactualizandolasvariables Mayor ymenor.
La codificación de este problema se encuentra en la página Web del libro.
18.10. Doscolas C1 y C2 soniguales, sitienenelmismonúmerodeelementosyademásestáncolocadosenelmismoor den.Por
loquelacodificaciónestansencillacomoirextrayendoelementosdelasdoscolasycomprobandoquesiguensiendoiguales.Seimplementaconunb uclevorazqueinicializaunavariable bool sw a true eiteramientrasquedendatosenlas
doscolasyelsw sigamanteniéndoseatrue.Unavezquesehaterminadodeextraerlosdatosdelascolas, paraquesean
igualesdebenestarlasdoscolasvacías, yademáslavariable sw estara true.
La codificación de este problema se encuentra en la página Web del libro.
18.11. Lafunciónrecibecomoparámetrounacolaporreferencia C yunelemento e.Medianteunbucle while poneenunacola
C1 todosloselementosdelacolaqueserecibecomoparámetroquecumplenlacondicióndesermenoresoigualesqueel
elementoe queserecibecomoparámetro.Unavezterminadoelprocesosecopialacola C1 enlapropiacola C.
La codificación de este problema se encuentra en la página Web del libro.
18.12. Unejemplodeunafrasepalíndromaes: “dabalearrozalazorraelabad”.Pararesolverelproblemabastaconseguirlasiguienteestrategia: añadircadacarácterdelafr asequenoseablancoaunapilayalavezaunacola.Lae xtracciónsimultáneadecaracteresdeambasysucompar acióndeterminasilafraseesonopalíndroma.Lasoluciónestádadaenla
funciónpalíndroma.Seusaademásunafunción, SonIguales, quedecidesiuna Pila yuna Cola querecibecomoparámetrosconstandelosmismoscar acteres.
La codificación de este problema se encuentra en la página Web del libro.
18.13. Laimplementaciónqueser ealizaestábasadaenlacolacir cularexplicadaenlateoría.Sehanomitidoalgunasprimitivasdeg estióndelacola, dejándosesolamenteelconstructor, destructor, AnadeC queañadeunelementoalacolay BorraC queborraunelementodelacolaylor etorna.Lazonaprotegidatienedeclaradounpuntero A altipogenérico TipoDato queesdeclaradoenunaplantilladeclases.AestepunterogenéricoA selereservamemoriaenelmomentoquese
CAPÍTULO 18 Pilas y colas
364
llamaalconstructor, yenelcasodequesepr oduzcaalgúnerr orenlamemoriaselanzalacorr espondienteexcepción.
Parapoderlanzarlase xcepcionesdelosmétodosqueañadenyborr anundatodelacola, sedefinelasfuncionesmiembroocultasenunazonaprivada EsvaciaC y EstallenaC quedecidensilacolaestávacíaollena.Lafunciónmiembr o
AnadeC añadeundatoalacolasihayespacio, obienlanzaunae xcepciónenelcasodequenopuedahacerloporestar
lacolallena.Lafunciónmiembr o BorraC eliminaelprimerelementodelacolasilohay , yenotrocasolanzalae xcepcióncorrespondiente.Enelpr ogramaprincipalsedeclar aunacolade2datosyser ecogenlase xcepcionescorrespondientesenelcasodequelashubier a.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
18.1. Obtenerunasecuenciade10elementosreales, guardarlosenunarrayyponerlosenunapila.Imprimirlasecuenciaoriginaly, acontinuación, imprimirlapilae xtrayendoloselementos.
18.2. Setieneunapiladeenterospositi vos.Conlasoperacionesbásicasdepilasycolasescribirunfragmentode
códigoparaponertodosloselementosquesonparesde
lapilaenlacola.
18.3. Escribirunprogramaenelquesegeneren100números
aleatoriosenelrango–25...+25yseguardenenuna
pilaimplementadamedianteunarrayconsideradocircular.Unavezcreadalacola, elusuariopuedepedirque
seformeotracolaconlosnúmerosne gativosquetiene
lacolaoriginal.
18.4. Escribirunafunciónquein viertaelcontenidodeuna
colausandolosmétodosdeunaclase Cola.
PROBLEMAS PROPUESTOS
18.1. Unabicolaesunaestructuradedatoslinealenlaquela
inserciónyborradosepuedenhacertantoporele xtremofrente comoporelextremofinal.Suponerquese
haelegidounarepresentacióndinámica, conpunteros, y
quelosextremosdelalistasedenominanfrente yfinal.Escribirlaimplementacióndelasoperaciones: InsertarFrente(), InsertarFinal(), EliminarFrente() yEliminarFinal().
18.2. Considereunabicoladecaracteres, representadaenun
arraycircular.Elarrayconstade9posiciones.Lose xtremosactualesyloselementosdelabicola:
frente = 5
final = 7
•
•
•
•
Añadirelelemento M porel final delabicola.
Eliminardoscaracteresporel frente.
Añadirloselementos K y L porel final delabicola.
Añadirelelemento S porel frente delabicola.
18.3. Conunarchivodetextosequierenrealizarlassiguientesacciones: formarunalistadecolas, detalformaque
encadanododelalistaestéladireccióndeunacolaque
tienetodaslaspalabrasdelarchi voqueempiezanpor
unamismaletra. Visualizarlaspalabrasdelarchi vo,
empezandoporlacolaquecontienelaspalabrasquecomienzanpor a, acontinuaciónlasdelaletra b, asísucesivamente.
Bicola: A,C,E
Escribirlosextremosyloselementosdelabicolasegún
serealizanestasoperaciones:
• Añadirloselementos F y K porel final delabicola.
• Añadirloselementos R, W y V porel frente delabicola.
18.4. Escribirunprogramaenelquesemanejenuntotalde
n =5pilas: P1, P2, P3, P4 y P5.Laentradadedatosserá
paresdeenteros(i,j) talque1 ≤ abs(i) ≤ n.Detal
formaqueelcriteriodeseleccióndepila:
• Sii espositivo, debedeinsertarseelelementoj enla
pilaPi.
CAPÍTULO 18 Pilas y colas
• Si i esnegativo, debedeeliminarseelelemento j de
lapila Pi.
• Sii escero, findelprocesodeentrada.
Losdatosdeentradaseintroducenporteclado.
Cuandoterminaelprocesoelprogramadebeescribirel
contenidodelanpilas enpantalla.
18.5. Setratadecrearunacolademensajesquesirv acomo
buzónparaquelosusuariospuedandepositaryrecoger
mensajes.Losmensajespuedentenercualquierformato, perodebencontenerelnombredelapersonaalaque
vandirigidosyeltamañoqueocupaelmensaje.Los
usuariospuedendejarsusmensajesenlacolayalrecogerlosespecificarsunombreporelquerecibiránelprimermensajequeestáasunombreounaindicaciónde
quenotienenningúnmensajeparaellos.Realizarel
365
programadeformaquemuestreunainterfazconlasopcionesindicadasyqueantesdecerrarseguardelos
mensajesdelacolaenunarchi vobinariodelquepuedarecogerlosenlasiguienteejecución.
18.6. Escribaunafunciónquerecibaunae xpresiónennotaciónpostfijaylaevalúe.
18.7. Unav ariantedelconocidoproblemadeJoséeselsiguiente.Determinarlosúltimosdatosquequedande
unalistainicialden >5númerossometidaalsiguiente
algoritmo: seinicializan1 a2.Seretirandelalistalos
númerosqueocupanlasposiciones 2, 2+n1, 2+2∗n1,
2 +3*.n1, ..., etc.Seincrementa n1 enunaunidad.Si
quedanenlalistamenosde n1 elementossepara, en
otrocasoseitera. Escribirunprogramaqueresuelvael
problema.
CAPÍTULO 19
Recursividad
Introducción
Larecursividad (recursión)eslapropiedadqueposeeunafuncióndepermitirquedichafunciónpuedallamarseasímisma.
Sepuedeutilizarlarecursi vidadcomounaalternati vaalaiteración.Larecursiónesunaherramientapoderosaeimportante
enlaresolucióndeproblemasyenlaprogramación.Unasoluciónrecursi vaesnormalmentemenoseficienteentérminosde
tiempodecomputadoraqueunasolucióniterativa;sinembargo, enmuchascircunstanciaselusodelarecursiónpermitealos
programadoresespecificarsolucionesnaturales, sencillas, queserían, encasocontrario, difícilesderesolver.
19.1. La naturaleza de la recursividad
Unafunciónrecursiva esaquellaquesellamaasímismobiendirectamente, obienatravésdeotrafunción.Enmatemáticas
existennumerosasfuncionesquetienencarácterrecursi vo, deigualmodo, numerosascircunstanciasysituacionesdelavida
ordinariatienencarácterrecursi vo.Unafunciónquetienesentenciasentrelasqueseencuentraalmenosunaquellamaala
propiafunciónsedicequees recursiva.
EJEMPLO 19.1. Funciónrecursivaquecalculaelfactorialdeunnúmer on>0.
Esconocidoque 5! = 5.4.3.2.1 = 5.4! = 120.Esdecir n! = n.(n – 1)!
Asípues, ladefiniciónrecursivadelafunciónfactorialeslasiguiente:
Factorial(n) = n*Factorial(n–1) si n > 0
Factorial(n) = 1 si n = 0.
Unacodificacióndelafunciónes:
int Factorial(int n)
{
if (n == 0)
return 1;
else
return (n * Factorial (n – 1));
}
367
CAPÍTULO 19 Recursividad
368
19.2. Funciones recursivas
Unafunciónrecursiva esunafunciónqueseinvocaasímismodeformadirectaoindirecta.En recursión directa elcódigo
delafunción f() contieneunasentenciaqueinvocaa f(), mientrasqueenrecursión indirecta f() invocaalafunción g()
queinvocaasuvezalafunciónp(), yasísucesivamentehastaqueseinvocadenuevoalafunciónf().Unrequisitoparaque
unalgoritmorecursivoseacorrectoesquenogenereunasecuenciainf initadellamadassobresímismo.Enconsecuencia, la
definiciónrecursivadebeincluirun componente base (condicióndesalida)enelque f(n) sedefinadirectamente(esdecir,
norecursivamente)paraunoomásv aloresde n.Cualquieralgoritmoquegenereunasecuenciadeestetipopuedenoterminarnunca.Todafunciónrecursivausaunapiladellamada.Cadavezquesellamaaunafunciónrecursivatodoslosvaloresde
losparámetrosformalesyvariableslocalessonalmacenadosenunapila.Cuandoterminadeejecutarseunafunciónrecursi va
seretornaalni velinmediatamenteanterior, justoenelpuntodeprogramasiguientealqueprodujolallamada.Enlapilase
recuperanlosvalorestantodelosparámetroscomodelasdev ariableslocales, ysecontinúaconlaejecucióndelasiguiente
instrucciónalallamadarecursiva.
EJEMPLO 19.2. Funciónrecursivadirectaquecuenta, visualizandolosresultadosymostr andoelfuncionamiento
delapilainterna.
Elsiguienteprogramapermiteobservarelfuncionamientodelarecursi vidad.Lafunción contar decrementaelparámetroylomuestraysielv aloresmayorquecero, sellamaasímismadondedecrementaelparámetrounav ezmás
encasodequeseapositi vo, yencasodequenoseapositi vonohacenada, queeslaparadadelafunción.Cuandoel
parámetroalcanzaelvalordecerolafunciónyanosellamaasímismayseproducensucesi vosretornosalpuntosiguienteadondeseefectuaronlasllamadas, dondeserecuperadelapilaelv alordelparámetroysemuestra.
#include <cstdlib>
#include <iostream>
using namespace std;
void contar(int n)
{
n -- ;
cout << " " << n << endl;
if (n > 0)
contar(n);
cout <<" " << n << endl;
}
int main(int argc, char *argv[])
{
int n;
do
{
cout << " Escriba un numero entero positivo: ";
cin >> n;
} while (n <= 0);
contar(n);
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 19.3. Funcionesrecursivasindirectasquevisualizanelalfabeto.
ElprogramaprincipalllamaalafunciónrecursivaA() conelargumento'Z' (laúltimaletradelalfabeto).Lafunción A
examinasuparámetro c.Si c estáenelordenalfabéticodespuésque 'A', lafunciónllamaa B(), queinmediatamen-
CAPÍTULO 19 Recursividad
369
tellamaa A(), pasándoleunparámetropredecesorde c.Estaacciónhaceque A() vuelvaaexaminarc, ynuevamenteunallamadaaB(), hastaquec seaiguala'A'.Enestemomento, larecursiónterminaejecutandocout << c; veintiséisvecesyvisualizandoelalfabeto, carácteracarácter.
#include <cstdlib>
#include <iostream>
using namespace std;
void A(char c);
void B(char c);
void A(char c)
{
if (c > 'A')
B(c);
cout << c;
}
void B(char c)
{
A(--c);
}
int main(int argc, *argv[])
{
A('Z');
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
EJEMPLO 19.4. Seimplementandosfuncionesconrecursividadindirecta.
Lafunción f retornaelvalordesuparámetrossiésteesmenoroigualque 3.Enotrocasollamaalafunción g decrementandoelparámetroendosunidades, yretornadoelvalorobtenidomáselpropioparámetro.Porsupartelafunción
g retornaelvalordesuparámetrosiésteesmenoroigualque 2.Enotrocasoretornaelv alorobtenidodelallamada
alafunción f decrementandoelparámetroendosunidadesmáselpropioparámetro.
float f( float y);
float g( float y);
float g( float y)
{
if (y <= 3)
return y ;
else
return y + f(y – 2);
}
float f( float y)
{
if (y <= 2)
return y ;
else
return y + g(y – 2);
}
CAPÍTULO 19 Recursividad
370
19.3. Recursión versus iteración
Tantolaiteracióncomolarecursiónsebasanenunaestructuradecontrol: laiteraciónutilizaunaestructurarepetitivaylarecursiónutilizaunaestructuradeselección.Laiteraciónutilizaexplícitamenteunaestructurarepetitivamientrasquelarecursiónconsiguelarepeticiónmediantellamadasrepetidasafunciones.Larecursiónin vocarepetidamentealmecanismodellamadasafuncionesy , enconsecuencia, senecesitauntiempoyespaciosuplementariopararealizarcadallamada.Esta
característicapuederesultarcaraentiempodeprocesadoryespaciodememoria.Laiteraciónseproducedentrodeunafuncióndemodoquelasoperacionessuplementariasdelasllamadasalafunciónyasignacióndememoriaadicionalsonomitidas.Todafunciónrecursivapuedesertransformadaenotrafunciónconesquemaiterativo, paraelloavecessenecesitanpilas
dondealmacenarcálculosparcialesyv aloresdevariableslocales.Larazónfundamentalparaele girlarecursiónesquee xistennumerososproblemascomplejosqueposeennaturalezarecursi vay, enconsecuencia, sonmásfácilesdediseñareimplementarconalgoritmosdeestetipo.
EJEMPLO 19.5. VersiónrecursivaeiterativadelafuncióndeFibonacci.
LafuncióndeFibonaccisedef inerecursivamentedelasiguienteforma:
Fibonacci( n ) = Fibonacci( n – 1) + Fibonacci( n – 2)
Fibonacci(n) = n enotrocaso.
si n > 1;
Pararealizarlaprogramacióniterativa, hayqueobservarquelasecuenciadenúmerosdef ibonaccies: 0, 1, 1, 2, 3, 5,
8, 13…Estasecuenciaseobtienepartiendodelosnúmeros0, 1yapartirdeelloscadanúmeroseobtienesumando
losdosanteriores: an = an – 1 + an – 2.Sisedefinendosvariableslocales a1 ya2, convenientementeinicializadasa
0 ya1 respectivamente, elsiguientevalordelaserieseobtienesumando a1 ya2 enotravariablelocala3.Siahorase
hacea1 = a2 y a2 = a3, setienenenestasdosvariableslosdossiguientesnúmerosdelaserie, porloquealiterar
sevanobteniendotodoslossucesivosvalores.
long Fibonacci(int n)
{
if (n == 0 || n == 1)
return (n);
else
return(Fibonacci(n – 1) + Fibonacci(n – 2));
}
// recursiva
long FibonacciIterativa(int n)
{
long a1 = 0, a2 = 1, a3, i;
for ( i = 2; i <= n; i++)
{
a3 = a1 + a2;
a1 = a2;
a2 = a3;
}
return a3;
}
19.4. Recursión infinita
Larecursión infinita seproducecuandounallamadarecursivarealizaotrallamadarecursivayéstaasuvezotrallamadarecursivayasíindefinidamente.Unarecursióninfinitaocurresilaetapaderecursiónnoreduceelproblemaencadaocasiónde
modoqueconverjasobreelcasobaseocondicióndesalida.Elflujodecontroldeunafunciónrecursi varequieretrescondicionesparaunaterminaciónnormal:
CAPÍTULO 19 Recursividad
371
• Untestparadetener(ocontinuar)larecursión( condicióndesalida ocasobase).
• Unallamadarecursiva(paracontinuarlarecursión).
• Uncasofinalparaterminarlarecursión.
EJEMPLO 19.6. Funciónrecursivaquecalculalasumadeloscuadr adosdelosNprimerosnúmerospositivos.
Lafunción sumacuadrados implementadarecursivamente, requiereladefiniciónpreviadelasumadeloscuadrados
primerosN enterosmatemáticamenteenformarecursivatalcomosemuestraacontinuación:
suma(N) =
5
1
si
N = 1
N2 + suma(N–1)
en caso contrario
int sumacuadrados(int n)
{
if (n == 1)
//test para parar o continuar (condición de salida)
return 1;
//caso final. Se detiene la recursión
else
return n*n + sumacuadrados (n – 1);
//caso recursivo. la recursión
//continúa con llamada recursiva
}
Estarecursiónparasiemprequesellamealafunciónconunv alorde n positivo, peroseproduceunarecursividadinfinitaencasodequesellameconunv alorde n negativoonulo.
EJEMPLO 19.7. Funciónrecursivaquecalculaelproductodedosnúmerosnaturales, usandosumas.
Elproductodedosnúmerosnaturalesa yb sepuededefinirrecursivamentedelasiguienteforma: Producto(a, b)= 0
si b = 0; Producto(a, b) = a + Producto(a, b – 1) si b > 0.Estafuncióntendráunallamadarecursi vainfinitasiesllamadaconelv alordelsegundoparámetronegativo.
int Producto(int a, int b)
{
if (b = 0)
return 0;
else
return a + Producto(a, b – 1);
}
EJERCICIOS
19.1. Expliqueporquélasiguientefunciónpuedeproducirunvalorincorrectocuandoseejecute:
long factorial (long n)
{
if (n = = 0|| n = = 1)
return 1;
else
return n * factorial (--n);
}
CAPÍTULO 19 Recursividad
372
19.2. ¿Cuáleslasecuencianuméricag eneradaporlafunciónrecursivafenellistadosiguiente?
long f(int n)
{
if (n = = 0|| n = = 1)
return 1;
else
return 3 * f(n – 2) + 2 * f(n – 1);
}
19.3. Cuáleslasecuencianuméricag eneradaporlafunciónrecursivasiguiente?
int f(int n)
{
if (n = = 0)
return 1;
else if (n = = 1)
return 2;
else
return 2 * f(n – 2) + f(n – 1);
}
19.4. Escribirunafunciónquecalculeelelementomayordeunarr aydenenterosrecursivamente.
19.5. Escribirunafunciónr ecursivaquer ealicelabúsquedabinariadeunaclaveenunvectoror denadocrecienteyr ecursivamente.
PROBLEMAS
19.1. Escribirunafunciónquecalculelapotenciaa n recursivamente, siendonpositivo.
19.2. Escribirunafunciónrecursivaquecalculelafunciónde Ackermanndefinidadelasiguienteforma:
A(m, n) = n + 1
A(m, n) = A (m – 1, 1)
A(m, n) = A(m – 1, A(m, n – 1))
si
si
si
m = 0
n = 0
m > 0, y n > 0
19.3. Escribirunafunciónrecursivaquecalculeelcocientedeladivisiónenter adenentrem, siendomyndosnúmer osenterospositivosrecursivamente.
19.4. Escribirunprogramaquemedianteunafunciónr ecursivacalculelasumadelosnprimer osnúmerospares, siendonun
númeropositivo.
19.5. EscribirunprogramaenC++quemedianter ecursividadindirectadecidasiunnúmer onaturalpositivoesparoimpar .
19.6. Escribirunafunciónrecursivaparacalcularelmáximocomúndivisordedosnúmer osnaturalespositivos.
19.7. Escribirunafunciónrecursivaqueleanúmerosenterospositivosordenadosdecrecientementedelteclado, eliminelosrepetidosylosescribaalrevés, esdecir, ordenadocrecientemente.Elfindedatosvienedadoporelnúmer oespecial0.
CAPÍTULO 19 Recursividad
373
19.8. Escribirunafuncióniterativayotrarecursivaparacalcularelvaloraproximadodelnúmeroe, sumandolaserie:
e =1+1/1 !+1/2 !+...+1/n !
hastaquelostérminosadicionalesasumarseanmenor esque1.0e –8.
19.9. Escribirunafunciónrecursivaquesumelosdígitosdeunnúmer onatural.
19.10. Escribirunafunciónr ecursiva, quecalculelasumadeloselementosdeunvectorder ealesvqueseanmayor esqueun
valorb.
19.11. Escribirunaclase ListaS queconlaayudadeunaclase Nodo, permitalaimplementacióndelistasenlazadasr ecursivas
conobjetos.Incluirenlaclase ListaS funcionesmiembroquepermitaninsertarr ecursivamente, yborrarrecursivamente, enunalistaenlazadaordenadacrecientemente, asícomomostrarrecursivamenteunalista.
19.12. AñadaalaclaseListaS delProblema19.11queimplementaunalistaenlazadaordenadarecursivamenteconobjetosfuncionesmiembroquepermitanlainserciónyborradoiterativo.
SOLUCIÓN DE LOS EJERCICIOS
19.1. Lafunciónfactorialescritaproduceunbucleinfinitosiselellamaporprimeravezconunvalordennegativo.Ademássi
sesuponequelafunciónhasidoescritapar acalcularelfactorialdeunnúmer o, hayqueobservarquenopr oduceelresultadodeseado.Laejecucióndelafuncióncuando n esmayorque 1 comienzaconunallamadarecursivaquedecrementaelvalordenenunaunidad, porloquecuandoseejecutaelpr oductonomultiplicapor n, sinopor n – 1.Esdecir, la
funciónenlugardecalcularelfactorialdeunnúmer on calculaelfactorialde n–1, sinesmayoroigualque2.Siseejecutaelsiguienteprogramaseobtieneelresultadoquevisualizaloexplicado.
La codificación de este ejercicio se encuentra en la página Web del libro.
19.2. Paraelcasodeque n valga 0 o 1 lafunciónretornasiempre 1.Enotrocasoretornaelvalorde 3 * f(n – 2) + 2 *
f(n – 1).Esdecir, multiplicaelvaloranteriordelafunciónpor2, yselosumaaltripledelvalorobtenidoporlafunciónenelvaloranteriordelanterior .Portanto, laserieeslasiguiente: 1, 1, 5, 13, 41, 121, 365, 1093, 3281,
9841.Porejemplo, 41 = 5*3 + 13*2.
19.3. Sin vale0, retornaelvalorde 1, sin vale2, retornaelvalorde 2, sin vale3, retornaelvalorde 2*1 + 2 = 4, sin vale
4, retornaelvalorde 2*2+ 4= 8.Lasecuenciadeejecuciónes: 1, 2, 4, 8, 16, 32, 64, 128, 256, ...
19.4. Sedefineenprimerlugarlafunciónint max(int x, int y); quedevuelveelmayordedosenterosx ey.Sedefineposteriormentelafunción int maxarray(int a[], int n) queutilizalarecursiónparadevolverelelementomayordea.
Condicióndeparada:
Incrementorecursivo:
n == 1
maxarray = max(maxarray(a[0]...a[n–2]),a[n–1])
La codificación de este ejercicio se encuentra en la página Web del libro.
19.5. Lafunción busquedaBR, recibecomoparámetrounvector, la clave yelrangoinferiorysuperiordondesedeber ealizar
labúsqueda.Lafunciónretornaunaposicióndelvectordondeseencuentr alaclave, obienelvalorde –1 encasodeque
noseencuentre.Labúsquedasebasaencalcularel centro delalistaqueseencuentraaigualdistanciadelaparteinferiorylasuperior.Labúsquedaterminaconéxito, sien centro seencuentrala clave.Serealizaunallamadarecursivaa
CAPÍTULO 19 Recursividad
374
laizquierdadecentro enelcasodequelaclaveseamayorqueelelementoqueocupalaposiciónylallamadar ecursiva
serealizaaladerechaenotrocaso.Hayquetenerencuentaque clave puedenoencontrarseenelvector.Estaposibilidadsedetectacuandoelr angoinferiorexcedealrangosuperior.
La codificación de este ejercicio se encuentra en la página Web del libro.
SOLUCIÓN DE LOS PROBLEMAS
19.1. Lapotenciadea n sepuededefinirrecursivamentedelasiguienteforma: an =1 sin =0 yes a ∗nn –1 enotrocaso.Hay
queobservarquesóloesválidopar avaloresdenpositivo.
La codificación de este problema se encuentra en la página Web del libro.
19.2. Lafunciónde Ackerman esunejemplodefunciónr ecursivaanidada, dondelallamadarecursivautilizacomoparámetro
elresultadodeunallamadarecursiva.
La codificación de este problema se encuentra en la página Web del libro.
Lossucesivosvaloresdelaserieson:
A(m,n)
m = 0
m = 1
m = 2
m = 3
m = 4
n = 0
1
2
3
5
13
n = 1
2
3
5
13
65533
n = 2
3
4
7
29
265536–3
n = 3
4
5
9
61
n = 4
5
6
11
125
n = 5
6
7
13
253
n = 6
7
8
15
509
19.3. Elcocientedeladivisiónenter ade n entre m, siendoambosnúmer osenterospositivossecalcular ecursivamentedela
siguienteformasi n < m entonces cociente(n, m) = 0, si n >= m entonces cociente(n, m) = 1 + cociente
(n – m, m), porloquelacodificacióndelafunciónes:
La codificación de este problema se encuentra en la página Web del libro.
19.4. Lasumadelosnprimerosnúmerospares, siendonpositivo, vienedadaporlaexpresión:
n
S =2∗ 1+2∗ 2+...+2 ∗ (n –1)+2 ∗ n =Σ 2∗ i =(n +1)n
i=1
Elprogramasolicitaalusuarioelvalorde n validandolaentr adayejecutalafunción sumapares, querecibecomo
argumentoelvalordei.Siestevaloresmayorque1 obtienelasumaejecutandolasentencia2 * i + sumapares(i–1).
Enotrocaso, lasumadelprimernúmeroparessiempre2.
La codificación de este problema se encuentra en la página Web del libro.
19.5. Seprogramandosfuncionesmutuamenter ecursivasquedecidensiunnúmer oespar, paraloquesetieneencuentaque:
par(n) = impar(n – 1) si n >1.
par(0) = true
impar(n) = par(n – 1) si n > 1.
impar(0) = false.
Seincluye, además, unprogramaquerealizaunallamadaalafunciónpar.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 19 Recursividad
375
19.6. Elmáximocomúndivisortieneunaseriedeaxiomasqueladef inendelasiguienteforma: Mcd(m, n) = Mdc(n, m) si
m < n; Mcd(m, n) = Mdc(n, m mod n) si m >= n y m mod n != 0; Mcd(m, n)= n si n <= m y n mod m = 0.Por
loqueunacodificacióneslasiguiente:
int Mcd(int m, int n)
{
if ((n <= m) && (m % n == 0))
return n;
else if (m < n)
return Mcd(n, m);
else
return Mcd(n, m % n);
}
19.7. Lafunciónrecursivaqueseescribetieneunparámetrollamadoant queindicaelúltimonúmeroleído.Inicialmentesellamaalafunciónconelvalor –1 quesesabequenopuedeestarenlalista.Loprimer oquesehaceesleerunnúmeron de
lalista.Comoelfinaldelalistavienedadapor 0, siseleeel0 entonces“serompe” larecursividadysedaunsaltodelínea.Encasodequeelnúmer oleídonosea 0 setienendosposibilidades: laprimeraesque n nocoincidaconelanterior
dadoen ant, encuyocasosellamaalar ecursividadconelvalorde ant, dadopor n, para, posteriormenteyalavuelta
delarecursividad, escribireldaton;lasegundaesquen coincidaconant, encuyocasosellamaalarecursividadconel
nuevovalorde ant, dadopor n, peroahoraalavueltadelar ecursividadnoseescribe n, puesestárepetido.
La codificación de este problema se encuentra en la página Web del libro.
19.8. Lafunciónloge(), calculaiterativamentelasumadelaserieindicadadelasiguienteforma: lavariabledelta contieneen
todomomentoelvalordelsiguientetérminoasumar.Esdecir, tomarálosvaloresde1, 1/1!, 1/2!, 1/3!, ... 1/n!.
Lavariablesuma contienelassumasparcialesdelaserie, porloqueseinicializaacero, yencadaiteraciónsevasumando
elvalorde delta.Lavariable n contienelosvaloresporlosquehayquedividir delta encadaiteraciónparaobtenerel
siguientevalorde delta conocidoelvaloranterior.Lafunción logeR() codificalaserierecursivamente.Tienecomoparámetroelvalorde n yelvalor delta.Elvalorde n debeserincrementadoenunaunidadencadallamadar ecursiva.El
parámetro delta contieneencadamomentoelvalordeltérminoasumardelaserie .Sieltérminoasumaresmayoro
igualque1.0 e–8, sesumaeltérminoalallamadarecursivadelafunciónrecalculandoenlapropiallamadaelnuevovalorde delta (dividiéndoloentren +1).Sieltérminoasumardeltaesmenorque 1.0 e–8 seretornaelvalorde 0, yaque
sehaterminadodesumarlaserie .
La codificación de este problema se encuentra en la página Web del libro.
19.9. Lasumadelosdígitosdeunnúmer onaturalpositivosepuedecalcularrecursivamentemediantelaexpresión.
SumaRecursiva(n)=
5
n mod10+SumaRecursi va(ndiv10)s: n >0
0enotrocaso
La codificación de este problema se encuentra en la página Web del libro.
19.10. Seprogramalafunción suma delasiguienteforma: lafuncióntienecomoparámetr oselvector v, elvalorde b, yunparámetro n queindicaquefaltaporr esolverelproblemaparalosdatosalmacenadosenelvectordesdelaposición 0 hastalan – 1.Deestaformasi n vale1 elproblematieneunasolucióntrivial: siv[0] < = b devuelve0 ysiv[0] > b devuelve v[0].Si n esmayorque 1, entonces, debecalcularserecursivamentelasumadesdelaposición 0 hastala n–2 y
despuéssumar v[n–1] enelcasodeque v[n–1] seamayorque b.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 19 Recursividad
376
19.11. Sedeclaraenprimerlugareltipoelementocomounenter oenun typedef.Posteriormente, seavisaquee xistelaclase
Nodo, queserácodificadaposteriormente.Deestaformalaclase ListaS, puedetenerunatrib utoprotegido p queesun
punteroalaclase Nodo.Enlaclase ListaS, sedeclaranlosconstructoresylosdestructoresdelaformaestándar, yademássólotresfuncionesmiembroquepermiten: insertarunelementoenunalistaenlazadaordenadacrecientementedeformarecursiva;borrarunelementoenunalistaenalazadaor denadacrecientementerecursivamente;mostarunalistaenlazadarecursivamente.Laclase Nodo sedeclaracondosatrib utosqueson: elelemento e yunatributo Sig queesdetipo
ListaS.Estadeclaracióncruzadaentrelasdosclases Nodo yListaS, permiteimplementardeunaformasencillaobjetos
recursivos.Lasfuncionesmiembrodelaclase Nodo secodificandelaformaestándar, talycomosehahechoenloscapítulos17y18deListasenlazadas, PilasyColas.Sóloseincluyeunapequeñadifer enciaenlafunciónmiembr o OSig(),
queretornaunar eferenciaauna ListaS, enlaquesede vuelveelatrib uto Sig enlugardeunacopiadelatrib uto Sig,
comosehizoenloscapítulosindicados.Estapequeñamodif icaciónpermitemodificarelpropioatributo Sig deun Nodo,
yfacilitarlaimplementaciónr ecursivadelasfuncionesmiembr odelaclase ListaS.Laimplementacióndelafunciones
recursivasdelaclase ListaS son:
• ListaS & ListaS:: InsertaOrec( Telemento x).Silalistaestávacíaentonceslainser cióndeunnuevonodoconsisteencrearunnodo, conlainformacióncorrespondienteyponerlocomoprimerelementodelalista.Silalistanoestá
vacía, haydosposibilidades, queelelementoainsertarseamayorqueelelementoqueseencuentr aenlaposiciónactual, encuyocasobastaconinsertarlorecursivamenteensunodosiguiente, oquenolosea, encuyocasohayque: crear
unnuevonodoconlainformación;enlazarsuatrib uto Sig con *this;ydecirqueelnue voprimerelementodelalista
eselpropionodo.Unavezterminadotodoelpr ocesoseretorna*this.
• ListaS & ListaS::BorrarOrec(Telemento x).Silalistaestávacía, entoncesnuncaseencuentr aelelementoenla
lista.Enotrocasohaytresposibilidades: quelainformacióncontenidaenelnodoactualdelalistaseamayorqueelelementoaborrarencuyocasonuncasepuedeencontr arelelementoenlalista;quelainformaciónelnodoactualdela
listaseamenorqueelelementoaborr arencuyocasobastaconllamarr ecursivamenteaborr arenelnodosiguiente;
queelnodoactualtengaunainformaciónquecoincidaconelelementoaborr ar, encuyocasoseenlazaelpunterodela
listaconelatrib uto Sig delnodoactual, ysedestruyeelnodoactual.Unavezterminadotodoelpr ocesoser etorna
*this.
• void ListaS::muestrarec().Sihaydatos, muestralainformaciónactual, yposteriormentemuestrarecursivamenteel
siguiente.
Enlaimplementaciónseincluye, además, unprogramaprincipalqueinsertayborraenlistasordenadas, asícomoun
resultadodeejecución.
La codificación de este problema se encuentra en la página Web del libro.
19.12. Lainsercióniterativa, enlalistadeclaradaenelProblema19.11, comienzaconlabúsquedadelaposicióndondecolocarel
elemento, dejandoelobjeto ant yact enlistasqueapuntanalnodoanterioryactualdondedebeserañadidoelnue voelemento.Posteriormente, seprocedealainsercióndelnuevonodoteniendoencuentaquepuedeserelprimerelementodela
lista, onoserlo.Elborr adoiterativocomienzaconlabúsquedadelelementoaborr ar, dejandoelobjetoantyactenlistas
queapuntanalnodoanterioryactualdondedebeserborradoelnodo.Posteriormentesilabúsquedahaterminadoconéxitoseprocedealborradodelnodo, puenteándolo, teniendoencuentaquepuedequeseaonoelprimerelementodelalista.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 19 Recursividad
377
EJERCICIOS PROPUESTOS
19.1. Escribirunafunciónrecursi vaquecalculelosv alores
delafunción funcionx definidadelasiguienteforma:
funcionx(0) = 0,
funcionx(1) = 1
funcionx(2) = 2
funcionx(n) = funcionx(n–3)+ 2*funcionx(n–2)
+funcionx(n–1) si n > 2.
19.2. ¿Cuáleslasecuencianuméricageneradaporlafunción
recursivaf enellistadosiguiente?
int f( int x)
{
if (x <= 0)
return 2;
else
return( n + 2 * f(n – 2));
}
19.3. ¿Cuáleslasecuencianuméricageneradaporlafunción
recursivaf enellistadosiguiente?
float f( float y);
float g(float y)
{
if (y <= 3)
return ( y );
else
return( y + f(y – 2));
}
float f ( float y)
{
if (y <= 2)
return ( y );
else
return( y + g(y – 2));
}
PROBLEMAS PROPUESTOS
19.1. Escribaunafunciónrecursivadeprototipoint consonantes(const char * cd) paracalcularelnúmerode
consonantesdeunacadena.
Sugerencia:
19.2. Escribaunafunciónrecursi vaquecalculaelproducto
escalardedosvectoresdenelementosrecursi vamente.
dondeCn, n yCn, 0 son1paracualquiervalorden.
Larelaciónderecurrenciadeloscoeficientesbinomialeses:
19.3. Escribaunafunciónrecursi vaquesumelosnprimeros
númerosnaturalesqueseanmúltiplode3.
C(n, 0)=1
C(n, n)=1
C(n, k)=C(n –1, k –1)+C(n –1, k)
(x +1)n =Cn, nxn +Cn, n–1xn–1 +Cn, n–2xn–2 +...+
+Cn, 2x2 +Cn, 1x1 +Cn, 0x0
19.4. Escribaunprogramaquetengacomoentradaunasecuenciadenúmerosenterospositivos(medianteunavariableentera).Elprogramadebellamaraunafunción
quecalculeelmayordetodoslosenterosintroducidos
recursivamente.
19.6. Dadaslasletrasdelabecedarioa, b, c, d, e, f, g, h, i, jy
dosnúmerosenteros0<n<=m<=10,escribaunprogramaquecalculelasv ariacionesdelosmprimeros
elementostomadosdenenn.
19.5. Leerunnúmeroenteropositivon<10.Calculareldesarrollodelpolinomio (x + 1)n.Imprimircadapotencia
x2 delaforma x**i.
19.7. Añadaalaclase ListaS delProblemaresuelto19.11
funcionesmiembroquepermitanlainserciónrecursi va
yelborradoderecursivodeunnodoqueocupelaposiciónpos.
CAPÍTULO 20
Árboles
Introducción
Losárbolessonestructurasdedatos nolineales alcontrarioquelosarraysylaslistasenlazadasqueconstituyen estructuras
lineales.
Losárbolessonmuyutilizadospararepresentarfórmulasalgebraicas, comométodoeficienteparabúsquedasgrandesy
complejas, listasdinámicas, etc.Casitodoslossistemasoperativosalmacenansusarchivosenárbolesoestructurassimilares
aárboles.Ademásdelasaplicacionescitadas, losárbolesseutilizanendiseñodecompiladores, procesodetextosyalgoritmosdebúsqueda.
Enelcapítuloseestudiaráelconceptodeárbolgeneralylostiposdeárbolesmásusuales, binarioybinariodebúsqueda.Asimismoseestudiaránalgunasaplicacionestípicasdeldiseñoyconstruccióndeárboles.
20.1. Árboles generales
Unárbol esuntipodedatoestructuradoquerepresentaunaestructurajerárquicaentresuselementos.Ladefinicióndeunárbolvienedadarecursivamentedelasiguienteforma:
Unárbol esunconjuntodeunoonodostalesque:
1. Hayunnododiseñadoespecialmentellamado raíz.
2. Losnodosrestantessedi videnenn ≥0 conjuntosdisjuntostalesque T1 ...Tn, sonunárbol.AT1, T2, ...Tn selesdenominasubárbolesdelraíz.
Siunárbolnoestávacío, entonceselprimernodosellama raíz.LaFigura20.1muestraunárbol, general.
Terminología árboles
•
•
•
•
•
•
•
Elprimernododeunárbol, normalmentedibujadoenlaposiciónsuperior, sedenominaraíz delárbol.
Lasflechasqueconectanunnodoaotrosellaman arcos oramas.
Losnodosterminales, (nodosdeloscualesnosededuceningúnnodo), sedenominanhojas.
Losnodosquenosonhojassedenominan nodos internos onodos no terminales.
Sienunárbolunaramav adeunmodo n1 aunnodon2, sedicequen1 eselpadre den2 yquen2 esunhijo den1.
n1 sellamaascendiente den2 sin1 eselpadrede n2 osin1 eselpadredeunascendientede n2.
n2 sellamadescendiente den1 sin1 esunascendientede n2.
379
CAPÍTULO 20 Árboles
380
raíz
A
B
C
E
D
F
G
H
I
Figura 20.1. Árbol.
•
•
•
•
•
Uncamino den1 an2 esunasecuenciadearcoscontiguosquev anden1 an2.
Lalongitud de un camino eselnúmerodearcosquecontiene(enotraspalabras, elnúmerodenodos–1).
Elnivel deunnodoeslalongituddelcaminoqueloconectaalraíz.
Laprofundidad oaltura deunárboleslalongituddelcaminomáslar goqueconectaelraízaunahoja.
Unsubárbol deunárbolesunsubconjuntodenodosdelárbol, conectadosporramasdelpropioárbol, estoesasuvez
unárbol.
• SeaSAunsubárboldeunárbol A: siparacadanodo n deSA, SAcontienetambiéntodoslosdescendientesde n enA.
SAsellamaun subárbol completo deA.
• Unárbolestáequilibrado cuando, dadounnúmeromáximo K dehijosdecadanodoylaalturadelárbol h, cadanodo
denivelk <h –1tieneexactamenteK hijos.
EJEMPLO 20.1. Árbolqueilustraalgunasdefiniciones.
A
Nivel 0
B
Nivel 1
Nivel 2
C
Rama AF
E
D
padres: A, B F
hijos: B, E, F, C, D, G, H, I
hermanos: {B, E, F}, {C, D}, {G, H, I}
F
G
H
Rama FI
I
Hojas: C, D, E, G,
20.2. Árboles binarios
Unárbolbinario esaquélenquecadanodotienecomomáximogradodos.Portanto, unárbolbinario esunárbolenelque
ningúnnodopuedetenermásdedossubárboles.Enunárbolbinario, cadanodopuedetener, cero, unoodoshijos(subárboles).Seconoceelnododelaizquierdacomo hijoizquierdo yelnododeladerechacomo hijoderecho.
• Unárbolbinarioestá perfectamenteequilibrado, silossubárbolesdetodoslosnodostienenlamismaaltura.
• Unárbolbinariosedicequees completo sitodoslosnodos interiores, esdeciraquélloscondescendientes, tienendos
hijos.
CAPÍTULO 20 Árboles
381
• Unárbolbinariosedicellenositodassushojasestánalmismonivelytodosusnodosinteriorestienencadaunodoshijos.Siunárbolbinarioes lleno entoncesescompleto.
EJEMPLO 20.2. Árbolbinariocompletoylleno.
A
A
completo
B
C
B
C
lleno
D
H
E
I
J
F
G
D
E
F
G
K
20.3. Estructura y representación de un árbol binario
Laestructuradeunárbolbinarioesaquellaqueencadanodosealmacenaundatoysuhijoizquierdoehijoderecho.EnC++
puederepresentarsedelasiguienteforma.
1. Laclasenodoseencuentraanidadadentrodelaclaseárbol.
class arbol
{
class nodo
{
public:
char *datos;
private:
nodo *derecho;
nodo *izquierdo;
friend class arbol;
};
public:
nodo *raiz;
arbol() {raiz = NULL; };
// ... otras funciones miembro
};
// raíz del árbol (raíz)
2. LaclaseArbolBin notienedentrolaclase NodoArbol, peroesdeclaradacomoclaseamiga.Serealizaademáscontiposgenéricos.
template <class T>
class ArbolBin;
// aviso a la clase NodoArbol.
// declara un objeto nodo árbol de un árbol binario
template <class T>
CAPÍTULO 20 Árboles
382
class NodoArbol
{
private:
// apunta a los hijos izquierdo y derecho del nodo
NodoArbol <T> *izquierdo;
NodoArbol <T> *derecho;
T datos;
public:
// constructor
NodoArbol (T item, NodoArbol <T> *ptri,NodoArbol <T> *ptrd)
{
datos = item;
izquierdo = ptri;
derecho = ptrd;
}
// métodos de acceso a los atributos puntero
NodoArbol <T>* OIzquierdo() {return izquierdo;}
NodoArbol <T>* ODerecho(void) {return derecho;};
void PIzquierdo(NodoArbol <T>* Izq) {izquierdo = Izq;}
void PDerecho(NodoArbol <T>* Drc) {derecho = Drc;}
// métodos de acceso al atributo dato
T Odatos() { return datos;}
void Pdatos( T e){ datos = e;}
// hacer a ArbolBin un amigo ya que necesita acceder a los
// campos puntero izquierdo y derecho del nodo
friend class ArbolBin <T>;
};
template <class T>
class ArbolBin
{
private:
NodoArbol <T> * p;
public:
ArbolBin() { p = NULL;}
// otras funciones miembro
} ;
Unárbol de expresión esunárbolbinarioconlassiguientespropiedades:
1. Cadahojaesunoperando.
2. Losnodosraízeinternossonoperadores.
3. Lossubárbolessonsubexpresionesenlasqueelnodoraízesunoperador .
CAPÍTULO 20 Árboles
383
EJEMPLO 20.3. Árbolesdeexpresiones.
*
*
+
–
X
Y
A
+
B
–
X
Y
Árbol de empresión (X+Y) * (A–B)
A
*
F
Z
Árbol de empresión (X+(Y*Z)) + (A–B)
EJEMPLO 20.4. Árbolesdeexpresionesasociadosa:
(A+B)*C,
A+B*(-(C+D))
(A*(X+Y))*C
+
*
+
A
C
B
*
A
*
B
*
–
A
+
C
(A+B)*C
A+B*(–(C+D))
C
+
C
D
D
(A*(X+Y))*C
20.5. Recorridos de un árbol
Paravisualizaroconsultarlosdatosalmacenadosenunárbolsenecesita recorrer elárbolo visitar losnodosdelmismo.Se
denominarecorridoalprocesoquepermiteaccederunasolavezacadaunodelosnodosdelárbol.Existendiversasformasde
efectuarelrecorridodeunárbolbinario:
Recorrido en anchura
Consisteenrecorrerlosdistintosni veles(delinferioralsuperior), ydentrodecadani vel, losdiferentesnodosdeizquierda a
derecha(obiendederechaaizquierda).
CAPÍTULO 20 Árboles
384
Recorrido en profundidad
Preorden
RID. Visitarlaraíz, recorrerenpreordenelsubárbolizquierdo,
recorrerenpreordenelsubárbolderecho.
Inorden
IDR. Recorrerinordenelsubárbolizquierdo, visitarlaraíz, recorrerinordenelsubárbolderecho.
Postorden IDR. Recorrerenpostordenelsubárbolizquierdo, recorrerenpostordenelsubárbolderecho, visitarla
raíz.
Existenotrostresrecorridosmásenprofundidadperoapenasseusan.RDI, DRI, DIR.
EJEMPLO 20.5. Recorridosenpreorden, inordenypostorden.
A
A
A
1
4
7
B
C
B
C
B
C
2
5
2
6
3
6
D
E
F
G
D
E
F
G
D
E
F
G
3
4
6
7
1
3
5
7
1
2
4
5
Camino: A, B, D, E, C, F y G
Camino: D, B, E, A, F, C y G
Camino: D, E, B, F, G, C y A
Preorden
Inorden
Postorden
20.6. Árbol binario de búsqueda
Unárbol binario de búsqueda esaquelquedadounnodocualquieradelárbol, todoslosdatosalmacenadosenelsubárbol
izquierdosonmenoresqueeldatoalmacenadoenestenodo, mientrasquetodoslosdatosalmacenadosenelsubárbolderechosonmayoresqueeldatoalmacenadoenestenodo.
EJEMPLO 20.6. Árbolesbinariosdebúsqueda.
55
30
4
5
75
41
30 menor que 55
41 mayor que 30
75 mayor que 55
85 mayor que 75
12
4
85
1
7
6
3
8
8
7.5
7
9
16
11
CAPÍTULO 20 Árboles
385
20.7. Operaciones en árboles binarios de búsqueda
Lasoperacionesmásusualessobreárbolesbinariosdebúsquedason: búsqueda deunnodo; inserción deunnodo;borrado de
unnodo.
Búsqueda
Labúsquedadeunnodocomienzaenelnodoraízysigueestospasos:
•
•
•
•
Sielárbolestávacíolabúsquedaterminaconf allo.
Laclavebuscadasecomparaconlacla vedelnodoraíz.
Silasclavessoniguales, labúsquedasedetieneconéxito.
Silaclavebuscadaesmayorquelaclaveraíz, labúsquedasereanudaenelsubárbolderecho.Silaclavebuscadaesmenorquelaclaveraíz, labúsquedasereanudaconelsubárbolizquierdo.
Inserción
Laoperacióndeinserción deunnodoesunae xtensióndelaoperacióndebúsqueda.Elalgoritmoes:
• Asignarmemoriaparaunanuevaestructuranodo.
• Buscarenelárbolparaencontrarlaposicióndeinsercióndelnuevonodo, quesecolocarásiemprecomounnuevonodo
hoja.
• Enlazarelnuevonodoalárbol.Paraelloenelprocesodebúsquedahayquequedarseconelpunteroqueapuntaasupadreyenlazarelnuevonodoasupadreconvenientemente.Encasodequenotengapadre(árbolv acío), seponeelárbol
apuntandoalnuevonodo.
EJEMPLO 20.7. Inserciónde14enelárboldebúsquedae xpresado.
Elsiguienteejemplomuestraelcaminoase guirparainsertarelelementodecla ve14enelárbolbinariodebúsqueda
acontinuaciónrepresentado.
30
30
10
8
40
25
12
32
10
8
40
25
12
14
32
CAPÍTULO 20 Árboles
386
EJEMPLO 20.8. Insertarunelementoconclave80y36enelárbolbinariodebúsquedasiguiente:
30
30
5
40
5
2
30
40
2
5
80
a) Inserción de 80
40
2
36
80
b) Inserción de 36
Borrado
Laoperacióndeborrado deunnodoesunae xtensióndelaoperacióndebúsqueda.Despuésdehaberb uscadoelnodoaborrarhayquetenerencuenta:
• Sielnodoeshoja, sesuprime, asignandonuloalpunterodesuantecesor.
• Sielnodotieneúnicohijo.Elnodoanteriorseenlazaconelhijodelquesequiereborrar .
• Sitienedoshijos.Sesustituyeelv aloralmacenadoenelnodoporelv alor, inmediatosuperior(oinmediatoinferior).
Estenodoseencuentraenunavancealaderecha(izquierda)delnodoaborrarytodoalaizquierda(derecha), hastaque
seencuentreNULL.Posteriormente, seborraelnodoquealmacenaelvalorinmediatosuperior(oinmediatoinferior)que
tienecomomáximounhijo.
• Porúltimo, hayqueliberarelespacioenmemoriaocupadoelnodo.
EJEMPLO 20.9. Borradodeunahoja.Seborr alaclave36.
30
30
5
2
5
40
36
85
2
40
85
CAPÍTULO 20 Árboles
387
EJEMPLO 20.10. Borradodeunnodoconunsolohijo.Seborr alaclave4.
Seborraelnodoquecontiene5puentesalnodoquecontieneel4yseeliminael4.
5
5
4
7
1
7
3
1
6
3
8
7
6
9
8
7
9
EJEMPLO 20.11. Borradodeunnodocondoshijos.Seborr alaclave60.
Sereemplaza60bienconelelementomayor(55)ensusubárbolizquierdooelelementomáspequeño(70)ensusubárbolderecho.Siseoptaporreemplazarconelelementomayordelsubárbolizquierdo.Semueveel55alraízdelsubárbolysereajustaelárbol.
40
40
20
10
60
30
50
45
70
55
54
20
10
55
30
45
50
70
54
CAPÍTULO 20 Árboles
388
EJERCICIOS
20.1. Explicarporquécadaunadelassiguientesestructur asnoesunárbolbinario.
A
B
D
E
A
C
A
B
C
F
B
D
C
E
D
F
20.2. Considéreseelárbolsiguiente.
a)
b)
c)
d)
e)
f)
P
¿Cuálessualtura?
¿Estáelárbolequilibrado?¿Porqué?
Listartodoslosnodoshoja.
¿Cuáleselpredecesorinmediato(padre)delnodoU?
ListarloshijosdelnodoR.
ListarlossucesoresdelnodoR.
Q
S
R
T
W
U
V
X
20.3. Paraelárboldelejercicioanteriorrealizarlossiguientesrecorridos: RDI, DRI, DIR.
20.4. Paracadaunadelassiguienteslistasdeletr as:
a) Dibujarelárbolbinariodebúsquedaqueseconstruyecuandolasletr asseinsertanenelordendado.
b) Realizarrecorridosinorden, preordenypostordendelárbolymostrarlasecuenciadeletrasqueresultanencadacaso.
(I)
(III)
M,Y,T,E,R
T,Y,M,E,R
(II)
(IV)
R,E,M,Y,T
C,O,R,N,F,L,A,K,E,S
20.5. Dibujarlosárbolesbinariosquerepresentanlassiguientesexpresiones:
a)
b)
c)
d)
e)
(A + B) / (C – D)
A + B + C / D
A-(B -(C - D) / (E + F))
(A + B) * ((C + D) / (E + F))
(A - B) / ((C * D) - (E / F))
20.6. Elrecorridopreordendeunciertoárbolbinariopr oduce ADFGHKLPQRWZ, yenrecorridoinordenproduce GFHKDLAWRQPZ.
Dibujarelárbolbinario.
CAPÍTULO 20 Árboles
389
PROBLEMAS
20.1. Codifiquelaclase arbol comoclaseamigadeunaclase Nodo yquepermitar ealizarmétodosrecursivos.Laclaseárbol
debecontenerlasfuncionesmiembr o Obtener yponertantoelhijoizquier doyder echocomoelelementodelar aízdel
árbol.
20.2. Añadiralaclase arbol delejercicioanteriorelconstructordecopia.
20.3. AñadiralaclaseárboldelPr oblema20.1unafunciónmiembr oquecopieelobjetoactualenunobjetoquer ecibacomo
parámetro.
20.4. Sobrecargueeloperadordeasignacióndelaclase arbol parapermitirasignarárbolescompletos.
20.5. Escribaunmétododelaclase arbol querealiceelespejodelobjetoárbol.Elespejodeunárbolesotr oárbolqueesel
mismoqueelquesevesiser eflejaraenunespejo, talycomoseindicaenelsiguienteejemplo:
20
20
11
6
25
15
8
22
25
32
30
32
11
22
15
30
6
8
20.6. EscribirfuncionesmiembrodelaclaseárboldelProblema20.1parahacerlosrecorridosrecursivosenprofundidadinorden, preorden, postorden.
20.7. Escribirunafunciónmiembrodelaclase arbol quenoscuenteelnúmerodenodosquetiene.
20.8. Añadiralaclase arbol unmétodoquecalculeelnúmerodehojasdelobjeto.
20.9. Añadiralaclaseárbolunafunciónmiembroquerecibacomoparámetrounnúmeronaturaln queindiqueunnivel, ymuestrotodoslosnodosdelárbolqueseencuentr enenesenivel.
20.10. Construirunafunciónmiembrodelaclasearbol paraescribirtodoslosnodosdeunárbolbinariodebúsquedacuyocampoclaveseamayorqueunvalordado.
20.11. Escribirunafunciónmiembrodelaclasearbol recursivayotraiterativaqueseencarguedeinsertarlainformacióndada
enunelementoenun arbol binariodebúsqueda.
20.12. Escribirfuncionesmiembrosdelaclasearbol iterativasyrecursivasparaborrarunelementodeunárbolbinariodebúsqueda.
CAPÍTULO 20 Árboles
390
SOLUCIÓN DE LOS EJERCICIOS
20.1. LaprimeraestructuranoesunárbolbinarioyaqueelnodocuyocontenidoesBtienetr eshijosyelmáximonúmer ode
hijosdeunárbolbinarioesdos.Estaestructur aesunárbolg eneral.Lasegundanoesunárbolbinariopor quehaydos
caminosdistintosparairalnodoFy, portanto, noseexpresalajerarquíadeladefinicióndeárbolunárboleng eneraly
deunbinarioenparticular.Laterceraporlamismarazónquelasegundanoesunárbolbinario.
20.2. a)
b)
c)
d)
e)
f)
Sualturaescuatro.
Elárbolestáequilibradoyaqueladiferenciadelasalturasdelossubárbolesizquierdoyderechoescomomáximo uno.
Losnodoshojason: W, T, X, V.
Elpredecesorinmediato(padre)delnodoUeselnodoquecontiene R.
Loshijosdelnodo R sonU yV.
Lossucesoresdelnodo R sonU, V, X.
20.3. • RecorridoRDI: P, R, V, U, X, Q, T, S, W.
• RecorridoDRI: V, R, X, U, P, T, Q, S, W.
• RecorridoDIR: V, X, U, R, T, W, S, Q.
20.4. Losgráficossolicitadosenelapartadoason:
M
R
E
Y
E
Y
T
M
T
R
I
II
C
T
M
Y
E
A
O
R
N
S
F
L
E
K
III
R
IV
CAPÍTULO 20 Árboles
391
b) Losrecorridoseninorden, preordenypostordendecadaunodelosárbolesson:
Inorden: E, M, R, T, Y
Preorden: M, E, Y, T, R
Postorden: E, R, T, Y, M
Inorden: E, M, R, T, Y
Preorden: R, E, M, Y, T
Postorden: M, E, T, Y, R
I
II
Inorden: A, C, E, F, K, L, N, O, R, S
Preorden: C, A, O, N, F, E, L, K, R, S
Postorden: A, E, K, L, F, N, S, R, O, L
Inorden: E, M, T, R, Y
Preorden: T, M, E, Y, R
Postorden: E, M, R, Y, T
III
IV
20.5. Losárbolesdeexpresionessonlossiguientes:
/
+
+
–
B
A
A
C
+
D
B
(A+B)/(C–D)
X
A
A
/
–
+
–
C
D
C
A+B+C/D
–
B
/
+
B
C
F
E
D
A
I
A–(B–(C–D)/(E+F))
+
D
E
(A+B)*((C*D)–(E/F))
/
–
A
–
B
/
*
C
D
E
F
(A–B)/((C*D)–(E/F))
F
CAPÍTULO 20 Árboles
392
20.6. Sisetieneelrecorridoenpreordeneinordenyademásnohayclavesr epetidas, entoncessepuedeusarelsiguientealgoritmorecursivopararesolverelproblema.Elprimerelementodelpr eordenessiemprelar aízdelárbol, ytodosloselementosdelárbolaconstruirseencuentranentrelaposiciónizquierda=primera=1delinordenyladerecha=última.Se
buscalaposiciónidondeseencuentralaraízdelárbolenelrecorridoeninorden.Elsubárbolizquierdodelaraízyaencontrada(enelpr eorden)estáentrelasposicionesizquier daei-1delr ecorridoeninorden(llamadarecursiva), yelhijo
derechoestáentrelasposiciones i + 1 yderechadelrecorridoeninorden(llamadarecursiva).Enelejemplolar aízdel
árbolgenerales A, ysuhijoizquier dovienedadoenelr ecorridoeninordenporlosdatos GFHKDL, ysuhijoder echopor
WRQPZ.Elalgoritmovaavanzandoporelr ecorridoenpreorden, yaquesiempreseencuentralaraízdelárbolaconstruir
enlasiguienteposición, yterminacuandoyanoquedandatosenelrecorridoenpreorden.Encadallamadarecursivahay
dosposibilidades, queelárbolseavacío, oquenolosea.Elárbolesvacío, sienelrecorridoeninordenlaizquierdayderechasehancruzado, yhaydatossinosehancruzado.
A
D
F
G
P
Q
L
Z
R
H
K
W
PREORDEN: A, D, F, G, H, K, L, P, Q, R, W, Z
INORDEN: G, F, H, K, D, L, A, W, R, Q, P, Z
SOLUCIÓN DE LOS PROBLEMAS
20.1. Sedeclarael Telemento comounsinónimodeltipodedatoquealmacenaelárbol.Enestecasounenter o.Seavisadela
creacióndelaclaseNodo, paraquelaclaseArbol declareunpunteroalaclaseNodocomoprotegido.LaclaseArbol tienecomofuncionesmiembr olasnecesariaspar aobteneryponerlar aízdelárbol(enestecasoeselelementoquealmacena), yobteneryponerelhijoizquierdoyderecho, ademásdelconstructorydestructordelaclase Arbol.Laclase Nodo
almacenacomoatributosprivadoselhijoizquierdoyderechodelnododelárbolasícomoelelementoquealmacena, declarandoalaclaseArbol comoamigaparapermitiraccederalosatributosdelaclaseNodo ydeestaformaseamássencillalacodificacióndelasfuncionesmiembrodelaclase Arbol.
La codificación de este problema se encuentra en la página Web del libro.
20.2. Elconstructordecopiaseactivacadavezqueser ealizaunallamadaaunobjetoporvalor .Esteconstructorcopiarealizaunacopiadelparámetroactualarb.Laprogramaciónrecursivaestansencillacomolosiguiente:sielárbolquesepasa
estávacío( arb.a = NULL)elobjetoactualsequedavacío;enotr ocaso, secreaunnuevo Nodo queesasignadoalpunteroa.Alhacerlallamadaalconstructorde Nodo, ésterecibecomoparámetroselhijoizquierdoyderechodelparámetro,
porloqueseactivalacopiar ecursivamente.
La codificación de este problema se encuentra en la página Web del libro.
CAPÍTULO 20 Árboles
393
20.3. Paracopiarelobjetoactualenunárbolquesepaseporr eferencia, bastaconcrearun Nodo enelquesecopieelelementodelaraízdelobjeto, ycomohijoizquierdoyderecholacopiadelhijoizquierdoyderecho.
La codificación de este problema se encuentra en la página Web del libro.
20.4. Lasobrecargadeloperadordeasignaciónserealizaconuncódigosimilaraldelconstructordecopia,exceptoquesedebe
retornarelcontenidodelpunterothis.Antesderealizarlacopiaseborraelárbolactual.
La codificación de este problema se encuentra en la página Web del libro.
20.5. Pararealizarlafunciónespejo, bastaconcrearun Nodo enelquesecopiaelelementodelar aízdelobjeto, ycomohijo
izquierdoyderecholacopiadelhijoderechoeizquierdorespectivamente.
La codificación de este problema se encuentra en la página Web del libro.
20.6. DelosseisposiblesrecorridosenprofundidadIDR, IRD, DIR, DRI, RID, RDIsepide IDR, IRD RID, queseprogramanen
lassiguientesfunciones:
• IRD orecorridoenInorden.Serecorreelhijoizquier do, sevisitalar aízyser ecorreelhijoder echo.Portanto, lafuncióndebecodificarsedelasiguienteforma: sielárbolesvacíonosehacenada.Enotr ocaso, serecorrerecursivamenteelhijoizquierdo, seescribelaraíz, yposteriormenteserecorrerecursivamenteelhijoderecho.
• RID orecorridoenPreorden.Sevisitalaraíz.Serecorreelhijoizquierdo, ydespuésserecorreelhijoderecho.Portanto, lacodificaciónesanálogaaladeInorden, perocambiandoelordendellamadas.
• IDR orecorridoenPostorden.Serecorreelhijoizquier do, serecorreehijoder echo, yposteriormentesevisitalar aíz.
La codificación de este problema se encuentra en la página Web del libro.
20.7. Siunárbolesvacíoelnúmer odenodosquetieneescer o, ysinoestávacíoelnúmer odenodosesunomáslasumadel
númerodelonodosquetengasuhijoizquierdoysuhijoderecho.LafunciónmiembroqueresuelveelproblemaesCuantos.
La codificación de este problema se encuentra en la página Web del libro.
20.8. Paracalcularelnúmerodehojasdeunárbol, bastaconobservar, quesiunárbolesvacíosunúmer odehorasescero.Si
noestávacío, haydosposibilidades, queelárbolseaunahojaencuyocasovale1, oquenoloseaconloquepar acalcularlasbastaconsumarlashojasquetengaelhijoizquier doyelhijoderecho.
La codificación de este problema se encuentra en la página Web del libro.
20.9. Sielárbolestávacíolosnodosquehayenesenivelescer o.Enotrocaso, hayqueescribirelnodosiestáenelnivel1, y
encasodequenoloestéhayquecalcularlosnodosquehayenelnivelinmediatamentesiguiente(r estarunoalnivelque
sebusca)desuhijoizquierdoehijoderecho.
La codificación de este problema se encuentra en la página Web del libro.
20.10. Bastaconhacerunrecorridodelárbolyescribirlosdatosquecumplanlacondicióndada.
La codificación de este problema se encuentra en la página Web del libro.
20.11. SeimplementanmediantelasfuncionesmiembroAnadeAyAnadeAIqueinsertanelnodoquecontengaelelemento.
• AnadeA.Realizalainser ciónrecursivadelasiguienteforma: sielárbolestávacíoseinsertaelnue vonodocomouna
hojadeunárbol.Sinoestávacío, silainformaciónalmacenadaenlar aízcoincideconlaqueseestáb uscandohabría
quetratarlasclavesrepetidasalmacenándolasenunaestructuradedatosauxiliar(nosehace), enotrocasohabráque
continuarlainserciónoporelhijoizquierdoobienporelhijoderechodependiendodelacomparaciónentreelelementoquesevaainsertarylainformaciónalmacenadaenelnodo.
CAPÍTULO 20 Árboles
394
• AnadeAI.Seusauninterruptor enc queseinicializaa false, unpunteroa Nodo pos queseinicializaalprimernodo
raízdelárbol, ymedianteunbuclemientrasno enc ynosehayaterminadoelárbol( pos != NULL)hacer: sicoinciden
loscontenidosponer enc a true, enotrocasosedesplazaalaizquier daolader echaquedándoseconsuanteriordependiendodelcontenidodelar aízydelelementoqueseestéb uscando.Posteriormente, seinsertaelnodosilabúsquedaterminóenfalloteniendoencuentaquepuedeserelr aíztotalobienunhijoizquier doobienunhijo.
La codificación de este problema se encuentra en la página Web del libro.
20.12. Elborradoqueseimplementaesele xplicadoenlateoría, usandoelpredecesorinmediatoqueseencuentr aunoalaizquierdaytodoasuderecha.Lasfuncionesquelocodif icanson:
• BorrarA.Esunmétodopúblicodelaclase Arbol.Realizalabúsquedadelnodoaborr arrecursivamente, yunavezencontradoelnodoconsideralostrescasos.Notienehijoizquierdo, encuyocasoseenlazaelpunteroconsuhijoderecho.
Notienehijoderecho, encuyocasoseenlazaelnodoconsuhijoizquierdo.Tienedoshijos, encuyocasosellamaauna
función BorP queseencargadebuscarelpredecesorinmediato, copialainformaciónenelnodoquesequier eborrar,
cambiaelnodoaborrarqueeselpredecesorinmediato.Porúltimo, seliberamemoria.
• BorP.Esunmétodoprivadodelaclase Arbol.Mediantellamadasr ecursivashaceloindicadoanteriormenteyr ealiza
elenlaceconelhijoizquierdodelpredecesorinmediato.
• BorrarAI.Realizalabúsquedadelnodoaborr ariterativamente.Enelcasodeéxitoenlabúsquedaconsider alostres
casosconsideradosenelBorrarA, peroahora, alrealizarlosdosprimeroscasos(notienehijoizquierdo, onotienehijo
derecho)hadetenerencuentasielnodoaborrareselraízdelárbol(Ant= =NULL)alahoraderealizarlosenlaces.Para
elcasodelborr adodelnodocondoshijos, labúsquedadelpredecesorinmediatoserealizaiterativamentemediantela
condiciónnotienehijoderechoconlafunción BorPI.Unavezencontrado, seintercambianlainformaciónyseprocede
alborradodelnodopredecesorinmediato.
• BorPI.Esunmétodoprivadodelaclase Arbol.RealizalamismatareaquelafunciónmiembroBorP.
La codificación de este problema se encuentra en la página Web del libro.
EJERCICIOS PROPUESTOS
20.1. ParalosárbolesdelEjercicioresuelto20.4,recorrercada
árbolutilizandolosórdenessiguientes: RDI, RNI, RIN.
sielárbolescompletoyf
trario.
also( false)encasocon-
20.2. Escribirunafunciónquetomeunárbolcomoentraday
devuelvaelnúmerodehijosdelárbol.
20.4. Diseñarunafunciónrecursivaquedevuelvaunpuntero
aunelementoenunárbolbinariodebúsqueda.
20.3. Escribirunafunción booleana alaqueselepaseun
punteroaunárbolbinarioyde vuelvaverdadero(true)
20.5. Diseñarunafuncióniterativaqueencuentreunelementoenunárbolbinariodebúsqueda.
CAPÍTULO 20 Árboles
395
PROBLEMAS PROPUESTOS
20.1. Escribirunprogramaqueleauntextodelongitudindeterminadayqueproduzcacomoresultadolalistadetodaslaspalabrasdiferentescontenidasenelte xto, así
comosufrecuenciadeaparición.
20.2. Sedisponedeunárbolbinariodeelementosdetipoentero.Escribirfuncionesquecalculen:
a) Lasumadesuselementos.
b) Lasumadesuselementosquesonmúltiplosde3.
20.3. Escribirunafunciónbooleana IDENTICOS quepermita
decirsidosárbolesbinariossoniguales.
20.4. Crearunarchivodedatosenelquecadalíneacontenga
lasiguienteinformación:
Nombre
NúmerodelaSeguridadSocial
Dirección
30caracteres
10caracteres
24caracteres
Escribirunprogramaqueleacadaregistrodedatos
delarchivoylosalmacenesenunárbol, demodoque
cuandoelárbolserecorraenordenlosnúmerosdela
SeguridadSocialsealmacenenenordenascendente.
Imprimirunacabecera “DATOS DE EMPLEADOS ORDENADOS DE ACUERDO AL NUMERO DE LA SEGURIDAD
SOCIAL” yacontinuaciónimprimirlosdatosdelárbol
conelformatoColumnas:
1-10
20-50
55-79
NúmerodelaSeguridadSocial
Nombre
Dirección
20.7. Unárbolbinariodebúsquedapuedeimplementarsecon
unarray.Larepresentaciónnoenlazadacorrespondienteconsisteenqueparacualquiernododelárbolalmacenadoenlaposición I delarray, suhijoizquierdose
encuentraenlaposición2*I ysuhijoderechoenlaposición2*I + 1 .Diseñarapartirdeestarepresentación
loscorrespondientesprocedimientosyfuncionespara
gestionarinteractivamenteunárboldenúmerosenteros.
(Comenteelincon venientedeestarepresentaciónde
caraalmáximoymínimonúmerodenodosquepueden
almacenarse.)
20.8. UnamatrizdeNelementosalmacenacadenasdecaracteres.Utilizandounárbolbinariodebúsquedacomoestructuraauxiliarordenarascendentementelacadenade
caracteres.
20.9. Dadounárbolbinariodebúsqueda, diseñarunafunción
quelistelosnodosdelárbolordenadosdescendentemente.
20.10. EscribirunprogramaC++queleaunae xpresióncorrectaenformainfijaylapresenteennotaciónpostfija.
20.11. Escribirunprogramaqueleauntextodelongitudindeterminadayqueproduzcacomoresultadolalistadetodaslaspalabrasdiferentescontenidasenelte xto, así
comosufrecuenciadeaparición.Hacerusodelaestructuraárbolbinariodebúsqueda, cadanododelárbol
quetengaunapalabraysufrecuencia.
20.12. Escribirfuncionespararecorrerunárbolen inorden y
preorden iterativamente.
20.5. Diseñarunprogramainteracti voquepermitadaraltas,
bajas, listar, etc., enunárbolbinariodebúsqueda.
20.13. Escribirunafunciónquerealiceelrecorridoenanchuradeunárbolbinario.
20.6. Dadosdosárbolesbinariosdebúsquedaindicarmedianteunprogramasilosárbolestienenonoelementos
comunes.
20.14. Dadounárbolbinariodebúsquedadecla vesenteras,
diseñarunafunciónquelisteenordencrecientelosnodosdelárbolquecumplanlacondicióndesercapicúa.
Índice
A
Abstracción, 5
Algoritmo, 1
burbuja, 248
concepto, 1
Ámbito, 114
deprograma, 114
deunafunción, 114
delarchivofuente, 114
global, 114
local, 114
Apuntador(véasepuntero), 203
Árbol, 379
altura, 380
camino, 380
longitud, 380
completo, 380
definición, 379
equilibrado, 380
padre, 379
perfectamente, 380
hoja, 379
nivel, 380
profundidad, 380
recorridos, 383
inorden, 384
postorden, 384
preorden, 384
subárbol, 379
raíz, 379
Árbolbinario, 380
debúsqueda, 385
deexpresión, 382
estructura, 381
representación, 381
Árbolbinariodebúsqueda, 385
borrado, 386
inserción, 385
Archivos, 311
apertura, 316
cabecera, 20
Array, 135
argumentos, 141
caracteres, 137
declaración, 135
indexaciónbasadaencero, 135
inicialización, 136
396
parámetros, 141
cadenascomoparámetros, 145
matricescomoparámetros, 144
númerodeelementos, 138
rango, 135
subíndice, 135
Arraysmultidimensionales, 138
bidimensionales, 144
inicialización, 135
matrices, 144
tridimensionales, 140
Arreglo, 135
Asignación, 33
Asociatividad, 45
Atributos, 259
Auto, 116
B
Bibliotecastring.h, 189
Bit, 172
bool, 23
break, 62, 81
Bucle, 77
anidados, 86
bandera, 80
centinela, 79
comparación, 84
controladosporcontador, 78
infinito, 79, 80
Búsqueda, 245
binaria, 247
algoritmo, 247
dicotómica, 245
lineal, 245
secuencial, 245
algoritmo, 245
C
C++, 7
Cadena, 183
declaración, 184
inicialización, 184
lectura, 183
Camposdebits, 172
char, 21
cin, 27
cin.getline(), 185
cin.get(), 185
cin.putback(), 188
cin.ignore(), 188
Clase, 7, 354
abstracta, 286
arbol, 389
base, 7
cola, 354
compuesta, 268
concepto, 259
constructor, 264
decopia, 265
pordefecto, 264
definición, 259
derivada, 7, 278
destructor, 265
inicialización, 265
ifstream, 316
istream, 312
lista, 327
pila, 348
ofstream, 316
ostream, 312
nodo, 324
subclase, 7
superclase, 7
class, 278
Cola, 347, 353
clase, 354
especificación, 354
FIFO, 354
implementación, 354
conarraycircular, 354
conlistasenlazadas, 356
Comentarios, 18
Constantes, 23
cadena, 23
carácter, 23
definidas, 24
declaradas, 24
enteras, 24
literales, 23
reales, 23
cons, 24
ÍNDICE
397
D
parámetros, 108
argumentosporomisión, 111
const, 110
porreferencia, 110
porvalor, 108
recursivas, 368
sobrecarga, 121
utilidad, 121
virtuales, 287
visibilidad, 121
Datosocultación, 6
Declaracionesglobales, 11
define, 113
delete, 233
Diagrama, 1
deflujo, 1
Diseño, 3
do-while, 77, 83, 84
double, 21
E
Encapsulación, 6
Enumeración, 170
enum, 170
Espaciodenombres, 28
Especialización6
Estructuras, 161
acceso, 163
anidadas, 165
asignación, 165
declaración, 161
tamaño, 164
Evaluaciónencortocircuito, 64
Estructurasdecontrol, 57
iterativas, 77
repetitivas, 77
Expresiones, 35
aritmética, 36
condicional, 63
lógica, 64
Excepción, 296
diseño, 297
lanzamiento, 296
manejador, 297
extern, 116
G
Generalización, 6
Genericidad, 293
M
main(), 17
Memoria, 227
dinámica, 227
Métodos, 259
Módulo(ofunción), 103
N
H
Heap, 227
Herencia, 6, 277
múltiple, 282
privada, 279
protegida, 279
simple, 280
pública, 279
tipos, 280
I
Identificador, 19
if, 57
if-else, 59
anidados, 61
include, 15
inline, 112
int, 20
F
K
false, 23
Knuth, 1
FIFO, 354
float, 21
Flujo, 311
clases, 311
for, 77, 81, 84
bucles, 77
Función, 103
alcance, 114
anidada, 104
carácter, 119
definición, 114
definidasporelusuario, 18
declaraciónenlínea, 112
defechayhora, 121
estructura, 104
matemáticas, 104
numéricas, 120
plantillas, 123
prototipos, 106
Listadoblementeenlazada, 332
clase, 334
eliminación, 335
inserción, 334
Llamadaporreferencia, 108
Llamadaporvalor, 109
L
LIFO, 347
Listas, 327
clasificación, 324
contiguas, 327
declaración, 327
Listasenlazadas, 323
clase, 327
implementación, 324
operaciones, 325
insertar328
buscar, 330
eliminar, 331
Listacircular, 336
inserción, 337
eliminación, 337
namespace, 28
new, 228
Nodo, 325
NULL, 206
O
Objetos, 7, 259
estado, 261
métodos, 261
constructor, 264
destructor, 265
Ocultación, 7
Operador, 35
deinserción, 16
deextracción, 27
?, 42, 63
(), 44
[], 44
+, 36
++, 36
––, 33
=, 33
==, 40
->, 42, 164
., 42, 164
::, 44
acceso, 42,164
aritméticos, 36
asociatividad, 46
coma, 43
debits, 41
dedirección, 42
deincrementación, 34
dedecrementación, 39
demanipulacióndebits, 41
dedesplazamiento, 41
lógicos, 40
evaluacióncortocircuito, 40, 46
prioridad, 46
molde, 45
relacionales, 39
sizeof, 293
sobrecarga, 293
ÍNDICE
398
concepto, 203
constante, 209
declaración, 203
inicialización, 203
pasoconparámetros, 212
yarray, 206
yarraydedosdimensiones, 210
Ordenación, 245
burbuja, 248
inserción, 251
lineal, 251
binaria, 252
selección250
shell, 253
P
R
Palabrasreservadas, 19
Parámetros, 108
argumentosporomisión, 111
const, 110
arrays, 141
cadena, 145
porreferencia, 109
porvalor,109
Pila, 347
clase, 348
definición, 347
especificación, 348
implementaciónconarray, 348
implementaciónconlistasenlazadas, 351
insertar, 347
Plantillas, 293
declases, 294
defunciones, 123, 293
Polimorfismo, 7, 121, 277, 278
Prioridad, 45
Programa, 15
conceptosbásicos, 15
elementosdeunProgramaC++, 19
estructurageneral, 2, 15
Programación, 1
estructurada, 3
orientadaaobjetos, 1, 11
Prototipo, 116
Pseudocódigo, 1
Puntero, 203
aconstante, 209
afunción, 213
aestructuras, 216
Recursión, 367
Recursividad, 367
condicióndeterminación, 368
directa, 368
indirecta, 368
infinita, 370
versusiteración, 370
register, 116
Registro, 161
Repetición, 77
return, 104
struct, 161
switch, 62
etiquetascase, 62
etiquetasdefault, 62
T
Tablas, 135,138
TAD, 5
Tipoabstractodedatos, 1, 5
Tiposdedatos, 20
básicos, 20
rangodevalores, 20
numéricos, 20
true, 23
typedef, 172
U
Union, 161, 168
definición, 168
S
Sentencias
asignación, 35
do while, 77, 83, 84
for, 77, 81, 84
if, 9
if anidados, 61
switch, 62
while, 77, 84
Separador, 20
Signosdepuntuación, 20
sizeof, 44
Sobrecarga, 293
asignación, 305
defunciones, 121
deoperadores, 293
unitarios, 300
binarios, 303
static, 117
V
Variables, 25
declaración, 25
definición, 25
deobjetos, 26
dinámica, 26
duración, 25
estáticas, 117
externas, 116
globales, 26
inicialización, 25
void, 206
volatile, 24
W
while, 77, 84