Programacion en c de byron

desantiago 2,693 views 190 slides Oct 09, 2010
Slide 1
Slide 1 of 670
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49
Slide 50
50
Slide 51
51
Slide 52
52
Slide 53
53
Slide 54
54
Slide 55
55
Slide 56
56
Slide 57
57
Slide 58
58
Slide 59
59
Slide 60
60
Slide 61
61
Slide 62
62
Slide 63
63
Slide 64
64
Slide 65
65
Slide 66
66
Slide 67
67
Slide 68
68
Slide 69
69
Slide 70
70
Slide 71
71
Slide 72
72
Slide 73
73
Slide 74
74
Slide 75
75
Slide 76
76
Slide 77
77
Slide 78
78
Slide 79
79
Slide 80
80
Slide 81
81
Slide 82
82
Slide 83
83
Slide 84
84
Slide 85
85
Slide 86
86
Slide 87
87
Slide 88
88
Slide 89
89
Slide 90
90
Slide 91
91
Slide 92
92
Slide 93
93
Slide 94
94
Slide 95
95
Slide 96
96
Slide 97
97
Slide 98
98
Slide 99
99
Slide 100
100
Slide 101
101
Slide 102
102
Slide 103
103
Slide 104
104
Slide 105
105
Slide 106
106
Slide 107
107
Slide 108
108
Slide 109
109
Slide 110
110
Slide 111
111
Slide 112
112
Slide 113
113
Slide 114
114
Slide 115
115
Slide 116
116
Slide 117
117
Slide 118
118
Slide 119
119
Slide 120
120
Slide 121
121
Slide 122
122
Slide 123
123
Slide 124
124
Slide 125
125
Slide 126
126
Slide 127
127
Slide 128
128
Slide 129
129
Slide 130
130
Slide 131
131
Slide 132
132
Slide 133
133
Slide 134
134
Slide 135
135
Slide 136
136
Slide 137
137
Slide 138
138
Slide 139
139
Slide 140
140
Slide 141
141
Slide 142
142
Slide 143
143
Slide 144
144
Slide 145
145
Slide 146
146
Slide 147
147
Slide 148
148
Slide 149
149
Slide 150
150
Slide 151
151
Slide 152
152
Slide 153
153
Slide 154
154
Slide 155
155
Slide 156
156
Slide 157
157
Slide 158
158
Slide 159
159
Slide 160
160
Slide 161
161
Slide 162
162
Slide 163
163
Slide 164
164
Slide 165
165
Slide 166
166
Slide 167
167
Slide 168
168
Slide 169
169
Slide 170
170
Slide 171
171
Slide 172
172
Slide 173
173
Slide 174
174
Slide 175
175
Slide 176
176
Slide 177
177
Slide 178
178
Slide 179
179
Slide 180
180
Slide 181
181
Slide 182
182
Slide 183
183
Slide 184
184
Slide 185
185
Slide 186
186
Slide 187
187
Slide 188
188
Slide 189
189
Slide 190
190
Slide 191
191
Slide 192
192
Slide 193
193
Slide 194
194
Slide 195
195
Slide 196
196
Slide 197
197
Slide 198
198
Slide 199
199
Slide 200
200
Slide 201
201
Slide 202
202
Slide 203
203
Slide 204
204
Slide 205
205
Slide 206
206
Slide 207
207
Slide 208
208
Slide 209
209
Slide 210
210
Slide 211
211
Slide 212
212
Slide 213
213
Slide 214
214
Slide 215
215
Slide 216
216
Slide 217
217
Slide 218
218
Slide 219
219
Slide 220
220
Slide 221
221
Slide 222
222
Slide 223
223
Slide 224
224
Slide 225
225
Slide 226
226
Slide 227
227
Slide 228
228
Slide 229
229
Slide 230
230
Slide 231
231
Slide 232
232
Slide 233
233
Slide 234
234
Slide 235
235
Slide 236
236
Slide 237
237
Slide 238
238
Slide 239
239
Slide 240
240
Slide 241
241
Slide 242
242
Slide 243
243
Slide 244
244
Slide 245
245
Slide 246
246
Slide 247
247
Slide 248
248
Slide 249
249
Slide 250
250
Slide 251
251
Slide 252
252
Slide 253
253
Slide 254
254
Slide 255
255
Slide 256
256
Slide 257
257
Slide 258
258
Slide 259
259
Slide 260
260
Slide 261
261
Slide 262
262
Slide 263
263
Slide 264
264
Slide 265
265
Slide 266
266
Slide 267
267
Slide 268
268
Slide 269
269
Slide 270
270
Slide 271
271
Slide 272
272
Slide 273
273
Slide 274
274
Slide 275
275
Slide 276
276
Slide 277
277
Slide 278
278
Slide 279
279
Slide 280
280
Slide 281
281
Slide 282
282
Slide 283
283
Slide 284
284
Slide 285
285
Slide 286
286
Slide 287
287
Slide 288
288
Slide 289
289
Slide 290
290
Slide 291
291
Slide 292
292
Slide 293
293
Slide 294
294
Slide 295
295
Slide 296
296
Slide 297
297
Slide 298
298
Slide 299
299
Slide 300
300
Slide 301
301
Slide 302
302
Slide 303
303
Slide 304
304
Slide 305
305
Slide 306
306
Slide 307
307
Slide 308
308
Slide 309
309
Slide 310
310
Slide 311
311
Slide 312
312
Slide 313
313
Slide 314
314
Slide 315
315
Slide 316
316
Slide 317
317
Slide 318
318
Slide 319
319
Slide 320
320
Slide 321
321
Slide 322
322
Slide 323
323
Slide 324
324
Slide 325
325
Slide 326
326
Slide 327
327
Slide 328
328
Slide 329
329
Slide 330
330
Slide 331
331
Slide 332
332
Slide 333
333
Slide 334
334
Slide 335
335
Slide 336
336
Slide 337
337
Slide 338
338
Slide 339
339
Slide 340
340
Slide 341
341
Slide 342
342
Slide 343
343
Slide 344
344
Slide 345
345
Slide 346
346
Slide 347
347
Slide 348
348
Slide 349
349
Slide 350
350
Slide 351
351
Slide 352
352
Slide 353
353
Slide 354
354
Slide 355
355
Slide 356
356
Slide 357
357
Slide 358
358
Slide 359
359
Slide 360
360
Slide 361
361
Slide 362
362
Slide 363
363
Slide 364
364
Slide 365
365
Slide 366
366
Slide 367
367
Slide 368
368
Slide 369
369
Slide 370
370
Slide 371
371
Slide 372
372
Slide 373
373
Slide 374
374
Slide 375
375
Slide 376
376
Slide 377
377
Slide 378
378
Slide 379
379
Slide 380
380
Slide 381
381
Slide 382
382
Slide 383
383
Slide 384
384
Slide 385
385
Slide 386
386
Slide 387
387
Slide 388
388
Slide 389
389
Slide 390
390
Slide 391
391
Slide 392
392
Slide 393
393
Slide 394
394
Slide 395
395
Slide 396
396
Slide 397
397
Slide 398
398
Slide 399
399
Slide 400
400
Slide 401
401
Slide 402
402
Slide 403
403
Slide 404
404
Slide 405
405
Slide 406
406
Slide 407
407
Slide 408
408
Slide 409
409
Slide 410
410
Slide 411
411
Slide 412
412
Slide 413
413
Slide 414
414
Slide 415
415
Slide 416
416
Slide 417
417
Slide 418
418
Slide 419
419
Slide 420
420
Slide 421
421
Slide 422
422
Slide 423
423
Slide 424
424
Slide 425
425
Slide 426
426
Slide 427
427
Slide 428
428
Slide 429
429
Slide 430
430
Slide 431
431
Slide 432
432
Slide 433
433
Slide 434
434
Slide 435
435
Slide 436
436
Slide 437
437
Slide 438
438
Slide 439
439
Slide 440
440
Slide 441
441
Slide 442
442
Slide 443
443
Slide 444
444
Slide 445
445
Slide 446
446
Slide 447
447
Slide 448
448
Slide 449
449
Slide 450
450
Slide 451
451
Slide 452
452
Slide 453
453
Slide 454
454
Slide 455
455
Slide 456
456
Slide 457
457
Slide 458
458
Slide 459
459
Slide 460
460
Slide 461
461
Slide 462
462
Slide 463
463
Slide 464
464
Slide 465
465
Slide 466
466
Slide 467
467
Slide 468
468
Slide 469
469
Slide 470
470
Slide 471
471
Slide 472
472
Slide 473
473
Slide 474
474
Slide 475
475
Slide 476
476
Slide 477
477
Slide 478
478
Slide 479
479
Slide 480
480
Slide 481
481
Slide 482
482
Slide 483
483
Slide 484
484
Slide 485
485
Slide 486
486
Slide 487
487
Slide 488
488
Slide 489
489
Slide 490
490
Slide 491
491
Slide 492
492
Slide 493
493
Slide 494
494
Slide 495
495
Slide 496
496
Slide 497
497
Slide 498
498
Slide 499
499
Slide 500
500
Slide 501
501
Slide 502
502
Slide 503
503
Slide 504
504
Slide 505
505
Slide 506
506
Slide 507
507
Slide 508
508
Slide 509
509
Slide 510
510
Slide 511
511
Slide 512
512
Slide 513
513
Slide 514
514
Slide 515
515
Slide 516
516
Slide 517
517
Slide 518
518
Slide 519
519
Slide 520
520
Slide 521
521
Slide 522
522
Slide 523
523
Slide 524
524
Slide 525
525
Slide 526
526
Slide 527
527
Slide 528
528
Slide 529
529
Slide 530
530
Slide 531
531
Slide 532
532
Slide 533
533
Slide 534
534
Slide 535
535
Slide 536
536
Slide 537
537
Slide 538
538
Slide 539
539
Slide 540
540
Slide 541
541
Slide 542
542
Slide 543
543
Slide 544
544
Slide 545
545
Slide 546
546
Slide 547
547
Slide 548
548
Slide 549
549
Slide 550
550
Slide 551
551
Slide 552
552
Slide 553
553
Slide 554
554
Slide 555
555
Slide 556
556
Slide 557
557
Slide 558
558
Slide 559
559
Slide 560
560
Slide 561
561
Slide 562
562
Slide 563
563
Slide 564
564
Slide 565
565
Slide 566
566
Slide 567
567
Slide 568
568
Slide 569
569
Slide 570
570
Slide 571
571
Slide 572
572
Slide 573
573
Slide 574
574
Slide 575
575
Slide 576
576
Slide 577
577
Slide 578
578
Slide 579
579
Slide 580
580
Slide 581
581
Slide 582
582
Slide 583
583
Slide 584
584
Slide 585
585
Slide 586
586
Slide 587
587
Slide 588
588
Slide 589
589
Slide 590
590
Slide 591
591
Slide 592
592
Slide 593
593
Slide 594
594
Slide 595
595
Slide 596
596
Slide 597
597
Slide 598
598
Slide 599
599
Slide 600
600
Slide 601
601
Slide 602
602
Slide 603
603
Slide 604
604
Slide 605
605
Slide 606
606
Slide 607
607
Slide 608
608
Slide 609
609
Slide 610
610
Slide 611
611
Slide 612
612
Slide 613
613
Slide 614
614
Slide 615
615
Slide 616
616
Slide 617
617
Slide 618
618
Slide 619
619
Slide 620
620
Slide 621
621
Slide 622
622
Slide 623
623
Slide 624
624
Slide 625
625
Slide 626
626
Slide 627
627
Slide 628
628
Slide 629
629
Slide 630
630
Slide 631
631
Slide 632
632
Slide 633
633
Slide 634
634
Slide 635
635
Slide 636
636
Slide 637
637
Slide 638
638
Slide 639
639
Slide 640
640
Slide 641
641
Slide 642
642
Slide 643
643
Slide 644
644
Slide 645
645
Slide 646
646
Slide 647
647
Slide 648
648
Slide 649
649
Slide 650
650
Slide 651
651
Slide 652
652
Slide 653
653
Slide 654
654
Slide 655
655
Slide 656
656
Slide 657
657
Slide 658
658
Slide 659
659
Slide 660
660
Slide 661
661
Slide 662
662
Slide 663
663
Slide 664
664
Slide 665
665
Slide 666
666
Slide 667
667
Slide 668
668
Slide 669
669
Slide 670
670

About This Presentation

este es un muy buen libro para empezar a programar en c


Slide Content

2"EDICiÓN
REVISADA
¡¡APRUEBATUEXAMENCONSCHAUM!!
ByronGottfried
REDUCETUTIEMPODEESTUDIO
332EJEMPLOSDETALLADOS,450CUESTIONESDEREPASO
Y214PROBLEMAS DECOMPRENSiÓN
705
PROBLEMASPROPUESTOS
8APÉNDICESQUERESUMENLASINTAXISDELLENGUAJE
UtilizadopOI'
millonesde
udiantesy
omendado
I'ofesol'es
detodoel
mundo

,
PROGRAMACION ENC
Segundaediciónrevisada

,
PROGRAMACION ENC
Segundaediciónrevisada
BYRONs.GOTTFRIED
ProfesordeIngenieríaIndustrial
UniversidaddePittsburgh
Traducción:
JOSÉRAFAELGARCÍALÁZARO
Dpto.LenguajesyComputación
UniversidaddeAlmería
Revisióntécnica:
ALFONSOBOSCHARÁN
Dpto.Lenguajes
yComputación
UniversidaddeAlmería
MADRID.BUENOSAIRES·CARACAS·GUATEMALA· LISBOA.MÉXICO
NUEVA
YORK·PANAMÁ.SANJUAN·SANTAFÉDE BOGOTÁ·SANTIAGO·SÁOPAULO
AUCKLAND•HAMBURGO •
LONDRES·MILÁN·MONTREAL· NUEVADELHI
PARIS•SAN
FRANCISCO·SIONEY.SINGAPUR· SToLOUIS• TOKIO.TORONTO

Lainformacióncontenidaenestelibroprocededelatraduccióndelasegundaedicióneningléseditadapor
McGraw-HillCompanies,Inc.Noobstante,McGraw-Hillnogarantizalaexactitudoperfeccióndela
informaciónpublicada.Tampocoasumeningúntipodegarantíasobreloscontenidosylasopinionesvertidas
endichostextos.
Estetrabajosepublicaconelreconocimientoexpresode queseestáproporcionandounainformación,pero
notratandodeprestarningúntipodeservicioprofesionalotécnico.Losprocedimientosylainformación
quesepresentaneneste librotienensólolaintencióndeservircomoguíageneral.
McGraw-Hillhasolicitadolospermisosoportunosparalarealizaciónyeldesarrollo
deestaobra.
PROGRAMACIÓN ENC.Segundaediciónrevisada
Noestápermitidalareproduccióntotaloparcialdeestelibro,nisutratamientoinformático,nila
transmisióndeningunaformao
porcualquiermedio,yaseaelectrónico,mecánico, porfotocopia,por
registrouotrosmétodos,sinelpermisoprevioyporescritodelostitularesdelCopyright.
McGraw-Hill/lnteramericana
deEspaña,S.A.U.
DERECHOSRESERVADOS©2005,respectoalasegundaediciónenespañol,por
McGRAW-HILLIINTERAMERICANA DE
ESPAÑA,S.A.U.
EdificioValrealty, \.'planta
Basauri,17
28023Aravaca(Madrid)
Traducidodelasegundaedición
eninglésde
PROGRAMMING WITHC
http://www.mcgraw-hill.es
[email protected]
Copyright©MCMXCVI,porMcGraw-HillCompanies,Inc.
ISBN:0-07024-035-3
ISBN:84-481-9846-80-1
Depósitolegal:
M.0.000-2005
Editores:ConcepciónFemández
ICarmeloSánchez
CompuestoenPuntographic,
S.L.
IMPRESOENMEXICO-PRINTED INMEXICO
Estaobraseterm'móde
ImprimirenFebrerode2005en
ProgramasEducativos,
SAdeC.v.
Calz.ChabacanoNo.
65-A
Col.Asturias,
C.P.06850,Méx. D.F.
EmpresaCertificadaporelInstituloMexicano
deNormalizaciónyCel1ificaciónA.C.,bajola
NormaJSO-9002:1994/NMX-CC-004: 1995con
elnúm.deRegistroRSC-048ybajolaNorma
ISO-14001-1996fNMX-SAA-001: 19981MNC
conelnúm.deRegistroRSAA-003

Contenido
Ejemploscompletosdeprogramas ix
Prólogo xi
1.Conceptosbásicos...........................................................................................................1
1.1.Introducciónalascomputadoras 1
1.2.Característicasdelascomputadoras 2
1.3.Modos
deoperación 5
lA.Tiposdelenguajesdeprogramación 8
1.5.IntroducciónalC 9
1.6.AlgunosprogramassencillosenC
13
1.7.Característicasdeseables deunprograma 23
2.ConceptosbásicosdeC ,......................................................31
2.1.Elconjunto decaracteresdeC 31
2.2.Identificadoresypalabrasreservadas 32
2.3.Tiposdedatos
33
2A.Constantes 35
2.5.Variablesyarrays 43
2.6.Declaraciones 45
2.7.Expresiones 49
2.8.Instrucciones 50
2.9.Constantessimbólicas
51
3.Operadoresyexpresiones 59
3.1.Operadoresaritméticos 59
3.2.Operadoresunarios 65
3.3.Operadoresrelacionalesylógicos 68
3A.Operadoresdeasignación 71
3.5.Eloperadorcondicional....................................................................................75
3.6.Funciones debiblioteca 77
4.Entrada ysalidadedatos 87
4.1.Introducción 87
4.2.Entrada deuncarácter-Lafunción getchar 88
4.3.Salidadeuncarácter-Lafunción putchar 89
4A.Introduccióndedatos- Lafunciónscanf ;...........................91
4.5.Mássobrelafunción scanf 96
4.6.Escritura
dedatos-Lafunción printf 101
4.7.Mássobrelafunción printf ;...........................................107
v

vi CONTENIDO
4.8.Lasfunciones getsyputs.............................................................................114
4.9.Programacióninteractiva(conversacional) 114
5.
Preparaciónyejecuciónde unprogramaene 127
5.1.PlanificacióndeunprogramaenC 127
5.2.Escriturade
unprogramaenC 129
5.3.Introduccióndeunprogramaen
lacomputadora 131
5.4.Compilaciónyejecuciónde unprograma 133
5.5.Mensajesdeerror 135
5.6.Técnicasdedepuración 140
6.
Instruccionesdecontrol................................................................................................153
6.1.Introducción.......................................................................................................153
6.2.Ejecucióncondicional:Lainstrucción
if-else 156
6.3.Bucles:lainstrucción
while 159
6.4.Mássobrebucles:lainstruccióndo-
while 163
6.5.Másaúnsobrebucles:lainstrucción
for 166
6.6.Estructurasdecontrolanidadas 170
6.7.Lainstrucción
switch 181
6.8.Lainstrucción break 190
6.9.Lainstrucción
continue 193
6.10.Eloperadorcoma 195
6.11.Lainstrucción
gota..........................................................................................199
7.
Funciones 217
7.1.Introducción 218
7.2.Definicióndeunafunción 219
7.3.Accesoaunafunción........................................................................................223
7.4.Prototiposdefunciones 226
7.5.Pasodeargumentosaunafunción 235
7.6.Recursividad 241
8.
Estructuradeunprograma 257
8.1.Tiposdealmacenamiento 257
8.2.Variablesautomáticas :.....................258
8.3.Variablesexternas(globales) 261
8.4.Variablesestáticas 268
8.5.Programasdevariosarchivos 272
8.6.Mássobrefuncionesdebiblioteca ;....282
.9.Arrays 299
9.1.Definicióndeunarray 300
9.2.Procesamientode
unarray 305
9.3.Pasodearraysafunciones 308
9.4.Arraysmultidimensionales 321
9.5.Arrays
ycadenasdecaracteres........................................................................328

CONTENIDO vii
10.Punteros 345
10.1.Conceptosbásicos 345
10.2.Declaracióndepunteros 349
10.3.Pasodepunterosaunafunción 350
10A.Punterosyarraysunidimensionales. 358
10.5.Asignacióndinámica
dememoria 363
10.6.Operacionesconpunteros 365
10.7.Punterosyarraysmu1tidimensiona1es 369
10.8.Arraysdepunteros 375
10.9.Pasodefuncionesaotrasfunciones 388
10.10.Mássobredeclaraciones
depunteros 397
11.
Estructuras
yuniones 415
11.1.Definicióndeunaestructura 415
11.2.Procesamiento
deunaestructura 421
11.3.Tipos
dedatosdefinidosporelusuario (typedef) 433
1104.Estructurasypunteros 436
11.5.Pasodeestructurasaunafunción 441
11.6.Estructurasautorreferenciadoras 453
11.7.Uniones 467
12.Archivosdedatos 489
12.1.Aperturaycierredeunarchivo 490
12.2.Creacióndeunarchivo 492
12.3.Procesamientodeunarchivo 499
1204.Archivossinformato 505
13.
Programaciónabajonivel 519
13.1.Variablesregistro 519
13.2.Operacionesanivel debits 523
13.3.Camposde bits 535
14.CaracterísticasadicionalesdeC 553
14.1.Enumeraciones 553
14.2.Parámetrosdelalínea
deórdenes 559
14.3.Mássobrefunciones
debiblioteca 563
1404.Macros 563
14.5.ElpreprocesadordeC 573
ApéndiceASistemasderepresentaciónde
números 585
ApéndiceBSecuenciasdeescape 587
ApéndiceC
Resumendeoperadores.. 589
ApéndiceDTiposdedatos
yreglasdeconversióndedatos 591

viiiCONTENIDO
ApéndiceEElconjuntodecaracteresASCII 593
ApéndiceFResumendeinstruccionesdecontrol............. 595
ApéndiceGCaracteresdeconversiónmásusadosde
scanfyprintf 597
Caracteresdeconversión descanf 597
Caracteresdeconversión
deprintf 598
Indicadores 599
ApéndiceHFunciones debibliotecamásusadas 601
Respuestasaproblemasseleccionados 607
Índice 649

Ejemploscompletosdeprogramas
Acontinuaciónselistanlosejemplosdeprogramassegúnelordenenqueapareceneneltexto.
Losejemplosvandesdelosmássencillosalosdecomplejidadmoderada.Sepresentanvarias
versionesdealgunosdeellos,enespecialdelosmássencillos.
1.Areade uncirculo- Ejemplos1.6-1.13
2.Conversióndeuncarácterdeminúsculaamayúscula- Ejemplos3.31, 7.1
3.Conversióndetexto enminúsculasamayúsculas- Ejemplos4.4,6.9,6.12,6.16,9.2
4.Lecturayescritura deunalíneadetexto- Ejemplos4.19,4.31
5.Calificacionesmediasdelosestudiantes- Ejemplo4.32
6.Cálculodelinteréscompuesto- Ejemplos5.1-5.4,8.13
7.Erroressintácticos- Ejemplo5.5
8.Erroresdeejecución(Raícesreales deunaecuacióndesegundogrado)- Ejemplo5.6
9.Depuraciónde unprograma- Ejemplo5.7
10.Depuracióncon undepuradorinteractivo- Ejemplo5.8
11.Generacióndecantidadesenterasconsecutivas- Ejemplos6.8,6.11,6.14,6.15
12.Mediadeunalistadenúmeros- Ejemplos6.10,6.13, 6.17,6.31
13.Repeticióndelamediadeunalista denúmeros- Ejemplo6.18
14.Conversióndevariaslíneasdetextoamayúsculas- Ejemplos6.19,6.34
15.Codificacióndeunacadena decaracteres- Ejemplo6.20
16.Cálculosrepetidosdelinteréscompuestocondeteccióndeerror- Ejemplo6.21
17.Solucióndeunaecuaciónalgebraica- Ejemplo6.22
18.Cálculodeladepreciación- Ejemplos6.26,7.13
19.Búsquedadepalíndromos- Ejemplo6.32
20.Mayor detrescantidadesenteras- Ejemplo7.9
21.Cálculodefactoriales- Ejemplos7.10, 7.14,8.2
22.Simulación deunjuegodeazar (<<ShootingCraps»)- Ejemplos7.11,8.9
23Escriturainversa- Ejemplo7.15
24.Lastorres deHanoi- Ejemplo7.16
25.Longitudmedia devariaslíneas detexto- Ejemplos8.3,8.5
26.Búsqueda deunmáximo- Ejemplos8.4,8.11
27.Generación denúmerosdeFibonacci- Ejemplos8.7,8.12,13.2
28.Desviacionesrespectoa lamedia- Ejemplos9.8,9.9
29.Reordenación deunalistadenúmeros- Ejemplos9.13,10.16
30.Ungeneradorde«PigLatín»- Ejemplo9.14
31.Sumadedostablasdenúmeros- Ejemplos9.19,10.22,10.24
32.Reordenación deunalistadecadenasdecaracteres- Ejemplos9.20,10.26
33.Análisisdeunalíneadetexto- Ejemplo10.8
34.Presentacióndeldíadelaño- Ejemplo10.28
35.Valorfuturodedepósitosmensuales(cálculodeinteresescompuestos)- Ejem­
plos10.30,14.13
ix

X EJEMPLOSCOMPLETOS DEPROGRAMA
36.Actualizaciónderegistrosdeclientes- Ejemplos11.14,11.28
37.Localizaciónderegistrosdeclientes- Ejemplo11.26
38.Procesamientodeunalistaenlazada- Ejemplo11.32
39.Elevacióndeunnúmeroaunapotencia- Ejemplos11.37,14.5
40.Creacióndeunarchivodedatos(conversióndetextodeminúsculasamayúsculas)- Ejem-
plo12.3
41.Lecturadeunarchivodedatos- Ejemplos12.4,14.9
42.Creacióndeunarchivoquecontieneregistrosdeclientes- Ejemplo12.5
43.Actualizacióndeunarchivoquecontieneregistrosdeclientes- Ejemplo12.6
44.Creacióndeunarchivodedatossinformatoquecontieneregistrosdeclientes- Ejem­
plo12.7
45.Actualizacióndeunarchivodedatossinformatoquecontieneregistrosdeclientes- Ejem­
plo12.8
46.Presentacióndepatronesdebits- Ejemplo13.16
47.Compresióndedatos(almacenamientodenombresyfechasdenacimiento)- Ejemplo13.23

Prólogo
Desdelapublicación delaprimeraedicióndeestelibro,lapopularidad deChaseguidoaumen­
tando.Lamayoría delosúltimoscompiladoresaparecidosproporcionannumerosasampliaciones
alestándarANSI1989,asícomoentornos
deprogramacióngráficosmuysofisticadosque
inclu­
yenundepurador,ungestordeproyectosyunaayudaenlíneamuydetallada.Másaún,elinterés
deCnohadisminuidoporlaaparicióndeC++,debidoaquelascaracterísticasdeestenovedoso
lenguajedeprogramaciónexigenunsólidoconocimiento
deC.
EstasegundaedicióninstruyeenelusodellenguajeC,dentrodelcontextodelestilo de
programacióndeCcontemporáneo.Incluyeexplicacionescompletasycomprensibles delas
fa­
cetasdeC deusomáscomún,incluidaslasdelestándarANSIactual.Además,ellibropresenta
unenfoquemodernodelaprogramación,insistiendoenlaimportancia
delaclaridad,
legibili­
dad,modularidadyeficienciaeneldiseñodelosprogramas. Selepresentanallector deesta
formalosprincipios
delabuenaprogramación,asícomolasreglasespecíficasdel C.Aparecen
programasenCcompletosportodoellibro,apartirdelprimercapítulo.Seponeespecialénfasis
eneluso
deunestilodeprogramacióninteractivo.
Ellibropuedeserusadoporunagranvariedad
delectores,desdeprogramadoresqueestén
iniciándosehastalosprofesionalesexpertos.Seadaptabiencomolibro
detextoauncurso de
introducciónalaprogramaciónparaestudiantesaniveluniversitario,ocomountexto
comple­
mentario,oindependientemente,comounaeficienteguía.
Seincluyenmuchoejemploscomoparteprincipaldeltexto.Éstosincluyenasuveznumero­
sosejemplosdeprogramación decomplejidadvariable,asícomoilustrativosproblemastipo
ejercicioqueseadaptanalestándarANSI
C.Muchosdelosejemplosseencuentranresueltosen
otroslenguajes
deprogramaciónenloslibroscorrespondientes delaserieSchaum,proporcio­
nandodeestaformaallectorunabaseparalacomparación
devarioslenguaj espopulares.
Alfinaldecadacapítuloaparecenconjuntos
decuestionesderepasoyejercicios.Las
cuestio­
nesderepasopermitenallectorprobarlaasimilacióndelmaterialpresentadoencadacapítulo.
Aportantambiénuneficazresumendelmismo.Losejerciciosrefuerzanlosprincipiospresenta­
dosencadacapítulo.Ellectordeberíaresolverelmayornúmeroposibledeestosproblemas.Al
finaldellibroaparecenlassolucionesalamayoría
delosejercicios.
LosproblemasquerequierenlaescrituradeprogramascompletosescritosenCsepresentan
alfinaldecadacapítulo,apartirdelnúmerocinco.
Seinstaallectoraescribiryejecutarel
mayornúmeroposibledeestosprogramas.Estoaumentará
deformaconsiderablelaconfianzaen
símismoyestimularásuinterésporeltema.(Paralaprogramaciónsenecesitahabilidad,igual
queparaescribirunlibrootocaruninstrumentomusical.Estahabilidadnoseadquiere
simple­
menteleyendounlibro detexto.)
Lamayoríadeestosproblemas deprogramaciónnorequierenconocimientosmatemáticoso
técnicosespeciales.Pueden,
portanto,serresueltosporunamplioespectrodelectores.Encaso
deutilizarestelibroenuncursodeprogramación,esposiblequeelinstructordeseeañadira
estosproblemasotrosqueresultendeespecialinterésendeterminadas disciplinas.
Sehanrealizadounaserie
decambiosconrespectoalaediciónanterior. Sehaescritode
nuevoelCapítulo5,conlautilizacióndelentornodeprogramaciónTurboC++deBorland
xi

xiiPRÓLOGO
InternationalparailustrarelusodelC,yseharedactadodenuevoyampliadoelmaterial
correspondientealastécnicas
dedepuración.SehanreordenadolostópicosdelCapítulo6de
maneraquesecorrespondenconelordenenquesesuelenpresentarenlamayoría
deloscursos
deintroducciónalaprogramación,conlabifurcaciónantes
delosbucles.Sehaeliminadodel
Capítulo7partedelmaterialsobreeluso
delasfunciones,elcualreflejabaunestilo deprogra­
maciónobsoleto,ysehaañadidoalCapítulo
10unasecciónsobreasignacióndinámica dememo­
ria.
Enlamayoríadelosejemplosdeprogramaciónsehanrealizadocambios deestilo;más
concretamente,losprogramasqueutilizanvariasfuncioneshacenahoraespecialénfasisenel
prototipadocompleto
delafunción,talycomorecomiendaelestándarANSIactual.
Todoslosejemplos
deprogramaciónymuchos delosproblemasqueaparecen alfinaldelos
capítulossehanresueltoyejecutadoenunPC
(<<compatibleIBM»),utilizandoversionesdiferen­
tesdelcompiladorTurbo
C++deBorlandIntemational.
LasprincipalescaracterísticasdeCestánresumidasenlosApéndicesdelAhastaelHalfinal
dellibro.Esrecomendableusarestematerialfrecuentementecomoreferenciarápida.Esparticu­
larmenteútilalescribirodepurarnuevosprogramas.
BYRONS.GOTTFRIED

CAPíTULO1
Conceptosbásicos
Estelibroinstruye enlaprogramacióndecomputadorasenunlenguajepopularyestructurado:
ellenguajeC.Además,veremoscómoanalizarproblemasquesondescritosinicialmenteen
términosmuygenerales,cómoesbozadosycómoobtenerfinalmenteprogramas
ebienorgani­
zados.Lamultituddeproblemasdeejemploqueincluyeeltextomuestrancondetalleestos
conceptos.
1.1.INTRODUCCIÓN ALASCOMPUTADORAS
Lascomputadorasdehoydíasepresentanenunaampliavariedad deformas.Surangoseex­
tiendedesdelos
«mainframes»(grandescomputadoras)y supercomputadorasmasivasymul­
tipropósitohastalas
computadoraspersonales deescritorio.Entreambosextremosnosencon­
tramosconuninmensoconjunto
deminicomputadorasyestacionesdetrabajo.Lasgrandes
minicomputadorasseaproximanalos«mainframes»enpotenciadecálculo,mientrasquelas
estacionesdetrabajosonpotentescomputadoraspersonales.
Los«mainframes»ylasgrandesminicomputadorasseutilizanenmuchosnegocios,univer­
sidades,hospitalesyagenciasgubernamentalesparadesarrollarsofisticadoscálculoscientíficos
yfinancieros.Estascomputadorassonmuycaras(lasgrandescuestanmillones
dedólares)y
requierenunaplantillagrande
depersonalparasufuncionamiento,asícomounentornoespecial
ycuidadosamentecontrolado.
Porotrolado,lascomputadoraspersonalessonpequeñasybaratas.Dehecho,enlaactuali­
dadmuchosestudiantesyprofesionalesqueviajanconfrecuenciautilizanmuchocomputadoras
«portátiles»conbateríaincorporadayconunpesoinferiora 2 o 3kilogramos.Enmuchases­
cuelasyempresasseutilizanampliamentelascomputadoraspersonales,quesehanconvertido
enelementosdeusodoméstico.Lamayoríadelosestudiantesutilizancomputadoraspersonales
cuandoaprendenaprogramaren
C.
LaFigura1.1muestraaunestudiantetrabajandoconunacomputadoraportátil.
Apesardesupequeñotamañoybajoprecio,lasmodernascomputadoraspersonalesrivali­
zanenpotenciadecomputaciónconmuchasminicomputadoras.Ahoraseutilizanparamuchas
aplicacionesqueantesserealizabanencomputadorasmásgrandesymáscaras.Másaún,su
potenciaaumentaalavezquesupreciodisminuyeprogresivamente.Eldiseño
deunacomputa­
dorapersonalpermiteunaltonivel
deinteracciónentreelusuarioylacomputadora.Muchas
aplicaciones(porejemploprocesadoresdetexto,programas
detratamientodegráficos,hojas de
cálculoyprogramasdegestióndebasesdedatos)estánespecialmentediseñadasparasacar
1

2 PROGRAMACiÓN ENC
Figura1.1.
partidodeesteentorno,proporcionandoalusuarioentrenadounaampliavariedad deherramien­
tascreativasparaescribir,dibujarorealizarcálculosnuméricos.Lasaplicacionescongráficos
dealtaresoluciónsontambiénfrecuentes.
Muchasvecesseconectancomputadoraspersonalescongrandescomputadorasoconotras
computadoraspersonales,permitiendosuutilizaciónbiencomodispositivosautónomosobien
comoterminalesenuna
reddecomputadoras.Sonfrecuentestambiénlasconexionesatravés de
líneastelefónicas.Dentro deestecontexto,podemosverquelascomputadoraspersonalestien­
dena
complementarmásquea reemplazaralasgrandescomputadoras.
1.2.CARACTERÍSTICAS DELASCOMPUTADORAS
Todaslascomputadorasdigitales,independientementedesutamaño,sonbásicamentedispositi­
voselectrónicosquepuedentransmitir,almacenarymanipular
información(datos). Unacom­
putadorapuedeprocesardistintostipos
dedatos.Estoincluye datosnuméricos,alfanuméricos
(nombres,direcciones,etc.), gráficos(mapas,dibujos,fotografías,etc.)y sonido(música,lectu­
radetextos,etc.).Desdeelpuntodevistadelprogramadorreciéniniciado,losdostipos
dedatos
másfamiliaressonlosnúmerosyloscaracteres.Lasaplicacionescientíficasytécnicasinvolu­
cranprincipalmentedatosnuméricos,.mientrasquelasaplicacionesempresarialesnormalmente
requierenprocesartantodatosnuméricoscomoalfanuméricos.
Paraquelacomputadoraproceseunconjuntoparticulardedatos
esnecesariodarleuncon­
juntoapropiadodeinstruccionesllamado
programa.Estasinstrucciones
seintroducenenlacom­
putadoraysealmacenanenunapartedela
memoriadelamáquina.

CONCEPTOS BÁSICOS 3
Unprogramaalmacenadosepuede ejecutarencualquiermomento.Suejecuciónsuponelos
siguientespasos:
1.Seintroduceenlacomputadora(desdeunteclado,undisquete,etc.)unconjuntode
información,los
datosdeentrada, ysealmacenaenunapartedelamemoriadeésta.
2.Losdatosdeentradaseprocesaránparaproducirciertosresultadosdeseados,los datos
desalida.
3.Losdatosdesalida,yprobablementealgunosdelosdatosdeentrada, seimprimiránen
papelosepresentarán enunmonitor(unapantalladiseñadaespecialmenteparavisuali­
zarsalidadecomputadora).
Esteprocedimientodetrespasossepuederepetirtantasvecescomosedesee,procesandorá­
pidamenteunagrancantidaddedatos.
Encualquiercaso,sedebetenerpresentequeestospasos,
especialmenteel2 yel3,puedenserlargosycomplicados.
EJEMPLO1.1. Unacomputadorahasidoprogramadaparacalcularelárea deuncirculoutilizando
lafórmula
a=
nr,d~ndoelvalornumérico delradiocomodatodeentrada.Esnecesarioseguirestos
pasos:
l.Leer
elvalornumérico delradiodelcirculo.
2.Calcularelvalordeláreautilizandolafórmulaanterior.Estevalor sealmacenará,junto conlos
datosdeentrada,enlamemoriadelacomputadora.
3.Imprimir(presentar enelterminal)losvaloresdelradioy deláreacorrespondiente.
4.Parar.
Cadaunodeestospasosrequiereunainstruccióno másenunprograma.
Loanteriormentedichoilustradoscaracterísticasimportantesde
unacomputadoradigital:
memoriaycapacidaddeserprogramada. Otrascaracterísticasimportantessonsu velocidady
fiabilidad.
Hablaremosmásdememoria,velocidadyfiabilidad enlossiguientespárrafos. La
programabilidadserádiscutidaampliamenteenelrestodellibro.
Memoria
Cadafragmentodeinformaciónalmacenado enlamemoriade lacomputadoraescodificado
comounacombinaciónúnicadecerosyunos.Estoscerosyunossellaman
bits(dígitos
bina­
rios).Undispositivoelectrónicorepresentacadabit, enciertosentido,como«apagado»(cero)o
«encendido»(uno).
Lascomputadoraspersonalestienenlamemoriaorganizada
engruposde8bits,denomina­
dos
bytes,comosemuestraenlaFigura1.2.Hayqueadvertirquecadabitestánumerado,empe­
zando
porO(elbitdelextremo derecho)yterminandoen7(elbitdelextremoizquierdo).
Normalmente,
uncarácter(porejemplounaletra,unsolodígitoo unsímbolodepuntuación)
ocupará
unbytedememoria. Unainstrucciónpuedeocupar 1,2 o 3bytes.Unaciertacantidad
numéricapuedeocupardeI a 8bytes,dependiendodela
precisión(elnúmerodecifrassignifi­
cativas)yel
tipo(entero,comaflotante,etc.).

4 PROGRAMACiÓN ENC
bitnúmero:7 6 5 4 3 2 1 O
mUIIIJ
Unbyte
Figura1.2.
Normalmenteseexpresaeltamañodelamemoriacomputadoracomoalgúnmúltiplode2
10
=
1024by-tes;estoes, lK.Lascomputadoraspersonalesactualestienenmemoriasdetamaños
comprendidostípicamenteentre256y1024megabytes,siendo1megabyte(1M)equivalentea
2
10
•2
10
bytes,o 2
1
°K=1024Kbytes.
EJEMPLO1.2. Lamemoriadeunacomputadorapersonaltieneunacapacidad de16Mbytes.Asipues,
sepuedenalmacenar ensumemoria16.1024.1024=16777216caracteresy/oinstrucciones.Sise
utilizalamemoriacompletapararepresentarcaracteres (locualespocoprobablel,entonces sepodrán
almacenar
unos200000nombresydireccionesa lavez,suponiendounos80caracteresporcadanombre
ydirección.
Siseutilizalamemoriaparaalmacenar datosnuméricosenvezdenombresydirecciones,sepodrán
almacenar
másde4millonesdenúmerosala vez,suponiendoquecadacantidadnuméricarequiera4
bytes
dememoria.
Lasgrandescomputadorastienenmemoriasorganizadasenpalabrasenlugardebytes.Cada
palabratendráunnúmerorelativamentegrandedebits,típicamente32o36.EnlaFigura
1.3apa­
recelaorganizaciónaniveldebitsdeunapalabrade32bits.Nótesequelosbitsestánnumerados,
comenzandoporelO(elbitdelextremoderecho)yfinalizandoen
31(elbitdelextremoizquierdo).
bit
n.":313029282726252423222120191817161514131211109876543210
Unapalabrade32bits
Figura1.3.
LaFiguralAmuestralamismapalabrade32bitsorganizadaencuatrobytesconsecutivos.
Losbytesestánnumeradosdelamismaformaquelosbitsindividuales,deO(elbytedelextremo
derecho)a 3(elbytedelextremoizquierdo).
Elusodepalabrasde32o36bitspermiterepresentar
unacantidadnuméricao unpequeño
grupodecaracteresen
unasolapalabradememoria.Normalmentelasgrandescomputadoras
tienenvarios millonesdepalabras(variasmegapalabras)dememoria.
bit
n.":
31302928272625242322212019 1817 16 1514131211109 8 7 6 5 4 3 2 1 O
Unapalabrade4bytes(32bits)
Figura1.4.

CONCEPTOS BÁSICOS 5
EJEMPLO1.3. Lamemoriadeunagrancomputadoratieneunacapacidadde32M(32768K)palabras,
loqueesequivalentea32.1024.1024
=33554432palabras.Siseusalamemoriaenterapararepresen­
tardatosnuméricos(locualnoesmuyprobable),entoncessepodránalmacenarenlacomputadoramásde
33
mi110nesdenúmerosalavez,suponiendoquecadacantidadnuméricarequieraunapalabradememoria.
Siseutilizalamemoriacompletapararepresentarcaracteresenlugardedatosnuméricos,
sepodrán
almacenarmásde130
mi110nesdecaracteresalavez,suponiendo4caracteresporpalabra.Estamemoria
essuficienteparaalmacenarloscontenidosdevarioslibrosvoluminosos.
Lamayoríadelascomputadorasutilizantambién dispositivosauxiliaresdealmacenamiento
(porejemplocintasmagnéticas,discos,dispositivosópticos dememoria)además delamemoria
principal.Estosdispositivospuedenalmacenargigabytes
(lG=1024M)deinformación.Ade­
más,permitenquesegrabe permanentementelainformación,pudiendonormalmenteserdesco­
nectados
delacomputadorayalmacenadoscuandonoseutilicen.Sinembargo,eltiempode
acceso(eltiemponecesarioparaalmacenarorecuperarinformación)deestosdispositivosauxi­
liaressueleserconsiderablementemayorqueeldelamemoriaprincipal
delacomputadora.
Velocidadyfiabilidad
Graciasasuvelocidadextremadamentealta,unacomputadorapuedeefectuarenunospocos
minutoscálculosquerequeriríanmuchosdías,posiblementemesesoaños,
sisehiciesenamano.
Porejemplo,sepuedenprocesarlascalificaciones
definaldesemestredetodoslosestudiantes
deunagranuniversidadenunospocosminutosdetiempo
decómputo.
Eltiemporequeridoparaefectuartareasdecálculosencillas,comosumardosnúmeros,
seexpresahabitualmenteen
microsegundos(1
IJ.seg=10-
6
seg)o nanosegundos(lnseg=
=
10-
3
IJ.seg=10-
9
seg).Portánto,siunacomputadorapuedesumardosnúmerosen 10nano­
segundos(típico
deunacomputadoramediaactual),puedeefectuar100millones(lO') desumas
enunsegundo.
Estaaltavelocidadesacompañadaporunnivelequivalentedefiabilidad.Unacomputadora
nuncacometeráunerrorporsímisma.Lostandivulgados «erroresdecomputadoras»,tales
comoqueaunapersonaselecargueunrecibodeteléfonodevariosmillones
dedólares,sonel
resultado
deerroresdeprogramaciónodeerroresenlaintroduccióndedatos, ynocausadospor
lapropiacomputadora.
1.3.MODOSDEOPERACIÓN
Unagrancomputadorapuedesercompartídapormuchosusuariosdedosformasdiferentes.
Éstassonel
mododeprocesamientoporlotesyelmodointeractivo.Cadamodotienesuspro­
piasventajasparaciertostiposdeproblemas.
Procesamientoporlotes
Enelprocesamientoporlotessecarganunaseriedetareasenlacomputadora,sealmacenan
internamenteyluegoseprocesansecuencialmente.(Una
tareaesunprogramaysusconjuntos
dedatosdeentradaasociados.)Trasserprocesadalatarea,unaimpresora
dealtavelocidad
imprimeenmúltipleshojasdepapellasalidajuntoconellistadodelprograma.Normalmenteel

6 PROGRAMACiÓN ENC
usuariorecogerálasalidaimpresatrasunciertotiempotranscurridodesdequelatareahayasido
procesada.
Enel
procesamientoporlotesclásico (hoydíaobsoleto)elprogramaylosdatoserangra­
badosen
tarjetasperforadas. Estainformaciónseintroducíaenlacomputadoramedianteun
lectormecánico
detarjetasy acontinuaciónseprocesaba.Enlosalbores delainformática,todas
lastareasseprocesaban
deestamanera.
El
procesamientoporlotesmoderno vaunidogeneralmenteasistemasdetiempocompartido
(verpróximasección).Enestossistemaselprogramaylosdatossonintroducidosenlacompu­
tadoramedianteun
terminalounacomputadorapersonal. Sealmacenaentonceslainformación
enlamemoriadelacomputadorayesprocesadaenundeterminadoorden.Estaforma
deproce­
samientoporlotesespreferiblealaclásica,yaqueeliminalanecesidaddeutilizartarjetasper­
foradasypermitelaedicióndelainformación
deentrada(programaydatos)mientrasseintro­
duce.
Enelprocesamientoporlotespuedencircularmuyrápidamentegrandescantidades
deinfor­
mación(programasydatos)haciadentroyfueradelacomputadora.Además,elusuariono
necesitaestarpresentemientrasseprocesalatarea.Estemododeoperaciónseadecúaatareas
querequierengrancantidaddetiempodecómputooqueson,engeneral,muylargas.Porotra
parte,eltiempototalrequeridoparaqueunatareaseaprocesadadeestaformapuedevariar
entrevariosminutosyvariashoras,auncuandolatareapuedasólonecesitarunoodossegundos
detiemporeal
decómputo.(Cadatareadebeesperarsuturnohastaqueescargada,procesaday
escritasusalida.)Deestaforma,elprocesamientoporlotespuedeserpocodeseablecuandoes
necesarioprocesarmuchaspequeñastareasypresentarsusresultados
loantesposible(como,
porejemplo,cuandoseaprendeaprogramar).
Sistemasdetiempocompartido
Unsistemade tiempocompartido permiteadiferentesusuariosutilizarunasolacomputadoraa
lavez.Lacomputadoraanfitrionapuedeserun«mainframe»,unaminicomputadoraounagran
computadora
desobremesa.Losusuariossecomunicanconlacomputadoraatravés desuster­
minalesindividuales.
Enlasredesdetiempocompartidomodernasesfrecuenteutilizarlascom­
putadoraspersonalescomoterminales.Lacomputadoraanfitrionapuedesoportarmuchostermi­
nalesalavez,yaquetrabajamuchomásrápidoqueunoperadorhumanoen suterminal.Deeste
modo,cadausuarioseráajenoalapresencia
deotrosusuariosycreerá tenertodalacomputado­
raanfitrionaasudisposición.
Cadaterminalindividualpuedeestarbienconectadodirectamentealacomputadoracentral,
obienatravésdelaslíneastelefónicas,deuncircuito
demicroondasoinclusounsatéliteespa­
cial.Elterminalpuede,portanto,estarlocalizadolejos
--quizáscientosde kilómetros-desu
computadoracentral.Sonparticularmentefrecuenteslossistemasenquelascomputadorasper­
sonalesseconectanagrandes«mainframes»através
delíneastelefónicas.Talessistemashacen
uso
demódems(dispositivosmoduladores/demoduladores)paraconvertirlasseñalesdigitales
delacomputadoraenseñalestelefónicasanalógicasyviceversa.Atravésdedichaconfigura­
ción,unapersonaquetrabajaehcasapuedefácilmenteaccederconsucomputadorapersonala
lacomputadoraremotadelcolegioode
laoficina.
Unsistemadetiempocompartido
esmásadecuadoparaelprocesamiento detareasrelativa­
mentesencillasquenorequieran
delatransmisióndemuchosdatosodegrandescantidadesde

CONCEPTOS BÁSICOS 7
tiempodecómputo.Muchasaplicacionesdelasescuelasydelas oficinascomercialespresentan
estascaracterísticas.Utilizandoeltiempocompartidosepuedenprocesartalesaplicacionesde
unaformarápida,fácilybarata.
EJEMPLO1.4. Unagranuniversidaddisponedeunacomputadora detiempocompartidoconcapaci­
dadpara200terminalesy
80conexionestelefónicasseparadas.Losterminalessituadosendiferenteslu­
garesdelcampusestánconectadosdirectamenteaungran«mainframe».Cadaterminalescapaz
detrans­
mitirinformacióna odesdelacomputadoracentralaunavelocidadmáximade960caracteresporsegundo.
Lasconexionestelefónicaspermitenaestudiantesqueno
seencuentranenelcampusconectarsus
computadoraspersonalesalacomputadoracentra!.Cadacomputadorapersonalpuedetransmitirdatosa o
desdelacomputadoracentralaunavelocidadmáximade240caracteresporsegundo.Asipues,los280
terminalesycomputadoraspuedeninteractuarconlacomputadoracentralalavez,estandocadaestudian­
tedespreocupadodequelosdemásestáncompartiendoalmismotiempolacomputadora.
Computacióninteractiva
Lacomputacióninteractiva esuntipodeentornodecomputaciónquesurgióconlossistemasde
tiempocompartidocomercialesyquehasidomejoradoconelampliousodelascomputadoras
personales.Enunentornodecomputacióninteractivo,durantelasesióndetrabajoexisteinter­
acciónentreelusuarioylacomputadora.Deestemodo,elusuarioseráconsultadoperiódica­
menteparaqueproporcioneciertainformación,lacualdeterminarálasaccionespertinentesa
realizarporlacomputadorayviceversa.
EJEMPLO1.5. Unestudiantedeseausarunacomputadorapersonalpara calcularelradio deuncírculo
cuyaáreatieneelvalorde100.
Sedisponedeunprogramaquecalculaeláreadelcírculo,dado elradio.
(Nótesequeestoesjusto
locontrariodeloqueelestudiantedeseahacer.)Esteprogramanoesexactamen­
teloquenecesita,peropermite
alestudianteprocederpor elmétododepruebayerror.Elprocedimiento
consistiráenadivinarunvalorparaelradioyluegocalculareláreacorrespondiente.Elprocedimiento
de
pruebayerrorcontinuaráhastaqueelestudianteencuentreunvalordelradioparaqueeláreasea lo
suficientementepróximaa100.
Unavezquecomienzalaejecucióndelprograma,apareceelmensaje
Radio
~?
Entonceselestudianteintroduceunvalordelradio.Supongamosqueda unvalorde
5.Lacomputado­
raresponderápresentando:
Area
~78.5398
¿Deseasrepetirelcálculo?
Elestudianteresponde síono.Sielestudiantedice sí,entoncesaparecedenuevoelmensaje:
Radio~?
yserepetiráde.nuevoelproceso.Si elestudiantedice no,entoncessepresentaenlapantalla:
Adiós
yfinalizalaejecucióndelprograma.

8 PROGRAMACiÓN ENC
Acontinuaciónsemuestraunacopiaimpresa delainformaciónpresentadaduranteunasesióninterac­
tivatípica,usando
elprogramaantesdescrito.Enestasesiónsedeterminaunvaloraproximadode
r=5.6despuésdesólotrescálculos. Sehasubrayadolainformaciónaportadaporelestudiante.
Radio=?
.2­
Area=78.5398
¿Deseasrepetirelcálculo?sí
Radio=?Q
Area=113.097
¿Deseasrepetirelcálculo?sí
Radio=?2......Q
Area=98.5204
¿Deseasrepetirelcálculo?no
Adiós
Nóteselaforma enqueparecenconversarlacomputadorayelestudiante.Observetambiéncómoel
estudianteesperahastaqueveelvalordeláreacalculadoantesdedecidirsicontinúaonohaciendocálcu­
los.Siseiniciaotronuevocálculo,elnuevovalordelradioqueproporcioneelestudiantedependerádelos
resultadosdecálculosanteriores.
Aveceslosprogramasdiseñadosparaaplicaciones detipointeractivosedenominan conver­
sacionales.
Losjuegos decomputadorassonexcelentesejemplosdeaplicacionesdeestetipo.
Enellosaparecenelaboradosgráficosyaccionesrápidas,auncuandolasrespuestasdelusuario
sonmásdetiporeflejoquenuméricasoverbales.
1.4.TIPOS DELENGUAJESDEPROGRAMACIÓN
Sepuedenutilizarmuchoslenguajesparaprogramarunacomputadora.Elmásbásico esellen­
guajemáquina,
unacoleccióndeinstruccionesmuydetalladasycrípticasquecontrolanlacir­
cuiteríainterna
delamáquina.Ésteeseldialectonatural delacomputadora.Muypocosprogra­
masseescribenactualmenteenlenguajemáquinapordosrazonesimportantes:primero,porque
ellenguajemáquinaesmuyincómodoparatrabajar,ysegundo,porquelamayoría
delasmáqui­
nastienensusrepertoriosdeinstruccionespropios.Así,unprogramaescritoenlenguajemá­
quinaparaunacomputadoranopuedeserejecutadoenotra
dedistintotiposinmodificaciones
importantes.
Lomásfrecuente
esutilizarlenguajesde altonivel,cuyasinstruccionessonmáscompatibles
conloslenguajesylaformadepensarhumanos.Lamayoríasonlenguajesde
propósitogeneral,
comoC.(Otroslenguajes depropósítogeneralsonPascal,FortranyBASrC.)Haytambiénlen­
guajesde
propósitoespecial queestándiseñadosespecíficamenteparaalgúntipoparticularde
aplicación.AlgunosejemploscomunessonCSMPySrMAN,quesonlenguajesorientadosala
simulación,yLISP,unlenguajeorientadoal tratamientodelistas queseutilizaampliamenteen
aplicaciones
deinteligenciaartificial.
Pornormageneral,unasolainstruccióndeunlenguajedealtonivelseráequivalenteavarias
delenguajemáquina.Estosimplificaenormementelatareadeescribirprogramascompletosy

CONCEPTOS BÁSICOS 9
correctos.Además,lasreglasdeprogramaciónenunlenguaje dealtonivelsepuedenaplicara
todaslascomputadoras,
demaneraque unprogramaescritoparaunacomputadorasepuede
ejecutarnormalmenteenotrasmáquinasdiferentesconmuypocasmodificacionesodirecta­
mente.Portanto,eluso
deunlenguajedealtonivelofrecetresventajasimportantesrespectoal
lenguajemáquina:sencillez,uniformidadyportabilidad(independencia
delamáquina).
Entodocaso,unprogramaescritoenlenguajedealtonivelhadesertraducidoalenguaje
máquinaantesdepoderserejecutado.Estoseconocecomocompilaciónointerpretación,de­
pendiendodecómoselleveacabo.(Loscompiladorestraducenelprogramacompletoalengua­
jemáquinaantesdeejecutarcualquiera delasinstrucciones.Losintérpretes,porotrolado,reco­
rrenelprogramatomandoinstruccionesunaaunaenpequeñosgruposquetraducenyejecutan.)
Encualquiercaso,latraducciónsellevaacabodeformaautomáticaporlacomputadora.De
hecho,losprogramadoresreciéniniciadosavecesnosedancuenta
dequeestehechoestáocu­
rriendo,yaquetípicamentesólovenelprogramaoriginalenaltonivel,losdatosdeentradaylos
resultadosobtenidos.Lamayoría
delasimplementacionesdeCoperancomocompiladores.
Uncompiladorointérprete
esasuvezunprograma.Aceptacomodatos deentradaun
progra­
maenaltonivel(porejemplounprogramaenC)ygeneracomoresultadoelcorrespondiente
programaenlenguajemáquina.
Elprogramaoriginalenlenguaje dealtonivelsellamaprograma
fuente,yelprogramaresultanteenlenguajemáquinasellamaprogramaobjeto.Cadacomputadora
debedisponerdesupropiocompiladorointérpreteparacadalenguajedealtonivelparticular.
Esmásconveniente,pornormageneral,desarrollarunprogramanuevoutilizandounintér­
preteenvezdeuncompilador.Unavezquesehaconseguidoelprogramasinerrores,unaver­
sióncompiladaseejecutaránormalmentedeformamuchomásrápidaqueunainterpretada.Las
razonesporlasqueocurreestoquedanfueradelámbitodelapresentediscusión.
1.5.INTRODUCCIÓN ALC
Cesunlenguajedeprogramaciónestructuradodepropósitogeneral.Susinstruccionesconstan
detérminosqueseparecenaexpresionesalgebraicas,además deciertaspalabrasclaveinglesas
como
if,else,for,doywhile.Enestesentido,Crecuerdaaotroslenguajesdeprograma­
ciónestructuradoscomoPascalyFortran.Ctienetambiénalgunascaracterísticasadicionales
quepermitensuusoaunnivelmásbajo,cubriendoasielvacioentreellenguajemáquinaylos
lenguajesdealtonivelmásconvencionales.EstaflexibilidadpermiteelusodeCenlaprogra­
macióndesistemas(porejemplo,paraeldiseñosistemasoperativos)asicomoenlaprograma­
cióndeaplicaciones(porejemplo,pararedactarunprogramaqueresuelvauncomplicadosiste­
ma
deecuacionesmatemáticasounprogramaqueescribalasfacturasparalosclientes).
Csecaracterizaporhacerposiblelaredaccióndeprogramasfuentemuyconcisos,debidoen
partealgrannúmerodeoperadoresqueincluyeellenguaje.Tieneunrepertoriodeinstrucciones
relativamentepequeño,aunquelasimplementacionesactualesincluyennumerosasfunciones
de
bibliotecaquemejoranlasinstruccionesbásicas.Esmás,ellenguajepermitealosusuarioses­
cribirfunciones
debibliotecaadicionalesparasupropiouso.Deestaforma,lascaracterísticasy
capacidadesdellenguajepuedenserampliadasfácilmenteporelusuario.
HaycompiladoresdeCdisponiblesparacomputadoras
detodoslostamaños,ylosintérpre­
tesdeCseestánhaciendocadavezmáscomunes.Loscompiladoressonfrecuentementecom­
pactosygeneranprogramasobjetoque'sonpequeñosymuyeficientesencomparaciónconlos

10 PROGRAMACiÓN ENC
programasgeneradosapartir deotroslenguajes dealtonivel.Losintérpretessonmenoseficien­
tes,aunqueresultandeusomáscómodoeneldesarrollo
denuevosprogramas.Muchosprogra­
madorescomienzanutilizandounintérprete,yunavezquesehadepuradoelprograma(elimi­
nadoloserroresdelmismo)utilizanuncompilador.
Otracaracteristicaimportante
deCesquelosprogramassonmuyportables,másquelos
escritosenotroslenguajes
dealtonivel.Larazóndeesto esqueCdejaenmanos delasfuncio­
nesdebibliotecalamayoría
delascaracterísticasdependientesdelacomputadora.Todaversión
deCseacompaña
desupropioconjuntodefunciones debiblioteca,queestánescritasparalas
característicasparticularesdelacomputadoraenlaqueseinstale.Estasfunciones
debiblioteca
estánrelativamentenormalizadasyelaccesoacadafuncióndebiblioteca
esidénticoentodas
lasversiones
deC.Deestaforma,lamayoríadelosprogramasenCsepuedencompilaryejecu­
tarenmuchascomputadorasdiferentesprácticamentesinmodificaciones.
Historiadel e
CfuedesarrolladooriginalmenteenlosañossetentaporDennisRitchieenBellTelephoneLabora­
tories,Inc.(ahoraunasucursal
deAT&T).Eselresultado dedoslenguajesanteriores,elBCPL
yelB,quesedesarrollarontambiénenloslaboratoriosBell.Cestuvoconfinadoalusoenlos
laboratoriosBellhasta1978,cuandoBrianKernighanyRitchiepublicaronunadescripcióndefini­
tivadellenguaje
*.LadefinicióndeKernighanyRitchiesedenominafrecuentemente«K&RC».
Traslapublicación
deladefinicióndeK&R,losprofesionalesdelascomputadoras,impre­
sionadosporlasmuchascaracterísticasdeseablesdel
C,comenzaronapromoverelusodellen­
guaje.AmediadosdelosochentalapopularidaddelCsehabíaextendidoportodaspartes.
Se
habíanescritonumerososcompiladoreseintérpretes deCparacomputadorasdetodoslostama­
ñosysehabíandesarrolladonumerosasaplicacionescomerciales.Esmás,muchasaplicaciones
quesehabíanescritooriginalmenteenotroslenguajessereescribieronenCparatomarpartido
desueficienciayportabilidad.
Lasprimerasimplementacionescomerciales
deCdiferíanenpartedeladefiniciónoriginal
deKernighanyRitchie,creandopequeñasincompatibilidadesentrelasdiferentesimplementa­
cionesdellenguaje.Estásdiferenciasreducíanlaportabilidadqueellenguajeintentabapropor­
cionar.Consecuentemente,elInstitutoNacionalAmericanodeEstándares
**(comitéANSI
X3Jll)desarrollóunadefiniciónestandarizadadellenguaje C.Lamayoríadeloscompiladores
eintérpretescomercialesdeCactualesadoptanelestándarANSI.Algunoscompiladorestam­
biénpuedenproporcionarcaracterísticasadicionalespropias.
Enladécadadelosochenta,BjarneStroustrup ***desarrollóenloslaboratoriosBellotro
lenguajedeprogramacióndealtoniveldenominado
C++.ÉstesebasaenC,yportantotodaslas
característicasestándar
deCestándisponiblesen C++.Sinembargo,C++noesunameraexten­
siónde
C.Incorporanuevosfundamentosqueconstituyenunabaseparalaprogramaciónorien­
tadaaobjetos
-unnuevoparadigmadelaprogramación deinterésparalosprogramadores
•BrianW.KernighanyDermis M.Ritchie,TheeProgrammingLanguage, Prentice-Hall,1978.
••EstándarANSIX3.159-1989.InstitutoNacionalAmericanodeEstándares,1430Broadway,NewYork,NY,
10018.(VertambiénBrian
W.KernighanyDennis M.Ritchie,TheeProgrammingLanguage,
2.'edición,Prentice­
Hall,1988.)
•••Stroustrup,Bjarne, TheeProgrammingLanguage, segundaedición,Addison-Wesley,1991.

CONCEPTOS BÁSICOS 11
profesionales-oEnestelibronosedescribeC++,perosíhayqueindicarqueunsólidoconoci­
mientodeCesunbuenpunto
departidaparaaprenderC++.
Estelibrodescribelascaracterísticas
deCincluidasenelestándarANSIysoportadasporlos
compiladoreseintérpretescomercialesde
C.Ellectorqueasimiletodoestematerialnotendrá
dificultad
enadaptarunprogramaenC aunaversiónparticulardellenguaj e.
Estructuradeunprogramaen e
TodoprogramaenCconsta deunoomásmódulosllamadosfunciones.Una delasfuncionesse
llama
main.Elprogramasiemprecomenzaráporlaejecucióndelafunción maín,lacualpue­
deaccederalasdemásfunciones.Lasdefinicionesdelasfuncionesadicionalessedebenrea­
lizaraparte,bienprecediendoosiguiendoa
maín(encontrarámásinformaciónsobreestoen
losCapítulos7 y8).
Cadafuncióndebecontener:
1.Unacabeceradelafunción,queconstadelnombre delafunción,seguidodeunalista
opcional
deargumentosencerradosentreparéntesis.
2.Unalistadedeclaracióndeargumentos,siseincluyenéstosenlacabecera.
3.Unainstruccióncompuesta,quecontieneelresto
delafunción.
Losargumentossonsímbolosquerepresentaninformaciónqueselepasaalafuncióndesde
otrapartedelprograma.(Tambiénsellamaparámetrosalosargumentos.)
Cadainstruccióncompuestaseencierraconunpardellaves,{
}.Lasllavespuedencontener
combinacionesdeinstruccioneselementales(denominadasinstrucciones
deexpresión)yotras
instruccionescompuestas.Asílasinstruccionescompuestaspuedenestaranidadas,unadentro
deotra.Cadainstrucción
deexpresióndebeacabarenpuntoycoma(;).
LoscomentariospuedenaparecerencualquierpartedelprograIl1a,mientrasesténsituados
entrelosdelimitadores
/*y*/(porejemplo:/*estoesuncomentario*1).Los
comentariossonútilesparaidentificarloselementosprincipales
deunprogramaoparaexplicar
lalógicasubyacente
deéstos.
Estoscomponentesdelprogramasediscutiránmástardeenestelibroconmuchomásdeta­
lle.Porahorasóloseexponeunavisióngeneral
delascaracterísticasbásicasquecaracterizanla
mayoríadelosprogramasen
C.
EJEMPLO1.6.Áreadeuncírculo. Heaquíunprogramaeneelementalqueleeelradíodeuncírculo,
calcula
suáreayescribeleresultadocalculado.
/*programaparacalcular
eláreadeuncírculo*/
#include<stdio.h>
maín()
{
floatradio
larea¡
printf("Radio
~?");
scanf("%f",&radío);
/*TITULO(COMENTARIO)*/
/*ACCESOAARCHIVODEBIBLIOTECA*/
/*CABECERADEFUNCION*/
/*DECLARACION DEVARIABLES*/
/*INSTRUCCION DESALIDA*/
/*INSTRUCCION DEENTRADA*/

14 PROGRAMACiÓN ENC
floatprocesar(floatr)
{
/*definicióndefunción*/
floata; /*declaracióndevariablelocal* /
a=PI*r*r;
return(a);
}
Estaversiónutilizaunafuncióndefinidaporelprogramador,lafunción procesar,queseocupade
efectuarrealmenteloscálculos.Dentro
deestafunción,resunargumento(o parámetro)querepresenta
elvalordelradioproporcionadodesde
main,yaeselresultadocalculadoquesedevuelvea main.
Apareceunareferenciaalafunciónen main,dentrodelainstrucción
area=procesar(radio);
Unadeclaracióndefunción precedealafunción main,queindicaque procesaraceptaunargu­
mentoencomaflotante
ydevuelvetambiénunvalorencomaflotante.Elusodefuncionessediscutirácon
detalleenelCapítulo
7.
Esteprogramatambiéncontieneuna constantesimbólica, PI,querepresentaelvalornumérico
3 .
14159.Éstaesunafonnaderepresentaciónqueexisteparaconvenienciadelprogramador.Cuandose
compilaelprograma,laconstantesimbólicasereemplazaautomáticamenteporsuvalornumérico.
Cuandoseejecutaesteprograma,
secomportadelamismafonnaqueelprogramadelEjemplo1.6.
EJEMPLO1.8.Áreadeuncírculoconcomprobacióndeerror.Consideremosahoraunavariación
delprogramadadoenelEjemplo1.7.
/*programaparacalculareláreadeuncírculo
concomprobacióndeerror*/
#include<stdio.h>
#definePI3.14159
<O)
O;
floatprocesar(floatradio)
main( )
{
floatradio,area¡
printf("Radio=?");
scanf(tl%fU,&radio);
if(radio
area=
else
area=procesar(radio)
printf(
II
Ar-ea=%f
ll
,area)¡
}
/*prototipodefunción*/
/*declaracióndevariables*/

floatprocesar(floatr)
(
CONCEPTOS BÁSICOS 15
/*definicióndefunción*/
floata', /*declaracióndevariablelocal*/
}
a=PI*r*r;
return(a);
EsteprogramacalculadenuevoeláreadeunCÍrculo.Incluyelafunción
procesarylaconstante
simbólica
PI,comosediscutióenelejemploanterior.Hemosañadidounasencillarutina decorrecCÍón
deerrores,quecompruebasielvalordelradio
esmenorquecero.(Matemáticamente,unvalornegativo
delradio
notienesentido.)Lacomprobación sellevaacabodentrode main,utilizandounainstrucción
if-else(versección6.6).Deestaforma,si radiotieneunvalornegativo,seleasignaa areael
valorcero;encualquierotrocaso,secalculaelvalorde
areaenprocesar,comovimosanteriormente.
EJEMPLO1.9.ÁreasdevariosCÍrculos. Ampliandolosanterioresprogramashemosredactadoéste,
en
elquesecalculanlasáreasdevarios CÍrculos.
/*programaparacalcularáreasdevarioscírculos
usandounbuclefor*/
#include<stdio.h>
#definePI3.14159
floatprocesar(floatradio);/*prototipodefunción*/
main( )
{
floatradio,area;
intcont,n;
/*declaracióndevariables*/
/*declaracióndevariables*/
printf
("N"
scanf(lI%d",
decírculos?
&n);
")
<O)
O;
}
for(cont=1;cont<=n;++cont){
printf("Círculon"%d:Radio= ?
scanf(lI%f
ll
,&radio);
if(radio
area=
else
area=procesar(radio);
printf("Area=%f",area);
}
cont);

16 PROGRAMACiÓN ENC
floatprocesar(floatr)
{
/*definicióndefunción*/
floata; /*declaracióndevariablelocal*/
a=PI*r*r;
return(a);
}
Enestecasoelnúmerototal decírculos,representadoporlavariableentera n,sedebeintroducirantesde
queserealicecualquiercálculo.Seutilizaentonceslainstrucción
forpara calculariterativamentelas
áreas
delosncírculos(versección6.4).
Observeelusodelavariable
cont,queseutilizacornouncontadordentrodelbucle for(dentrode
laporcióndelprogramaqueserepite).Elvalorde
contseincrementaráen 1encadapasadaporel bu­
cle.Nótesetambiénlaexpresión ++contqueapareceenlainstrucción foroÉstaesunanotaciónabre­
viadaparaincrementarelvalordelcontadoren
1;dehechoesequivalentea cont=cont+1(versec­
ción3.2).
Cuandoseejecutaelprograma,generaundiálogointeractivocornoelquesemuestraacontinuación.
Lasrespuestasdelusuarioestán,
denuevo,subrayadas.
NQdecírculos?
1
Círculon
Q
1:Radio ?1
Area=28.274309
Círculon
Q
2:Radio=?1.
Area=50.265442
Círculon
Q
3:Radio=?.5.
Area=78.539749
EJEMPLO1.10.Áreasde unnúmeroindeterminadodecírculos. Elprogramaanteriorsepuede
mejorardemaneraqueproceseunnúmeroindeterminadodecírculos,haciendoquecontinúenloscálculos
hastaqueseintroduzcaunvalorceroparaelradio.Estoevitalanecesidaddecontar,ademásdeespecifi­
carporadelantadoelnúmero
decírculos.Estoesespecialmenteútilcuandohayqueprocesarunagran
cantidaddedatos.
Ésteeselprogramacompleto.
/*programaparacalcularáreasdevarioscírculos,usando
unbuclefor;noseespecificaelnúmerodecírculos*/
#include<stdio.h>
#definePI3.14159

CONCEPTOS BÁSICOS 17
floatprocesar(floatradio);/*prototipodefunción*/
main( )
{
floatradio,area;
intcont;
/*declaracióndevariables*/
/*declaracióndevariables*/
}
printf("ParaPARAR,introducirOenelvalordelradio");
printf("Radio =?");
scanf(lI%f",&radio);
for(cont=1;radio!=O;++cont){
if(radio<O)
area=O;
else
area=procesar(radio);
printf("Area=%f",area)
printf("Radio=?");
scanf(n%f 11I&radio)i
}
floatprocesar(floatr)
{
floata;
a=PI*r*ri
return(a);
}
/*definicióndefunción*/
/*declaracióndevariablelocal*/
Nótesequeesteprogramapresentaráunmensajealcomienzo delaejecución,informando alusuario
decómofinalizarloscálculos.
Abajosemuestraeldiálogoresultantedeunaejecucióntípica
deesteprograma.Unavezmás,las
respuestasdelusuarioestánsubrayadas.
ParaPARAR,introducirOenelvalordelradio
Radio=?
.l
Area=28.274309
Radio=?1:
Area=50.265442
Radio=?.5-
Area=78.539749
Radio=?Q

18 PROGRAMACiÓN ENC
EJEMPLO1.11.Áreasdeunnúmeroindeterminadodecírculos. Heaquíunavaríantedelprograma
mostradoen
elejemploanterior.
/*programaparacalcularáreasdevarioscírculos,usando
unbuclewhile;noseespecificaelnúmerodecírculos*/
#include<stdio.h>
#definePI3.14159
floatprocesar(floatradio);
main( )
{
floatradio,area¡
/*prototipodefunción*/
/*declaracióndevariables*/
printf("ParaPARAR,introducirOenelvalordelradio");
printf(l1Radio =?")¡
scanf{ll%f
ll
,&radio)¡
while(radio!=O){
if(radio<O)
area Oi
else
area=procesar(radio);
printf("Area=%f",area);
printf("Radio =?");
scanf("%f",&radio)¡
}
}
floatprocesar(floatr)
{
floata;
a=PI*r*r;
return(a)
;
}
/*definicióndefunción*/
/*declaracióndevariablelocal*/
Esteprogramarealizalamismafunciónqueelmostradoenelejemploanterior.Sinembargo,hemosusado
ahoraunainstrucción
whileenvezde unaforparallevaracabo laejecuciónrepetidadelprograma
(versección6.2).Lainstrucción
whileseguiráejecutándosemientrasseleasignea radiounvalorque
noseacero.
Engeneral,lainstrucciónwhilecontinuaráejecutándosemientraslaexpresióncontenidaenlos
paréntesisseconsidere
verdadera.Deestaformasepuedeescribirmásbrevementelainstrucción whi1 e
como:

CONCEPTOS BÁSICOS 19
while(radio){
enlugarde
while(radio!=O){
porquecualquiervalor deradiononuloseinterpretarácornounacondición verdadera.
Algunosproblemas seadecúanmejoralautilización delainstrucciónfor,mientrasqueotros aluso
dewhile.Lainstrucciónwhileesalgomássencillaenestaaplicaciónenparticular.Hayunatercera
instrucciónparagenerarbucles,lainstrucción
do-while,queessimilarala whilemostradaanterior­
mente.(Mássobreesto
enelCapítulo6).
Cuandoseejecutaesteprograma,generaundiálogointeractivoidénticoalquesemostróenelEjem­
plo1.10.
EJEMPLO1.12.Cálculoyalmacenamientodel
áreadevarioscírculos.Algunosproblemasrequie­
renque
sealmaceneenlacomputadoraunaseriederesultadosyacalculados,quizáparaserutilizadosen
cálculosposteriores.Losdatosdeentradacorrespondientes
sepuedentambiénalmacenarinternamente
juntoconlosresultadoscalculados.Estosepuedellevaracabomedianteeluso
dearrays.
Elsiguienteprogramautilizadosarrays,llamados radioyarea,paraalmacenarelradioyelárea
dehasta
100círculos.Cadaarraysepuedevercomounalista denúmeros.Cadaunodelosnúmeros
individualesdentrodecadalista
esunelementodearray. Loselementos deunarrayestánnumerados,
empezandopor
O.Asíelradiodelprimercírculosealmacenarádentrodelelemento radio[O],elradio
delsegundocírculosealmacenaráen
radio[1],yasísucesivamente.Deigualforma,lasáreascorres­
pondientessealmacenaránen
area[O],area[1],etc.
Éstees
elprogramacompleto.
/*programaparacalcularáreasdevarioscírculos,usando
unbuclewhile;losresultadossealmacenanenunarray;
noseespecificaelnúmerodecírculos*/
#include<stdio.h>
#definePI3.14159
f10atprocesar(f10atradio);/ *prototipodefunción* /
main( )
{
intn,
f10at
i
;;;:O;
radio[100],
area[100];
/*declaracióndevariables*/
/*declaracióndearrays*/
printf("ParaPARAR,introducirOenelvalordelradio");
printf(IIRadio::::;?11);
scanf("%f",&radio[i])
while(radio[i]){
if(radio[i]
area[i]
<O)
=Oi

20 PROGRAMACiÓN ENC
else
area[i]=procesar(radio[i]) ;
printf(URadio:;::?11);
scanf('%f',&radio[++i])
}
n :;::--i¡ /*Elmayorvalordei*/
/*presentarloselementosdelarray*/
printf('Relaciónderesultados');
for(i=O;i<=n;++i)
printf('Radio=%f Area=%f',radio[i],area[i]);
}
floatprocesar(floatr)
(
floata;
a :;::PI*r*r;
return(a);
}
/*definicióndefunción*/
/*declaracióndevariablelocal*/
Comoenejemplosanteriores,seintroduciráunnúmeroindeterminadoderadios.Seintroducecadavalor
delradioysealmacenaelvalori-ésimode
radio[i].Secalculaentonceseláreacorrespondienteyse
almacenaen
area[i].Esteprocesocontinuaráhastaque seintroduzcantodoslosradiosyalfinalse
proporcioneelvalor
Oparaelradio. Sepresentafinalmenteelconjuntoenterodevaloresalmacenados
(elementosdelarraycuyosvaloresnosoncero).
Observemoslaaparicióndelaexpresión
++idosvecesenelprograma.Cadauna deestasexpresio­
neshaceque
seincrementeen1elvalorde i;dehechosonequivalentesa i =i +1.Análogamente,la
instrucción
n :;::--i¡
hacequeelvaloractual deiseadecrementadoen1 yseasignaentoncesesenuevovalora n.Enotras
palabras,lainstrucciónesequivalentea
i:;::i- 1;
n
:;::i¡
EnelCapítulo3(sección3.2)sediscutencondetalleexpresionescomo ++iy--i.
Cuandoseejecutaelprograma,segeneraundiálogointeractivocomoelquesemuestraacontinua­
Ción.Denuevolasrespuestasdelusuarioestánsubrayadas.
ParaPARAR,introducirOenelvalordelradio
Radio=?.l
Radio=?.1
Radio=?2
Radio=?
-º-

CONCEPTOS BÁSICOS 21
Relaciónderesultados
Radio
Radio
=
Radio=
3.000000
4.000000
5.000000
Area=28.274309
Area=50.265442
Area=78.539749
Estesencilloprogramanohaceuso delosvaloresquesehanalmacenadoenlosarrays.Suúnico
propósitoesmostrarlosmecanismosqueutilizanlosarrays,Enunejemplomáscomplicado,podríamos
quererdeterminarelvalormediodelasáreas,yentoncescompararcadaáreaindividualmenteconlame­
dia.Parahacerestotendríamosquerecurriracadaunodelosvaloresdelasáreas(loselementosdelarray
area[O],area[1],,."etc.).
Elusodearrays
sediscutebrevementeenelCapítulo2 yextensamenteenelcapítulo 9.
EJEMPLO1.13.Cálculo yalmacenamientodelasáreasdevarioscírculos. Éstaesunaaproxima­
ciónmásdetalladaalproblemadescrito enelejemploanterior.
/*programaparacalcularáreasdevarioscírculos,usando
unbuclewhile;
losresultadossealmacenanenunarray;
noseespecificaelnúmerodecírculos;
seintroduceunacadenadecaracteresparacadaconjunto
dedatos*/
#include<stdio.h>
#definePI3.14159
floatprocesar(floatradio);/*prototipodefunción*/
main( )
{
intn,i=O;
struct{
/*declaracióndevariables*/
}
char
float
float
circulo[10];
texto[20];
radio;
area¡
/*declaracióndevariabletipo
estructura*/
printf("ParaPARAR,introducirFINenelidentificador");
printf("Identificador:");
scanf(
11%'8nIcirculo[i].texto)i
while(circulo[i].texto[O]!='F'
11circulo[i].texto[1]! ='I'
11circulo[i].texto[2]!='N'){
printf("Radio=?");
scanf("%f",&circulo[i].radio);

22 PROGRAMACiÓN ENC
if(circulo[i].radio<O)
circulo[i].area=O;
else
circulo[i].area=procesar(circulo[il.radio);
++i¡
printf("Identificador:");
/*siguienteconjuntodedatos*/
scanf("%s",circulo[i].texto);
}
n--i;/*Elmayorvalordei*/
.texto,
.radio,
.area);
%f",circulo[i]
circulo[i]
circulo[i]
Area
::::
/*presentarloselementosdelarray*/
printf("Relación deresultados");
for(i=O;i<=n;++i)
printf("%sRadio=%f
}
floatprocesar(floatr) /*definicióndefunción*/
{
floata; /*declaracióndevariablelocal*/
a=PI*r*r¡
return(a);
}
Enesteprogramaseintroduceuntexto descriptor,seguidodelvalordelradio,paracadacírculo.Los
caracteresdeldescriptorsealmacenanenelarray
texto.Estoscaracteressonenconjuntouna constante
decadenadecaracteres
(versección2.4).Enesteprogramaeltamañomáximodecadaconstantede
cadenadecaractereses20.
Eldescriptor,elradioyeláreacorrespondientedecadacírculosedefinencomocomponentesde
una
estructura(verCapitulo11).Definimosentonces circulocomounarraydeestructuras.Esdecir,
cadaelementode
circuloseráunaestructuraquecontieneundescriptor,unradioyunárea.Por
ejemplo,
circulo[O].textohacereferenciaaldescriptordelprimercírculo, circulo[O].radio
hacereferenciaalradiodelprimercírculoy circulo[O].areahacereferenciaaláreadelprimer
círculo.(Hayquerecordarqueelsistemadenumeracióndeloselementosdelarraycomienzapor
O,no
porl.)
Cuandoseejecutaelprograma,seintroduceundescriptorparacadacírculo,seguidodelvalordel
radio.Estainformaciónsealmacenaen
circulo[i].textoycirculo[i].radio.Secalculael
áreacorrespondienteysealmacenaen
circulo[i].area.Esteprocesocontinúahastaqueseintrodu­
ceeldescriptor
FIN.Entoncessepresentatodalainformaciónalmacenadaenloselementosdelarray
(descriptor,radioyáreadecadacírculo)yterminalaejecución.
Cuandoseejecutaelprograma,segeneraundiálogointeractivocomoelquesemuestraacontinua­
ción.Nótesequelasrespuestasdelusuarioestánsubrayadasdenuevo.

CONCEPTOS BÁSICOS 23
ParaPARAR,introducirFINenelidentificador
Identificador:ROJO
Radio:2
Identificador:BLANCO
Radio:.4.
Identificador:AZUL
Radio:.2.
Identificador:FIN
Relaciónderesultados
ROJO
BLANCO
AZUL
Radio=3.000000
Radio=4.000000
Radio=5.000000
Area=28.2743O9
Area=50.265442
Area=78.539749
1.7.CARACTERÍSTICAS DESEABLESDEUNPROGRAMA
Antesdeconcluirestecapítuloexaminemosbrevementealgunascaracterísticasimportantes de
losprogramasbienescritos.Estascaracteristicassepuedenaplicaraprogramasnosóloescritos
en
e,sinoen cualquierlenguajedeprogramación.Puedenap"rtamosunaserie denormasgene­
ralesmuyútilesparacuandocomencemosaescribirpróximamente,enestelibro,nuestrospro­
piosprogramasen
C.
1.Integridad.Serefierealacorreccióndeloscálculos.Estáclaroquetodaposibleamplia­
cióndelprogramanotendrásentidosiloscálculosnoserealizan
deformacorrecta,pues
laintegridaddeloscálculosesabsolutamentenecesariaencualquierprograma
decom­
putadora.
2.Laclaridadhacereferenciaalafacilidad delecturadelprogramaenconjunto,conparti­
cularénfasis
enlalógicasubyacente. Siunprogramaestáescrito deformaclara,seráposi­
bleparaotroprogramadorseguirlalógicadelprogramasinmuchoesfuerzo.Tambiénhará
posiblealautororiginalseguirsupropio programadespués
dehaberlo
.dejadoduranteun
periodolargodetiempo.UnodeIpsobjetivosaldiseñar efueeldesarrollodeprogramas
clarosydefácillecturaatravésdeunenfoque
delaprogramaciónordenadoydiscipli­
nado.
3.Sencillez.Laclaridadycorrecccióndeunprogramasesuelenverfavorecidasconhacer
l<tscosasdeformatansencillacomoseaposible,consistenteconlosobjetivosdelpro­
gramaen suconjunto.Dehechopuedeserdeseablesacrificarciertacantidad
deeficien­
ciacomputacionalconvistasanocomplicarlaestructuradelprograma.
4.Laeficienciaestárelacionadaconlavelocidad deejecuciónylautilización·eficientede
lamemoria.Ésteesunodelos
objetivosimportantes,aunquenosedebeconseguira
expensasdelapérdidadelaclaridadolasencillez.Muchosprogramascomplicados

24 PROGRAMACiÓN ENC
conducenauncompromisoentreestascaracterísticas.Entalessituacionesesnecesario
recurriralaexperienciayalsentidocomún.
5.Modularidad.Muchosprogramassepuedendividirenpequeñassubtareas.Esunabue­
napráctica
deprogramaciónimplementarcadaunadeestassubtareascomounmódulo
separadodelprograma.EnCestosmódulossonlasfunciones.Eldiseñomodulardelos
programasaumentalacorrecciónyclaridad
deéstosyfacilitalosposiblescambiosfutu­
rosdelprograma.
6.Generalidad.Normalmentequeremosqueunprogramasealomásgeneralposible,den­
trodeunoslímitesrazonables.Porejemplo,podemoshacerunprogramaquelealos
valores
deciertosparámetrosenlugardedejarlosfijos.Comonormageneralsepuede
conseguirconmuypocoesfuerzoadicionalunnivelconsiderable
degeneralidad.
1.1.¿Quéesun«mainframe»?¿Dóndesepuedenencontrar?¿Paraquésesuelenutilizarnor­
malmente?
1.2.¿Quéesunacomputadorapersonal?¿Enquésediferencian delos«mainframes»?
1.3.¿Quéesunasupercomputadora?¿Yunaminicomputadora?¿Yunaestación detrabajo?
¿Enquésediferencianunasdeotras?¿Enquédifierendelos«mainframes»ydelas
computadoraspersonales?
1.4.Mencionarcuatrotiposdedatosdistintos.
1.5.¿Quéseentiendeporunprogramadecomputadora?¿Quéocurreengeneralcuandose
ejecutaunprograma?
1.6.¿Quéeslamemoriadeunacomputadora?¿Quéclasedeinformaciónsealmacenaenla
memoriadeunacomputadora?
1.7.¿Quéesunbit?¿Quéesunbyte?¿Cuál esladiferenciaentreunbyteyunapalabrade
memoria?
1.8.¿Quétérminosseutilizanparadescribirlamemoriadeunacomputadora?¿Cuálessonlos
tamañostípicosdelasmemorias?
1.9.Mencionaralgunosdispositivosauxiliaresdealmacenamiento.¿Enquésediferencianestos
dispositivosdealmacenamientodelamemoriaprincipal?
1.10.¿Quéunidaddetiemposeutilizaparaexpresarlavelocidadenlaqueserealizanlasta­
reaselementalesenunacomputadora?
1.11.¿Cuálesladiferenciaentreelprocesamiento porlotesyeltiempocompartido?¿Qué
ventajasydesventajaspresentacadauno?
1.12.¿Quésignificalacomputacióninteractiva?¿Paraquétipo desistemasseadecúanmejor
estossistemas?
1.13.¿Quéesellenguajemáquina?¿Enquésediferencianellenguajemáquinayloslenguajes
dealtonivel?
1.14.Mencionaralgunoslenguajesdealtonivel deusofrecuente.¿Cuálessonlasventajasde
utilizarlenguajesdealtonivel?
1.15.¿Quéseentiendeporcompilación?¿Quésignificainterpretación?¿Enquésediferencian
estosdosprocesos?

CONCEPTOS BÁSICOS 25
1.16.¿Quéesunprogramafuente?¿Yunprogramaobjeto?¿Porquésonimportantesestos
conceptos?
1.17.¿Cuálessonlascaracteristicasgenerales deC?
1.18.¿Dóndeyporquiénfuedesarrollado C?¿Porquésehaestandarizadoestelenguaje?
1.19.¿QuéesC++?¿QuérelaciónhayentreC yC++?
1.20.¿CuálessonloscomponentesprincipalesdeunprogramaenC?¿Quésignificadolleva
asociadoelnombre
main?
1.21.DescribirlacomposicióndeunafunciónenC.
1.22.¿Quésonlosargumentos?¿DóndeaparecenlosargumentosenunprogramaenC?¿Qué
otrotérminoseutilizaavecesenlugar
deargumento?
1.23.¿Quéesunainstruccióncompuesta?¿Cómoseescribenlasinstruccionescompuestas?
1.24.¿Quéesunainstruccióndeexpresión?¿Sepuedeincluirunainstruccióndeexpresiónen
unainstruccióncompuesta?¿Sepuedeincluirunainstruccióncompuestaenunainstruc­
ción
deexpresión?
1.25.¿CómosepuedenincluirloscomentariosenunprogramaenC?¿Dóndesepuedenponer
loscomentarios?
1.26.¿EsnecesarioescribirlosprogramasenCenminúsculas?¿Sepuedenutilizarparaalgo
lasmayúsculasenunprogramaen
C?Explicarlo.
1.27.¿Quéesunainstruccióndeasignación?¿Cuáleslarelaciónentreunainstrucción deasig­
naciónyunainstruccióndeexpresión?
1.28.¿Quésignodepuntuaciónseponealfinaldelamayoríadelasinstruccionesen C?¿Ter­
minantodaslasinstruccionesdeestaforma?
1.29.¿Porquésesangranalgunas delasinstruccionesdeunprogramaenC?¿Porqué seinclu­
yennormalmentelíneasenblancoenunprogramaenC?
1.30.Comentarbrevementeelsignificadodecadaunadelassiguientescaracterísticasdelos
programas:integridad,claridad,sencillez,eficiencia,modularidadygeneralidad.¿Porqué
esimportantecadaunadeestascaracterísticas?
1.31.Determinar,lomejorquesepueda,elpropósitodecadaunodelossiguientesprogramas enC.
Identificartodaslasvariablesdecadaprograma.Identificartodas lasinstruccionesdeentraday
salida,todaslasinstruccionesdeasignaciónycualquierotracaracteristicaimportante quesereco­
nozca.
a)main()
{
printf("¡Bienvenidoa·laInformática!In");
}

26 PROGRAMACiÓN ENe
b)#defineMENSAJE"iBienvenidoalainformática!"
main()
{
printf(MENSAJE);
}
e)main()
{
floatbase,altura,areai
printf(IIBase:")¡
scanf("%f",&base);
printf("Altura:");
scanf("%f",&altura);
area=(base*altura)/2.;
printf("Area:%f",area);
}
d)main()
{
floatbruto,impuesto,neto;
printf("Salariobruto:");
scanf(Il%fllI&bruto);
impuesto=0.14*bruto;
neto=bruto-impuesto;
printf("Impuestos:%.2f",impuesto};
printf("Salarioneto:%.2f",neto);
}
e)intmenor(inta,intb);
main()
{
intalb,mini
printf(nIntroduzcaelprimernúmero: 11),;
scanf(n%d",&a)i

CONCEPTOS BÁSICOS 27
printf(IlIntroduzcaelsegundonúmero:")i
scanf("%dll/&b);
min=menor(a,b);
printf("Elnúmeromenores:%d",min);
}
intmenor(inta,intb)
{
if(a<=b)
return(a);
else
return(b);
}
flintmenor(inta,intb);
main( )
{
intcont,n,alb,mini
printf("¿Cuantosparesdenúmeros?");
scanf("%d",&n);
for(cont=1;cont<=n;++cont){
printf("Introduzcaelprimernúmero:");
scanf(11%d 11I&a);
printf("Introduzcaelsegundonúmero:");
scanf("%d",&b);
min=menor(a,b)¡
printf("Elnúmeromenores:%d",min);
}
}
intmenor(inta,intb)
{
if(a<=b)
return(a)
;
else
return(b);
}

28 PROGRAMACiÓN ENC
g)intmenor(inta,intb);
main()
{
inta,b,mini
printf("ParaPARAR,introducirOencadanúmero");
printf(11Introduzcaelprimernúmero:")i
scanf(Il%dllI&a)i
printf("Introduzcaelsegundonúmero:");
scanf("%d",&b);
while(a!=O11b!=O){
min=menor(a,b);
printf("Elnúmeromenores%d",min);
printf("Introduzcaelprimernúmero:");
scanf("%dll,&a);
printf("Introduzcaelsegundonúmero:");
scanf("%d",&b);
}
}
intmenor(inta,intb)
{
if(a<=b)
return(a);
else
return(b);
}
h)intmenor(inta,intb);
main()
{
intn,i ;;;::O;
inta[100],b[100],min[100];
printf(,¡ParaPARAR,introducirOencadanúmero");
printf("Introduzcaelprimernúmero:");
scanf("%d",&a[i]) ;

CONCEPTOS BÁSICOS 29
printf("Introduzcaelsegundonúmero:");
scanf("%d",&b[i]);
while(a[i]1Ib[i]){
min[i]menor(a[i],b[i]) ;
}
printf("Introduzcaelprimernúmero:");
scanf(lI%d
ll
,&a[++i])¡
printf(nIntroduzcaelsegundonúmero: 11)i
scanf("%d",&b[i]);
n=i·,
printf("Relaciónderesultados");
for(i=O;i <=n;++i)
printf("a=%d b=%dmin=%d",a[i],b[i],min[i]);
}
intmenor(inta,intb)
{
if(a<=b)
return(a);
else
return(b);
}

CAPíTULO2
ConceptosbásicosdeC
,
Enestecapítulopresentaremosloselementosbásicosparalaconstruccióndeinstruccionessim­
plesde
C;entreéstosseencuentraelconjuntodecaracteres,losidentificadoresypalabrasreser­
vadasde
C,lostiposdedatos,lasconstantes,variablesyarrays,lasdeclaraciones,expresiones
einstrucciones.Veremoscómocombinarestoselementosparaformarcomponentesmásgran­
desdeprogramas.
Partedeestematerialsepresentadeformadetalladaypuederesultardificildeasimilar,
sobretodopara programadoresconpocaexperiencia.Hayqueseñalarqueelpropósito
deeste
capítuloespresentarciertosconceptosbásicosyalgunasdefinicionesnecesariasparalostemas
quesetratanenlossiguientescapítulos.Portanto,cuandoleaestecapítuloporprimeravez
puedesersuficienteadquirirunaciertafamiliaridadconlosconceptosque
sepresentan.Secon­
seguiráunacomprensiónmásprofundadeestoselementostraslasrepetidasreferenciasaeste
capítuloque
seencuentranenlossiguientes.
2.1.ELCONJUNTODE CARACTERES DE C
Paraformarloselementosbásicosdelprograma(constantes,variables,operadores,expresiones,
etc.),Cutilizacomobloquesdeconstrucciónlasletrasmayúsculasdela
Aalaz,
lasminúsculis
delaa ala z,losdígitosdelOal9 yciertoscaracteresespeciales.Sepresentaacontinuación
unalistadeestoscaracteresespeciales:
+
<
?
>
* /
"
= % & #
\ I
] { }
(espacioenblanco)
Lamayoríadelasversionesdellenguajetambiénpermitenqueotroscaracteres,como@y $,
seincluyanencadenasdecaracteresycomentarios.
Cutilizaciertascombinacionesdeestoscaracteres,como
,y
\t,parirepresen­
tarelementosespecialescomoelretroceso deunespacio,nuevalíneayuntabulador,respec­
tivamente.Estascombinacionesdecaracteresseconocencomo
secuenciasdeescape. Trata­
remoslassecuenciasdeescape
enlasección2.4.Porahoranoslimitaremosaidecirquecada
secuenciadeescaperepresentaunsolocarácter,auncuando seescribacondosomáscarac­
teres.
31

32 PROGRAMACiÓN ENC
2.2.IDENTIFICADORES YPALABRASRESERVADAS
Losidentificadoressonnombresqueselesdaavarioselementosdeunprograma,comovaria­
bles,funcionesyformaciones.Unidentificadorestáformado
porletrasydígitos,encualquier
orden,excepto
elprimercarácter,que debeserunaletra. Sepuedenutilizarmayúsculasymi­
núsculas,aunqueescostumbreutilizarminúsculasparalamayoríadelosidentificadores.Nose
puedenintercambiarmayúsculasyminúsculas(estoes,unaletramayúsculanoesequivalentea
lacorrespondienteminúscula.)Elcarácterdesubrayado
L)sepuedeincluirtambién,yescon­
sideradocomounaletra.Sesueleutilizarestecarácterenmediodelosidentificadores.Uniden­
tificadortambiénpuedecomenzarconuncarácterdesubrayado,aunque
enlaprácticanose
suelehacer.
EJEMPLO2.1. Lossiguientesnombres sonidentificadoresválidos.
x
nombres
y12
area
_temperatura
TABLA
Lossiguientesnombres nosonidentificadoresválidosporlasrazonesseñaladas.
4num
"XII
orden-no
indicadorerror
elprimercarácter debeserunaletra
caracteresilegales
(n)
carácterilegal (-)
carácterilegal(espacio enblanco)
N
Ohaylímitepara lalongituddelosidentificadores.AlgunasimplementacionesdeCreco­
nocensólolosochoprimeroscaracteres,aunquelamayoríadeellasreconocenmás(típicamen­
te,
31caracteres).Elrestodeloscaracteressonutilizadospara lacomodidaddelprogramador.
EJEMPLO2.2. Losidentificadores
suma~de_valores ysuma_de_variacionessonváli­
dosgramaticalmente.Sinembargo,algunoscompiladores deepuedennosercapacesdedistinguirlos,
ya
queambostienenlasmismasochoprimerasletras. Deestaforma,enunmismo
progratllasólosepodrá
utilizar
unodeestosidentificadores.
Comonormageneral,unidentificadordebetenerlossuficientescaracteresparaquesusigni­
ficadosereconozcafácilmente;
porotraparte,sedebeevitar unexcesivonúmerodecaracteres.
EJEMPLO2.3. Seestáescribiendounprogramaeneparacalcularelvalorfuturo deunainversión.
Losidentificadoresvalor
yvalor---,futurosonnombres.simbólicosapropiados. Sinembargo,v y
fvseríandemasiadocortos,ya quenoquedaclaroel.significado deestosidentificadores.Porotraparte,
unidentificador
comovalor_futuro_de_una_inversionnoseráadecuadoporserdemasiado
largoe
incóiUodo.
.
Hayciertaspalabras reservadasquetienenenCunsignificadopredefinidoestándar.Las
palabrasreservadassólosepuedenutilizarpara
supropósitoyaestablecido;nosepuedenutili­
zarcomoidentificadoresdefinidos
porelprogramador.

CONCEPTOS BÁSICOS DEC33
Laspalabrasreservadasson:
auto
break
case
char
const
continue
default
do
double
else
enuro
extern
float
for
goto
if
int
long
register
return
short
signed
sizeof
static
struct
switch
typedef
union
unsigned
void
volatile
while
Existencompiladoresqueincluyentodasoalgunasdelassiguientespalabrasreservadas:
ada
asro
entry
far
fortran
huge
near
pascal
AlgunoscompiladoresdeCpuedenreconocerotraspalabrasreservadas.Paraobteneruna
listacompletadelasmismasparauncompiladordeterminadosedebeconsultarsumanual
de
referencia.
Observequetodaslaspalabrasreservadasestánenminúsculas.Comoloscaracteresenmi­
núsculasymayúsculasnosonequivalentes,sepuedeutilizarunapalabrareservadaescritaen
mayúsculascomounidentificador.Estonosesuelehacernormalmente,yseconsiderapropio
deunestilodeprogramaciónpobre.
2.3.TIPOSDE DATOS
Cofrecedistintostiposdedatos,cadaunodeloscualessepuedeencontrarrepresentadode
formadiferenteenlamemoria
delacomputadora.Acontinuaciónsepresentaunalistadelos
tiposdedatosbásicos.Tambiénsedanlosrequerimientos
dememoriatípicos.(Elrequerimiento
dememoriaparacadatipo dedatosnuméricosdeterminaráelrangopermisibledevalorespara
esetipodedatos.Hayqueseñalarquelasnecesidades
dememoriaparacadatipodedatospue­
denvariardeuncompiladordeC aotro.)
Tipodedatos Descripción
int Cantidadentera
char Carácter
float Númeroen
comaflotante
(unnúmeroqueincluyepunto
decimaly/oexponente)
Requisitotípicodememoria
2bytesounapalabra
(varía
deuncompiladoraotro)
1byte
1palabra(4bytes)

34 PROGRAMACiÓN ENC
Tipodedatos Descripción Requisitotípicodememoria
doubleNúmeroencomaflotante dedoble 2palabras (8bytes)
precisión(máscifrassignificativas
ymayorvalorposibledelexponente)
Loscompiladores
deCdiseñadosparacomputadoraspersonalesominicomputadoras(com­
putadorasconlongitud
depalabramenorque32bits)representan generalmenteunapalabracon
4bytes(32bits).
Algunostiposbásicos
dedatossepuedenampliarutilizandolos cualificadoresdetiposde
datos
short(corto),long(largo),signed(consigno)y unsigned(sinsigno).Porejem­
plo,sepuedendefinircantidadesenterascomo
shortint,longintounsignedint
(estostiposdedatossesuelenescribirsimplemente short,longounsigned,ysesupone
quesonenteros).Lainterpretacióndeuntipodedatosenteroconuncualificadordelantepuede
variardeuncompiladordeC aotro,aunqueexisteunarelacióndesentidocomún.Deestaforma
un
shortintrequerirámenosmemoriaolamismaqueun intordinario,peronuncamás.De
igualforma,un
longintpuederequerirlamismacantidad dememoriaomásqueun int
ordinario,peronuncaunacantidaddememoriamenor.
Si
shortinteintrequierenlamismamemoria(porejemplo2bytes),entonces long
int,generalmente,ocuparáeldoble(porejemplo4bytes).Osi intylongintocupanla
mismamemoria(porejemplo4bytes),entonces
shortintocuparálamitad dememoria(por
ejemplo2bytes).Recuerdequeestasespecificacionespuedenvariar
deuncompiladordeC a
otro.
Un
unsignedintocupalamismamemoriaqueun intordinario.Sinembargo,enel
casodeun
intordinario(oun shortintounlongint),elbitdelextremoizquierdose
reservaparaelsigno.Enun
unsignedint,todoslosbitsseutilizanpararepresentarelvalor
numérico.Deestaforma,un
unsignedintpuedellegaraalmacenarunvalornumérico
aproximadamenteeldoblequeun
intordinario(aunque,porsupuesto,nopuedealmacenar
valoresnegativos).Porejemplo,siun
intordinariopuedevariarde -32768a+32767(esto
espropiodeun
intde2bytes),entoncesun unsignedintpodrátomarvalorescomprendi­
dosentre
Oy65535.Elcualificadorunsignedsepuedeaplicartambiéna otrosintsya
cualificados,porejemplo
unsignedshortintounsignedlongint.
Eltipocharseutilizapararepresentarcaracteresindividuales.Portanto,eltipo char
requerirásólounbyte dememoria.Cadatipo chartieneunarepresentacióncomoenteroequi­
valente,deestaformaun charesrealmenteunaclase
espeCialdeenterocorto(versección
2.4).Enlamayoría
deloscompiladores,undatotipo charpodrátomarvaloresde Oa255.
Algunoscompiladoresrepresentaneltipo dedatoscharconunrangodevaloresde -128a
+127.Tambiénsepuedenutilizardatos unsignedchar(convaloresde Oa255),odatos
signedchar(convaloresde-128a+127).
Algunoscompiladorespermitenlaaplicacióndelcualificador longaf10atodouble,
porejemplolongfloatolongdoub1e.Detodosmodos,el significado deestostipos
dedatosvaríadeuncompilador
deC aotro.Así longfloatpuedeserequivalentea
doub1e.Además,
longcjoublepuedeserequivalente adouble,opuedehacerreferencia
auntipodedatosdedobleprecisión«extralargo»,querequieramásdedospalabras
deme­
mona.

CONCEPTOS BÁSICOSDEC 35
Posteriormenteseintroduciránenestelibrodostiposdedatosadicionales, voidyenum
(voidestratadoenlasección 7.2;enumsediscuteenlasección14.1).
CadaidentificadorquerepresentaunnúmeroouncarácterdentrodeunprogramaenCdebe
estarasociadoaunodelostiposdedatosbásicosantesdequeelidentificadoraparezcaenuna
instrucciónejecutable.Estosellevaacabomediante
unadeclaracióndetipo,comosedescribe
en
lasección2.6.
2.4.CONSTANTES
Ctienecuatrotiposbásicosdeconstantes: constantesenteras,constantes encomaflotante,cons­
tantes
decarácteryconstantesdecadenadecaracteres (haytambién constantesenumeradas,
quesetratanen lasección14.1).Esmás,haydistintasciasesdeconstantesenterasyencoma
flotante,comosediscuteacontinuación.
Lasconstantesenterasyencomaflotanterepresentannúmeros.Selasdenomina,engeneral,
constantesde
tiponumérico.Lassiguientesreglassepuedenaplicaratodaslasconstantesnu­
méricas.
l.Nosepuedenincluircomasniespaciosenblancoenlaconstante.
2.Sisedesea,laconstantepuedeirprecedidadeunsignomenos
(-).(Realmente,elsigno
menoses
unoperadorquecambiaelsignodeunaconstantepositiva,aunquesepuede
vercomopartedelaconstantemisma.)
3.Elvalordeunaconstantenopuedeexcederunlímitemáximoyunmínimoespecifica­
dos.Paracadatipodeconstante,estoslímitesvaríandeuncompiladordeC aotro.
Veamoscadatipodeconstanteindividualmente.
Constantesenteras
Unaconstanteentera esunnúmeroconunvalorentero,consistenteenunasecuenciadedígitos.
Lasconstantesenterassepuedenescribirentressistemasnuméricosdiferentes:decimal(base
10),octal(base8)yhexadecimal(base16).Normalmente,losprogramadoresqueseestánini­
ciandonoutilizaránmásquelasconstantesenterasdecimales.
Unaconstanteentera
decimalpuedesercualquiercombinacióndedígitostomadosdelcon­
juntodeOa9.Silaconstantetienedosomásdígitos,elprimerodeellosdebeserdistintode
O.
EJEMPLO2.4. Acontinuaciónsemuestranvariasconstantesenterasdecimales.
o 1743 5280 32767 9999
Lassiguientesconstantesenterasdecimalesestánescritasincorrectamenteporlasrazones quese
indican.
12,245
36.0
102030
123-45-6789
0900
carácterilegal
(.).
carácterilegal (.).
carácterilegal(espacio enblanco);·
carácterilegal(~).
elprimerdígito nopuedesercero.

36 PROGRAMACiÓN ENC
Unaconstanteenteraoctalpuedeestarformadaporcualquiercombinacióndedígitostoma­
dosdelconjuntoO a7.Elprimerdígitodebeserobligatoriamente
O,conelfindeidentificarla
constantecomounnúmerooctal.
EJEMPLO2.5. Acontinuaciónsemuestranvariasconstantesenterasoctales.
o 01 0743 077777
Lassiguientesconstantesenterasoctalesestánescritas deformaincorrectaporlasrazones quese
señalan.
743
05280
0777.777
nocomienzaporO
dígitoilegal(8)
carácterilegal
(.)
Unaconstanteenterahexadecimaldebecomenzarpor OxoOX.Puedeaparecerdespuéscual­
quiercombinacióndedígitostomadosdelconjuntodeOa 9 ydea a
f(tantominúsculascomo
mayúsculas).Lasletrasdelaa a
laf(odelaA alaF)representanlascantidades(decimales)
lOa15,respectivamente.
EJEMPLO2.6. Acontinuaciónsemuestranvariasconstantesenterashexadecimales.
Ox OX1 OX7FFF Oxabcd
Lassiguientesconstantesenterashexadecimalesestánescritas deformaincorrectapor lasrazonesque
seseñalan.
OX12.34
OBE38
OX.4bff
OXDEFG
carácterilegal (.)
nocomienzapor OxoOX.
carácterilegal (.).
carácterilegal (G).
Elvalordeunaconstanteenterase hadeencontrarentreceroyalgúnvalormáximoque
varíadeunacomputadoraaotra(yde
uncompiladoraotroenunamismacomputadora).Un
valormáximotípicoenlamayoríadelascomputadoraspersonalesymuchasminicomputadoras
es
32767endecimal(equivalentea 77777enoctalo a 7 f f fenhexadecimal),oloquees
igual,2
15
-1.Lasgrandescomputadoras(<<mainframes»)suelenpermitirvaloresmásgran­
des,talescomo2
147483647(estoes,2
31
-1)*.Ellectordebedeterminarelvalordela
versióndeCqueutiliceensucomputadora.
Constantesenteraslargas ysinsigno
Lasconstantesenteras sinsignopuedentener unvalormáximodeaproximadamenteeldobledel
máximodelasconstantesenterasordinarias,perosuvalornopuedesernegativo
*.Unacons-
*Supóngasequeuna computadorautiliza unapalabradenbits.Entonces, unacantidadenteraordinariaseen­
contraráen elrango_2
n
-1
a+2
n
-1
_
1,yunacantidadentera sinsignovariaráentreO y2
n
_
LParaunenterocortohabrá
quesustituirnporn/2,yparaunolargo,n por
2n.Estasreglaspuedenvariardeunacomputadoraaotra.

CONCEPTOS BÁSICOS DEC37
tanteenterasinsignoseidentificaañadiéndolelaletra U,mayúsculaominúscula (Udelinglés
unsigned),alfinaldelaconstante.
Lasconstantesenteras
largaspuedentomarvaloresmáximosmayoresquelasconstan­
tesenterasordinarias,pero ocupanmásmemoriadelacomputadora.Enalgunascomputadoras
(y/oalgunoscompiladores)segeneraráunaconstanteenteralargacuandosimplementesees­
pecifiqueunacantidadqueexcedaelvalormáximo.Encualquiercaso,
siempreesposible espe­
cificarunaconstanteenteralargaañadiendolaletraL(mayúsculaominúscula)alfinal
de
ésta.
Unaconstanteenteralargasinsignosepuedeespecificarañadiendolasletras
ULalfinalde
laconstante.Lasletraspuedenestarenmayúsculasominúscula.Sinembargo,la
Udebeirde­
lantedela
L.
EJEMPLO2.7. Acontinuaciónsemuestranvariasconstantesenteraslargasysinsigno.
Constante
50000U
123456789L
123456789UL
0123456L
0777777U
OX50000U
OXFFFFFUL
Sistemadenumeración
decimal(sinsigno)
decimal(larga)
decimal(largasinsigno)
octal(larga)
octal
(sinsigno)
hexadecimal(sinsigno)
hexadecimal(larga sinsigno)
Losvaloresmáximospermitidosdelasconstantesenteras largasysinsignovarían deuna
computadora(y
deuncompilador)aotra.Enalgunascomputadoras,elvalormáximopermitido
deunaconstanteenteralargapuedeserelmismoqueeldeunaconstanteenteraordinaria;otras
computadoraspermitenqueelvalordeunaconstanteenteralargaseamuchomayorqueel
de
unaordinaria.Serecomiendadenuevoallectorquedetermineestosvaloresen suversiónparti­
cular
deC.
Constantesencomaflotante
Unaconstanteencomaflotante esunnúmeroenbase 10quecontieneunpuntodecimaloun
exponente(oambos).
EJEMPLO2.8. Acontinuaéiónsemuestranvariasconstantesencomaflotante.
O.
50000.
2E-8
l.
0.000743
0.006e-3
0.2
12.3
1.6667E+8
827.602
315.0066
.12121212e12

38 PROGRAMACiÓN ENC
Lassiguientesnosonconstantesencomaflotanteporlasrazonesindicadas.
1
1,000.0
2E+10.2
3E10
Debenencontrarsepresentes unpuntodecimalounexponente.
Carácterilegal(,).
Elexponentedebeserunacantidadentera (nopuedecontenerunpunto
decimal).
Carácterilegal(espacioenblanco)enelexponente.
Sie~dsteunexponente,suefectoesel dedesplazarlaposicióndelpuntodecimalaladere­
cha
sielexponenteespositivo,o alaizquierdasi esnegativo.Sinoincluyepuntodecimalenel
número,sesuponequeseencuentraaladerechadelúltimodígito.
Lainterpretacióndeunaconstanteencomaflotanteconexponente
esjustamentelamisma
queennotacióncientífica,exceptoquesesustituyelabase
10porlaletra E(oe).Deesta
forma,elnúmero1.2x10-
3
sedeberíaescribircomo 1.2E-301.2e-3.Estoesequivalentea
O
.12e-2o12e-4,etc.
EJEMPLO2.9. Lacantidad3 xlO'sepuederepresentarenCporcualquieradelassiguientesconstan­
tesencomaflotante:
300000.
.3e6
3eS
0.3E6
3e+S
30E4
3ES
30.E+4
3.0e+S
300e3
Deigualforma,lacantidad5.026x10-
17
sepuederepresentarconcualquieradelassiguientescons­
tantesencomaflotante:
S.026E-17 0.S026e-16 SO.26e-18 0.000S026E-13
Losvaloresquepuedentenerlasconstantesencomaflotanteseencuentrandentrodeun
rangomuchomayorqueel
delasconstantesenteras.Típicamente,lamagnituddeunaconstante
encomaflotantepuedevariarentreunvalormínimodeaproximadamente3 .
4E-38Yunmáxi­
mode
3 .4E+38.Algunasversionesdellenguajepermitenconstantesencomaflotanteque
cubrenunrangomuchomayor,comode
1 .7E- 3O8al.7E+3O8.Tambiénesunaconstante
encomaflotanteválidaelvalorO. O(queesmenoraúnque
3 . 4 E- 38 o1 .7E- 3O8).Ellector
debeocuparsedeaveriguarestosvaloresparasucomputadoraysuversiónparticular
deC.
LasconstantesencomaflotanteserepresentanenCnormalmentecomocantidadesdedoble
precisión.Portanto,cadaconstanteencomaflotanteocupará,típicamente,dospalabras
(8bytes)
dememoria.Algunasversiones deCpermitenlaespecificación deconstantesencomaflotante
de«simpleprecisión»,añadiendolaletraF(mayúsculaominúscula)alfinal delaconstante(por
ejemplo
3ESF).Deformaanáloga,algunasversionesdeCpermitenlaespecificacióndeuna
constanteencomaflotante«larga»añadiendolaletra1(mayúsculaominúscula)alfinaldela
constante(porejemploO
.1234S6789E-33L).
Laprecisióndelasconstantesencomaflotante(elnúmerodecifrassignificativas)puede
variardeunaversión
deC aotra.Dehecho,todaslasversionesdellenguajepermitenalmenos
seiscifrassignificativas,yalgunasversionesproporcionandieciochocifrassignificativas.De
nuevoellectordebeocuparse
dedeterminaresevalorparasuversión deC.

CONCEPTOS BÁSICOS DEC39
Precisiónnumérica
Debequedarclaroquelasconstantesenterassoncantidadesexactas,mientrasquelasconstantes
encomaflotantesonaproximaciones.Lasrazonesdeestoseencuentranfueradelámbito
deesta
discusión.
Encualquiercaso,ellectordebetenerpreseuteque laconstanteencomaflotante
1 .
Opuedeserrepresentadaen lamemoriadelacomputadoracomo O.9 9 99 9 999...,aun
cuandoaparezcacomo
1.Ocuandosepresenteporpantalla(debidoalredondeoautomático).
Porestarazónnosepuedenutilizarlosvaloresencomaflotanteparaciertasfunciones,tales
comoconteo,indexación,etc.,enlasquesonnecesariosvaloresexactos.Discutiremosestas
restriccionessegúnvayanapareciendoenpróximoscapítulosdeestelibro.
Constantesdecarácter
Unaconstantedecarácter esunsolocarácter,encerradoconcomillassimples.
EJEMPLO2.10. Acontinuaciónsemuestranvariasconstantes decarácter.
'A' 'X' '3' '?f
Observequelaúltimaconstanteconsisteenunespacioenblancoencerradoconcomillassimples.
Lasconstantesdecaráctertienenvaloresenterosdeterminadosporelconjuntodecaracteres
particulardelacomputadora.Portanto,elvalordeunaconstantedecarácterpuedevariarde
unacomputadoraaotra.Sinembargo,lasconstantesensísonindependientesdelconjuntode
caracteres.Estehechoeliminaladependenciade
unprogramaenCde unconjuntodecaracteres
enparticular(mássobreestomásadelante).
Lamayoríadelascomputadoras,yprácticamentetodaslascomputadoraspersonales,utili­
zanelconjuntodecaracteres
Ascn(CódigoEstándarAmericanoparaelIntercambiodeInfor­
mación),enelcualcadacarácterindividualsecodificanuméricamenteconsupropiacombina­
ciónúnicade7bits(existen,pues,untotalde
2'=128caracteresdiferentes).LaTabla2.1
contieneelconjuntodecaracteres
ASCn,dondeaparecetambiénelequivalenteendecimalde
los7bitsquerepresentanacadacarácter.Obervequeademásdecodificados,loscaracteres
estánordenados.
Enparticular,losdígitosestánordenadosconsecutivamenteensupropiase­
cuencianumérica
(Oa9),ylasletrasestándispuestasenordenalfabético,precediendolasma­
yúsculasalasminúsculas.Estopermitequelasunidadesdedatosdetipocaráctersepuedan
compararentresí,basándoseensuordenrelativodentrodelconjuntodecaracteres.
EJEMPLO2.11. Acontinuaciónsemuestranvariasconstantesdecarácter ysuscorrespondientesvalo­
resenelconjuntodecaracteresASCII.
Constante Valor
lA' 65
'x' 120
',3' 51
'?f 63
32

40 PROGRAMACiÓN ENC
Tabla2.1.Elconjuntodecaracteres ASCII
o NUL 32 espacioen 64 @ 96
blanco
1
SOH 33 65 A 97 a
2 STX 34
" 66 B 98 b
3 ETX 35
# 67 C 99 c
4 EOT 36
$ 68 D 100 d
5 ENQ 37 % 69 E
101 e
6
ACK 38 & 70 F 102 f
7 BEL 39 71 O 103 g
8 BS 40
( 72 H 104 h
9 HT 41
) 73 I 105
10 LF 42
*
74 J 106 J
11 VT 43 + 75 K 107 k
12 FF 44 76 1. 108 1
13
CR 45 77 M 109 m
14 SO 46
78 N 110 n
15 SI 47 / 79 O 111 o
16 DLE 48
O 80 P 112 P
17 DC1 49 1 81 Q 113 q
18 DC2 50 2 82 R 114 r
19 DC3 51 3 83 S 115 s
20 DC4
52 4 84 T 116 t
21
NAK 53 5 85 U 117 u
22
SYN 54 6 86 V 118 v
23 ETB 55 7 87
W 119 w
24 CAN 56 8 88 X 120 x
25 EM 57 9 89 Y 121 Y
26 SUB 58 90 Z 122 z
27 ESC 59 91 [ 123 {
28 FS 60
< 92 \ 124 I
29 OS 61 93 ] 125 }
30. RS 62 > 94
A
126
31 US 63 ? 95 127 DEL
Losprimeros32caracteres yelúltimosoncaracteresdecontrol.Normalmente nosepuedenpresen-
tar.Sinembargo,algunasversionesdeC(enalgunascomputadoras)soportancaracteresgráficos
especialesparadichosvaloresASCII.
Porejemplo,001puederepresentarelcarácter
Q.,002puede
representar11.,yasísucesivamente.

CONCEPTOS BÁSICOSDEC 41
Estosvaloresseránlos mismosparatodas lascomputadorasqueutilicenelconjuntodecaracteres
ASCn.
Sinembargo,serándiferentesparacomputadoras queutilicenunconjuntodecaracteresalter­
nativo.
Los«mainframe»deIBMutilizanelconjuntodecaracteresEBCDIC(CódigodeInformaciónDeci­
malCodificadaenBinarioExtendido), enelcualcadacarácterindividual secodificanuméricamente con
unacombinaciónúnica de8bits.ElconjuntodecaracteresEBCDICesdiferentedelconjuntoASCn.
Secuenciasdeescape
Ciertoscaracteresnoimprimibles,asícomolabarrainclinadahaciaatrás ()ylacomillasimple
(
'),sepuedenexpresar entérminosde secuenciasdeescape. Unasecuenciadeescapesiempre
comienzaconunabarrainclinadahaciaatrásyesseguidaporunoomáscaracteresespeciales.
Porejemplo,unsaltodelínea(LF),quesedenomina
carácterdenuevalínea enC,sepuede
representarcomo
.Unasecuenciadeescapesiemprerepresentaunsolocarácter,auncuando
seescribacondosomáscaracteres.
Acontinuaciónselistanlassecuenciasdeescapeutilizadasconmayorfrecuencia.
sonido(alerta)
\a
retroceso \ b
tabuladorhorizontal \
t
tabuladorvertical \ v
nuevalínea(avancedelínea)

avancedepágina \ f
retomodecarro \ r
comillas(n) \ n
comillasimple (') \ '
signodeinterrogación(?) \
?
barrainclinadahaciaatrás () \ \
nulo \
O
Carácter Secuenciadeescape ValorASCII
007
008
009
011
010
012
013
034
039
063
092
000
EJEMPLO2.12. Acontinuaciónsemuestranvariasconstantes decarácter,expresadas cornosecuen­
cias
deescape.
Il '''\', 1 \ \ ' '\11,
Observequelastresúltimassecuencias deescaperepresentanunacomillasimple,unabarrainclinada
haciaatrás
yunascomillasdobles,respectivamente.
Lasecuenciadeescape\ Oesdeespecialinterés.Representael carácternulo (ASCII000),
queseutiliza
paraindicarelfinalde unacadenadecaracteres (vermásadelante).Hayque
señalarquelaconstantedecarácternulo
'\O'noesequivalentea laconstantedecarácter
'O'.
Unasecuenciadeescapetambiénsepuedeexpresar entérminosdeuno,dosotresdígitos
octalesquerepresentanpatronesdebitscorrespondientesauncarácter.
Laformageneraldetal
secuenciadeescapees
\000,dondecadaorepresenta undígitooctal(de Oa7).Algunasver-

42 PROGRAMACiÓN ENC
sionesde etambiénpennitenexpresarunasecuenciadeescape entérminosdeunoomásdigitos
hexadecimales,precedidosporlaletra
x.Lafonnageneraldeunasecuenciadeescapeenhexa­
decimales
\xhh,dondecadahrepresentaundígitohexadecimal(deO a 9 ydea a f).Las
letraspuedenestartantoenmayúsculascomo
enminúsculas.Utilizarunasecuenciadeescape
enoctalo
enhexadecimalesnormalmentemenosrecomendablequeescribirdirectamentelacons­
tantedecarácter,yaquelospatronesdebitsdependendelosconjuntosdecaracteresparticulares.
EJEMPLO2.13. LaletraA serepresentapor elvalordecimal 065enelconjuntodecaracteresASCII.
Estevaloresequivalentealoctal101.(Elvalorbinarioequivalente es001000001.)Portanto,laconstan­
tedecarácter'A'sepuedeexpresarcomolasecuenciadeescapeenoctal'\1O1 ' .
Enalgunasversiones. deC,laletraAtambién sepuedeexpresar comounasecuenciadeescapeen
hexadecimal.E!equivalenteenhexadecimalalvalordecimal 65es41.(E!equivalenteenbinarioes
0100OO01.)Portanto,laconstantedecarácter'A'sepuedeexpresarcomo'\x41'ocomo'\X41' .
Lamejorformaderepresentarestaconstante decarácteressimplemente'A'.Deestaforma,lacons­
tante
decarácternodependedesurepresentaciónenASCII.
Lassecuenciasdeescapesólosepuedenescribirparaciertoscaracteresespeciales,tales
comoloslistadosantes,oenténninosdedígitosoctalesohexadecimales.Siunabarrainclinada
haciaatrásesseguidaporcualquierotrocarácter,elresultadoesimpredecible.Seignorarásim­
plemente
enlamayoríadeloscasos.
Constantesdecadenadecaracteres
Unaconstantedecadena decaracteresconstadecualquiernúmerodecaracteresconsecutivos
(oninguno),encerradosentrecomillas(dobles).
EJEMPLO2.14. Acontinuaciónsemuestranvariasconstantes decadenadecaracteres.
lIverde
ll
"$19.95"
"Washinton,D.C.20005"
"LARESPUESTA CORRECTA ES"
"270-32-3456"
"2*(1+3)/J"
11Línea1Línea 2Línea 3n lI.n
Nótesequelaconstantedecadenadecaracteres"Línea1Línea 2Línea 3"ocupatres
líneas,acausa
deloscaracteresdenuevalínea queseincluyenenella.Estaconstantedecadenadecarac­
teres
semostraríaasí:
Línea1
Línea2
Línea3
Advertirtambién que""esunacadenadecaracteresnula(vacía).
Avecesesnecesarioincluirciertoscaracteresespeciales(como labarrainclinadahaciaatrás
olascomillas
)en
Unaconstantedecadenadecaracteres.Estoscaracteresse debenrepresentar
enténninosdesussecuenciasdeescape,Deigualfonna,ciertoscaracteresnoimprimibles(por
ejemploeltabulador,nuevalínea)sepuedenincluir
encadenasdecaracteressiserepresentan
enténninosdesuscorrespondientessecuenciasdeescape.

CONCEPTOS BÁSICOSDEC 43
EJEMPLO2.15. Lasiguienteconstante decadenadecaracteresincluye trescaracteresespeciales que
serepresentanporsuscorrespondientessecuencias deescape.
" Paracontinuar,pulsarlatecla\"RETURN\""
Loscaracteresespecialesson\ t(tabuladorhorizontal), \"(comillas,queaparecedosveces)y (nue­
valínea).
Elcompiladorinsertaautomáticamenteuncarácternulo
(\O)alfinaldetodaconstantede
cadenadecaracteres,comoelúltimocarácterdeésta(antesdefinalizarconlascomillasdo­
bles).Estecarácternoaparececuandosevisualizalacadena.Sinembargo,podemosexaminar
individualmenteloscaracteresdeunacadenadeformafácil
ycomprobarsicadaunodeelloses
ono
uncarácternulo(veremoscómohacerestoenelCapítulo6).Deestaformasepuedeiden­
tificarrápidamenteelfinaldeunacadenadecaracteres.Estoesdegranayuda
silacadenaes
examinadacarácteracarácter,comoserequiereenmuchasaplicaciones.Además,enmuchas
situacionesestadesignacióndelfinalde
lacadenaeliminalanecesidaddeespecificarunalongi­
tudmáximadelascadenasdecaracteres.
EJEMPLO2.16. LaconstantedecadenadecaracteresqueapareceenelEjemplo2.15contienereal­
mente
43caracteres.Incluye cincoespaciosenblanco,cuatrocaracteresespeciales(tabuladorhorizontal,
doscomillasdoblesyunodenuevalínea)representadosporsecuencias deescapeyelcarácternulo(\O)
alfinaldelacadena.
Recordaraquíqueunaconstantedecarácter(porejemplo 'A')ysucorrespondientecons­
tantedecadenadecaracteresdeunosólo("
A")nosonequivalentes.Señalartambiénqueuna
constantedecaráctertieneunvalorenterocorrespondiente,mientrasqueunaconstantedecade­
nadeunsolocarácternotieneunvalorenteroequivalente
ydehechoconstade doscaracteres
-elcarácterespecificadoseguidodeuncarácternulo (\O).
EJEMPLO2.17. Laconstantedecarácter'w'tieneunvalorentero de119enelconjuntodecaracte­
resASCII.Notieneuncarácternulo alfinal.Sinembargo,laconstantedecadenadecaracteres"w"
consisteenrealidadendoscaracteres,laletraminúscula wyelcarácter11ulo\O.Estaconstantenotiene
unvalorenterocorrespondiente.
2.5.VARIABLES
YARRAYS
UnavariableeSunidentificadorque sel1tilizapararepresentarciertotipodeinformaciónden­
trodeunadeterminadapartedelprograma.
Ensuformamássencilla, unavariablees un
identificadorqueseutilizapararepresentarundatoindividual;esdecir,unacantidadnumérica
ounaconstantede
carácteLEnalgunapartedelprogramaseasigna eldatoalavariable.Este
valor
.sepuederecuperardespués.en elprogramaconsimplemente hacerreferencia
alnombrede
lavariable.
A
unavariableselepuedenasignardiferentesvalores endistintaspartesdelprograma.De
estaforma
lainformaciónrepresentada.puedecambiardurante laejecucióndelprograma.Sin
embargo,eltipodedatosasociadoa
lavariablenopuedecambiar.

44 PROGRAMACiÓN ENC
EJEMPLO2.18. Unprogramaen econtienelassiguienteslíneas:
inta,b,c;
chard;
a=3 ;
b=5 ;
e=a+b;
d='a';
a=4 ;
b=2 .,
e=a-b;
d='W';
Lasdosprimeraslíneasson declaracionesdetipo,enlascuales seestableceque a,b y esonvariables
enterasyqued
esunavariabledetipocarácter.Deestaforma a,b y erepresentaránsendascantidades
enterasy drepresentaráuncarácter.Estasdeclaraciones
detiposemantienenparatodoelprograma(más
sobreestoenlasección2.6).
Lassiguientescuatrolíneashacenlosiguiente:a a
seleasignalacantidadentera3,a b seleasigna
5
yacseleasignalasuma dea+b(esdecir8).A d seleasignaelcarácter
'a'.
Enlaterceralíneadeestegrupopuedeversecómoseaccedealosvaloresdelasvariablesa y b
simplementeescribiéndolasaladerechadelsignoigual.
Lasúltimascuatrolíneascambianlosvaloresasignadosalasvariables
delaformasiguiente: lacan­
tidadentera4
esasignadaa a,sustituyendoelanteriorvalor3;después seasigna2 a b,reemplazandoal
valoranterior,5;seleasignaa eladiferenciaentrea y b(esdecir,2),reemplazandoalanteriorvalor,8.
Finalmente,
seleasignaa delcarácter 'W',sustituyendoalanteriorcarácter, 'a'.
Elarrayesotraclasedevariableque seutilizaconfrecuenciaenC.Unarrayesunidentifi­
cadorquereferenciaunacoleccióndedatosconelmismonombre.Losdatosdebenserdel
mismotipo(porejemplo,todosenteros,todoscaracteres,etc.). Cadaunodeestosdatosesrepre­
sentado
porsuelementodelarray correspondiente(porejemplo,el primerdatoes representado
porelprimerelementodelarray,etc.). Loselementosindividualesdel arraysedistinguenunos
deotrosporelvalorqueseleasignaal índice.
EJEMPLO2.19. Supongamosquex esunarrayde 10elementos.El
primerelementoes x[O],el
segundox [1 ] , yasísucesivamente.
Elúltimoelementoseráx [9 1.
Elíndiceasociadoacadaelemento seencierraentrecorchetes.Deestaforma,elvalordelíndicepara
acceder
alprimerelemento esO,
paraaccederalsegundoelemento es1,Yasísucesivamente.Paraun
array
denelementos,losvaloresdelíndice seencontraránentreOy n-lo
Haydiferentestipos dearrays(arrays deenteros,arrays decaracteres,arrays unidimensio­
nales,arraysmultidimensionales).Porahoraconcentraremosnuestraatenciónenunsolotipode
array:el arraydecaracteresunidimensional (tambiénllamadoarraydetipocarácter).General­
menteseutilizaestetipodearraypararepresentar
unacadenadecaracteres.Cadaelementodel
arrayrepresentaráuncarácterdelacadena:Deestaformasepuedeveralarrayenconjunto
comounalistaordenadadecaracteres.

CONCEPTOS BÁSICOS DEC45
Comoelarrayesunidimensional,tendráunsolo índice,cuyovalordetenninaloselementos
individualesdelarray.Si
elarraycontiene nelementos,elíndiceseráunacantidadenteracuyos
valoresseencuentranentre
Oyn-l.Observequeunacadena dencaracteresrequeriráunarray
de
(n+1)elementos,debidoalcarácternulo (\O)queseañadeautomáticamentealfinal dela
cadena.
EJEMPLO2.20. Supongamosquedeseamosalmacenarlacadena "California"enunarrayde
caracteresunidimensionalllamado
letras.Como"California"contiene10caracteres,letras
seráunarrayde 11elementos.Deestaforma, letras[O1representarálaletra C,letras[1]repre­
sentarálaletra
a,yasísucesivamente,talycomoserepresentaacontinuación.Observequeelúltimo
elemento,
letras[10],representaalcarácternuloqueindicaelfinal delacadena.
Númerode Valordel Elemento Datocorrespondiente
elemento índice delarray (carácter
delacadena)
1 O letras[O] C
2
1 letras[l] a
3 2
letras[2] 1
4 3 letras[3] i
5 4
letras[4] f
6 5
letras[5] o
7 6
letras[6] r
B 7
letras[7] n
9 B
letras[B] i
10 9 letras[9] a
11 10 letras[lO] \0
Enestalistasepuedeobservar, porejemplo,queelquintoelementodel array, letras[4],representala
letra
f,Yasísucesivamente.
LoselementosdelarrayysucontenidosemuestranesquemáticamenteenlaFigura
2.1.
Valordelíndice:o1 2 3 4 5 6 7 8 9 10
Unarraydecaracteresdeonceelementos
Figura2.1.
DiscutiremoslosarraysconmayordetalleenlosCapítulos9 y 10.
2.6.DECLARACIONES
Unadeclaraciónasociauntipodedatosespecificadoaungrupodevariables. Sedebendeclarar
todaslasvariablesantesdequeaparezcanenlasinstruccionesejecutables.
Unadeclaraciónconstade
untipodedatos,seguidodeunoomásnombresdevariables,
finalizandoconunpuntoycoma.(Lostiposdedatospennitidossehandiscutidoenlasec-

46 PROGRAMACiÓN ENC
ción2.3.)Cadavariablearraydebeirseguidadeunpardecorchetes,conunenteropositivo
dentrodeéstosque especificaeltamaño(elnúmerodeelementos)delarray.
EJEMPLO2.21. Unprogramaen econtienelassiguientesdeclaracionesdetipos:
inta,b,e;
floatraizl,raiz2;
charindicador,texto[80];
Deestaforma sedeclarana,by ccomovariablesenteras, raizlyraiz2sonvariablesencoma
flotante,
indicadorunavariabledetipocaráctery textounarraydetipocarácterde80elementos.
Observeloscorchetesquedelimitanlaespecificacióndetamañode
texto.
Tambiénsepodríanhaberescritolasdeclaracionesanteriorescomosigue:
inta¡
intb;
intc¡
floatraizl;
floatraiz2;
charindicadori
chartexto[80];
Estaformapuedeserútilsiseacompañaacadavariableconuncomentarioqueexpliquesupropósito.Sin
embargo,enpequeñosprogramaslasvariablesdelmismotiposesuelenincluirenunasoladeclaración.
Lasvariablesdetipoenterose puedendeclararcomoenteroscortos parapequeñascantida­
desenteras,o enteroslargos paracantidadesenterasmayores.
(AlgUnoscompiladoresdeCse
ocupandereservarmenosespaciodememoriaparaenteroscortosqueparalargos.)Estasvaria­
blessepuedendeclararescribiendoshortintylongint,osimplementeshortylong,
respectivamente.
EJEMPLO2.22. Unprogramaen econtienelassiguientesdeclaraciones detipo:
short
long
int
inta,b,c¡
intr,S,ti
PIq¡
Algunoscompiladoresde ereservaránmenosespaciodememoriaparalasvariablesenterascortas a,
b y cqueparalasvariablesenterasp yq.Losvalorestípicossondosbytesparacadavariabledeclarada
comoenteracortaycuatrobytes(unapalabra)paracadavariableentera.Lo~ v\lloresmáximospermisiples
para
a,b y cseránmáspequeñosquelosdep y qcuandoseutiliceuncompilador deestetipo.
Deformasemejante,algunoscompiladoresreservaránespaciodememoriaadicionalparalasvaria­
blesenteraslargas
r,s y t
queparalasvari\lblesenterasp yq.Esunvalortípicoeldedospalabras
(8bytes)paracadavariableenteralargaydeunapalabra (4bytes)paracadavariableenteraordinaria.Los
valbresmáximospermisiblesparaT,sytseránmayoresquelosdepy qsiseutilizaun.éompiladorde
estetipo.

CONCEPTOS BÁSICOS DEC47
Lasdeclaracionesanterioressepuedenescribirtambiéncomo
shorta,
longr,
intp,
b,
s,
q;
e;
t·,
Porconsiguiente,shortyshortintsonequivalentes,asicomo longylongint.
Tambiénsepuededeclararunavariableentera comosinsigno,escribiendounsignedint,
osimplementeunsigned,comoindicadordetipo.Lascantidadesenteras sinsignopuedenser
mayoresquelascantidades enterasordinarias(aproximadamente eldoble),pero nopuedenser
negativas.
EJEMPLO2.23. Unprogramaen econtienelassiguientesdeclaraciones:
intalb;
unsignedX,y;
Lasvariablessinsignox e ypuedenrepresentarvaloresaproximadamentedosvecesmayoresquelosque
puedenrepresentara y
b.Sinembargo,x e y nopuedenrepresentarcantidadesnegativas.Porejemplo, si
lacomputadorautiliza2bytesparacadaentero,a y bpodrántomarvaloresentre
-32768 Y+32767,
mientrasquelosvalores
dex e ypodránvariarentreOy +65535.
Se
puedendeclararvariables encomaflotantecomodedobleprecisión utilizandoelindica­
dordetipodoubleolongfloatenlugardefloat.Enlamayoríadelasversiones deC,
elexponentedeunacantidaddedobleprecisiónesmayorenvalorabsolutoqueelexponentede
unacantidadordinariaencomaflotante.Portanto,lacantidadrepresentadaporunavariablede
dobleprecisiónsepodráencontrardentrodeunrangomayor. Además,unacantidaddedoble
precisióntendrámayornúmerodecifrassignificativas.
EJEMPLO2.24. Unprogramaen econtienelassiguientesdeclaraciones:
floatel,e2,e3;
doubleraizl,raiz2;
Enuncompilador deeenconcreto,lasvariables dedobleprecisiónraizlyraiz2representan
valoresquepuedenvariar(envalorabsoluto)aproximadamenteentre1,7
X10-
308
Y1,7x
10+
308
•Sinem­
bargo,lasvariablesencomaflotante
el,e2ye3tienencomolímites(envalorabsoluto)3,4x10-
38
y
3,4
X
10+38.Además,losvaloresrepresentadospor raizlyraiz2sealmacenaráncon 18cifrassignifi­
cativas,mientrasquelosvaloresrepresentadospor
el,e 2 y e 3loestaránconsólo6cifrassignificativas.
Laúltimadeclaración
sepodriahaberescrito
longfloatraizl,raiz2;
aunquelaformaoriginal (doubleraizl,raiz2;)esmáscomún.
Selepuedenasignarvaloresiniciales alasvariablesdentrodela.declaracióll detipo.Para
haceresto,ladeclaracióndebeconsistirenuntipodedatos,seguido porun
nombredevariable,

48 PROGRAMACiÓN ENC
unsignoigual (=)yunaconstantedeltipoapropiado. Alfinalsedebeponer, comodecostum­
bre,unpuntoycoma(;).
EJEMPLO2.25. Unprogramaen econtienelassiguientesdeclaracionesdetipo:
int
char
float
double
c=12;
estrella='*,;
suma=O.;
factor=0.21023e-6;
Porconsiguiente,c esunavariableenteracuyovalorinicial es12,estrellaesunavariabledetipo
carácteralaque
seleasignainicialmenteelcarácter' * ,,sumaunavariableencomaflotantecuyovalor
inicial
esO.Yfactorunavariablededobleprecisióncuyovalorinicial es0,21023x10-6.
Unarrayde tipocaráctertambiénsepuedeinicializarenunadeclaración.Parahaceresto,se
sueleescribirel arraysinunaespecificacióndetamañoexplícita(loscorchetesestánvacíos).A
continuación
delnombredelarrayseescribeunsignoigual, lacadenadecaracteres(encerrada
encomillasdobles)y unpuntoycoma.Éstaesunaformamuycómodadeasignarunacadenade
caracteresa unaformacióndetipocarácter.
EJEMPLO2.26. Unprogramaen econtienelasiguientedeclaracióndetipo:
chartext[]="California";
Estadeclaraciónharáque textoseaunarraydecaracteresde 11elementos.Losprimeros 10ele­
mentosrepresentaránlosdiezcaracteres
delapalabraCali fornia,yelelementoundécimorepresenta­
ráelcarácternulo
(\O)queseañadeautomáticamentealfinaldelacadena.
También
sepodríahaberescritoladeclaracióndela siguienteforma:
chartexto[ll]="California";
endondeeltamañodelarray seespecificaexplícitamente.Enestoscasos esimportantequeeltamaño se
especifiquecorrectamente.Si seespecificauntamañomáspequeñoqueelnecesario,porejemplo,
chartexto[10l="California";
seperderánloscaracteresdelfinal delacadena(enestecaso,elcarácternulo).Si seespecificauntamaño
demasiadogrande,porejemplo,
chartexto[20]="California";
selesasignaráncerosaloselementossobrantesdelarray,oesposibleque serellenenconcaracteressin
sentido.
Lasdeclaracionesdearraysqueincluyenasignaciones
devaloresinicialessólopuedenapa­
recerenciertasparlesdeunprogramaenC(verCapítulo9).

CONCEPTOS BÁSICOS DEC49
EnelCapítulo8veremosquese puedeclasificaralasvariables porsutipodealmacena­
miento
lomismoqueporsutipodedatos.Eltipo dealmacenamientoespecificalapartedel
programadentrodelacualsereconocea lavariable.Esmás,eltipo dealmacenamientoasocia­
doa
unarraydeterminasise puedeinicializarono.Estoseexplica enelCapítulo9.
2.7.EXPRESIONES
Unaexpresiónrepresentaunaunidaddedatossimple,tal comounnúmeroouncarácter.La
expresiónpuedeconsistirenunaentidadsimple,comounaconstante,unavariable,unele­
mentodeunarrayounareferenciaaunafunción.Tambiénpuedeconsistirenalgunacombi­
nacióndetalesentidadesinterconectadasporunoomásoperadores.Elusodeexpresiones
involucrandooperadoresesespecialmentefrecuenteenC,comoenmuchosotroslenguajesde
programación.
Lasexpresionestambiénpuedenrepresentarcondicioneslógicasque sonverdaderasofalsas.
EnClascondiciones verdaderoyfalsoserepresentanporlosvalores1 y O,respectivamente.
Portanto,lasexpresioneslógicasrepresentan enrealidadcantidadesnuméricas.
EJEMPLO2.27. Acontinuaciónsemuestranunaserie deexpresionessencillas.
a+b
x=y
e=a+b
x<=y
x--y
++i
Enlaprimeraexpresiónapareceel operadorsuma (+).Laexpresiónrepresentalasuma delosvalo­
resasignadosalasvariablesa
yb.
Enlasegundaexpresiónapareceel operadordeasignación(=).Enestecasolaexpresiónhaceque
elvalorquecontenga
yseleasignea x.Yahemosvistoenanterioresejemploseluso deesteoperador
(verejemplos1.6a1.13,2.25
Y2.26).eposeevariosoperadores deasignaciónadicionales,comose
discuteenlasección3.4.
Enlaterceralínea
seasignaa lavariableeelvalor delaexpresión(a+b).Observeque sehan
combinadolascaracterísticas
delasdosprimerasexpresiones(suma yasignación).
Lacuartaexpresióntendráelvalor1(verdadero)
sielvalordex esmenoroigual aldey.Deotra
forma,laexpresióntendráelvalor
O(falso).Enestaexpresión, <=esunoperadorrelacional quecompara
losvalores
delasvariablesx e y.
Laquintaexpresiónesunacomprobación deigualdad(compáreseconlasegundaexpresión,que es
unaexpresióndeasignación).Por consiguiente,laexpresióntendráelvalor1(verdadero) sielvalordex
esigualalvalordey.Encualquierotrocaso,laexpresióntendráelvalor O(falso).
Laúltimaexpresiónhacequeelvalor
delavariableiseincrementeen 1.Portanto,laexpresión es
equivalentea
i=i+1;
Eloperador++,queindicaincrementoen 1,esunoperador unarioporquesólotieneun operando(eneste
caso,lavariable
i).etienevariosoperadoresmás deestetipo,como sediscuteenlasección3.2.

50 PROGRAMACiÓN ENC
EllenguajeCincluyemuchasclasesdiferentesdeoperadoresyexpresiones.Lamayoríase
describencondetalleenelCapítulo
3.Otrossetrataránencualquierotrolugardeestelibro,
segúnsevayahaciendonecesario.
2.8.INSTRUCCIONES
Unainstrucciónhacequelacomputadoraefectúealgunaacción. Haytrestipodiferentesde
instruccionesenC.Éstassonlas
instruccionesdeexpresión,instruccionescompuestas einstruc­
ciones
decontrol.
Unainstruccióndeexpresiónconsiste enunaexpresiónseguidade unpuntoycoma. La
ejecucióndeunainstruccióndeexpresiónhacequeseevalúelaexpresión.
EJEMPLO2.28. Acontinuaciónsemuestranvariasinstrucciones deexpresión.
a
::::;3;
e=a+b;
++i¡
printf(UArea-%fllrarea)¡
Lasdosprimerasinstrucciones deexpresiónsoninstruccionesdetipoasignación.Cada unahacequeel
valordelaexpresióna laderechadelsignoigual leseaasignadoalavariable delaizquierda.Latercera
instrucción
deexpresiónesunainstruccióndetipoincremento,quehacequeelvalordeiseaincremen­
tadoen
1.
Lacuartainstrucción deexpresiónhace quelafunciónprintfseaevaluada.Ésta esunafunciónde
bibliotecadeCestándarquevisualizaresultadosen lacomputadora(másdetallesenlasección3.6). En
estecasosevisualizaráelmensajeArea
=,seguidodelvaloractual delavariablearea.Así,siarea
tieneelvalor100. ,lainstruccióngenerará elmensaje
Area=100.000000
Laúltimainstrucción deexpresiónnohacenada,yaqueconstasólo deunpuntoy coma.Esunsenci­
llomecanismo
deconseguirunainstrucción deexpresiónvacía enlugaresdonde serequieraestetipo de
instrucción.Consecuentemente, sedenominainstrucciónnula.
'
Unainstruccióncompuestaestáformada porvariasinstruccionesindividualesencerradas
conunpardellaves{ }.Las.instruccionesindividualespuedenserasuvezinstruccionesde
expresión,instruccionescompuestasoinstruccionesdecontrol.
Portanto,lainstruccióncom­
puestahaceposibleincluirinstruccionesdentrodeotrasinstruccíones.Adiferencia de,una
.ins­
truccióndeexpresíón,unainstruccióncompuestano acabaconunpuntoycoma.
EJEMPLO2.29. Semuestraacontinuaciónunainstruccióncompuesta.
{
pi=3.141593;
circunferencia=2*pi*radio;
a;r'ea..::=;.pi:*radio*radioi
}

CONCEPTOS BÁSICOS DEC 51
Estasecuenciacompuesta enparticularconsta detresinstruccionesdeexpresióndetipoasignación,aun­
queesconsideradacomounaúnicaentidaddentro delprogramaenqueaparece.Observe quelainstruc­
cióncompuesta
noacabaconunpuntoycomadespuésdelallave.
Lasinstruccionesdecontrolseutilizan
paraconseguirciertasaccionesespecialesenlos
programas,talescomocomprobacioneslógicas,buclesybifurcaciones.Muchasinstrucciones
decontrolrequierenqueotrasinstruccionesseencuentrenincluidasenellas,comoseilustraen
elsiguienteejemplo.
EJEMPLO2.30. Lasiguienteinstrucción decontrolcrea unbuclecondicionalenelqueseejecutan
variasaccionesrepetidamente,hasta
quesesatisfaceunacondición enparticular.
while(cont<=n){
printf(!1x=H);
scanf("%f",&x);
suma+=x;
++cont;
}
Estainstruccióncontieneunainstruccióncompuesta, queasuvezcontienecuatroinstrucciones deexpre­
sión.Lainstruccióncompuesta seseguiráejecutandohasta queelvalordecontsupereelvalorden.
Nótese
quecontseincrementaenunoencadapasadaporelbucle.
EnelCapítulo6 setratanconmayordetallelasinstruccionesdecontro!.
2.9.CONSTANTES SIMBÓLICAS
Unaconstantesimbólica esunnombrequesustituyeunasecuenciadecaracteres.Loscaracteres
puedenrepresentarunaconstantenumérica,unaconstantedecarácterounaconstantedecadena
decaracteres.Portanto,una.constantesimbólicapermitequeaparezca
unnombreenlugarde
unaconstantenumérica,unaconstantedecarácterounaconstantedecadenadecaracteres.Cuan­
dosecompilaunprograma,cadaaparicióndeunaconstantesimbólicaesreemplazada
porsu
correspondientesecuenciadecaracteres.
Lasconstantessimbólicassesuelen definiralcomienzodelprograma.Lasconstantessimbó­
licaspuedenentoncesaparecerdespués
enelprogramaenlugarde las.constantesnuméricas,las
constantesdecarácter,etc.,querepresentandichasconstantessimbólicas.
Sedefineunaconstantesimbólicaescribiendo
#definenombretexto
endondenombrerepresentaunnombresimbólico,quesesueleescribirenletrasmayúsculas,
ytexto
representa)asecuenciadecaracteresasociada alnombresimbólico.Adviértaseque
textonoacabaconunpuntoycoma,yaqueladefinicióndeunaconstantesimbólicanoesuna
verdaderainstrucciónde
C.Esmás,si textoacabasecon unpuntoycoma,estepuntoycoma
setrataríacomosifuesepartede
laconstantenumérica,laconstantedecaráctero laconstante
decadenadecaracteresquesesustituyeporelnombresimbólico.

52 PROGRAMACiÓN ENC
EJEMPLO2.31. Unprogramaen econtienelassiguientesdefinicionesdeconstantessimbólicas:
#defineINTERES0.23
#definePI3.141593
#defineTRUE1
#defineFALSEO
#defineAMIGA11Susana 11
Nótesequelosnombressimbólicosestánescritosenmayúsculas,paradistinguirlosdelosidentificadores
ordinariosde
C.Adviértasetambiénquelasdefinicionesnoacabanenpuntoycoma.
Supóngaseahoraqueelprogramacontiene lainstrucción
area=PI*radio*radio;
Duranteelprocesodecompilación,cadaaparicióndeunaconstantesimbólicaseráreemplazadaporsu
correspondientetexto.Portanto,lainstrucciónanteriorsetransformaráen
area
~3.141593*radio*radio;
Supongamosahoraquesehaincluido(incorrectamente)unpuntoycomaenladefiniciónde PI,
estoes,
#definePI3.141593;
Lainstruccióndeasignaciónde areasetransformaríaentoncesen
area~3.141593;*radio*radio;
Adviértaseelpuntoycomaqueprecedealprimerasterisco.Estoesclaramenteincorrecto,yprovocaráun
errordurantelacompilación.
Lasustitucióndetextoporuhaconstantesimbólicaserállevadaacaboencualquiersitioa
continuacióndelainstrucción#define,exceptodentrodeunacadenadecaracteres.Portanto,
cualquiertextoencerradoentrecomillas(dobles)noseveráafectadoporesteprocesodesusti­
tución.
EJEMPLO2.32. Unprogramaen econtienelassiguientesinstrucciones:
#defineCONSTANTE 6.023E23
floate;
printf("CONSTANTE
~%f",e);
Lainstrucciónprintfnoseveráafectadaporladefinicióndelaconstantesimbólica,yaqueeltérmino
"CONSTANTE~%f"esunaconstantedecadena decaracteres.Si,encambio,sehubieraescritola
instrucción
printfdelaforma
printf("CONSTANTE
~%f",CONSTANTE);

CONCEPTOS BÁSICOS DEC53
entonceslainstrucciónprintfsehabríatransformado en
printf("CONSTANTE =%f",6.ü23E23);
duranteelprocesodecompilación.
Lasconstantessimbólicasnosonnecesariasparaescribirprogramasen C.Sinembargo,se
recomiendasuutilización,yaquecontribuyenaldesarrollo
deprogramasclarosyordenados.
Porejemplo,lasconstantessimbólicasseidentificandeformamásrápidaquelainformación
querepresentan,ylosnombressimbólicossuelensugerirelsignificadodesusdatosasociados.
Además,esmuchomásfácilcambiarelvalordeunaúnicaconstantesimbólicaquecambiartoda
aparicióndealgunaconstantenuméricaquepuedaaparecerenvarioslugaresdelprograma.
Laexistenciade
#define,queseutilizaparadefinirconstantessimbólicas,esuna delas
principalescaracterísticasincluidasenel
preprocesadordeC(unprogramaqueseocupa deun
primerpasoenlatraducción
deunprogramaenC alenguajemáquina).Elpreprocesador deCse
trataconmayordetalleenelCapítulo
14(versección14.6).
2.1.¿Quécaracteresincluyeelconjuntodecaracteresde C?
2.2.Mencionarlasreglasreferentesalosnombresdelosidentificadores.¿Sonequivalentes
lasletrasmayúsculasalasminúsculas?¿Sepuedenincluirdígitosenunidentificador?
¿Sepuedeincluircualquiercarácterespecial?
2.3.¿Cuántoscaracterespuedetenerunidentificador?¿Sontodosloscaracteressignificativos
enigualforma?
2.4.¿QuéesunapalabrareservadaenC?¿Quérestriccionestienesuuso?
2.5.Mencionarydescribirloscuatrotiposbásicos dedatosenC.
2.6.Mencionarydescribirloscuatrocualificadores detiposdedatos.¿Aquétipos dedatosse
puedeaplicarcadacualificador?
2.7.Nombrarydescribirloscuatrotiposbásicosdeconstantesen C.
2.8.Mencionartodaslasreglasqueseaplicanatodaslasconstantesdetiponumérico.
2.9.¿Quéreglasespecialesselesaplicanalasconstantesenteras?
2.10.Alescribirconstantesenteras,¿cómosediferencianlasconstantesdecimales,octalesy
hexadecimales?
2.11.¿Cuáles,típicamente,elmayorvalorpermisible deunaconstanteentera?Escribirlares­
puesta
endecimal,octalyhexadecimal.
2.12.¿Quéesunaconstanteenterasinsigno?¿Yunaconstanteenteralarga?¿Enquésedife­
renciandelasconstantesenterasordinarias?¿Cómosepuedenescribirydiferenciar?
2.13.Describirdosformasdiferentesdeescribirconstantesencomaflotante.¿Quéreglasespe­
cialesseaplicanacadacaso?
2.14.¿Cuáleselpropósitodelexponente(opcional)enunaconstanteencomaflotante?
2.15.¿Cuáles,típicamente,elmayorvalorquepuedetenerunaconstanteencomaflotante?
Compáreseconel
deunaconstanteentera.

54 PROGRAMACiÓN ENC
2.16.¿Cómosepuedenescribireidentificarlasconstantesencomaflotante de«simplepreci­
sióm>y«largas»?
2.17.¿Cuántascifrassignificativastienecomomáximo,típicamente,unaconstanteencoma
flotante?
2.18.Describirlasdiferencias deprecisiónentreunaconstanteenterayunaencomaflotante.
¿Enquécircunstanciassedebeutilizarcadauna
deellas?
2.19.¿Quéesunaconstantedecarácter?¿Enquésediferencianlasconstantesdecarácter delas
constantes
detiponumérico?¿Representanvaloresnuméricoslasconstantesdecarácter?
2.20.¿QuéeselconjuntodecaracteresASCII?¿Es
suusocomún?
2.21.¿Quéesunasecuenciadeescape?¿Quépropósitotiene?
2.22.Mencionarlassecuenciasdeescapeestándaren C.Describirotrassecuencias deescape
noestándarnormalmentedisponibles.
2.23.¿Quéesunaconstantedecadenadecaracteres?¿Enquésediferencianlasconstantes de
cadenadecaracteresdelasconstantesdecarácter?¿Representanvaloresnuméricoslas
constantes
decadenadecaracteres?
2.24.¿Sepuedenincluirenunaconstantedecadena decaracteressecuenciasdeescape?Expli­
carlo.
2.25.¿Quéesunavariable?¿Cómosepuedencaracterizarlasvariables?
2.26.¿Quéesunavariablearray?¿Enquésediferenciaunavariablearraydeunavariable
ordinaria?
. .
2.27.¿Quérestriccióndebensatisfacertodoslosdatoscontenidosenunarray?
2.28.¿Cómosepuedendistinguirentresíloselementos deunarray?
2.29.¿Quéesuníndice?¿Quérango devalorespuedetenerelíndicedeunarrayunidimensio-
nal
denelementos?
2.30.¿Cuáleselpropósitodeunadeclaracióndetipo?¿Dequéconstaunadeclaración detipo?
2.31.¿Sedebendeclarartodaslasvariablesqueaparecenenunprogramaen C?
2.32.¿Cómoselespuedeasignarvaloresinicialesalasvariablesenunadeclaración. detipo?
¿Cómoselespuedeasignarcadenasdecaracteresaarraysunidimensionalesdetipoca­
rácter?
2.33.¿Quéesunaexpresión?
¿Ql.\éclasedeinformación esrepresentadaenunaexpresión?
2.34.¿Quéesunoperador?Describirvariostiposdiferentesdeoperadoresqueesténincluidos
enellenguaje
C.
"
2.35.Mencionarlostrestiposdiferentesdeinstruccionesen C.Describirlacomposiciónde
cadaunadeellas.
2.36.¿Sepuedenincluirinstruccionesdentrodeotras?Explicarlo.
2.37.¿Quéesunaconstantesimbólica?¿Cómosedefineunaconstantesimbólica?¿Cómose
escribe
ladefinición?¿Dóndesedebeponerladefinición deunaconstantesimbólicaen
unprogramaen C?
2.38.¿Quélesocurrealasconstantes.simbólicasqueaparecenenunprogramaenCduranteel
procesodecompilación?

CONCEPTOS BÁSICOS DEC55
2.39.Determinarcuálesdelossiguientessonidentificadoresválidos.Sinosonválidos,explicar
porqué.
a)registrol
b)lregistro
e)archivo3
ti)return
e)$impuesto
j)nombre
g)nombreydireccion
h)nombre_y_direccion
i)nombre-y-direccion
j)123-45-6789
2.40.SupongamosquelaversióndeCpuedereconocersólolosochoprimeroscaracteresdelnombrede
unidentificador,aunquelosnombresdelosidentificadorespuedanserdelongitudarbitraria.
¿Cuá­
lesdelossiguientesparesdenombresdeidentificadoresseconsideraráncomoidénticosycuáles
sedistinguirán?
a)nombre,nombres
b)direccion,Direccion
e)identificador_l,identificador2
ti)listal,lista2
e)respuesta,RESPUESTA
j)carl,car_l
2.41.Determinarcuálesdelosiguientesvaloresnuméricossonconstantesválidas.Si unaconstantees
válida,especificarsiesenteraoreal.Especificartambiénlabaseenqueestáescritacadaconstante
enteraválida.
a)0.5
b)27,822
e)9.3e12
ti)9.3e-12
e)12345678
j)12345678L
g)O.8E+0.8
h)O.8E8
i)0515
j)018CDF
k)OXBCFDAL
l)
Ox87e3ha
2.42.Determinarcuálesdelassiguientessonconstantesdecarácterválidas.
a)'a' e),\\' h)'\0'
b)'$, j)
I\aI i)'xyz/
e),' g)'T' J)'\052'
ti)'In'
2.43.Determinarcuálesdelassiguientessonconstantesdecadenadecaracteresválidas.
a)'8:15P.M.'
~"Rojo,BlancoyAzul"
e)"Nombre:
ti)"Capítulo3(Cont\'d)"
e)"1.3e-12"
j)"NEWYORK, NY10020"
g) nElprofesordijoIuparfavornoseduermanenclase11
2.44.Escribirlasdeclaracionesapropiadasparacadagrupodevariablesyarrays.

56 PROGRAMACiÓN ENC
a)Variablesenteras: p,q
Variablesencomaflotante:
x,y,z
Variables
decarácter:a,b,c
b)Variablesencomaflotante: raiz1,raiz2
Variableenteralarga: contador
Variableenteracorta: indicador
e)Variableentera: indice
Variableenterasinsigno: num_c1iente
Variablesdedobleprecisión: bruto,impuesto,neto
d)Variablesdecarácter: actual,ultimo
Variableenterasinsigno: contador
Variableencomaflotante: error
e)Variablesdecarácter: primero,ultimo
Arraydecaracteresde80elementos: mensaje
2.45.Escribirdeclaracionesapropiadasyasignarlosvaloresinicialesdadosparacadagrupodevaria­
blesyarrays.
a)Variablesencomaflotante: a=-8.2,b=O.005
Variablesenteras: x=129,y=87,z=-22
Variablesdecarácter:c1='w',c2='&'
b)Variablesdedobleprecisión:d1=2.88x
10-
8
,d2=-8.4 xlO'
Variablesenteras: u=711(octal),v=ffff(hexadecimal)
e)Variableenteralarga:
grande=123456789
Variablededobleprecisión: c
=O.3333 3 3 3 3 3 3
Variabledecarácter: eo1=carácterdenuevalínea
d)Arrayunidimensionaldecaracteres: mensaje="ERROR"
2.46.Explicarelpropósitodecadaunadelassiguientesexpresiones.
1)a<(b/c)
g)--a
d)a>=b
e)(a%5)==O
a)a -b
b)a*(b+c)
e)d=a*(b+c)
2.47.Identificarcuándocadaunadelasipstruccionessiguientesesunainstruccióndeexpresión,una
instruccióncompuestaounainstruccióndecontrol
a)a*(b+c)
b)while(a<100){
d=a*(b+c);
++a¡
}
e)if(x>O)
y
=2.O;
else
y=3 . O;
d)
{
++x¡
if(x>O)
Y=2.0;

CONCEPTOSBÁSICOSDEC 57
e1se
y=3 .O;
printf(lI%fll,y);
}
e){
++X;
if(x>O){
Y=2.O;
z=6.0;
}
e1se{
y=3.O;
z=9.O;
}
}
2.48.Escribirunadefiniciónapropiadaparacadaunadelassiguientesconstantessimbólicas,comosi
apareciesenenunprogramaen
C.
Constante Texto
a)
FACTOR -18
b)ERROR 0.0001
e)BEGIN {
END }
el)NOMBRE llAdrián
ll
e)EOLN ''
j)COSTE "$19.95"

CAPíTULO3
Operadoresyexpresiones
Yahemosvistoquelasconstantes,variables,elementos deunaformaciónyreferenciasafun­
cionessepuedenunirconvariosoperadoresparaformarexpresiones.Tambiénhemosmencio­
nadoqueCposeeungrannúmerodeoperadoresquesepuedenagruparendiferentescategorías.
Enestecapítuloexaminaremoscondetallevariasdeesascategorías.Concretamente,veremos
cómoutilizaroperadoresaritméticos,operadoresunarios,operadoresrelacionalesylógicos,
operadoresdeasignaciónyeloperadorcondicionalparaformarexpresiones.
Losdatossobrelosqueactúanlosoperadoressedenominan
operandos.Algunosoperadores
requierendosoperandos,mientrasqueotrosactúansólosobreunoperando.Lamayoría
delos
operadorespermitenquelosoperandospuedanserexpresiones.Existenalgunosoperadoresque
sólopermitenvariablescomooperandos(loveremosposteriormente).
3.1.OPERADORES ARITMÉTICOS
Existencinco operadoresaritméticos enC:
Operador
+
*
/
%
Propósito
suma
resta
multiplicación
división
restodedivisiónentera
Eloperador
%esavecesdenominadoeloperador módulo.
Nohayoperador depotenciaciónen C.Sinembargo,hayunafundóndebiblioteca(pow)
querealizalapotenciación(ver
secci<'m3.6).
Losoperandossobrelosque·actúanlosoperadoresaritméticosdebenrepresentarvalores
numéricos.Portanto,losoperandosdebensercantidadesenteras,encomaflotanteocaracteres
(recuérdesequelasconstantesdecarácterrepresentanvaloresenteros,losdeterminadosporel
conjuntodecaracteresdela computadora).
Eloperadorcleresto(%)requierequelosdosope­
randosseanenterosyelsegundooperandononulo.Análogamente,eloperador
dediyisiónC/}
requiereque elsegundooperandosea
nonulo.
Ladivisióndeuna
cantidaclenteraporotraesdenominadadivisión
entgra..Estaoperación
siempretier¡.ecomoresultadoelcocienteenterotruncado(sedesprecia]apartedecimaldelcocien-
59

60 PROGRAMACiÓN ENC
te).Porotraparte,si unaoperacióndedivisiónsellevaacabo condosnúmeros encomaflotan­
te,o
conunnúmeroencomaflotanteyunentero,elresultadoserá uncocienteencomaflotante.
EJEMPLO3.1. Supóngasequeunasvariablesa y btienenvalores 10Y3,respectivamente.Semuestran
acontinuaciónvariasexpresionesaritméticasenlas
queaparecenestasvariables,acompañadas·del
resultado.
Expresión Valor
a+b 13
a-b 7
a*
b 30
a/b 30
a%b 1
Observeelcocientetruncadoresultante delaoperacióndedivisión,ya queambosoperandos
repre.
sentancantidadesenteras.Observetambiénelrestoenteroresultantedelusodeloperadormóduloenla
últimaexpresión.
Supongamosahoraque
vlyv2sonvariablesencomaflotantecuyosvaloresson 12. 5Y2 .O,
respectivamente.Mostrarnosacontinuaciónvariasexpresionesaritméticasenlasqueaparecenestasva­
riables,acompañadasdelresultado.
Expresión Valor
vl+v2 14.5
vl-v2 10.5
vl*
v2 25.0
vl/v2 6,25
Supongamos,finalmente, queelye2sonvariablesdetipocarácterquerepresentanloscaracteres P
yT,respectivamente.Semuestranacontinuaciónvariasexpresionesaritméticasenlasqueaparecen
estasvariables,acompañadas
delosresultados(basadas enelconjuntodecaracteresASCII).
Expresión
el 80
el+e2 164
el+e2+5169
el+e2+
'5'217
Observarque Pestácodificadacomo80(endecimal), Testáco¡:lificadacorno84y 5corno53enel
conjunto
decaracteresASCII,comosemuestraenlaTabla2;1.
Si
unoolosdosoperandosrepresentanvaloresnegativos,lasoperaciones desuma,·resta,
multiplicaciónydivisióntendráncomoresultadovalorescuyossignos estándeterminadospor
lasreglasdelálgebra. Elresultadode ladivisiónestarátruncado haciacero,eSdecir,elresulta­
dosiempreserámenorenvalorabsolutoqueelverdadero·cociente.
Lainterpretacióndelaoperaciónderestonoestáclaracuandounodelosoperandoses

OPERADORES YEXPRESIONES 61
negativo.Lamayoríadelasversionesde easignanalrestoelmismosignodelprimeroperando.
Portanto,lacondición
a=((alb)*b)+(a%b)
siempresesatisface,sintener encuentalossignosdelosvaloresrepresentados pora yb.
Losprogramadoressinexperienciadebentenercuidadoconelusode laoperaciónderesto
cuandounodelosoperandosesnegativo.
Engeneralesmejorevitarsituacionescomoésta.
EJEMPLO3.2. Supongamosquea y bsonvariablesenterascuyosvalores son11y
-3,respectiva­
mente.Acontinuación
semuestranvariasexpresionesaritméticas enlasqueaparecenestasvariables,
acompañadas
delosresultados.
ExpresiÓn Valor
a+b 8
a
-b 14
a*b -33
a/b -3
a%b 2
Siselehaasignadoa a unvalorde-11y a b3,entonces elvalordea / baúnseria-3,peroel
valordea%bseria-2.Análogamente,sia y btienenasignadosvaloresnegativos(-11y-3,respec­
tivamente),entonceselvalor
dea / bseria3 yelvalor dea%bseria
-2.
Observe
quelacondición
a=((a/b)*b)+la%b)
sesatisfaceencada unodeloscasosanteriores.Lamayoria delasversionesdeedeterminaránelsigno
delrestodeestaforma,aunqueestepuntoestásinespecificarenladefiniciónformaldellengnaje.
EJEMPLO3.3. Acontinuaciónsepresentanlosresultadosobtenidosconoperandosencomaflotante
condiferentessignos.Supongamos
quer1yr2sonvariablesencomaflotantecuyosvaloresasignados
son
-O•66Y4 . 5o.Acontinuaciónsemuestranvariasexpresionesaritméticasenlas queaparecenestas
variables,acompañadas
delos
r~sultados.
ExpresiÓn
r1+r2
r1-r2
r1*r2
r1/r2
3.84
-5.16
-2.97
-0.1466.67
Losoperandosquedifiereneneltipopuedensufrirunaconversióndetipoantesdequela
expresiónalcance
suvalorfinal.Engeneral,elresultadofinalseexpresará con
lamayorpreci­
siónposible,deformaconsistente
conlostiposdedatosdelosoperandos.Sepuedenaplicarlas
reglassiguientescuandoningunodelosoperandoses
unsign<=d.

62 PROGRAMACiÓN ENC
1.Silosdosoperandossontipos encomaflotanteconprecisióndistinta (porejemploun
float yundouble),eloperandode menorprecisiónsetransformaráa laprecisióndel
otrooperandoyelresultadoseexpresará
conestamayorprecisión. Portanto,unaopera­
ciónentreunfloatyundoubledarácomoresultado undouble;entreunfloaty
unlongdoubledarálugara unlongdouble;yentreunlongdoubleyun
doubleseproduciráun longdouble.(Nota:enalgunasversionesde e,todoslos
operandosdetipo
floatseconviertenautomáticamente endouble).
2.Siunoperandoes untipoen
comaflotante(porejemplo float,doubleolongdou­
ble)yelotroes uncharounint(incluyendoshortintylongint),elchar
ointseconvertiránaltipo encomaflotantedelotrooperandoy elresultadoseexpresa­
rádeigualforma.
Portanto,unaoperaciónentreunintyundoubletendrácomo
resultadoundouble.
3.Si ningunodelosoperandoses deltipoencomaflotanteperounoesunlong
int,elotrosetransformará enlongintyelresultadoserálongint.Porconsi­
guiente,
unaoperaciónentre unlongintyuninttendrácomoresultado unlong
int.
4.Siningúnoperandoesdel tipoencomaflotanteni longint,ambosoperandosse
convertiránen
int(siesnecesario)yelresultadoserá int.Asíunaoperaciónentre un
shortintyuninttendrácomoresultadounint.
Puedeencontrarunarelaciónmásdetalladadeestasreglas enelApéndiceD.Tambiénapa­
recenlasconversionesqueinvolucranoperandos unsigned.
EJEMPLO3.4.Supongamos queiesunavariableenteracuyovalores 7,funavariableencoma
flotantecuyovalor
es5 . 5 Yeunavariable detipocarácterquerepresenta elcarácterw.Acontinuación
semuestranvariasexpresiones enlasqueaparecenestasvariables.Encadaexpresiónaparecen dosope­
randos
detiposdiferentes.Sesuponeque seutilizaelconjuntodecaracteresASCII.
Expresión Valor Tipo
i+f 12.5 dobleprecisión
i+e 126 entero
i+e-' O' 78 entero
(i+e)-(2*f!5 ) 123.8 dobleprecisión
Observequela
wsecodificacomo 119(endecimal)y elOcomo48enelconjuntodecaracteres
ASCn,como
semuestraenlaTabla2.1.
Sisedesea,sepuedeconvertir elvalor.resultantede unaexpresióna untipodedatosdife­
rente.
Parahaceresto,laexpresióndebe irprecedidaporelnombredeltipodedatosdeseado,
encerrado
conparéntesis,estoes
(tipodedatos)expresión
Estetipodeconstrucciónsedenomina.conversióndetipos (<<cast»).

OPERADORES YEXPRESIONES 63
EJEMPLO3.5.
Supongamosqueiesunavariableentera cuyovalores7yfunavariableencoma
flotanteconvalorasignado8 . 5.Laexpresión
(i+f)%4
noesválida,porqueelprimeroperando (i+f)esencomaflotanteenvezdeentero.Sinembargo,la
expresión
((int)(i+f))%4
hacequeelprimeroperando setransformeenenteroyportanto esválida,obteniéndose comorestodela
divisiónentera3.
Observe
quelaespecificaciónexplícita detiposeaplicasóloalprimeroperando,noatodalaexpre­
sión.
Eltipo
dedatosasociadoalaexpresión ensínoescambiado porun«cast».Esel valordela
expresiónelquesufre
laconversióndetipocuandoapareceel«cast».Estotieneespecialrele­
vanciacuandolaexpresiónconstadeunasolavariable.
EJEMPLO3.6. Supongamosquefesunavariableencomaflotantecuyovalores5 .5.Laexpresión
((int)f)%2
contienedosoperandosenterosyportanto esválida,dandocomoresultadoelrestoentero1.Sinembargo,
observe
quefsiguesiendounavariable encomaflotanteconunvalor de5.5,aunqueelvalor def
seconvirtieseenunentero(5)alefectuarlaoperacióndelresto.
Losoperadoresde
eseagrupanjerárquicamentedeacuerdoconsu precedencia(suordende
evaluación).Lasoperacionesconmayorprecedenciaseefectúanantesquelasquetienenmenor
precedencia.Sinembargo,sepuedealterarelordennaturaldeevaluaciónmedianteelusode
paréntesis,comosemuestraenelEjemplo
3.5.
Entrelosoperadoresaritméticos, *,/Y%seencuentrandentrodeunmismogrupodeprece­
dencia,
y+y -seencuentranenotro.Elprimer grupotienemayorprecedenciaqueelsegundo.
Portanto,lasoperacionesdemultiplicación,divisiónyrestoseefectuaránantesquelasdesuma
yresta.
Otraconsideraciónimportanteatener
encuentaesel ordenenqueseefectuaránoperaciones
consecutivasdentrodelmismogrupodeprecedencia.Esto
seconocecomo asociatividad.Den­
trodecadaunode
losgruposdeprecedenciadescritoanteriormente, laasociatividadeSdeiz­
quierdaaderecha.
Enotraspalabras,operacionesconsecutivasdesumayrestaseefectúande
izquierdaaderecha,asícomooperacionesconsecutivasdemultiplicación,divisiónyresto.
EJEMPLO3.7. Laexpresiónaritmética
a -b /e*d
esequivalentealafórmulaalgebraicaa
-[(b/e )xd].Portanto,si lasvariablesencomaflotantea,
b,e y dtienenasignados losvalores1 . , 2.,3.Y4 . ,respectivamente,laexpresióntendríacomovalor
-1.666666...,yaque

64 PROGRAMACiÓN ENC
1.-[(2./3.)x4.]=1.-[0.666666...x4.]=1.-2.666666...=-1.666666...
Observequeseefectúaenprimer Jugarladivisión,yaqueestaoperacióntieneunaprecedencia mayor
quelaresta.Elcocienteresultante semultiplicapor4 . , acausa delaasociatividaddeizquierdaaderecha.
Entonces
serestaelproductoal,obteniendoelvalorfinal de-1.666666...
Laprecedencianaturaldelasoperacionesse puedealterarmedianteelusodeparéntesis,
permitiendoéstosquesepuedanefectuaroperacionesaritméticasdeunaexpresión
enelorden
quesedesee.Dehecho,sepueden
anidarlosparéntesis,esdecir, unpardentrodeotro.Enestos
casosseefectúanprimerolasoperacionesmásinternas.
EJEMPLO3.8. Laexpresiónaritmética
(a-b)/(e*d)
esequivalenteala fórmulaalgebraica
Ca-b)/(exd).Portanto,silasvariablesencomaflotantea,
b,e y dtienenasignadoslosvalores1 . , 2 .,3 . Y 4 . ,respectivamente,laexpresióntendrá comovalor
-0.08333333...,yaque
(1.-2.)/(3.x4.)=-1./12.=-0.08333333...
Compáreseesteresultadocon elobtenidoenelEjemplo 3.7.
Avecesesunabuenaideautilizarparéntesisparahacermásclarauna expresión,aunqueno
seannecesarios.
Porotraparte,sedebenevitar en10posibleexpresionessobrecargadascomo
lasdelsiguienteejemplo.Expresionescomoéstasondificilesdeleer,
yamenudoseescribende
formaincorrecta
porlosparéntesisnoemparejados.
EJEMPLO3.9. Consideremoslaexpresiónaritmética
2*((i%5)*(4+(j-3)/(k+2)))
dondei,jy ksonvariablesenteras. Siselesasignaaestasvariables losvalores8, 15Y4,respectiva­
mente,laexpresiónanterior
seevaluaríacomosigue:
2x((8%5)x(4+(15-3)/(4+2)))=2x(3x(4+(12/6)))=
2x(3x(4+2))=2x(3x6)=2x18=36
Supongamosqueseleasignaelvalordeestaexpresiónalavariableentera w,estoes,
w=2*(Ci%5)*(4+(j -3)/(k+2)));
Esmejor,pornormageneral,fragmentarestalargaexpresiónaritmética.envariasexpresiones máscortas,
como
ti=i% 5 ;
v=4+(j-3 )/(k+2);
w=2*
(ti*
v);

OPERADORES YEXPRESIONES 65
dondetiYvsonvariablesenteras. Esmásdificilcometererrores enlaescrituradeestasexpresiones
equivalentes
queenlalargaexpresiónoriginal.
Lasexpresionesdeasignaciónsetrataráncondetalleenlasección3.4.
3.2.OPERADORES UNARIOS
eincluyeunaclasedeoperadores "queactúansobre unsolooperandoparaproducir unnuevo
valor.Estosoperadoressedenominan
operadoresunarios omonarios.Losoperadoresunarios
suelenprecederasuúnicooperando,aunquealgunosoperadoresunariosseescribendetrásde
suoperando.
Esprobablequeeloperadorunariodeusomásfrecuenteseael
menosunario, queconsiste
enunsignomenosdelantedeunaconstantenumérica, unavariableounaexpresión.(Algunos
lenguajesdeprogramaciónpermitenqueseincluyaelsignomenoscomopartedeunaconstante
numérica.Sinembargo,
enetodaslasconstantesnuméricassonpositivas.Portanto, unnúmero
negativoesenrealidadunaexpresión,queconsisteeneloperadorunariomenos,seguidode
una
constantenuméricapositiva.)
Adviértasequelaoperaciónmenosunariaesdistintadeloperadoraritméticoquerepresenta
laresta(-).Eloperadorrestarequieredosoperandos.
EJEMPLO3.10. Heaquívariosejemplos queilustranelusodelaoperaciónmenosunaria.
-743
-raizl
-OX7FFF
-(x+y)
-0.2
-3*(x+y)
-5E-S
Encadacaso,elsignomenos esseguidoporunoperandonumérico quepuedeserunaconstante entera,
unaconstante
encomaflotante,unavariablenuméricaounaexpresiónaritmética.
Otrosdosoperadoresunariosdeusofrecuentesonel
operadorincremento, ++,yelopera­
dordecremento,-
-.Eloperadorincrementohaceque suoperandoseincremente enuno,mien­
trasqueeloperadordecrementohacequesuoperandosedecremente
enuno.Eloperandoutili­
zadoconcadaunodeestosoperadoresdebeserunavariablesimple.
EJEMPLO3.11. Supongamosqueiesunavariableentera quetieneasignadoelvalor5.Laexpresión
++i,queesequivalenteaescribir i
=i +1,hacequeelvalordeisea6.Análogamentelaexpresión
--i,queesequivalentea i=i -1,hacequeelvalor(partiendodeloriginal)deipasea ser4.
Losoperadoresincrementoydecrementosepuedenutilizar,cadaunodeellos,dedosfor­
masdistintas,dependiendodesiel.operadorseescribedelanteodetrásdeloperando.Sielopee
radorprecedealoperando(porejemplo ++í),elvalordeloperandosemodificará antesdeque
seutilice
conotropropósito.Sinembargo,sieloperador siguealoperando(porejemplo í++),
entonceselvalordeloperandosemodificará despuésdeserutilizado.
EJEMPLO3.12. Unprogramaeneincluyeunavariableentera i,cuyovaloriniciales1.Supongamos
queelprogramaincluye lastressiguientesinstrucciones printf.(Paraunabreveexplicación delains­
trucción
printf,véaseelEjemplo1.6.)

66 PROGRAMACIÓN ENC
printf("i=
printf("i=
printf("i
%d n,
%d" /
%d",
i);
++i);
i);
Estasinstruccionesprintfgeneraránlastreslíneassiguientes.(Cadainstrucción printfgenerauna
línea.)
i=1
i=2
i=2
Laprimerainstrucciónhacequesevisualice elvalororiginalde i.Lasegundainstrucciónincrementa iy
presentadespuéssuvalor.Laúltimainstrucciónvisualiza
elvalorfinal
dei.
Supongamosahora queelprogramaincluyelastressiguientesinstrucciones printf,enlugardelas
tresdadasanteriormente.
printf("i=%d 11Ii);
printf("i=%d
n,i++);
printf("i=%d
ll
/i);
Observequelaprimeraytercerainstrucciónsonidénticasalasmostradasanteriormente.Sinembargo,en
lasegundainstruccióneloperadorunariosiguealavariableenteraenlugardeprecederla.
Estasinstruccionesgeneraránlastreslíneassiguientes.
i=1
i=1
i=2
Laprimerainstrucciónhace quesevisualiceelvalororiginalde icomoen elcasoanterior.Lasegunda
instrucciónhacequesevisualiceelvaloractualde
i(1)Ydespuésloincrementa(a2). Laúltima
instrucciónvisualizaelvalorfinalde
i (2 ) .
Hablaremosllmchomásdelusodelainstrucción
printfenelCapitulo4.Porahora,fijémonos
simplementeenladiferenciaentrelaexpresión.
+ +ienelprimergrupode.instruccionesylaexpresión
i++enelsegundogrupo.
Otrooperadorunarioquemerecesercitadoahoraeseloperadorsizeof.Esteoperador
devuelveeltamañodesuoperandoenbytes.Eloperadorsizeofsiempreprecedeasuoperan­
do.Eloperandopuedeserunaexpresiónopuedeserun«cast».
Enprogramassencillosnosesueleutilizaresteoperador.Sinembargo,esteoperadorpermi­
tedeterminarelnúmerodebytesasignadosadiferentestiposdedatos.Estainformaciónpuede
sermuyútilcuandosetransfiereelprogramaaunacom.putadoradiferenteo a una
nuevaversión
deC.Tambiénseutilizaparalaasignacióndinámicadelamemoria,comoseexplicaenla
sección10.4.
EJEMPLO3.13. Supongamosque iesunavariableentera,x·unavariableencomaflotante,duna
variablededobleprecisióny eunavariabledetipocarácter.Lasinstrucciones
printf("Entero:
..%d",
printf("Comaflotante:
sizeofi);
%d
ll
,sizeofx)¡

printf("DObleprecislon:
printf("Carácter:%d",
generaríanlasiguientesalida:
Entero:2
Comaflotante:4
Dobleprecisión:8
Carácter:1
OPERADORES YEXPRESIONES 67
%d",sizeofd),
sizeofc),
VernosportantoqueestaversióndeCreserva 2bytesparacadacantidadentera,4bytesparacadacanti­
dadencomaflotante,8bytesparacadacantidaddedobleprecisióny 1byteparacadacarácter.Estos
valorespuedenvariardeunaversióndeC aotra,cornoseexplicaenlasección
2.3.
Otraforma deconseguirlamismainformaciónesutilizarun«cast»enlugardeunavariabledentro de
cadainstrucciónpr:Í.ntf.Deacuerdoconesto,podríamosescribirlasinstrucciones printfdela
formasiguiente:
printf("Entero:%d",sizeof(integer)),
printf("Comaflotante:%d",sizeof(float)),
printf("Dobleprecisión:%d",sizeof(double)),
printf("Carácter:%d",sizeof(char)),
Estasinstruccionesprintfgeneraránunasalidaigualalasanteriores.Nótesequecada«cast»está
encerradoentreparéntesis,cornosevioenlasección3.1.
Consideremosfinalmenteladeclaración
chartexto[]=I1California
ll
¡
Lainstrucción
printf("Númerodecaracteres=%d",sizeoftexto),
generarálasiguientesalida.
Númerodecaracteres=11
Portantovernosquelaformación textocontiene11caracteres,corno seexplicóenelEjemplo 2.26.
Un«cast»sepuedeconsiderartambiéncomounoperadorunario(verEjemplo3.5ylaante­
riordiscusión):Enténninosgenerales,unareferenciaaloperador«cast»seescribeasí:
(tipo).
Portanto,losoperadoresunariosquehemosvistohastaelmomentoenestelibroson -,++,--,
sizeofy(tipo).
Losoperadoresunariostienenmayorprecedenciaquelosoperadoresaritméticos.Portanto,
siunoperadorunariomenosactúasobreunaexpresiónaritméticaquecontieneunoomásope­
radoresaritméticos,laoperaciónunariamenosseefectuaráprimero(amenos,porsupuesto,que
laexpresiónaritméticaestéentreparéntesis).Laasociatividad
delosoperadoresunariosestam­
bién
deizquierdaaderecha,aunqueesraroqueaparezcanenprogramassencillosoperadores
unariosconsecutivos.

68 PROGRAMACiÓN ENC
EJEMPLO3.14. Supongamosquex eysonvariablesenterasconvaloresasignados de10Y 2O,
respectivamente.Elvalordelaexpresión-x+yserá-10+20=-10.Observequelaoperaciónunaria
menosseefectúaantes quelasuma.
Supongamosahoraqueintroducimosparéntesis, deformatalquetenemoslaexpresión- ( 10+2 O) .
Elvalordeestaexpresiónes-(10+2O)= -3O.Notarqueahoralasumaprecedealaoperaciónunaria
menos.
eincluyeotrosoperadoresunarios.Seirántratandoenseccionesposterioresdeestelibro
segúnsevayanhaciendonecesarios.
3.3.OPERADORES RELACIONALES YLÓGICOS
Eneexistencuatro operadoresrelacionales:
Operador
<
<=
>
>=
Significado
menorque
menoroigualque
mayorque
mayoroigualque
Estosoperadoresseencuentrandentrodelmismogrupodeprecedencia,queesmenorque
la
delosoperadoresunariosyaritméticos. Laasociatividaddeestosoperadoresesdeizquierdaa
derecha.
Muyasociadosalosoperadoresrelacionales,existendos
operadoresdeigualdad:
Operador
l-.-
Significado
igualque
noigualque
Losoperadoresdeigualdadseencuentran
enotrogrupodeprecedencia,pordebajodelos
operadoresrelacionales.Laasociatividaddeestosoperadoresestambiéndeizquierdaaderecha.
Estosseisoperadoresseutilizanparaformarexpresioneslógicasquerepresentancondiciones
quepuedenserverdaderasofalsas.Laexpresiónresultanteserádetipoentero,
yaqueverdadero
esrepresentadoporelvalorentero1 y falsoporelvalor O.
EJEMPLO3.15. Supongamosquei,jYk
son.variablesenteras convaloresasignados 1,2Y3,res­
pectivamente.Acontinuación semuestranvariasexpresioneslógicas enlasqueaparecenestasvariables.
Expresión Interpretación Valor
i<j verdadero 1
(i+j )>;:;;:k verdadero 1
( j+k)>(i+5) falso O
k!=3 falso O
j 2 verdadero 1

OPERADORES YEXPRESIONES 69
Cuandoseefectúanoperacionesrelacionales ydeigualdad,silosoperandossondediferente
tipo,seconvertirándeacuerdoconlasreglascitadas
enlasección3.1.
EJEMPLO3.16. Supongamosqueiesunavariableenteracuyovalor es7,fesunavariableencoma
flotante
cuyovalores5 . 5Yeesunavariabledecarácterquerepresentaelcarácter
'w'.Acontinuación
semuestranvariasexpresioneslógicas quehacenusodeestasvariables.Encadaexpresiónaparecen dos
tiposdiferentesdeoperandos.(SesuponequeseutilizaelconjuntodecaracteresASCn.)
EXPresión Interpretación Valor
f>5 verdadero 1
( i+f)<=10 falso O
e--119 verdadero 1
e!='p' verdadero 1
e>=10*(i+f) falso O
Ademásdelosoperadoresrelacionales ydeigualdad,Cposeedos operadoreslógicos (de­
nominadostambién
conectivaslógicas). Estosson:
Operador
&&
1 I
Significado
y
o
Estosoperadoressedenominan ylógicayológica,respectivamente.
Losoperadoreslógicosactúansobreoperandosquesona
suvezexpresioneslógicas.Permi­
tencombinarexpresioneslógicasindividuales,formandootrascondicioneslógicasmáscompli­
cadasquepuedenserverdaderasofalsas.Elresultadode
unaoperaciónylógicaseráverdadero
sólosilosdosoperandossonverdaderos,mientrasqueelresultadodeunaoperación
ológica
seráverdaderosialgunodelosdosoperandosesverdaderooambosa lavez.Enotraspalabras,
elresultadodeunaoperación
ológicaseráfalsosólosilosdosoperandossonfalsos.
Enestecontexto,cualquiervalornonulo,nosóloel 1,seinterpretarácomoverdadero.
EJEMPLO3.17. Supongamosqueiesunavariableenteracuyovalor es7,funavariableencoma
flotante
cuyovalores5 . 5 Yeunavariable decarácterquerepresentaelcarácter
'w'.Acontinuaciónse
muestranvariasexpresioneslógicascomplejas enlasqueaparecenestasvariables.
Expresión Interpretación Valor
(i>=6 )&&(e--'w
/
)
verdadero 1
(i>=6 )
11
(e--119) verdadero 1
(f<11)&&(i>100) falso O
(e!='p')
11
((i+f)<=10) verdadero 1
Laprimeraexpresión esverdaderaporque losdosoperandossonverdaderos. Enlasegundaexpresión,
losdosoperandostambiénsonverdaderos,portantotodalaexpresión esverdadera.Laterceraexpresión
esfalsaporqueelsegundooperando esfalso.Y,finalmente,lacuartaexpresión esverdaderaporque el
primeroperando esverdadero.

70 PROGRAMACiÓN ENC
Cadaunodelosoperadoreslógicospertenecea supropiogrupodeprecedencia. Laylógica
tienemayorprecedenciaquelaológica.Losdosgruposdeprecedenciaseencuentranpordeba­
jodelgrupoquecontienelosoperadoresdeigualdad. Laasociatividadesdeizquierdaadere­
cha.Másadelanteserelacionanlosgruposdeprecedencia.
Ctambiénincluyeeloperadorunario
!,queniegaelvalordeunaexpresiónlógica;esdecir,
hacequeunaexpresiónqueeraoriginalmenteverdaderasehagafalsayviceversa.Esteopera­
dorsedenominaoperadordenegaciónlógica( onológico).
EJEMPLO3.18. Supongamosqueiesunavariableentera convalor7yfesunavariableencoma
flotanteconvalor5 .5.Acontinuaciónsemuestranvariasexpresioneslógicas enlasqueaparecenestas
variables
yeloperadordenegaciónlógica.
Expresión
f>5
!(f>5)
i<=3
!(i<=3)
i>(f+1)
!(i>(f+1))
Interpretación
verdadero
falso
falso
verdadero
verdadero
falso
I
O
O
I
I
O
Enpróximoscapítulosdeestelibroveremosotrosejemplosenlosqueapareceeloperador
denegaciónlógica.
Lajerarquíadeprecedenciadeoperadoresqueabarcatodoslosoperadoresdiscutidoshasta
ahorasevahaciendocadavezmásextensa.AcOl.tinuaciÓnsemuestraunarelacióndelaspre­
cedenciasdelosoperadores,demayoramenor.
Categoríadeoperador Operadores Asociatividad
operadoresunarios
-++--!sizeof(tipo) D
---7I
multiplicación,divisiónyresto
aritméticos
*/% I
---7D
sumayrestaaritméticas +- I---7D
operadoresrelacionales <<=>>= I---7D
operadoresdeigualdad --!= I---7D
Ylógica && I---7D
ológica
11
I---7D
Másadelantesemuestraunalistamáscompleta enlaTabla3.1.
EJEMPLO3.19. Consideremosdenuevolasvariablesi;fYe,comosehandescritoenlosEjem­
plos3.16
y3.17;esdecir,i=7,f=5.5Yc='w'.Acontinuaciónsemuestranvariasexpresioneslógicas
quehacenusodeestasvariables.
Expresión Interpretación.Valor
i+f
<=10 falso O
i>=6&&e--'w' verdadero I
e!='p'II
i+f<=10 verdadero I

OPERADORES YEXPRESIONES 71
Cadaunadeestasexpresiones sehapresentadoyaantes(laprimeraenelEjemplo3.16ylasotrasdosen
elEjemplo3.17), aunque
sehabíanincluidoparéntesisenlosejemplosanteriores.Losparéntesisnoson
necesariosacausa
delasprecedenciaspropias delosoperadores.Porconsiguiente,lasoperacionesarit­
méticas
seefectuaránautomáticamenteantesquelasoperacionesrelacionalesodeigualdad,ylasopera­
cionesrelacionalesydeigualdad
seefectuaránautomáticamenteantesquelasconectivaslógicas.
Consideremoslaúltimaexpresiónenparticular.Laprimeraoperaciónque
seefectuaráserálasuma
( i+f ) ;despuéslacomparaciónrelacional (i+f<=10);despuéslacomparación deigualdad
(c!='p, ) , yfinalmentelacondición ológica.
Lasexpresioneslógicascompuestasqueconstandeexpresioneslógicasindividuales unidas
porlosoperadoreslógicos & &YIIseevalúandeizquierdaaderecha,perosólohastaqueseha
establecidoelvalorverdadero/falsodelconjunto.Portanto,unaexpresiónlógicacompuestano
seevaluarácompletamentesisuvalorsepuedeestablecerapartirdelaevaluacióndealgunosde
susoperandos.
EJEMPLO3.20. Consideremos laexpresiónlógicacompuestaque semuestraacontinuación.
error>.0001&&cont<100
Sierror> .OOO1esfalso,entonceselsegundooperando (cont<100)noseevaluará,yaquela
expresiónenteratendráquesernecesariamentefalsa.
Porotraparte,supongamosquehemosescritolaexpresión
error>.0001IIcont<100
Sierror> .OOO1esverdadero,entonceslaexpresióncompleta seráverdadera.Portanto,nose
evaluaráelsegundooperando.Sinembargo,si
error> .OOO1esfalsoentonces,lasegundaexpresión
(cont<100)debeserevaluadaparadeterminarsitodalaexpresiónesverdaderaofalsa.
3.4.OPERADORES DEASIGNACIÓN
ExistenvariosoperadoresdeasignaciónenC.Todosseutilizanparaformarexpresionesde
asignación,enlasqueseasignaelvalordeuriaexpresiónaunidentificador.
Eloperadordeasignaciónmásusadoes=.Lasexpresionesdeasignaciónqueutilizaneste
operadorseescribendelasiguienteforma:
identificador=expresión
dondeidentificadorrepresentageneralmenteunavariableyexpresiónunaconstante,
unavariableo unaexpresiónmáscompleja.
EJEMPLO3.21. Heaquíalgunasexpresionesdeasignaciónquehacenusodeloperador =.
a=3
x=y
delta=0.001
suma=a+b
area=longitud*anchura

72 PROGRAMACiÓN ENC
Laprimeraexpresión deasignaciónhacequeseleasignea lavariablea elvalor3 ylasegunda
asignación
hacequeseleasigueelvalordeyax.Enlaterceraasignación, elvalorencomaflotante
O. OO
1seleasignaadeltaoEnlasdosúltimasasignacionesseleasignaaunavariableelresultadode
unaexpresión(elvalordea+bseleasignaa sumayelvalordelongitud*anchuraaarea).
Recuerdequeel operadordeasignación=yeloperadordeigualdad==sondistintos.El
operadordeasignaciónseutilizaparaasignarunvaloraunidentificador,mientrasqueelopera­
dordeigualdadseusaparadeterminarsidosexpresionestienenelmismovalor.Nosepueden
utilizarestosoperadores
deformaindistinta.Esfrecuentequealgunosprogramadores,cuando
estánaprendiendo,utilicen
deformaincorrecta eloperadordeasignacióncuandoquierencom­
probarunaigualdad.Elresultadodeesto
esunerrorlógicoquesueleserdifícildedetectar.
Lasexpresionesdeasignaciónsesuelenllamar
instruccionesdeasignación,yaquesesuelen
escribircomoinstruccionescompletas.Sinembargo,tambiénsepuedenescribirexpresionesde
asignacióncomoexpresionesqueestánincluidasdentrodeotrasinstrucciones(veremosmás
sobreestoenpróximoscapitulos).
Silosdosoperandosdeunaexpresión
deasignaciónsondetipo dedatosdiferentes,elvalor
delaexpresióndeladerecha(eloperando
deladerecha)seconvertiráautomáticamentealtipo
delidentificador
delaizquierda.Deestaforma,todalaexpresióndeasignaciónserádelmismo
tipo
dedatos.
Endeterminadoscasos,estaconversiónautomáticadetipopuedeconllevara
unaalteración
deldatoqueseestáasignando.Porejemplo:
•Unvalorencomaflotantepuedesertruncado
siseasignaaunidentificadorentero.
•Unvalordedobleprecisiónpuedeserredondeadosiseasignaaunidentificadorencoma
flotante(desimpleprecisión).
•Unacantidadenterapuedeseralteradasiesasignadaaunidentificador
deunenteromás
cortoo aunidentificador
decarácter(sepuedenperderalgunos delosbitsmássignifica­
tivos).
Además,cuandoseasigneaunidentificador
detiponuméricoelvalordeunaconstante deca­
rácter,estevalordependerádelconjuntodecaracteresqueseestéutilizando.Deestopueden
resultarinconsistenciasentredistintasversionesde
C.
Elusodescuidadodeconversiones detipoesunafuentedeerroresfrecuenteentrelospro­
gramadoresnoveles.
EJEMPLO3.22. Enlassiguientesexpresiones deasignación,supongamosqueiesunavariablede
tipoentero.
Expresión Valor
i=3.3 3
i=3.9 3
i=-3.9
-3
Supongamosahoraqueiyjsonvariablesdetipoenteroyqueajselehaasignadoelvalor5.
Mostramosacontinuaciónvariasexpresionesquehacenusodeestasdosvariables.

OPERADORES YEXPRESIONES 73
Expresión
i j
i=j
!2
i= 2*
j!2
i= 2*
( j!2)
5
2
5(asociatividaddeizquierdaaderecha)
4(divisióntruncada,seguida
demultiplicación)
Finalmente,supongamosque
iesunavariable detipoenteroyqueestamosutilizandoelconjunto de
caracteresAscn.
ExpresiÓn Valor
i='x' 120
i=
'O' 48
i= ('x/ IO' )!3 24
i= ('y'
, OI)
!3 24
Eneestánpermitidasasignacionesmúltiplesde laforma
identificador1=identificador2=...=expresión
Enestoscasos,lasasignacionesseefectúande derechaaizquierda.Portanto,laasignación
múltiple
identificador1=identificador2=expresión
esequivalentea
identificador1=(identificador2=expresión)
yasísucesivamenteconanidacionesdederechaaizquierda paraasignacionesmúltiples.
EJEMPLO3.23. Supongamosque iyjsonvariablesenteras.Laexpresión deasignaciónmúltiple
i=j=5
haráqueaiyjselesasigneelvalorentero5.(Parasermásexactos,primero seleasigna5 a jydespués
seleasignaelvalorde jai.)
Análogamente,laexpresióndeasignaciónmúltiple
i=j=5.9
haráquea iyjselesasigneelvalorentero5.Recordarquecuandose leasignaalavariableentera jel
valorencomaflotante5 .9,ésteestruncado.
eposee,además,loscincosiguientesoperadoresdeasignación: +=,-=,*=,/=Y%=.Para
vercómoseutilizan, consideremoselprimeroperador,+=.Laexpresióndeasignación
expresión1+=expresión2

74 PROGRAMACiÓN ENC
esequivalentea
expresión1=expresión1+expresión2
Deformaanáloga,laexpresión deasignación
expresión1-=expresión2
esequivalentea
expresión1=expresión1 -expresión2
ydeigualformaparaloscincooperadores.
Normalmente,
expresión1esunidentificadortalcomounavariableounelemento de
unaformación.
EJEMPLO3.24. Supongamosqueiyjsonvariablesenterasconvaloresasignadosde5y7,YfYg
variablesencomaflotanteconvalores5 . 5Y-3 .25.Acontinuaciónsemuestranvariasexpresionesde
asignaciónquehacenusodeestasvariables.Cadaexpresiónutiliza losvaloresoriginalesdei,j,fYg.
Expresión Expresiónequivalente Valorfinal
i+=5 i=i+5 10
f-=g f=f-g 8.75
j*=(i-3 ) j=j*(i-3 ) 14
f/=3 f=f/3 1.833333
i%=( j-2 ) i=i%( j-2 ) O
Losoperadoresdeasignacióntienenmenorprecedenciaqueelrestodelosoperadoresque
hemosdiscutidoanteriormente.Portanto,las
oper!lcionesunarias,aritméticas,relacionales, de
igualdadylógicasseefectúanantesquelasoperaciones deasignación.Además,lasoperaciones
deasignacióntienenasociatividaddederechaaizquierda.
Lajerarquíadeoperadores,atendiendoasuprecedencia,quepresentamosenlaúltimasec­
ción,sepuedemodificarcomosigueparaincluirlosoperadores
deasignación.Categoríadeoperador
operadoresunarios
multiplicación,división
yresto
aritméticos
suma
yrestaaritméticas
operadoresrelacionales
operadoresdeigualdad
ylógica
ológica
operadoresdeasignación
Operadores Asociat/v/dad
-++--!sizeof(tipo) D
~1
*/% 1~D
+- 1~D
<<=>>= 1~D
--!= 1~D
&& 1~D
II
1~D
=+=-=*.=/=%= D~1
LaTabla3.1contieneunalistacompleta.

OPERADORES YEXPRESIONES 75
EJEMPLO3.25.Supongamosque
x,yyzsonvariablesenterasquetienenasignadoslosvalores2,3
Y
4,respectivamente.Laexpresión
x*=
-2*(y+z)/3
esequivalentealaexpresión
x=x*(-2*(y+z)/3)
Ambasexpresionesharánqueseleasignea x elvalor-8.
Consideremoselordenenelqueseefectúanlasoperacionesenlaprimeraexpresión.Lasoperaciones
aritméticasprecedenalainstruccióndeasignación.Portantoseevaluaráprimerolaexpresión
(y+Z )
conunresultadode7.Despuéselvalordeestaexpresiónsemultiplicarápor
-2,obteniéndose-14.Este
productosedividiráacontinuaciónpor3
yserátmocado,conloqueresulta
-4.Finalmenteestecociente
truncado
semultiplicaporelvalororiginaldex (2),conloqueseobtieneelresultadofinal
-8.
Observequetodaslasoperacionesaritméticasexplícitasseefectúanantes
dequeserealicenlamulti­
plicaciónfinal
ylaasignación.
Cposeeotrosoperadoresdeasignaciónademás delosquehemosdescrito.Lostrataremosen
elCapítulo
13.
3.5.ELOPERADOR CONDICIONAL
Sepuedenefectuaroperacionescondicionalessimplesconel operadorcondicional (?:).Una
expresiónquehaceusodeloperadorcondicionalsedenomina
expresióncondicional. Sepuede
escribirunainstruccióndeestetipoenlugar
delainstrucciónmástradicional if-else,quese
trataráenelCapítulo6.
.Unaexpresióncondicionalseescribedelaformasiguiente:
expresión1?expresión2 :expresión3
Cuandoseevalúaunaexpresióncondicional, expresión1esevaluadaprimero.Siex­
presión1esverdadera(si,suvaloresnonulo),entonces expresión2esevaluadayéste
eselvalordelaexpresióncondicional.Sinembargo,si
expresión1esfalsa(sisuvalores
cero),entoncesseevalúa
expresión3yésteeselvalordelaexpresióncondicional.Nótese
quesóloseevalúaunadelas.expresiones
(expresión2 oexpresión3)cuandosedeter­
minaelvalordeunaexpresióncondicional.
EJEMPLO3.26.Enlaexpresióncondicionalquesemuestraacontinuación,supongamosque ies
unavariableentera.
(i<O)?O :100
Seevalúaprimerolaexpresión (i<O).Siesverdadera(siel valordeiesmenorque O),elvalorde
todalaexpresióncondicionales
O.Encualquierotrocaso(sielvalorde inoesmenorque O),elvalorde
todalaexpresióncondicionales
10O.

76 PROGRAMACiÓN ENC
Supongamosque fygsonvariablesencomaflotanteenlasiguienteexpresióncondicional.
(f<g)?f :g
Estaexpresióncondicionaltomaelvalor defsifesmenorqueg; deotraforma,laexpresióncondi­
cionaltomaelvalor
deg.Enotraspalabras,laexpresióncondicionaldevuelveelvalor delamenordelas
dosvariables.
Si losoperandos
(expresión2yexpresión3)sondetiposdiferentes, eltipodedatos
delaexpresióncondicional sedetenninarádeacuerdoconlasreglasdadas enlasección3.1.
EJEMPLO3.27. Supongamosahoraque iesunavariableentera yquefygsonvariablesencoma
flotante.Enlaexpresióncondicional
(f<g)?i :f
aparecenoperandos detipoenteroyencomaflotante.Eltipo dedatodelaexpresióncondicionalseráen
comaflotante,auncuandoseseleccioneelvalor
deicomovalordelaexpresión(porlaregla2dela
sección3.1).
Lasexpresionescondicionalessuelenaparecerenlapartederechadeunainstrucciónde
asignaciónsimple.Sele asignaalidentificadorde laizquierdaelvalorresultantedelaexpresión
condicional.
EJEMPLO3.28. Lasiguienteesunainstruccióndeasignaciónquecontieneunaexpresióncondicional
enlaparte
deladerecha.
indicador=(i<O)?O :100
Sielvalor deiesnegativo,seleasignaráa indicadorelvalorO.Siinoesnegativo,se le
asignaráa indicadorelvalor100.
Lasiguienteesotrainstrucción deasignaciónquecontieneunaexpresióncondicionalenlaparte
derecha.
min=(f<g)?f : g
Estainstrucciónhacequese leasignea minelmenorvalor defyg.
Eloperadorcondicionaltienesupropiaprecedencia,justamentesuperioralosoperadores de
asignación.Laasociatividadesdederechaaizquierda.
LaTabla3.1resumelasprecedenciasdetodoslos operadorestratadosenestecapítulo.
EnelApéndiceCsepresentaunalistacompletadetodoslosoperadoresdeC,lacuales más
ampliaquelamostradaenlaTabla3.1.
EJEMPLO3.29. Enlasiguienteinstrucción deasignación,a,bycsesuponenvariablesenteras.Enla
instrucciónaparecenoperadoresdeseisgrupos
deprecedenciadistintos.
C+=(a>O&&a<=10)?++a:a/b;
Lainstruccióncomienzaporlaevaluación delaexpresióncompuesta
(a>O&&a<=10)

OPERADORES YEXPRESIONES 77
Tabla3.1.Gruposdeprecedenciade operadores
operadoresunarios -++--!sizeof(tipo) D---7I
multiplicación,división
yrestoaritméticos *I% I---7D
sumayrestaaritméticas +- I---7D
operadoresrelacionales <<=>>= I---7D
operadoresdeigualdad --1= I---7D
Ylógica && I---7D
ológica
1I
I---7D
operadorcondicional ? : D---7I
operadoresdeasignacióu =+==*=1=%= D---7I
Siestaexpresiónescierta,seevalúalaexpresión++a.Sinoesasí,seevalúalaexpresióna/b.
Finalmenteseefectúalaoperacióndeasignación(+= ) ,haciendoqueseincrementee enelvalordela
expresióncondicional.
Si,porejemplo,a,byetienenlosvalores1,2 Y3,respectivamente,entonces elvalordelaexpresión
condicional
será2(porqueseráevaluadalaexpresión++a)yacseleasignaráelvalor5 (e=3+2).
Porotrolado, silosvaloresdea,byefuesen5O,10Y 2O,respectivamente,entonces elvalor
delaexpresióncondicionalsería5 (porqueseevaluaríalaexpresiónalb)Yelvalordeepasaríaaser
25(c=20+5).
3.6.FUNCIONESDEBIBLIOTECA
Ellenguajeeseacompañadeunciertonúmerode funcionesdebiblioteca querealizanvarias
operacionesycálculosdeusofrecuente.Estasfuncionesdebibliotecanosonpartedellenguaje
ensí,perolasincluyentodaslasimplementacionesdellenguajc.Algunasfuncionesdevuelven
undatoen sullamada;otrasindicancuándounadeterminadacondiciónesverdaderaofalsa,
devolviendounvalorde1 o
O,respectivamente;yotrasefectúanoperacionesespecificassobre
losdatosynodevuelvennada.Suelenexistirfuncionesdebibliotecaparaefectuarlasoperacio­
nesquesondependientesdelacomputadora.
Porejemplo,hayfuncionesdebibliotecaqueefectúanlasoperacionesestándar
deentrada!
salida(leeryescribircaracteres,leeryescribirnúmeros,abrirycerrararchivos,comprobarla
condicióndefindearchivo,etc.),funciones
.qUYrealizanoperacionessobrecaracteres(conver­
tirminúsculasenmayúsculas,determinarsiuncarácteresunaletramayúscula,etc.),funciones
querealizan operacionesencadenasdecaracteres(copiarunacadenadecaracteresenotra,
comparardoscadenas,concatenardoscadenas,etc.),yfuncionesquerealizandiversoscálculos
matemáticos(evaluacióndefuncionestrigonométricas,logarítmicayexponencial,cálculode
valoresabsolutos,raicescuadradas,etc.).Tambiénexistenfuncionesdebibliotecadeotrostipos.
Lasfuncionesdebibliotecadepropósitosrelacionadossesuelenencontraragrupadas
en
programasobjeto enarchivosdebibliotecaseparados.Estosarchivosdebibliotecasepropor­
cionan
comopartedecadacompiladordeC.Todosloscompiladoresde econtienenlosmis­
mosgruposdefuncionesdebiblioteca,aunquenoexisteunanormalizaciónprecisa.Portanto,

78 PROGRAMACiÓN ENC
puedeexistiralgunadiferenciaenlasfuncionesdebibliotecadisponiblesendiferentesversio­
nesdellenguaje.
Unconjuntodefuncionesdebibliotecatipicoincluiráungrannúmerodefuncionescomunes
paralamayoríadeloscompiladoresdee,talescomolasmostradasenlaTabla3.2.Enesta
tabla,lacolumna«tipo»serefierealtipodedatosdelresultadoquedevuelvelafunción.Eltipo
voidenlafunciónsrandindicaquelafunciónno devuelvenada.
Tabla3.2.Algunasfuncionesdebibliotecadeusocomún
abs(i) int
ceil(d) double
cos(d) double
cosh(d) double
exp(d) double
fabs(d) double
floor(d) double
fmod(dl,d2)double
getchar()int
log(d) double
pow(dl,d2)double
printf(...)int
putchar(c)int
rand() int
sin(d) double
sqrt(d) double
srand(u) void
scanf(...)int
tan(d) double
toascii(c)int
tolower(c)int
toupper(c)int
Devolverelvalorabsolutode i.
Redondearporexcesoalenteromáspróximo(elenteromáspequeño
queseamayoroigualad).
Devolverelcoseno
ded.
Devolverelcosenohiperbólicode
d.
elevarealapotenciad (e=2.7182818...eslabasedelsistema
logaritmiconatural(Neperiano».
Devolverelvalorabsolutoded.
Redondearpordefectoalenteromáspróximo(elenteromásgrande
quenoseamayorqued).
Devolverelrestode
di/d2(partenoenteradelcociente),conel
mismosignoque
dl.
Introduciruncarácterdesdeeldispositivo deentradaestándar.
Devolverellogaritmonaturalde
d.
Devolverdielevadoalapotencia d2.
Mandardatosaldispositivodesalidaestándar(losargumentosson
complicados;verCapitulo4).
Mandaruncarácteraldispositivodesalidaestándar.
Devolverunenteropositivoaleatorio.
Devolverel
SenOded.
devolverlaraízcuadradaded.
Inicializarelgeneradordenúmerosaleatorios.
Introducirdatosdeldispositivodeentradaestándar(losargumentos
soncomplicados;verCapítulo4).
Devolverlatangenteded.
.
ConvertirelvalordelargumentoaASCII.
Convertirunaletraaminúscula.
Convertirunaletraamayúscula.
Nota:Tiposerefierealtipo
dedatosdelresultadodevueltoporlafunción.
e
indicaargumentodetipocarácter.
iindicaargumeritodetipoentero.
d
indicaargumentodedobleprecisión.
u
indicaargumentoenterosinsigno.

OPERADORES YEXPRESIONES 79
EnelApéndiceHseincluyeunalistamáslarga,queincorporatodaslasfunciones debiblio­
tecaqueseutilizanenlosprogramasejemplopresentadosenestelibro.Paraconseguirunalista
completa,ellectordeberecurriralmanual
dereferenciadelprogramadordesuversión deC.
Seaccedeaunafuncióndebibliotecaescribiendosimplementeelnombre delafunción,
seguido
deunalistadeargumentosquerepresentaninformaciónqueselepasaalafunción.Los
argmnentossedebenencontrarencerradosentreparéntesisyseparadosporcomas.Puedenser
constantes,nombresdevariablesoexpresionesmáscomplicadas.Losparéntesisdebenestar
presentes,aunquenohayaargumentos.
Unafunciónquedevuelveundatopuedeaparecerencualquiersitiodentrodeunaexpresión,
enlugar
deunaconstanteounidentificador(unavariableounelemento deunaformación).Se
puedeaccederaunafunciónqueefectúaoperacionessobredatosperoquenodevuelveningún
valorsimplementeescribiendoelnombre
delafunción,yaqueestetipo dereferenciaauna
funciónconstituyeunainstrucción
deexpresión.
EJEMPLO3.30. Semuestraacontinuaciónunfragmentodeunprogramaen equecalculalasraíces
delaecuacióncuadrática
ax
2
+bx+c=O
utilizandolafórmula
-b±(b
2
_4ac)l/2
x=
2a
Esteprogramautilizaiafuncióndebiblioteca sqrtparaevaluarlaraizcuadrada.
main()
{
/*solucióndeunaecuacióncuadrática*/
doublealb,elraizrxl,x2¡
/*leervaloresdea,byc*/
raiz
xl
x2=
=sqrt(b*b - 4
(-b+raiz)/(2
(-b-raiz)/(2
*a*e);
*a);
*a)i
/ *escribirvaloresdea,b,c,xlyx2.* /
}
Parautilizarunafuncióndebibliotecapuedesernecesarioincluirciertainformacióndentro
delaparteprincipaldelprograma.Porejemplo,lasdeclaracionesdefuncionesydefinicionesde
constantessimbólicassuelennecesitarsecuandoseutilizanfuncionesdebiblioteca(verseccio­
nes7.3,8.5y8.6).Estainformaciónsueleencontrarsealmacenadaenciertosarchivosquese
proporcionanconelcompilador.Portanto, lainformaciónrequeridasepuedeobtenersimple­
menteaccediendoaestosarchivos.Estosellevaacabomediantelainstruccióndelpreprocesa­
dor
#include,quees
#include
<nombre~archivo>
endondenombre_archivorepresentaelnombredeundeterminadoarchivo.

SO PROGRAMACiÓN ENC
Losnombresdeestosarchivosespecialessonespecíficosdecadaimplementación deC,aun­
quehayciertosnombresdearchivoscomúnmenteusados,comos
tdio. h Yroath.h.Elsufi­
jo«h»generalmentedesignaunarchivode«cabecera»,queindicaquesedebeincluiralco­
mienzodelprograma.(Enlasección8.6sediscutenlosarchivosdecabecera.)
Nóteselasimilitudentrelainstruccióndelpreprocesador
#includeylainstruccióndel
preprocesador
#define,quesediscutióenlasección2.9.
EJEMPLO3.31.Conversióndeun carácterdeminúsculaamayúscula.Elsiguienteesunprograma
completoen
equelee unaletraminúscula,latransfonnaenmayúsculaylaescribe.
/*leerunaminúsculayescribirlamayúsculacorrespondiente*/
#include<stdio.h>
#include<ctype.h>
main()
{
intminusc,mayusc¡
minusc=getchar( ) ;
mayusc=toupper(minusc);
putchar(mayusc);
}
Enesteprogramaaparecentresfuncionesdebiblioteca: getchar,toupperyputchar.Lasdos
primerasdevuelvenunsolocarácter
(getchardevuelveuncarácterqueseintroduceporeltecladoy
toupperdevuelveelcarácterdelamayúsculacorrespondientea suargumento).Laúltimafunción
(putchar)hacequesevisualiceelvalordesuargumento.Nótesequelasdosúltimasfuncionestienen
unargumento,mientrasquelaprimeranotieneninguno,cornoseindicaconlosparéntesisvacíos.
Nótesetambiénlasinstruccionesdelpreprocesador
#include<stdio.h>y#include
<ctype.h>,queaparecenalcomienzodelprograma.Estasinstruccioneshacenqueseinsertenloscon­
tenidosdelosarchivos
stdio.hYctype.henelprogramaalcomienzodelprocesodccompilación.
Lainfonnacióncontenidaendichosarchivosesesencialparaelfuncionamientocorrectodelasfunciones
debiblioteca
getchar,putcharytoupper.
3.1.¿Quéesunaexpresión?¿Cuálessonsuscomponentes?
3.2.¿Quéesunoperador?Describirvariostiposdiferentesdeoperadores
deC.
3.3.¿Qué.esunoperando?¿Cuál eslarelaciónentreoperadoresyoperandos?
3.4.Describirloscincooperadoresaritméticosde
C.Mencionarlasreglasasociadasasuuti­
lización.
3.5.Mencionarlasreglasqueseaplicanaexpresionesconoperandosdetiposdistintos.
3.6.¿Cómosepuedecambiarelvalordeunaexpresiónauntipodedatosdiferente?¿Cómose
llamaaesto?

OPERADORES YEXPRESIONES 81
3.7.¿Quéseentiendeporprecedenciadeoperadores?¿Cuálessonlasprecedenciasrelativas
delosoperadoresaritméticos?
3.8.¿Quéseentiendeporasociatividad?¿Cuáleslaasociatividaddelosoperadoresaritmé­
ticos?
3.9.¿Cuándosedebenincluirparéntesisenunaexpresión?¿Cuándosedebeevitarelusode
paréntesis?
3.10.¿Enquéordenseefectúanlasoperacionesenunaexpresiónquecontieneparéntesisani­
dados?
3.11.¿Quéesunoperadorunario?¿Cuántosoperandosvanasociadosaunoperadoruna­
rio?
3.12.Describirlosseisoperadoresunariostratadosenestecapítulo.¿Cuáles
elpropósitode
cadauno
deellos?
3.13.Describirdosformasdistintasdeutilizarlosoperadores
deincrementoydecremento.¿Cuál
esladiferenciaentreellas?
3.14.¿Cómoeslaprecedenciadelosoperadoresunariosenrelaciónconla
delosoperadores
aritméticos?¿Cuálessuasociatividad?
3.15.¿Cómosepuededeterminarelnúmero
debytesqueocupacadatipo dedatosenundeter­
minadocompilador
deC?
3.16.Describirloscuatrooperadoresrelacionales
deC.¿Conquétipodeoperandossepueden
utilizar?¿Quétipo
deexpresiónseobtiene?
3.17.Describirlosdosoperadoresdeigualdad
deC.¿Enquésediferencian delosoperadores
relacionales?
3.18.Describirlosdosoperadoreslógicos
deC.¿Cuáleselpropósitodecadaunodeellos?
¿Conquétipo
deoperandossepuedenutilizar?¿Quétipodeexpresiónseobtiene?
3.19.¿Cuálessonlasprecedencias relativas
delosoperadoresrelacionales, deigualdadylógi­
cosentresíyrespectoalosoperadoresaritméticosyunarios?¿Cuálessonsusasociativi­
dades?
3.20.Describireloperador
nológico(negaciónlógica).¿Cuálessupropósito?¿Enquégru­
podeprecedenciaestáincluido?¿Cuántosoperandosrequiere?¿Cuálessuasociati­
vidad?
3.21.Describirlosseisoperadoresdeasignacióntratadosenestecapítulo.¿Cuáleselpropósito
decadauno
deellos?
3.22.¿Cómosedeterminaeltipodeunaexpresióndeasignacióncuandolosdosoperandosson
detiposdiferentes?¿Enquésentidopuedeserestoavecesunafuentedeerroresdepro­
gramación?
3.23.¿CómosepuedenescribirmúltiplesasignacionesenC?¿Enquéordenseefectuaránlas
asignaciones?
3.24.¿Cuáleslaprecedenciadelosoperadores
deasignaciónenrelaciónconotrosoperado­
res?¿Cuálessuasociatividad?
3.25.Describirelusodeloperadorcondicionalparaformarexpresionescondicionales.¿Cómo
seevalúaunaexpresióncondicional?
3.26.¿Cómosedeterminaeltipodeunaexpresióncondicionalcuandosusoperandossonde
tiposdiferentes?
3.27.¿Cómosepuedecombinareloperadorcondicionalconeloperador
deasignaciónpara
formarunainstruccióndeltipo«if-else»?

82 PROGRAMACiÓN ENC
3.28.¿Cuáleslaprecedenciadeloperadorcondicional enrelaciónconlosotrosoperadores
descritosenestecapítulo?¿Cuálessuasociatividad?
3.29.Describir,enténninosgenerales,lasclasesdeoperaciones ycálculosrealizadosporlas
funcionesdebibliotecade
C.
3.30.¿FonnanrealmentepartedellenguajeClasfuncionesdebiblioteca?Explicarlo.
3.31.¿Cómosesuelenencontraragrupadasgeneralmentelasfuncionesdebibliotecaenun
com­
piladordeC?
3.32.¿Cómoseaccedealasfuncionesdebiblioteca?¿Cómosepasainfonnaciónaunafunción
debibliotecadesdeelpuntodeacceso?
3.33.¿Quéesunargumento?¿Cómoseescribenlosargumentos?¿Cómoseescribeuna
llama­
daaunafuncióndebibliotecasinotieneargumentos?
3.34.¿Cómosealmacena lainfonnaciónquepuedenrequerirlasfuncionesdebiblioteca?¿Cómo
seintroduceestainfonnaciónenunprograma
enC?
3.35.¿Dentrodequécategoríageneralseencuentranlasinstrucciones #definey#inelude?
3.36.Supongamosquea,byesonvariablesenteras quetienenasignados losvaloresa=8,b=3y
e=
-5.Determinarelvalordecadauna delassiguientesexpresionesaritméticas.
a)a+b+e fJa%e
b)2*b+3*
(a-e) g)a*b/e
e)a/b h)a*
(b/e)
ti)a%b i)(a
*
e)%b
e)a/e j)a*(e%b)
3.37.Supongamosquex,yyzsonvariablesencomaflotantequetienenasignados losvaloresx=88,
y=3 . 5 Y z=- 5 .2.Determinar elvalordecadauna delassignientesexpresionesaritméticas.
a)x+y+z
b)2*Y+3*(x-z)
e)x / y
ti)x%y
e)x /(y+z)
fJ(x/y)+z
g)2*x /3*Y
h)2*x /(3*y)
3.38.Supongamosel,e 2ye 3variablesdetipocarácterquetienenasignados loscaracteresE,5 Y?,
respectivamente.Determinar elvalornumérico delassignientesexpresiones,basándose enelcon­
juntodecaracteresASCn(verTabla 2.1).
a)el fJel%e3
b)el-e2+e3 g)"2/+
r'2I
e)e2-2 h)(el/e2)
*e3
ti)e2-
12/
i)3*e2
e)e3+'#' j)
13/
*e2

OPERADORES YEXPRESIONES 83
3.39.Unprogramaen econtienelassiguientesdeclaraciones:
inti,ji
longix;
shortSi
floatx;
doubledx;
chare;
Determinareltipodedatosdecadaunadelassiguientesexpresiones:
a)i +e 1)s +j
b)x + e
g)ix+j
e)dx+ x h) s+ e
el)((int)dx)+ix i)ix+ e
e)i + x
3.40.Unprogramaen econtienelassiguientesdeclaraciones yasignacionesiniciales:
inti=8,j=5i
floatx=0.005,Y=-0.01;
chare='e',d='d';
Determinarelvalordecadaunadelassiguientesexpresiones.Utilizarlosvaloresasignadosini­
cialmentealasvariablesparacadaexpresión.
a)(3*i -2*j)%,(2*d -e)
b)2*((i /5)+(4*(j-3))%(i+j - 2))
e)(i-3*j)%(e+2*d)/(x-y)
el)-(i+j)
e)++i
1)i++
g)--j
h)++x
l')y--
j)i<=j
k)e >d
l)x>=O
m)x<y
n)j!=6
o)e==99
p)5*(i+j)>'e'
q)(2*x+y)==O
r)2*x+(y==O)
s)2*x+y==O
t)!(i<=j)
u) !(e==99)
v) !(x>O)

84 PROGRAMACiÓN ENC
w)(i>O)&&(j<S)
x)(i>O)
11
( j<S)
y)(x>y)&&(i>O)
11
(j<S)
z)
(x>y)&&(i>O)
11
(j<S)
3.41.UnprogramaenCcontienelassiguientesdeclaraciones yasignacionesiniciales:
inti=8,j=5,k;
floatx=O.OOS,y=-0.01,z;
chara,b,e='e',d='di;
Determinarelvalordecadaunadelassiguientesexpresionesdeasignación.Utilizarparacada
expresiónelvalorinicialasignadoalasvariables.
a)k=(i+j) l)y=x
b)z=(x+y) m)x'=2
e)
i=j n)i/=j
d)
k=(x+y) o)i%=j
e)k=e p)i+=( j-2)
1)z=i/j q)k=( j--S)?i:j
g)a=b=d r)k=( j>S)?i:j
h)i j =1.1 s)z=(x>=O)?x:O
i)z=k=x t)z=(y>=O)?Y: O
j)k=z=x u)a=(e<d)?e d
k)i+=2 v)i-=(j>O)?j O
3.42.Cadaunadelassiguientesexpresionesutilizaunafuncióndebiblioteca.Identificarelpropósitode
cadaexpresión.(VerenelApéndiceHunalistadelasfuncionesdebiblioteca.)
a)abs(i-2
,
j ) l)sqrt(x'x+y'y)
b)fabs(x+y) m)isalnum(lO
,
j )
e)isprint(c) n)isalpha(lO
,
j )
d)
isdigit(c) o)isascii(lO
,
j )
e)toupper(d) p)toascii(lO
,
j )
1)ceil(x) q)fmod(x,y)
g)floor(x+y) r)tolower(6S)
h)islower(c) s)pow(x-
y,3.0)
i)isupper(j) t)sin(x-y)
j)exp(x) u)strlen("hola\O")
k)log(x) v)strpos("hola\O"
,e/)
3.43.UnprogramaenCcontienelassiguientesdeclaraciones yasignacionesiniciales:
inti=8
1j=5i
doublex=O.OOS,y=-0.01;
chare='e',d='dI;
Determinarelvalordecadaunadelassiguientesexpresiones,quehacenusodefuncionesdebi­
blioteca.(VerenelApéndiceCunalistadelasfuncionesdebiblioteca.)

oabs(i- 2 *j)
b)fabs(x+y)
e)isprint(e)
ti)isdigit(e)
e)taupper(d)
j)eeil(x)
g)eeil(x+y)
h)flaar(x)
i)flaar(x+y)
j)islawer(e)
k)isupper(j)
l)exp(x)
'eI)
m)lag(x)
OPERADORES YEXPRESIONES 85
n)lag(exp(x))
osqrt(x*x+y*y)
p)isalnum(10*j)
q)isalpha(10*j)
~isaseii(lO*j)
~taaseii(lO*j)
t)fmad(x,y)
u)talawer(65)
opaw(x-y,3.0)
w)sin(x-y)
~strlen("hala\O")
y)s t r p a s ( "ha1 a \ O " ,
z)sqrt(sin(x)+eas(y))
3.44'.DeterminardecuálesdelasfuncionesdebibliotecamostradasenelApéndiceHdisponesucompi­
ladorde
C.¿Disponedealgunasdelasfuncionesconunnombredistinto?¿Quéarchivosdecabe­
ceraserequieren?

CAPíTULO4
Entradaysalidadedatos
" •
7Iwrr
"'"
YahemosvistoqueellenguajeCvaacompañado deunacoleccióndefuncionesdebiblioteca
queincluyeunciertonúmerodefuncionesdeentrada/salida.Enestecapítuloutilizaremosseis
deestasfunciones:
getchar,putchar,scanf,printf,getsyputs.Estasseisfuncio­
nespermitenlatransferenciadeinformaciónentrelacomputadoraylosdispositivos
deentrada/
salidaestándar(porejemplo,untecladoyunmonitor).Lasdosprimerasfunciones,
getchary
putchar,permitenlatransferenciadecaracteresindividualeshaciadentroyhaciafuera dela
computadora;
scanfyprintfsonmáscomplicadas,peropermitenlatransferencia decarac­
teresindividuales,valoresnuméricosycadenas
decaracteres;getsyputspermitenlaentra­
daysalidadecadenasdecaracteres.Unavezquehayamosaprendidoeluso
deestasfunciones;
seremoscapaces
deescribirunciertonúmero deprogramasenCsencillosperocompletos.
4.1.INTRODUCCIÓN
Sepuedeaccederaunafuncióndeentrada/salidadesdecualquiersitiodeunprograma .consim­
plementeescribirelnombre
delafunción,seguidodeunalistadeargumentosentreparéntesis.
Losargumentosrepresentanlosdatosquelesonenviadosalafunción.Algunasfunciones
de
entrada/salidanorequierenargumentos,perodebenaparecerlosparéntesisvacíos;
Losnombres
de
estasfuncionesquedevuelvendatospl.ledenaparecerdentrodeexpre­
siones,comosicadareferenciaa unafunciónfueseunavariableordinaria(porejemplo
c=getchar();),osepuedenreferenciarcOlIloinstruccionesseparadas(porejem­
ploscanf(...);).Algunasfuncionesnodevuelvenningúndato.Estasfunciobessereferen­
ciancomosifueseninstruccionesseparadas(porejemplo
putchar( );).
LamayoríadelasversionesdeCincluyenunacoleccióndearchivosdecabeceraquepro­
porcionan
lainformaciónnecesaria(porejemploconstantessimbólicas)paralasdistintasfun­
cionesdebiblioteca.Cadaarchivocontienegeneralmentelainformaciónnecesariaparalautili­
zación
dellndeterminadogrupode
fllncione~ debiblioteca.Estqsarchivosseincluyen.en .un
prograrnamediantelainstrucción#inclpdealcomienzodelprogranla.C0.rn0110rmageneral,
elarchivodecabecerarequeridoparalaentrada/salidaestándarsellamas
tdio.h(consulte.Iasección,8.6paramásinformaciónsobre elcOlltenidqdee.stosarchivosdecabecera)...
EJEMPLO4.1. ElsiguiehteesunesquemadeunprogramadeCtípicoqliehace usodevariasrutinaS
deentrada/salidadelabibliotecaestándar deC.
87

88 PROGRAMACiÓN ENC
/*ejemplodelusodefuncionesdebibliotecadeentrada/salida*/
#include<stdio.h>
main()
{
chare,di
floatx,y;
intiIj,k¡
c=getchar( ) ;
scanf(ll%fll,&x)¡
scanf("%d%d",&i
l&j)i
putchar(d);
printf("%3d%7.4f",k,y);
}
/*declaraciones*/
/*entradadeuncarácter*/
/*entradadenúmeroencoma
flotante*/
/*entradadeenteros*/
/*instruccionesdeacción*/
/*salidadeuncarácter*/
/*salidadenúmeros*/
Elprogramacomienzaconlainstruccióndelpreprocesador #include<stdio.h>.Estainstruc­
ciónhacequeseincluyaenelprogramaelcontenidodelarchivodecabecera
stdio.h.Estearchivo
proporcionalainformaciónreferentealasfuncionesdebiblioteca
scanfyprintf.(Lasintaxisdela
instrucción
#includepuedevariardeunaversiónde eaotra;algunasversionesdellenguajeutilizan
comillasenlugardelosparéntesisenángnlo,porejemplo
#include"stdio.h".)
Acontinuacióndelainstruccióndelpreprocesadorseencuentraelencabezamientodelprograma
main()yalgunasdeclaracionesdevariables.Aparecenvariasinstruccionesdeentrada/salidaenlas
líneasquesiguenalasdeclaraciones.Enconcreto,lainstruccióndeasignaciónc
=getchar( ) ;hace
queseleaunsolocarácterdeltecladoyseleasignealavariable
c.Laprimerareferenciaa scanfhace
queseleaportecladounvalorencomaflotanteyseleasignealavariable
x,mientrasquelasegunda
llamadaa s
canfhacequeseleandel tecladodoscantidadesenterasdecimalesyselesasignenalas
variablesi y
j,respectivamente.
Lasinstruccionesdesalidasecomportandeformaanáloga.Lallamada
aputcharhacequesevi­
sualiceelvalordelavariabledecarácterd.Análogamente,lareferenciaa printfhacequesevisualicen
elvalordelavariable,
eJ:lterak yeldelavariableencomaflotante y.
Losdetallesdecadainstruccióndeentrada/salidasediscutiránenlassiguientesseccionesdeeste
capítulo.Porahoraessuficienteconsegnirunavisióngeneral
de,lasinstruccionesdeentrada/salidainclni-
dasen
,elprogramaanterior.
'
4.2.ENTRADA DEUNCARÁCTER-LA FUNCIÓNgetchar
Mediantelafuncióndebibliotecageteb.ar,sepuedeconseguirlaentradadecaracter~s unoa
uno.
Yahemosvistoenlos
Capítu\os1y2YenelEjemplo4.1algúncaso enelqueseutilizaba
estafunción.Ahoralaveremosconmás,detalle.
Lafuncióir
geteharespartedelabibli6tecadeedeentrada/salidaestándar.Devuelve
uncarácterleídodeldispositivodeentradaestándar(típicamenteunteclado). Lafunciónno
I'i;)q),liereargumentos,aunq),leesneci;)sarioqueunparde.paréntesisvacíossigana lapalábra
getehar.

ENTRADAYSALIDA DEDATOS 89
Enformageneral,unareferenciaalafunción getcharseescribeasí:
variabledecarácter=getchar();
dondevariabledecarácter esalgunavariabledecarácterpreviamentedeclarada.
EJEMPLO4.2. Unprogramaenecontienelassiguientesinstrucciones.
charc¡
c=getchar( ) ;
Enlaprimerainstrucción sedeclaralavariablec detipocarácter.Lasegundainstrucciónhace queselea
deldispositivodeentradaestándaruncarácter yentoncesseleasigneac.
Siseencuentraunacondicióndefin
dearchivo(<<endo/file»)cuandoseestáleyendoun
carácterconlafunción
getchar,lafuncióndevolverádeformaautomáticaelvalorde la
constantesimbólica EOF.(Estevalorsedefinedentrodelarchivos
t4io .h.Normalmente
EOFtendráasignadoelvalor -1,aunquepuedevariardeuncompiladoraotro.) Ladetección
de
EOFdeestaformahaceposibledescubrirelfindearchivoenelmomentoylugarqueocurra.
Sepuedeentoncesactuarenconsecuencia.Ambas,ladetección
delacondiciónEOFylaac­
ciónoportuna,
sepuedenefectuarutilizandolainstmcción' if -e 1s equesedescribeen elCapí­
tulo
6.
Lafuncióngetchartambiénsepuedeutilizarparaleercadenasdevarioscaracteres,le­
yendoenunbuclelacadenacarácteracarácter.
EnelEjemplo4.4veremoscómosepuedehacer
esto.Haymásejemplosencapítulosposterioresdeestelibro.
, ,
4.3.SALIDADEUNCARACTER - LAFUNCIONputchar
Sepuedevisualizaruncarácterutilizandolafuncióndebiblioteca putchar.Estafunción es
complementariaaladeentradadeuncarácter getchar,quehemosvistoenlasecciónante­
rior.TambiénhemosvistoejemplosdeutilizacióndeestasdosfuncionesenlosCapítulos
1y 2
yenelEjemplo4.1.Ahoraveremos putcharconmásdetalle.
Lafunciónputchar,asícomogetchar,espartedelabibliotecadeentrada/salidaestán­
dar.Transmiteuncarácteraldispositivodesalidaestándar(típicamenteunmOllÍtor).Elcarácter
quesetransmiteestarárepresentadonormalmente
porunavariabledetipocarácter.Sedebe
proporcionarcomoargumentodela·función,encerrad()entreparéntesis,siguiendoa
lapalabra
putchar.
Engeneral,unareferenciaalafunción putcharseescribecomosigue:
putchar(variabledecarácter)
dondevariabledecarácterhacereferenciaaunavariabledetipocarácterpreviamente
declarada.

90 PROGRAMACiÓN ENC
EJEMPLO4.3. UnprogramaenCcontienelassiguientesinstrucciones.
charCi
putchar(c);
Enlaprimerainstrucción sedeclaralavariablec detipocarácter.Lasegundainstrucciónhaceque se
transmitaelvaloractual decaldispositivodesalidaestándar(porejemplounmonitor) endondesevisua­
lizará.(Compáresecon
elEjemplo4.2, queilustraeluso delafuncióngetchar.)
Lafunciónputcharsepuedeutilizar paravisualizarunaconstantede cadenadecaracteres
almacenando
lacadenadentrode unarrayunidimensionaldetipocarácter, comoseexplicóen
elCapitulo2.Se puedenescribirentonces medianteunbucleloscaracteres unoauno.Laforma
más
cómodadehacerestoesutilizando unainstrucciónfor,comose puedeverenelsiguiente
ejemplo.
(LainstrucciónforsetratacondetalleenelCapítulo6.)
EJEMPLO4.4.Conversióndeuntextodeminúsculasamayúsculas. Elsiguienteesunprograma
completoqueleeunalínea
detextoenminúsculas,la
almacena.enunarray detipocarácterunidimensio­
nalydespuéslaescribeenmayúsculas.
/*leerunalíneauntextoenminúsculasyescribirlaenmayúsculas*/
#include
<:stdio.h>
#include<ctype.h>
mai"( )
{
charletras[80];
intcont,auxiliar¡
/*leerlalínea-/
for(cont=O;(letras[c::ont]=getc::har())!='';++c::ont)
1*guardar·elc::ontadordecaracteres*1·
auxiliar·.=;cont¡
! *esbÚbirlalínéaenmayúsc::ulas*!
for(c::orit=O;cbnt<auxiliar;++cont)
putchar(toupper(letras[cont]));
}
Observeladeclaración
charletras[8O];

ENTRADAYSALIDA DEDATOS 91
Aquísedeclara letrascomounarray detipocarácterde 80elementos,loscualesrepresentaránlos
caracteres
delalíneadetexto.
Consideremosahoralainstrucción
for(cont=O;(letras[cont]=getchar())!='';
++cont)
Estainstruccióncreaunbuclequehacequeseintroduzcanloscaracter"senlacomputadoraylosasigna
aloselemelltosdelarray.Elbuclecomienzaasigllandoa
contelvalorc"ro.Selee.uncarácterdeldispo­
sitivo
deentradaestándaryseleasignaa letras[O1(elprimerelementodeletras).Elvalorde
contseincrementaenunoyentoncesserepiteelprocesoparaelsiguienteelementodelarray.Elbucle
continúaejecutándosehastaqueseintroduzcaelcarácter
denuevalínea ('\n') .Elcarácterde nueva
línea
indicaráelfinaldeltextoyfinalizaráportantoelproceso.
Unavezquesehanintroducidotodosloscaracteres,seleasignaa
auxiliarelvalordecont
correspondientealúltinlOcarácter.Comienzadespués
otrobuclefor,enelquesevisualizaneneldispo­
sitivo
desalidaestándarlasletrasmayúsculascorrespondientesaloscaracteresintroducidos. Loscaracte­
resqueeranoriginalmentedígitos,mayúsculas,signosdepuntuación,etc.,sevisualizaránensu
fOf!Ila
original.Portanto,siintroducimos
¡Eshoradequetodosloshombresdebienacudanen.ayudadesupais!
lasalidacorrespondienteserá
¡ESHORADEQUETODOSLOSHOMBRESDEBIENACUDANENAYUDADESUPAIS!
Nóteseque auxiliartendráasignadoelvalor69,yaquetras'elsignodefin deexclamaciónse
encuentraelcarácterdenuevalínea.
ElCapítulo6contieneinformaciónmásdetalladadelusodelainstrucción
forconarraysdecaracte­
res.Porahora,sóloesnecesarioentender
deformageneralquéesloquehaceelprograma.
4.4.INTRODUCCIÓN DEDATOS-LAFUNCIÓN scanf
Sepuedenintroducirdatosenlacomputadoraprocedentesdeldispositivodeentradaestándar
mediantelafunc,ióndelabibliotecade.C s c
q.nf,Estafunciémse puedeutilizarpara~l1troducir
cualqlliercombinac.ióndeyaloresnuméricos,caracteresindividual(lsycadenasdecaracteres.
Lafullcióndevuelveelnúmerode.datos.quesehanconseguidointrodllcircorrectamente.
Entérrninosgenerales,lafunGións<::q.nfseescribe .
,- ......,',...',..,'-..-'.. .
scanf(cadenadecontrol,argl,arg2,...,argn)
dondecadenadecontrolhacereferenciaajlnacadenade,caracteresquecolltieneGierta
informaciónsobreelformatodelosdatosyargl,arg2,...,argnsonargumentosquerepre­
sentanlosdatos.(Enrealidad,losargumentosrepresentanpunterosqueindicanJasdireccio­
nes
dememoriaendondeseencuentranlosdatos.EnelCapítuloIDsetrataestoconmás
detalle.)

92 PROGRAMACiÓN ENC
Enlacadenadecontrolseincluyen.gruposindividualesdecaracteres,conungrupodeca­
racteres
porcadadato deentrada.Cadagrupodecaracteresdebecomenzarconelsignode
porcentaje
(%).Ensuformamássencilla,ungrupodecaracteresestaráformadoporelsigno de
porcentaje,seguidode uncarácterdeconversiónqueindicaeltipodedatocorrespondiente.
Dentrodelacadena
decontrol,losdiferentesgrupos decaracterespuedenestarseguidoso
puedenestarseparadosporcaracteresdeespaciado(espaciosenblanco,tabuladoresocaracte­
resdenuevalínea).Siseutilizanloscaracteresdeespaciadoparaseparargruposdecaracteres
enlacadenadecontrol,entoncestodosloscaracteresdeespaciadoconsecutivos
enlosdatosde
entradaseleerán,peroseránignorados.Esmuyfrecuenteelusodeespaciosenblancocomo
separadoresdegruposdecaracteres.
LaTabla
4.1contieneloscaracteresdeconversióndeusomásfrecuente.
Tabla4.1.Caracteresdeconversióndelosdatosde entradadeusocomún
e
d
e
f
g
h
i
o
s
u
x
[...]
eldatoesuncarácter
eldatoesunenterodecimal
eldatoesunvalorencomaflotante
eldatoesunvalorencomaflotante
eldatoesunvalorencomaflotante
eldatoesunenterocorto
eldatoesunenterodecimal,octalohexadecimal
eldatoesunenterooctal
eldatoesunacadenadecaracteresseguida deuncarácterdeespaciado(seañade
automáticamenteelcarácternulo\ Oalfinal)
eldatoesunenterodecimalsinsigno
eldatoesunenterohexadecimal
eldatoesunacadenadecaracteresquepuedeincluircaracteresdeespaciado(ver
explicación
acontinuación)
Losargumentospuedenservariableso
arrays,ysustiposdebencoincidirconlos indica­
dosporlosgruposdecaracterescorrespondientesenlacadenadecontrol. Cadanombrede
variabledebe
serprecedidoporunampersand(&).(Enrealidadlosargumentossonpunteros
queindicandóndeseencuentransituadoslosdatosenlamemoriade
lacomputadora,comose
explicaenelCapítulo10.)Sinembargo,losnombresdearrays
nodebenirprecedidos porel
ampersand.
EJEMPLO4.5.
Lasiguienteesunaaplicacióntípica delafunciónscanf.
#include<stdio.h>
main()

ENTRADAYSALIDA DEDATOS 93
{
charconcepto[2O];
intnum-partida;
floatcoste;
scanf("%s%d%f",concepto,&num-partida,&coste);
}
Dentrodelafunciónscanf,lacadenadecontroles"%s%d%f".Contienetres gruposdecaracteres.
Elprimergrupo decaracteres,%s,indicaqueelprimerargumento (concepto)representaaunacadena
decaracteres.Elsegundogrupodecaracteres,%d,indicaqueelsegundoargumento(&num~partida)
representaunvalorenterodecimal,yeltercer grupodecaracteres,% f,indicaqueeltercerargumenio
(&coste)representaunvalorencomaflotante.
Observe
quelasvariablenuméricas
num-partidaYcostevanprecedidasporampersandsdentro
delafunciónscanf.Sinembargo,delante deconceptonohayampersand,yaqueconceptoesel
nombre
deunarray.
Observetambién quesepodríahaberescritolafunción scanf
scanf
("%s%d%f",concepto,&no_partida,&coste);
sincaracteresdeespaciadoenlacadenadecontrol.Estotambiénesválido,aunquelos datosdeentradase
podríanhaberinterpretado deformadiferentealutilizarconversionestipoe(mássobre estomásadelante
enestecapítulo).
Losdatospuedenservaloresnuméricos,caracteresindividuales,cadenasdecaractereso
algunacombinacióndeéstos.Seintroducen
deldispositivodeentradaestándar(típicameIlteun
teclado).Losdatosdebencorrespondersecon
losargumentosdelafunciónscanfennúmero,
entipoyenorden.Losdatosnuméricosdebenestarescritos delamisma
formaquelasconstan
c
tesnuméricas(versección2.4),aunque losvaloresoctales IlOnecesitanirprecedidospor unO,
ylosvaloreshexadecimalestampoconecesitanirprecedidos porOxoOX.Losvaloresencoma
flotantedebenincluiro
unpuntodecimal Ounexponente(oambos).
Si
seintroduce
ll
dos omásdatos,deben estarseparadosporcaracteresdeespaciado.(Una
posibleexcepciónaestareglaocurreconlasconversionestipo e,comosedescribe enlasec­
ción4.5)Losdatospuedenencontrarse
endosomáslíneas,ya
queelcarácterdenuevalínease
consideracomo
uncarácterdeespaciado
ypuedeportantoseparardatosconsecutivos.
Esmás,silacadenadecontrolempiezapor lalecturadeundiltotipocarácter,esgeneral­
mellte
unabuenaideaprecederel primercarácterdeconversióncOIllln espacio
enbl
aI1
c().Esto
hacequelafunción Scanfignoreloscaracteresextrañosquesepuedenhaberintroducidocon
anterioridad(porejemplo,alpulsar
latecla
IntrOtrasunalíneadedatosanterior).'
EJEMPLO4.6. Consideremosunavez máselesquémadelprogramaenCmostradoénelEjemplo4.5,
estoes,
#include<stdio;h>
main()

94 PROGRAMACiÓN ENC
{
charconcepto[2O];
intDUffi_partida;
floatcoste;
scanf("%s%d%f",concepto,&num_partida,&coste);
}
Observeelespacioenblancoqueprecede%s.Estoevitalaasignacióna conceptodecaracteresextra­
ñosintroducidosconanterioridad.
Sepodríanhaberintroducidolossiguientesdatosporeldispositivo deentradaestándarcuando se
ejecutaseelprograma.
cremallera123450.05
Seleasignaríana losdiezprimeroselementos delarrayconceptoloscaracteresqueintegranlacadena
cremallera;anum_partidaseleasignaríaelvalorentero 12345,y acosteleseríaasignadoel
valorencomaflotanteO •05.
Observe
quelosdatosseintroducenenunalínea,separadosporespacios enblanco.También sepo­
dríanhaberintroducido losdatosenlíneasseparadas,ya queloscaracteresdenuevalínea seconsiderarían
también
comocaracteresdeespaciado.Portanto, losdatosdeentradasepodríanhaberescríto así:
cremallera
12345
0.05
cremallera
12345 0.05
cremallera
0.05
12345
Q.bservequelacgnversióndecaracterestiposseaplicaaunacadenadecaracteresque
acaRaenuncarácter¡1eespaciado.Portanto, Unacadenadecaracteresque incluyecaracteresde
espaciado
no
sepuedeintroducirdeestaforma..Porsupuesto,existenfonnasdetrabajarque
incluyencaracteresdeespaciado.Una.fgnnaesutilizar
lafunción
getch¡¡.rdentrodeunbucle,
comose,vioenelEjemplo4.4.Tambiénsepuedeutilizar lafunciónscanfparaintroducir
cadenasdecaracteresdeestetipo.Para.haceresto,
laconversióndecaracterestiposdentrode
la
cadenadecontrolesree,mplazad~ porunasecuenciadecaracteresenceITadosentrecorchetes,
desiglladacomoL..l,L08c~racte~esdeespaciado sepuedenincluirdentrodejoscorche,­
tes,pudiéndoseportantgacomo¡1aracadenasque.pontengan.dichos.ca~acteres.
Cuan¡1gseejecutaelp~ograma, seleeránc~acteres sucesivamentedeldispositivosdeentra­
da.estándarmientrascadac.arácterdeentradacoincida conunodeloscaracteresdentrodelos
corchete~,.N"o.es. necesarioqlle elordende·loscaracteresdentrode.loscgrcl1e,tessecorresponda
¡;gllelde,lo~ c.¡¡,rac;teresque.se.estánintroduciendo.Los.caracte,resdeentradasepuedenrepetir,
Sinemba~go, l~...cadenade¡;aracterestelTllinarácuandoseencuentreunc:irácterdeentradaque
nocoincidaconningunodeloscaracteresincluidosentreloscorchetes.Seañadiráentonces,
automáticamente,uncarácternulo(.\O)alfinaldelacadena.
EJEMPLO4.7. Esteejemploilustra elusodelafunciónscanfparaintroducirunacadena decarac­
teres
queconstadeletrasmayúsculasyespacios enblanco.Lacadenaserá delongitudnodeterminada,
peroestará límitadaa79caracteres(realmente,
8 Ocaracteresincluyendoelcarácter nuloqueseañadeal
final).

ENTRADAYSALIDA DEDATOS 95
#include<stdio.h>
main()
{
char1inea[8O];
scanf("%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]", linea);
}
Siseintroducelacadena
CIUDADDEALMERIA
poreldispositivodeentradaestándarcuando seejecutaelprograma,seleasignaráalarraylineatoda la
cadena
decaracteres,ya queestácompuestasólopodetrasmayúsculasyespacios enblanco.Sin
embar
e
go,si·sehubieseescritolacadena
CiudaddeAlmería
sólosehabríaasignadoa linealaletraC,yaquelaprimeraletraminúscula(eneste casolai)se
interpretaríacomoelprimercarácteracontinuación delacadena.Sepodría,porsupuesto,haberincluido
mayúsculasyminúsculasdentro
deloscorchetes,pero estoyaresultaincómodo.
Otraformadehaceresto,queavecesesmásútil,esprecederloscaracteresdedentrodelos
corchetespor
unacentocircunflejo (A).Estohacequelossiguientescaracteresdedentrodelos
corchetesseinterpretendelaformaopuesta.Esto.es,cuandoseejecutaelprograma,se
leerán
sucesivamenteloscaracteresdeldispositivodeentradaestándarmientrasquecadacarácterde
entrada
nocoincidaconalgunodeloscaracteresincluidos enloscorchetes.
Siloscaracteresencerrados
porloscorchetessonsóloelacentocircunf1ejoseguidodeun
carácterdenuevalínea,lacadenadecaracteresintroducida
poreldispositivodeentradaestán­
darpuedetenercualquiercarácter ASCn,exceptoelcarácterdenuevalínea
(linefeed).Por
tanto,elusuariopuedeintroducir
10quedesee ypulsarlatecla INTRO.LateclaINTROpropor­
cionaráelcarácterdenuevalínea,indicandoconelloelfinalde
lacadena.
EJEMPLO4.8. Supongamosqueunprogramaenecontienelassiguientesinstrucciones.
#include<stdio.h>
main()
char1inea[8O];
scanf("%[A]",linea);
}

96 PROGRAMACiÓN ENe
Observeelespacioenblancodelante de%[A\n],paraignorar loscaracteresnodeseadosintroducidos
conanterioridad.
Cuandoseejecutalafunción scanf,seleerádeldispositivodeentradaestándar unacadenadecarac­
teres
delongitudnodeterminada(pero nomásde79caracteres)yseleasignaráa linea.Nohabrá
restricciones
enloscaracteresquelacompongan,salvo quequepanenunalínea.Porejemplo,lacadena
¡ElREALMADRIDesunodelosmejoresequiposdefútbolespañoles!
sepodríaintrodncirpor eltecladoyseleasignaríaalinea.
4.5.MÁSSOBRELAFUNCIÓN scanf
Estaseccióncontienealgunosdetallesadicionalesde lafuncións e anf.Losprogramadores
queesténempezandoahoracon
epuedensaltarseestasección porelmomento,si 10desean.
Loscaracteresconsecutivosquenoseandeespaciado
yquecomponen undato,definen, en
conjunto,uncampo.Esposiblelimitarelnúmerodeloscaracteresespecificandouna longitud
decampo
máximaparaesedato.Parahaceresto,seintroduce enlacadenadecontrol unentero
sinsignoqueindica
lalongituddecampo,entreelsignodeporcentaje (%)Yelcarácterde
conversión.
Eldatopuedeestarcompuesto
pormenoscaracteresdelosqueespecifique lalongitudde
campo.Sinembargo,elnúmerodecaracteresdeldato
realnopuedeexceder lalongi­
tuddecampoespecificada.
Noseleeránloscaracteresqueseencuentrenmásalládelalongitud
decampoespecificada.Estoscaracteressobrantespuedenserinterpretadosdeformaincorrecta
comoloscomponentesdelsiguientedato.
EJEMPLO
4,9.Acontinuaciónsemuestralaestructuraesquemática deunprogramaenC.
#include<stdio.h>.
main()
(
inta,b,c,;
scanf("%3d%3d%3<:1",&a,&b,&c);
}
Cuandoseejecutaelprograma, seintroducentrescantidadesenteraspor eldispositivodeentrada
estándar(elteclado).Supongamos
quelosdatosintroducidos son:
123
Entoncesseefectuaránlassiguientesasiguaciones:
a=1,b=2,e=3

ENTRADAYSALIDADEDATOS 97
Siseintroducenlosdatos
123456789
Entonceslasasignacionesserian:
a
=123,b=456,e=789
Supongamosahoraqueseintroduce
123456789
Entonceslasasignacionesserian:
a
=123,b=456,e=789
comoantes,yaqueseleasignariana alostresprimerosdigitos,lostressiguientesdigitosa b ylos
últimostresdigitosa
c.
Finalmente,supongamosquelosdatosqueseintroducenson
123456789
Lasasignacionesresultantesserianahora
a
=123,b=4,e=567
Losotrosdosdigitosrestantes (8Y9)seignorarán,anoserqueseleanacontinuaciónenotrainstruc­
ción
scanf.
EJEMPLO4.10.ConsideremosunprogramaenCquecontienelassiguientesinstrucciones.
#inc1ude<stdio.h>
main()
(
inti¡
floatx;
charc;
scanf("%3d%5f%c",&i,&x,&c);
}
Siintroducimoslossiguientesdatos
10256.875T
cuandoseejecutaelprograma,entoncesseleasignaráa ielvalor
10,a xelvalor 256.8ya esele
asignaráelcarácter7.Losotrosdoscaracteres
(5YT)seignorarán.

98 PROGRAMACiÓN ENC
Lamayoríadelasversionesdeepermitenqueciertoscaracteres deconversiónen lacadena
decontrolseanprecedidos porunprefijodeunasolaletra,que indicalalongituddelargumento
correspondiente.
Porejemplo,una1(Lminúscula) seutilizaparaindicarunargumentoentero
largo,tanto
consignocomosinsigno,o unargumentodedobleprecisión.Análogamentese
utilizaunahparaindicarunenterocortotantoconsignocomosinsigno.Tambiénalgunas
versionesde epermitenelusodeunaLmayúsculaparaindicarunlongdouble.
EJEMPLO4.11. Supongamosqueaparecenlassiguientesinstruccionesenunprogramaen C.
#include<stdio.h>
main( )
{
shortix,iy;
longlx,ly;
doubledx,dy;
scanf("%hd%ld%lf",&ix, &lx,&dx);
scanf("%3ho%7lx%15le",&iy, &ly,&dy);
}
Lacadenadecontroldelaprimerafunción scanfindicaqueelprimerdatoseráasignadoaunavariable
enteracortaendecimal,elsegundoaunavariablelargaendecimalyelterceroaunavariable
dedoble
precisión.Lacadena
decontroldelasegundafunción scanfindicaqueelprimerdato
t~ndráunalongi­
tud
decampomáxima detrescaracteresyseráasignadoaunavariableenteracortaenoctal,elsegundo
datotendráunalongitud
decampomáxima desietecaracteresyseráasignadoaunavariableenteralarga
enhexadecimal
yeltercerdatotendráunalongitud decampomáxima de15caracteresyseleasignaráa
unavariable
dedobleprecisión.
Algunasversionesdeepermitenelusodemayúsculascomocaracteresdeconversión para
indicarenteroslargos (consignoo sinsigno).Esposiblequese dispongadeestoademásdel
prefijo
"1",oreemplazandoelusodelprefijo.
EJEMPLO4.12. ConsideremosdenuevolaslíneasdelprogramaenCdadasenelEjemplo 4.11.En
algunasversiones
deCesposibleescribirlasfuncioness canfdeformadiferente,comosigue.
#include<stdio.h>
main()
{
shortix,iy;
longlx,ly;
doubledx,dy;

ENTRADAYSALIDA DEDATOS 99
scanf("%hd%D%f",&ix,&lx,&dx);
scanf("%3ho%7X%15e",&iy,&ly,&dy);
}
Observeeluso decaracteresdeconversiónenmayúsculas(enlasfunciones scanf)paraindicarenteros
largos.Lainterpretacióndelasfunciones
scanfeslamismaqueladelejemploanterior.
Enlamayoria delasversionesde eesposiblesaltarseundatosinqueleseaasignadoauna
determinadavariableoformación.Parahaceresto,elsigno
%esseguidoporunasterisco (*)
dentrodelacadena decontrol.Estosedenomina supresióndeasignación.
EJEMPLO4.13.EstaesunavariacióndelEjemplo4.6.
#include<stdio.h>
main()
{
charconcepto[2O];
intnUffi_partida¡
floatcoste;
scanf("%s%*d%f",concepto,&num_partida,&coste);
}
Observelapresenciadelasteriscoenelsegundogrupodecaracteres.
Silosdatosdeentradason
cremallera123450.05
entoncesa conceptoseleasignarácremallerayacosteseleasignará0.05;Sin embargo,a
num_partidanoseleasignará12345acausadelasterisco,queseinterpretacomouncarácterde
supresióndeasignación
..
Lacantidadentera 12345será leidaentre.losotrosdatos,aunque noseleasignea.lavariablecorres,
pondiente.
Sila·.cadena.de.controlcontienevariosgruposde.caracteres sinestarseparados.
poccaracte­
resdeespacíado,se.debetenercuidadoconlaconyersión tipoc.Enestoscasos,.siapareceentre

100 PROGRAMACiÓN ENC
losdatosdeentrada uncarácterdeespaciado,seinterpretarácomoundatomás. Parasaltarse
estoscaracteresdeespaciado yleerelsiguientecarácterquenoseadeespaciadosedebeutilizar
elgrupodeconversión%1s.
EJEMPLO4.14. ConsideremosunprogramaenCquecontienelassiguienteslíneas.
#inelude<stdio.h>
main()
{
scanf(n%c%c%cnI&cl,&c2I&c3);
}
Silosdatos deentradason
abe
(conespaciosenblancoentrelasletras), seefectuaránlassiguientesasignaciones:
c2=<espacioenblanco>, e3=b
Sinembargo,silafunciónseanfsehubieseescrito delasiguienteforma
seanf("%e%ls%ls",&el,&e2,&e3);
entonceslosmismosdatos deentradaharíanque serealízasenlassiguientesasiguaciones:
el=a,e2=b,e3=e
comodeseábamos.
Tengaencuentaquehayotrasformas
desolucionaresteproblema.Podríamoshaberescrítolafunción
seanfasí:
seanf("%e%e%e",&el,&e2,&e3);
conespaciosenblancodentrodelacadena decontrol,opodríamoshaberutilizadolafunción seanf
oríginal,parahilberescritolos·datos deentradacomocaracteresconsecutivossinespaciosenblanco,por
ejemplo
abe.
Cuandoseencuentrandentrodelacadenadecontrolcaracteresnoreconocidos,seespera
queaparezcanestos
,caracteresenlosdatosdeentrada.Estoscaracteresdeentradaseleerán,

ENTRADAYSALIDA DEDATOS 101
peronoseasignaránaningúnidentificador.Sila entrada nocoincideconloscaracteresdela
cadena
decontrol,terminarálaejecucióndelafunción scanf.
EJEMPLO4.15.ConsideremosunprogramaenCconlassiguienteslíneas.
#include<stdio.h>
main()
{
intii
floatX;
scanf(lI%da%f
ll
,&i,&x)i
}
Silosdatosdeentradason
1a2.0
seleeráelenterodecimal1 yseleasignaráa i,seleeráelcaráctera acontinuación yseignorará,yse
leeráelvalorencoma flotante2 . OYseleasignaráax.
Porotraparte,silaentradahubiesesido
12.0
laejecucióndelafunción scanfhnbieseacabadoalnoencontrarelcarácteresperado (al.Portanto,a
iselehabríaasignadoelvalor 1,peroa Xselehabríaasignadoautomáticamenteelvalor O.
Ellectordebetenerpresentequehayalgunasdiferenciasentrelascaracterísticasdes e anf
deunaversiónde eaotra.Losrasgosdescritosanteriormentesonbastantecomunesyseen­
cuentranenprácticamentetodaslasversionesdellenguaje.Sinembargo,puedehaberpequeñas
diferenciasensuimplementación.Ademássepodránencontrarprestacionesadicionalesenal­
gunasversionesdellenguaje.
4.6.ESCRITURADEDATOS-LAFUNCIÓN printf
Sepuedenescribirdatoseneldispositivodesalidaestándarutilizandolafuncióndebiblioteca
printf.Sepuedeutilizarestafunciónparaescribircualquiercombinacióndevaloresnuméri­
cos,caracteressueltosycadenasdecaracteres.Esanálogaalafuncióndeentrada
scanf,con
ladiferencia
dequesupropósitoesvisualizardatosenlugar deintroducirlosenlacomputadora.

102 PROGRAMACiÓN ENC
Estoes,lafunción printfseocupadetransferirdatosdelamemoriadelacomputadoraal
dispositivodesalidaestándar,mientrasquelafunción
scanfintroducedatosdeldispositivode
entradaestándarylosalmacena
enlamemoriadelacomputadora.
Entérminosgenerales,lafunción printfseescribe
printf(cadenadecontrol,argl,arg2,. argn)
endondecadenadecontrolhacereferenciaaunacadenadecaracteresquecontiene
informaciónsobreelformatode
lasaliday argl,arg2,...,argnsonargumentosque
representanlosdatosdesalida.Losargumentospueden
serconstantes,variablessimpleso
nombresdearraysoexpresionesmáscomplicadas.Tambiénsepuedenincluirreferenciasa
funciones.
Encontrasteconlafunción scanftratadaenlasecciónanterior,losargumentos
de
lafunciónprintfnorepresentandireccionesdememoriay portantonosonprecedidos
deampersands.
Lacadenadecontrolestácompuesta porgruposdecaracteres,conungrupodecaracteres
porcadadatodesalida.Cadagrupodecaracteresdebecomenzar
porunsignodeporcentaje
( %) .Ensuformamássencilla, ungrupodecaracteresconsistiráenelsignodeporcentajese­
guidodeun
carácterdeconversiónqueindicaeltipodeldatocorrespondiente.
Puedenincluirsevariosgruposdecaracteresseguidososeparados
porotroscaracteres,in­
cluidoslosdeespaciado.Estos«otros»caracteressontransferidosdirectamentealdispositivo
desalidaestándar,endonde
sonvisualizados.Esmuycomúnelusodeespaciosenblancocomo
separadoresdegruposdecaracteres.
LaTabla4.2contieneunalistadeloscaracteresdeconversiónmásfrecuentementeutili­
zados.
Tabla4.2.Caracteresdeconversióndelosdatosdesalidadeusocomún
c
d
e
f
g
i
o
s
u
x
eldatoesvisualizadocornouncarácter
eldatoesvisualizadocornounenterodecimalconsigno
eldatoesvisualizadocornounvalorencomaflotanteconexponente
eldatoesvisualizadocornounvalorencomaflotantesinexponente
eldatoesvisualizadocornounvalorencomaflotanteutilizando laconversión
tipo.e otipo
fsegúnsea elcaso.Nosevisualizanniloscerosfinalesniel
puntodecimalcuando noesnecesario.
eldatoesvisualizadocornounenteroconsigno
eldatoesvisualizadocornounenterooctal,sinelceroinicial
eldatoesvisualizadocornounacadenadecaracteres
eldatoesvisualizadocornounenterodecimalsinsigno
eldatoesvisualizadocornounenterohexadecimalsinelprefijo Ox
Observequealgunosdeestoscaracterestienen unsignificadodistintoqueenlafunción
scanf(verTabla4.1).

ENTRADAY SALIDADEDATOS 103
EJEMPLO4.16. Aquitenemosunprogramasencílloenelque seutílizalafunción printf.
#include<stdio.h>
#include<math.h>
main()
(
/*escribirvariosnúmerosencomaflotante*/
floati=2.0,j=3.0;
printf("%f%f%f%f",i,j,i+j,sqrt(i+j));
}
Observequelosdosprimerosargumentosdentrodelafunción printfsonvariablessimples, eltercer
argumentoesunaexpresiónaritméticayelúltimoargumentounareferenciaaunafunciónquetieneuna
expresiónnuméricacomoargumento.
Laejecucióndelprogramaproducelasiguientesalida:
2.0000003.0000005.0000002.236068
EJEMPLO 4.17. SupongamosquetenemosunprogramaenCqueincluyelassiguienteslíneas.En
ellaspuedeversecómosepuedenvisualizardistintostipos
dedatosmediantelafunción printf.
#include<stdio.h>
main()
{
charconcepto[2O];
intnuro_partida;
floatcoste;
printf(11%8%d%fll,conceptolno_partida,coste);
}
Lacadenadecontrol delafunciónprintfes"%s %d%f".Contíenetresgruposdecaracteres.El
primergrupodecaracteres,%s,indicaqueelprimerargumento
(concepto)representaunacadena de
caracteres.Elsegundogrupodecaracteres, %d,indicaqueelsegundoargumento (num_partida)re­
presentaunvalorenterodecimal,yeltercergrupodecaracteres,%
f,indicaqueeltercerargumento
(coste)representaunvalorencomaflotante.
Observequelosargumentosnoestánprecedidosporampersands.Estoesunavariaciónsobrelafun­
ción
scanf,querequiereampersandsentodoslosargumentosquenoseannombresdeformaciones(ver
Ejemplo
4.5).
Supongamosahoraquea concepto,num_partidaycosteseleshaasignadolosvalores
cremallera,12345y0.05,respectivamente,dentrodelprograma.Cuandoseejecutalainstrucción
printf,segeneralasiguientesalída.
cremallera123450.050000

104 PROGRAMACiÓN ENC
Losespaciosenblancoentrelosdatossongeneradosporlosespaciosenblancoqueaparecenenlacadena
decontrol
delainstrucciónprintf.
Supongamosquelainstrucción printfsehaescritoasí:
printf("%s%d%f",concepto,
num-partida,coste);
Lainstrucciónprintfesválidasintácticamente,aunquehacequelosdatosdesalidasepresentensin
separación,estoes,
cremallera1234S0.0S0000
Laconversióntipof ylatipoeseutilizanparavisualizarvaloresencomaflotante.Sin
embargo,laúltimahacequeseincluyaenlasalidaelexponente,mientrasquelaprimerano.
EJEMPLO4.18.Elsiguienteprogramageneralasalidadelmismovalorencomaflotantededosfor­
masdistintas.
#include<stdio.h>
main() / * visualizarunvalorencomaflotantededos
formasdiferentes*/
{
doublex=SOOO.O,y =0.002S;
printf("%f%f %f%f", x,y,x*y,x/y);
printf(l!%e%e %e %e
11
,x,y,x*y,x/y);
}
Lasdosinstruccionesprint ftienenlosmismosargumentos.Sinembargo,laprimerainstrucción print f
utilizalaconversióntipo
f,mientrasquelasegundautilizalaconversióntipo e.Observetambiénla
repeticióndelcarácterdenuevalíneaenlaprimerainstrucción
printf.Estohacequelasalidaaparezca
doblementeespaciada,comosemuestraacontinuación.
Cuandoseejecutaelprograma,segeneralasiguientesalida.
SOOO.OOOOOO 0.002S0012.S000002000000.000000
S.000000e+032.SOOOOOe-031.2S0000e+Ol2.000000e+06
Laprimeralíneadesalidamuestralascantidadesrepresentadaspor x,y,x*yyx/yenformatoencoma
flotanteestándar,sinexponentes.Lasegundalíneadesalidamuestralasmismascantidadesennotación
científica,conexponentes.
Observequecadavalorsepresentaconseiscifrasdecimales.Sepuedemodificar
elnúmerodecifras
decimalesespecificandola
precisiónencadagrupodecaracteresdentrodelacadena decontrol(haymás
informaciónsobreestoenlasección
4.7).
Lafunciónprintfinterpretalaconversióntiposdeformadiferenteacomolohacela
funciónscanf.Enlafunciónprintfseutilizalaconversióntiposparavisualizarunacade­
nadecaracteresqueacabaenelcarácternulo(\O) .Sepuedenincluircaracteresdeespaciado
enlacadenadecaracteres.

ENTRADAYSALIDADEDATOS 105
EJEMPLO4.19.Lecturayescrituradeunalinea detexto.Elsiguienteesunpequeñoprogramaen e
queleeunalíneadetextoydespuéslaescribe,talycomoseintrodujo.Elprogramailustralasdiferencias
sintácticas
enlalecturaylaescritnradeunacadenadecaracteresquecontiene,entreotros,caracteresde
espaciado.
#include<stdio.h>
main() /*leeryescribirunalíneadetexto* /
{
charlinea[80];
scanf("%[A]",linea);
printf(11%8
11,linea);
}
Observeladiferenciaenlascadenasdecontroldelasfunciones scanfyprintf.
Supongamosahoraque seintroduceporeldispositivodeentradaestándarlasiguientecadenadeca­
racterescuandoseejecutaelprograma.
¡ElREALMADRIDesunodelosmejoresequiposdefútbolespañoles!
Estacadenadecaracterescontieneletrasminúsculas,mayúsculas,signosdepuntuación ycaracteresde
espaciado.Sepuedeintroducirlacadenacompletaconlafunción
scanfsimplemente,siemprequeter­
mine
enuncarácterdenuevalinea(pulsandolatecla INTRO).Lafunciónprintfharáquesevisualice
lacadenacompletaeneldispositivodesalidaestándar,tal
ycomoseintrodujo.Portanto,lacomputadora
generaráelmensaje
¡ElREALMADRIDesunodelosmejoresequiposdefútbolespañoles!
Sepuedeespecificarunalongituddecampo mínimaanteponiendoalcarácterdeconversión
unenterosinsigno.
Sielnúmerodecaracteresdeldatocorrespondiente esmenorquelalongitud
decampoespecificada,entonceseldatoseráprecedidoporlosespaciosenblanconecesarios
paraqueseconsigalalongituddecampoespecificada.Sielnúmerodecaracteresdeldatoexce­
delalongituddecampoespecificada,sevisualizaráeldatocompleto.Estecomportamientoes
justoelcontrarioaldelindicadordelongitud
decampoenlafunción scanf,queespecificauna
longituddecampo
máxima.
EJEMPLO4.20.Elsiguienteprogramaen eilustraelusodelindicadordelongitnddecampomínima.
#include<stdio.h>
main()
{
/*especificacióndelongituddecampomínima*(
inti=12345;
floatx=345.678;
printf("%3d%5d%8d", i, i,i);
printf("%3f%10f%13f", x, x,x);
printf("%3e%13e%16e",x, x,x);
}

106 PROGRAMACiÓN ENC
Observelaaparición dedoscaracteresdenuevalíneaseguidosenlasdosprimerasinstrucciones prin­
tf.Estoharáquelaslíneas desalidaaparezcanconseparacióndoble,comosemuestraacontinuación.
Cuando
seejecutaelprograma,segeneralasiguientesalida.
1234512345 12345
345.678000345.678000 345.678000
3.456780e+023.456780e+02 3.456780e+02
Enlaprimeralínea desalidaapareceunenteroendecimalutilizandotreslongitudes decampomínimas
(tres,cincoyochocaracteres).Elvalorenterocompletosevisualizadentrodecadacampo,aunquela
longitud
decamposeademasíadopequeña(comoocurreconelprimercampoeneste ejemplo).
Elsegundovalor
desalidadelaprimeralínea esprecedídoporunespacioenblanco.Esteespacioen
blancoesgeneradoporelqueapareceenlacadenadecontrolseparandolosdosprímerosgrupos
de
caracteres.
Eltercervalordesalídaesprecedidoporcuatroespaciosenblanco.Unespacioenblancosedebe
alqueapareceenlacadenadecontrolseparandolosdosúltimosgruposdecaracteres.Losotrostres
espaciosenblancorellenanlalongituddecampomínima,queesmayorqueelnúmerodecaracteresdel
valordesalida(lalongituddecampomínimaesocho,peroelvalordesalidatienesólocincocarac­
teres).
Sepuedenobservarsituacionesanálogasenlasdoslíneassiguientes,en lasquesevisualizaunvalor
encomaflotanteutilizandolaconversióntipo f(línea2)ylaconversióntipoe(línea3).
EJEMPLO4.21. PresentamosunavariacióndelprogramadelEjemplo4.20,queutilízalaconversión
tipo
g.
#inc1ude<stdio.h>
main() /*especificacióndelongituddecampomínima*/
{
inti=12345;
floatx=345.678;
printf("%3d%5d%8d",
i,i,i);
printf("%3g%10g%13g", x,x,x)
printf("%3g%13g%16g",x, x,x);
)
Laejecucióndeesteprogramahacequesevisualicenlassiguienteslíneas.
1234512345 12345
345.678
345.678345.678
345.678
345.678
345.678
Losvaloresencomaflotantesevisualizanconunaconversióntipo f,loqueconllevaunaescrítura
máscorta.Laslongitudesdecamposeadecúanalasespecificacionesquesehacenenlacadenade
control.

ENTRADAYSALIDA DEDATOS 107
4.7.MÁSSOBRELAFUNCIÓN printf
Estaseccióncontienedetallesadicionalessobre lafunciónprintf.Losprogramadoresque
esténcomenzandocon
epuedensaltarseestasecciónporelmomento,silodesean.
Yahemosaprendidocómoespecificar unalongituddecampomínima enlafunciónprintf.
Tambiénesposibleespecificarelmáximonúmerodecifrasdecimales paraunvalorencoma
flotante,oelmáximonúmerodecaracteres
paraunacadenadecaracteres.Estaespecificación
sedenomina
precisión.Laprecisiónes unenterosinsignoquesiempreesprecedido porun
puntodecimal.Siseespecificala longituddecampomínimaademásdelaprecisión(comode
hechosuelehacerse),entonceslaespecificacióndelaprecisiónsiguealaespecificacióndela
longituddecampo.Estasdosespecificacionesenterasprecedenalcarácterdeconversión.
Unnúmero
encomaflotantese redondearásisedeberecortarparaajustarsealaprecisión
especificada.
EJEMPLO4.22. Acontinuaciónsemuestraunprograma queilustraelusodelaespecificacióndela
precisión
connúmerosencomaflotante.
#include<stdio.h>
main()/*visualizarunnúmeroencomaflotante
convariasprecisionesdiferentes*/
{
floatx=123.456;
printf("%7f%7.3f%7.lf", x,x,x);
printf("%12e%12.5e%12.3e",x,x,x);
}
Cuandoseejecutaelprograma,segeneralasigllientesalida:
123
..456000123.456123.5
1.234560e+021.23456e+021.235e+02
Laprimeralínea esprodllcidaporlaconversióntipo f.Observequeeltercernúmero seharedondea­
doac~usadelaprecisiónespecificada(unacifradecimal).Observetambién queseañadenespacios en
blancoparaconseguirunalongitud decampomínimaespecificada(sietecaracteres)...
Lasegundalínea,producidaporunaconversióntipo e,tieneanálogascaracterísticas. Denuevove­
mosqueseharedondeadoeltercernúmeroparasatisfacerlaespecificación deprecisiónhecha(trescifras
decimales).Observetambién
losespaciosenblancoañadidosparasatisfacerlalongitud decampomínima
(12caracteres).
Noesnecesarioquelaespecificacióndeprecisiónvayaacompañadade lalongituddecam­
pomínima.
Esposibleespecificar laprecisiónsin lalongituddecampomínima,aunque lapre­
cisióndebeseguirapareciendoprecedida
porun
¡:¡untodecimal.
EJEMPLO4.23. Reescribamosahora elprogramamostrado enelúltimoejemplosinningunaespecifi­
cación
delongituddecampomínima,peroconespecificacionesdeprecisión.

10S PROGRAMACiÓN ENC
#include<stdio.h>
main()/*visualizarunnúmeroencomaflotante
convariasprecisionesdiferentes*/
{
floatx=123.456,
printf("%f%.3f%.lf", x,x,x);
printf(lI%e%.5e%.3e",XIXIx)¡
}
Laejecucióndeesteprogramaproducelasalidasiguiente.
123.456000123.456123.5
1.234560e+021.23456e+021.235e+02
Observequeeltercernúmerodecadalíneanoesprecedidoporvariosespaciosenblanco,yaquenohay
longituddecampomínimaquesatisfacer.Salvoenestecaso,lasalidaeslamismaquelageneradaenel
ejemploanterior.
Lasespecificaciones
delongituddecampomínimaydeprecisiónsepuedenaplicaradatos
detipocarácterademás
deadatosnuméricos.Cuandoseaplicaaunacadenadecaracteres,la
longituddecampomínimaseinterpretadelamismaformaqueconunacantidadnumérica;es
decir,seañadenespaciosenblancosilacadenadecaracteresesmáscortaquelalongitudde
campomínimaespecificada,ysepresentarálacadenadecaracterescompletasiesmáslarga
quelalongituddecampomínimaespecificada.
Portanto, laespecificacióndelalongitudde
campomínimanoimpediránuncaquesevisualicelacadenadecaracterescompleta.
Sinembargo,laespecificacióndelaprecisióndeterminaelmáximonúmerodecaracteres
quepuedenservisualizados.Silaprecisiónespecificadaesmenorqueelnúmerototaldecarac­
teresdelacadena,nosemostraránloscaracteressobrantesdelapartederechadelacadena.
Estoocurriráauncuandolalongituddecampomínimaseamayorquelacadenadecaracteres,
añadiéndoseenestecasocaracteresenblancoalacadenatruncada.
EJEMPLO4.24. Lassiguienteslíneas deprogramailustran elusodelasespecificacionesdelongitud
decampomínimaydeprecisiónenlavisualizacióndeunacadenadecaracteres.
#inc1ude<stdio.h>
main()
{
charlinea[12]
,
printf("%10s%15s%15.5s%.5s",linea,linea,linea,linea);
}

ENTRADAYSALIDADEDATOS 109
Supongamosahoraque seleasignaa linealacadenadecaractereshexadecimal.Cuandoelprogra­
maseejecuta,
segeneralasiguientesalida:
hexadecimal hexadecimal hexadhexad
Laprimeracadena decaracteressevisualizacompleta,aunqueestacadenaconsta de11caracteresyla
longituddecampomínima
essólode10caracteres. Deestaforma,laprimeracadenasobrepasa laespe­
cíficación
delongituddecampomínima.Alasegundacadena decaracteresseañadencuatroespaciosen
blancoalaizquierdaparasatisfacerlalongitud
decampomínima de15caracteres;deestaforma, sedice
quelasegundacadenaestá
ajustadaa laderechadesucampo.Laterceracadenaconstadesólocinco
caracteresque
nosondeespaciado,acausa delaespecificacióndelaprecisióndecincocaracteres;sin
embargo,
sehanañadido10espaciosenblancoparasatisfacer laespecificacióndelongituddecampo
mínima,quees
de15caracteres.Laúltimacadenatambíénconsta decincocaracteresquenoson de
espaciado.Noseañadenespaciosenblancoporqueno sehaespecificadoningunalongituddecampo
mínima.
Lamayoríadelasversiones deepermitenelusodeprefijosdentro delacadenadecontrol
paraindicarlalongituddelargumentocorrespondiente. Losprefijospermitidos sonlosmismos
quelosprefijosutilizados conlafunciónscanf.Así,una1(Lminúscula) indicaunargumento
enterolargoconosinsigno,o unargumentodedobleprecisión; unahindicaunenterocorto
conosinsigno.Algunasversiones deepermitenunaL(mayúscula)paraindicarunlongdou­
ble.
EJEMPLO4.25. SupongamosqueunprogramaenCincluyelassiguientesinstrucciones.
#include<stdio.h>
main()
{
shorta,
b;
longc,d;
printf("%5hd%6hx%810 %lu",a,b,c,dI;
}
Lacadenadecontrolindicaqueelprimerdatoseráunenterocortoendecimal,elsegundounen­
terocortoenhexadecimal,eltercerounenterolargooctalyelcuartounenterolargosinsigno(de­
cimal).Nótesequelostresprimerosgrupostienenespecificadalalongitud
decampomíníma,peroel
cuartono.
Algunasversionesdeepermitenqueseescribanenmayúsculasloscaracteres deconversión
x,EyG.Estoscaracteresdeconversiónenmayúsculashacenquecualquierletradelosdatosde
salidasepresenteenmayúsculas.(Nóteseque esteusodecaracteresdeconversiónenmayúscu­
las
esdiferentequeelquesehaceenlafuncións e anf.)

110 PROGRAMACiÓN ENC
EJEMPLO4.26.Elsiguienteprogramailustralautilización decaracteresdeconversión enmayúsculas
enlafunción
printf.
#include<stdio.h>
main()
(
/*usodecaracteresdeconversiónenmayúsculas*/
inta=OxSOec;
floatb=0.3e-12;
printf("%4x%10.2e", a,b);
printf("%4X%10.2E",a,b);
}
Observequelaprimerainstrucción printfcontienecaracteres deconversiónenminúsculas,mientras
quelasegundainstrucción
printfcontienecaracteres deconversiónenmayúsculas.
Cuandoseejecutaelprograma,
segeneralasiguientesalida.
SOec
SOEC
3.00e-13
3.00E-13
Laprimeracantidadencadalíneaesunnúmerohexadecimal.Nótese
quelasletrasec(quesonpartedel
númerohexadecimal)semuestranenminúsculasenlaprimeralineayenmayúsculasenlasegunda.
Lasegundacantidad
decadalíneaesunnúmerodecimal encoma flotantequeincluyeunexponente.
Observequelaletra
e,queindicaelexponente,semuestracomominúsculaenlaprimeralínea ycomo
mayúsculaenlasegunda.
Selerecuerdadenuevoallectorquenotodosloscompiladorespermiteneluso
deCaracteresde
conversiónenmayúsculas.
Ademásdelalongituddecampomínima,laprecisión yelcarácterdeconversión,cadagru­
po
decaracteresdentrodelacadena decontrolpuedeincluirun indicador,queafectaacómose
muestralasalida.Elindicadorsedebeponerinmediatamenteacontinuacióndelsigno
deporcen­
taje
(%).Algunoscompiladorespermitenincluirdosomásindicadoresseguidosdentrodel
mismogrupodecaracteres.LaTabla4.3muestralosindicadores
deusomáscomún.
EJEMPLO4.27.Acontinuaciónsepresentaunsencilloprogramaen equeilustraelusodeindicado­
resconcantidadesenteras
yencomaflotante.
#include<stdio.h>
main()/*usodeindicadoresconnúmerosenterosyencomaflotante*/
(
inti=123;
floatx=12.0,Y=-3.3;
printf(":%6d%7.0f%10.le:",i,x,y);
printf(":%-6d%-7.0f%-10.le:",i,x,y);
printf(":
%+6d%-j-7.Of.%+10.le:",i,x,y);
printf(":%-+6d%-+7.0f%~+10.le:\n\n", i,x,y);
printf(":%7.Of%#7.Of%7g%#7g:",x, x,y,y);
}

ENTRADAYSALIDA DEDATOS 111
Tabla4.3.Indicadoresdeusocomúu
Eldato
seajustaalaizquierdadentrodelcampo(siserequierenespaciosenblanco
paraconseguirlalongitud
decampominima,seañaden despuésdeldatoenlu­
gar
deantes).
+ Cadadatonuméricoesprecedidoporunsigno (+o-J.Sinesteindicador,sólolos
datosnegativossonprecedidosporelsigno
-.
O Haceque sepresentencerosenlugar deespaciosenblanco. Seaplicasóloadatos
queesténajustadosaladerechadentro
decamposdelongitudmayorqueladel
dato.
(Nota:Algunoscompiladoresconsideranelindicadorcerocomoparte delaespeci­
ficación
delalongituddecampoenlugar decomoindicadorreal.Estoasegura
queel
Oesprocesadoelúltimo sihayvariosindicadorespresentes.)
(espacioenblanco)
Cadadatonuméricopositivoesprecedidoporunespacioenblanco.Esteindicador
seignorasiseencuentrapresentetambién
elindicador+.
# (conlasconversionestipo oytipox)
Hacequelosdatosoctalesyhexadecimalesseanprecedidospor OyOx,
respectivamente.
# (conlasconversionestipo e,tipofytipog)
Hacequesepresententodoslosnúmerosencomaflotanteconunpunto,aunque
tenganunvalorentero.Impideeltruncamientodelosceros
deladerechareali­
zadaporlaconversióntipo
g.
Cuandoseejecutaelprograma,seproducelasiguientesalida.(Losdospuntosindicanelprincipiodel
primercampoyelfinaldelúltimocampodecadalínea.)
123 12-3.3e+00:
:123 12 -3.3e+00
+123+12
73.3e+00:
:+123 +12 -3.3e+00
12 12. -3.3-3.30000:
Laprimeralíneasirveparailustrarcómoaparecenlosnúmerosenterosyencomaflotantesinningún
indicador.Cadanúmeroesajustadoaladerechadentrodesurespectivocampo.
Lasegundalíneamuestra
losmismos·números,utilizandolasmismasconversiones,conunindicador-encadagrupodecaracteres.
Observequelosnúmerosseajustanahoraalaizquierdadentro
desuscamposrespectivos.Laterceralínea
muestraelefectodeutilizarunindicador
+.Losnúmerosabaraseajustanaladerecha,comoenlaprimera
línea,perocadanúmero(tantopositivoscomonegativos)esprecedidoahoraporsusigilo.
Enlacuartalíneavemoselefectodecombinarunindicador-conunindicador
+.Losnúmerosestán
ahoraajustadosalaizquierdayprecedidosporsusigno.Finalmente,laúltimalíneamuestradosnúmeros
encomaflotante,cadaunomostradoprimerosinelindicador#,ydespuésconél.Observequeelefecto

112 PROGRAMACiÓN ENC
delindicadoresincluirunpuntodecimalenelnúmero 12.(queesescritoconlaconversióndetipo f)e
incluirlaristradecerosenelnúmero- 3 . 3 OOOO(escritoconlaconversióntipog).
EJEMPLO4.28. Consideremosahoraelsiguienteprograma,quevisualizanúmerosdecimales,octales
yhexadecimales.
#inc1ude<stdio.h>
main()/*usodeindicadoresconnúmerossinsigno
decimales,octalesyhexadecimales*/
{
inti =1234,j=01777,k=Oxa08c;
}
printf(":%8u %80%8x:",
i,
printf(":%-8u%-80%-8x:",
printf(":%#8u %#80 %#8X: ",
printf(":%08u%080%08X: " ,
j,k);
i,jik)¡
i,j,k)¡
i,j,k);
Laejecucióndeesteprogramaoriginalasiguientesalida.(Losdospuntosindicanelcomienzodel
primercampoyelfinaldelúltimocampodecadalínea.)
1234 1777 a08c:
:1234 1777 a08c
1234 01777 OXA08C:
:00001234000017770000A08C:
Laprimeralíneamuestralavisualizaciónde unenterosinsigno,octalyhexadecimalsinindicadores.
Observequelosnúmerosestánajustadosaladerechadentrodesusrespectivoscampos.Lasegundalínea
muestralosmismosdatos,utilizandolasmismasconversiones,peroconelindicador-encadagrupode
caracteres.Ahoralosnúmerosseencuentranajustadosalaizquierdadentrodesusrespectivoscampos.
Enlaterceralineavemoslasalidaqueseobtienecuandoseutilizaelindicador#.Esteindicadorhace
queelnúmerooctal
1777seaprecedidoporunO(apareciendocomo 01777)Yelnúmerohexadecimal
aparezcaprecedidopor
OX(estoes,OXA08C).Observequeelenterosinsignodecimal 1234noseve
afectadoporesteindicador.Observetambiénqueelnúmerohexadecimalcontieneahoraletrasmayúscu­
las,yaqueelcarácterdeconversiónestáescritocomomayúscula
(X).
Laúltimalineailustraelusodelindicador o.Esteindicadorhacequeloscamposserellenenconceros
enlugardeespaciosenblanco.Vemos denuevocaractereshexadecimalesenmayúsculas,enrespuestaal
carácterdeconversiónescritocomomayúscula(
X).
EJEMPLO4.29. Elsiguienteesquemadeprogramasirvecomoejemplodelusodeindicadoresenla
salidadecadenasdecaracteres.
#inc1ude<stdio.h>
main()
{
charlinea[12];

ENTRADAYSALIDA DEDATOS 113
printf(":%15s%15. 5s%.5s:", linea,linea,linea);
printf(":%-15s%-15.5s%-.5s",linea,linea,linea);
}
Supongamosahoraquealarraydecaracteres lineaseleasignalacadenadecaracteres menor-caso.
Segenerarálasignientesalidacuandoseejecuteelprograma.
menor-caso menormenor:
:menor-caso menor menor:
Enlaprimeralíneasevecómosevisualizanlascadenasdecaracterescuandonoseincluyenindicadores,
comoseexplicóenelEjemplo4.24.Lasegundalíneamuestralasmismascadenas,ajustadasalaizquier­
da,enrespuestaalindicador-encadagrupodecaracteres.
Loscaracteresdentrodelacadenadecontrolquenosereconozcansevisualizarántaly
comoaparezcan.Estonospermiteincluirrótulosymensajesentrelosdatos,si asílodeseamos.
EJEMPLO4.30. Enelsiguienteprogramasemuestracómosepuedenvisualizarrótulos.
#include<stdio.h>
main()
{
/*salidadenúmerosencomaflotanteconrótulos*/
floata =2.2,b =-6.2,xl=.005,x2=-12.88;
printf("$%4.2f%7.1f%%", a,b);
printf("xl=%7.3fx2=%7.3f",xl,x2);
}
Esteprogramahacequeelvalordea (2.2)seaprecedidoporelsignodeldólar ($)yquesepresente
traselvalordeb (- 6 .
2)unsignodeporcentaje(%).Observelosdossignos deporcentajeconsecuti­
vosenlaprimerainstrucción
printf.Elprimersignodeporcentajeindicaelcomienzo deungrupode
caracteres,mientrasqueelsegundoesinterpretadocomounrótulo.
Lasegundainstrucción
printfhacequeelvalor dexlaparezcaprecedidodelrótulo x2=.Apare­
cerántresespaciosenblancoseparandoestosdatosrotulados.
Semuestraacontinuaciónlasalidagenerada.
$2.20 -6.2%
xl=l0.005x2=-12.880
Ellectordebetenerpresenteslasposiblesvariacionesdelascaracterísticasdelafunción
printfendiferentesversionesdeC.Lasdescritasanteriormenteenestasecciónsonmuyco­
munes,aunquepuedenexistiralgunasvariacionesenlaformaenqueserealicen. Tambiénse
sueledisponerdeotrasposibilidadesenmuchasversionesdellenguaje.

114 PROGRAMACiÓN ENe
4.8.LASFUNCIONES getsYputs
Cdisponedeunciertonúmerodefuncionesdebibliotecaquepermitendiferentesformasde
transferenciadedatoshaciadentroofueradelacomputadora.Veremosalgunasdeestasfuncio­
nesenelCapítulo12,enelquetrataremoslosarchivosdedatos.Sinembargo,antesdeterminar
estecapítulomencionaremoslasfunciones
getsyputs,quefacilitanlatransferenciadecade­
nasdecaracteresentrelacomputadora
ylosdispositivosdeentrada/salidaestándar.
Cadaunadeestasfuncionesaceptaunsoloargumento.Elargumentodebeserundatoque
represente
unacadenadecaracteres(unaformacióndecaracteres). Lacadenadecaracteres
puedeincluircaracteresdeespaciado.Enelcasode
gets,lacadenaseintroduciráporeltecla­
do
yterminarácon uncarácterdenuevalínea(porejemplolacadenaterminarácuandoel
usua"'
riopulselatecla Intro).
Lasfuncionesgetsyputsofrecenalternativassencillasalusode scanfyprintfpara
lalectura
yescrituradecadenasdecaracteres,comosemuestraenelsiguienteejemplo.
EJEMPLO4.31.Lectura yescrituradeunalíneadetexto. Éstaesotraversióndelprogramapre­
sentadoenelEjemplo4.19, queleeunalineadetextoydespuéslaescribe ensufonnaorigina!.
#include<stdio.h>
main() /*leeryescribirunalíneadetexto* /
(
charlinea[80];
gets(linea)
;
puts(linea);
}
Esteprogramautiliza getsyputsenlugardescanfyprintfparatransferirtextohaciadentroy
haciafuera
delacomputadora.Nótese quelasintaxisesmássencillaenesteprograma(compárese conel
programadelEjemplo4.19). Porotraparte,lasfuncionesscanfyprintfenelprogramaanterior se
podríanexpandirincluyendo datosadicionales,mientras queenelpresenteprograma nosepuede.
Cuando
seejecutaesteprograma, secomportadelamismaforma queelmostradoenelEjem­
plo4.19.
4.9.PROGRAMACIÓN INTERACTIVA(CONVERSACIONAL)
Muchosprogramasdecomputadoramodernosestándiseñadospara'crearundiálogointeractivo
entre
lacomputadoraylapersonaqueutilizaelprograma(el"usuario»).Estosdiálogossuelen
involucrarunainteraccióndetipopregunta-respuesta,
enlaquelacomputadorahacelaspre­
guntas
yelusuarioproporcionalasrespuestas,oviceversa.Deestaformaparecequelacompu­
tadora
yelusuarioestándesarrollandounaciertaformadeconversaciónlimitada.
EnCestosdiálogossepuedencrearmedianteelusoalternativodelasfunciones seanfy
printf.Laprogramaciónrealessencilla,aunqueavecescausaconfusiónentrelosprograma­
doresqueseinicianen
equelafunción printfseutilicecuandoseintroducendatos(para

ENTRADAYSALIDA DEDATOS 115
visualizarlaspreguntasdelacomputadora)ycuandosemuestranresultados.Porotraparte,
scanfsóloseutilizaparalaverdaderaentradadedatos.
Enelsiguienteejemploseplasmanlasideasbásicas.
EJEMPLO4.32.Calificacionesmedias deexámenes.Enesteejemplosepresentaunsencillopro­
gramainteractivoen
equeleeelnombre deunestudianteytrescalificaciones deexámenes,ydespués
calculalacalificaciónmedia.Losdatosseintroducen
defonnainteractiva, lacomputadorapidelainfor­
maciónalusuarioyéstelaproporcionaconunfonnatolibre.Laentrada
decadadato sehaceenunalínea.
Unavezquesehanintroducidotodoslosdatos,lacomputadoracalcularálamediadeseadayescribirá
todoslosdatos(tantolos
deentradacomolamediacalculada).
Acontinuaciónsepresentaelprograma.
#include<stdio.h>
main() / *ejemplodeprogramainteractivo* /
{
charnombre[2O];
floatnotal,nota2,nota3,media;
printf("Porfavor,introducetu,nombre:");
/ *introducirnombre* /
scanf("%[A]
",nombre);
printf(11Porfavor,introducelaprimeranota:ti);
/*introducirnota1*/
scanf("%f",&notal);
printf("Porfavor,introducelasegundanota:");
/*introducirnota2*/
scanf(11%f"/&nota2);
printf("Porfavor,introducelaterceranota:");
/*introducirnota3*/
scanf(n%f11,&nota3)i
}
media ~(notal+nota2+nota3)/3;
printf("Nombre: %-s",nombre);
printf("Nota1:%-5.lf",notal);
printf("Nota2:%-5.lf",nota2);
printf("Nota3:%-5.lf", nota3);
printf("Media:%-5.lf", media);
/~calcular lamedia*/
/*escribirsalida*/
Observequehaydosinstruccionesasociadasacadadatodeentrada.Laprimeraesunainstrucción printf,
quegeneralasolicituddeldato.Lasegundainstrucción,unafunción scanf,hacequeseintroduzcael
datodeldispositivodeentradaestándar(porejemploelteclado).
Despuésdelnombredelestudiantey
lastrescalificacionesdelosexámenessecalculalapuntuación
media.
Acontinuaciónsevisualizanlosdatosdeentradaylamediacalculadacomoresultadodelaejecu­
cióndelgrupodeinstrucciones
printfqueaparecenalfinaldelprograma.

116 PROGRAMACiÓN ENC
Semuestraacontinuaciónunasesióninteractivatipica. Sehansubrayadolasrespuestasdelusuario
parailustrarlanaturalezadeldiálogo.
Porfavor!introducetunombre:RosaRamírez
Porfavor,introducelaprimeranota:~
Porfavor,introducelasegundanota:62.5
Porfavor,introducelaterceranota:~
Nombre:RosaRamírez
Nota1: 88.0
Nota2: 62.5
Nota3: 90.0
Media 80.2
Enmuchosejemplosdeloscapítulossiguientes deestelibrosepodránverotrosprogramasinteractivos.
4.1.¿Cuálessonlasfunciones deentrada/salidamáscomúnmenteusadasenC?¿Cómose
accedeaellas?
4.2.¿Cómosellamaelarchivo decabeceradeentrada/salidaestándarenlamayoría delas
versionesdeC?¿Cómosepuedeincluirelarchivoenunprograma?
4.3.¿Cuáleselpropósito delafuncióngetchar?¿Cómoseutilizadentrodeunprograma
en
C?
4.4.¿Quéocurrecuandosedalacondición defindearchivoalleercaracteresconlafunción
getchar?¿Cómosereconocelacondicióndefin dearchivo?
4.5.¿Cómosepuedeutilizarlafunción getcharparaleercadenasdecaracteres?
4.6.¿Cuáleselpropósito delafunciónputchar?¿Cómoseutilizadentrodeunprograma
en
C?Compararlaconlafunción getchar.
4.7.¿Cómosepuedeutilizarlafunción putcharparaescribircadenasdecaracteres?
4.8.¿Quéesunarraydetipocarácter?¿Quérepresentacadaelementodeunarraydetipo
carácter?¿Cómoseutilizanlosarraysdetipocarácterpararepresentarcadenasdecarac­
teres?
4.9.¿Cuáleselpropósito delafunciónscanf?¿Cómoseutilizadentro deunprogramaen
C?Compararlaconlafunción
getchar.
4.10.¿Cuáleselpropósito delacadenadecontrolenlafunción scanf?¿Quétipodeinforma­
ciónaporta?¿Dequéestácompuestalacadenadecontrol?
4.11.¿Cómoseidentificacadagrupodecaracteresdentrodelacadenadecontrol?¿Cuálesson
loscaracteresconstituyentes
deungrupodecaracteres?
4.12.Siunacadenadecontroldentrodeunafunción scanfcontienevariosgruposdeca­
racteres,¿cómoseseparanlosgruposdecaracteres?¿Serequierencaracteresdeespa­
ciado?

4.13.
4.14.
4.15.
4.16.
4.17.
4.18.
4.19.
4.20.
4.21.
4.22.
4.23.
4.24.
4.25.
4.26.
4.27.
4.28.
4.29.
4.30.
4.31.
4.32.
ENTRADAYSALIDADEDATOS 117
Siexistencaracteresdeespaciadodentrodeunacadenadecontrol,¿cómoseinter­
pretan?
Comentarel significadodeloscaracteresdeconversiónutilizadosmásfrecuentementeen
lacadena
decontroldelafuncións c anf .
¿Quésímbolosespecialessedebenincluirconlosargumentos,además
delacadenade
control,enlafunción scanf?¿Enquésediferenciaeltratamiento delosarraysdelos
restantesargumentos?
Cuandoseintroducendatosmediantelafunción
scanf,¿quérelacionesdebehaberentre
losdatosylosargumentoscorrespondientes?¿Cómoseseparanvariosdatosentresí?
Cuandoseintroducendatosmediantelafunción
scanf,¿debenirprecedidoslosdatos
octales
deO?¿Debenirprecedidosde Ox(oOx)losdatoshexadecimales?¿Cómose
debenescribirlosdatosencomaflotante?
Cuandoseintroduceunacadena
decaracteresmediantelafunción scanfutilizandouna
conversióntipo
s,¿cómofinalizalacadena?
Cuandoseintroduceunacadena
decaracteresmediantelafunción scanf,¿cómose
puedeintroducirunacadenaquecontengacaracteres
deespaciado?
Idearunmétodoparalaintroducción
decadenasdecaracteresdelongitudindeterminada
quecontengacaracteres
deespaciadoytodosloscaracteresimprimibles,yquetermineal
pulsar
elretomodecarro.Reponderalacuestióndeformarelativaaltipodeconversión
requeridoenlacadena
decontroldeunafunciónscanf.
¿Quéseentiendeporcampo?
¿Cómosepuedeespecificarlalongituddecampomáximaparaundatodentro
delafun­
ción
scanf?
¿Quéocurresiundatodeentradacontienemáscaracteresquelalongitud decampomáxi­
mafijada?¿Ysieldatotienemenoscaracteres?
¿Cómosepuedenindicarlosargumentosenteroscortos,enteroslargosy
dedoblepreci­
siónenlacadenadecontrol
delafuncións c anf?
¿Cómose puedenindicarlosargumentos longdoubledentrodelacadenadecontrol
delafunciónscanf?¿Sedispone deestaposibilidadenlamayoría delasversiones
deC?
¿Cómo
sepuedesuprimirlaasignacióndeundatodeentradaalargumentocorrespon­
diente?
Silacadenadecontrol
deunafunciónscanfcontienvariosgrupos decaracteresqueno
estánseparadosporcaracteres
deespaciado,¿quéproblemapuedeaparecer
alutilizarla
conversióntipo
c?¿Cómosepuedesolucionaresto?
¿Cómoseinterpretanloscaracteresnoreconocidosdentro
delacadenadecontroldela
función
scanf?
¿Cuáleselpropósitodelafunción printf?¿CómoseutilizaenunprogramaenC?
Compáresecon
lafuncións c anf .
¿Enquédifiere
lacadenadecontrol delafunciónprintfdelade.1afunciónscanf?
Silacadenadecontroldelafunciónprintfcontienevariosgruposdecaracteres,¿cómo
sepuedensepararlosgruposdecaracteres?¿Cómoseinterpretanlosseparadores?
Citarloscaracteres
deconversióndeusomásfrecuenteenlacadenadecontroldela
función
printfyexplicarsusignificado.Compárenseconloscaracteresdeconversión
queseutilizanenlafunción
scanf.

118 PROGRAMACiÓN ENC
4.33.Enlafunciónprintf,¿debenirprecedidoslosargumentos(aquellosquenoseancade­
nasdecaracteres)deampersands?Compáreseconlafunción
scanfyexplíquenselas
diferencias.
4.34.¿Cuálesladiferenciaentrelasconversionestipo f,tipoe ytipogcuandoseestánpre­
sentandodatosmediantelafunción
printf?
4.35.Compararelusodelaconversióntiposenlasfunciones printfyscanf.¿Enqué
difierelaconversióntiposcuandoseestántratandocadenas
decaracteresquecontienen
caracteresdeespaciado?
4.36.¿Cómosepuedeespecificarenlafunción printflalongituddecampomínimaparaun
dato?
4.37.¿Quéocurresiundatocontienemáscaracteresquelosespecificadosenlalongitudde
campomínima?¿Ysi
eldatocontienemenoscaracteres?Compáreseconlaespecifica­
cíóndelongituddecampomáximaenlafunción
scanf.
4.38.¿Quéseentiendeporprecisióndeundatodesalida?¿Aquétipo dedatosseaplicaesto?
4.39.¿Cómosepuedeespecificarlaprecisiónenlafunción printf?
4.40.¿Quéleocurreaunnúmeroencomaflotantesisedeberecortarparasatisfacerlapreci­
siónespecificada?
¿Yaunacadena decaracteres?
4.41.¿Debeiracompañadaunaespecificacióndeprecisióndeunaespecificacióndelongitud
decampomínimaenlafunción
printf?
4.42.¿Cómosepuedenindicarlosargumentos detipoenterocorto,enterolargo ydedoble
precisiónenlacadena
decontroldelafunción printf?¿Cómosepuedenindicarlos
argumentos
longdouble?
4.43.¿Cómoseinterpretanloscaracteres deconversiónenmayúsculasencomparaciónconlos
caracteresenminúsculascorrespondientesenlafunción
printf?¿Aquétiposdecon­
versionesseaplicaesto?¿Permitenestadistincióntodosloscompiladores
deC?
4.44.Mencionarelpropósito delosindicadorescomúnmenteutilizadosenlafunción printf.
4.45.¿Puedenaparecer dosomásindicadoresconsecutivamenteen elmismogrupodecaracteres?
4.46.¿Cómoseinterpretanloscaracteresnoreconocidosdentrodelacadena decontroldeuna
función
printf?
4.47.¿Cómosepuedenrotularlosdatospresentadosporunafunción printf?
4.48.Mencionarelusodelasfunciones getsyputsenlatransferenciadecadenasdecarac­
teresentrelacomputadora
ylosdispositivosdeentrada/salidaestándar.Compararestas
funcionescon
scanfyprintf.
4.49.Explicar,entérminosgenerales,cómosepuedegenerar.undiálogointeractivoconeluso
repetidodepares
defuncionesscanfyprintf.
4.50.Unprogramaenecontienelassiguientesinstrucciones:
#include<stdio.h>
charalb,c;

ENTRADAYSALIDA DEDATOS 119
a)Escribirlasinstrucciones getcharoportnnasquepermitanintroducirlosvaloresde a,b y e
enlacomputadora.
b)Escribirlasinstrucciones putcharqueseocupendevisualizarlosvalorespresentes dea,b
yc.
4.51.ResolverelProblema4.50utilizandosólounafunción scanfyunaprintfenlugardelas
instrucciones
getcharyputchar.CompararlarespuestaconlasoluciónalProblema4.50.
4.52.UnprogramaenCcontienelassiguientesinstrucciones:
#include<stdio.h>
chartexto[80];
a)Escribirunainstrucción forquepermitaintroducirunmensaje de60caracteresysealmacene
enelarray
texto.Incluirunallamadaalafunción getcharenelbucle for,cornoenel
Ejemplo4.4.
b)Escribirunainstrucción forqueescribalos60primeroscaracteresdelarray texto.Incluir
unallamadaalafunción
putcharenelbuclefor,cornoenelEjemplo4.4.
4.53.ModificarlasolucióndelProblema4.52 a)paraquesepuedaintroducirunarraydecaracteresde
longitudnoespecificada.Supóngasequeelmensajenovaaexcedernuncalos
79caracteresyque
seterminaconuncarácterde
nuevalínea ().(VerEjemplo4.4.)
4.54.ResolverelProblema4.53utilizandounainstrucción scanfenlugardelainstrucciónfor(ver
Ejemplo4.8).¿Quéinformaciónadicional
seconsigueconelmétododescritoenelProblema4.53?
4.55.UnprogramaenCcontienelassiguientesinstrucciones:
#include<stdio.h>
inti /j /k;
Escribirdeformaadecuadaunafunción scanfquepermitaintroducirlosvaloresnuméricos dei,
jYk,asumiendoque:
a)Losvaloresdei,jy ksonenterosdecimales.
b)Elvalorde iesunenterodecimal, junenterooctaly kunenterohexadecimal.
e)Losvaloresde
iyjsonenteroshexadecimalesy kunenterooctal.
4.56.UnprogramaenCcontienelassiguientesinstrucciones:
#include<stdio.h>
inti
lj ,k',
Escribirdeformaadecuadaunafunción scanfquepermitaintroducirlosvaloresnurnéricosde i,
jYk,asumiendoque:
a)Losvaloresde i,jY ksonenterosdecimalesycadaunonoexcedelosseiscaracteres.
.b)Elvalorde iesunenterodecimal, junenterooctaly kunenterohexadecimal,ycadacanti­
dadnoexcedelos8caracteres.
e)Losvaloresde iyjsonenteroshexadecimales ykunenterooctal.Cadacantidadtiene7 o
menoscaracteres.

120 PROGRAMACiÓN ENC
4.57.Interpretarelsignificado delacadenadecontroldecadafuncións e anf:
&a,&b,&c, &d);
&a,&b,&c, &d);
&b,&c, &d);
&b,&c, &d);
~scanf("%12Id%5hd%151f%151e",
~scanf("%10Ix%6ho%5hu %14Iu",
oscanf("%12D%hd%15f%15e",&a,
ti)scanf("%8d%*d%12lf%15If",&a,
4.58.Unprogramaen econtienelassiguientesinstrucciones:
#include<stdio.h>
inti,ji
longix;
shortSi
unsignedU;
floatx;
doubledx;
charc¡
Escribirunafunción scanfparacadaunodelossiguientesgruposdevariablesqueleaunconjun­
to
dedatoscorrespondienteenlacomputadora ylosasignealasvariables.Supóngasequetodoslos
enterosseleeráncomocantidadesdecimales.
a)
i,
b)i,
j,xydx
ix,j,xyti
e)i,uye
ti)e,x,dxys
4.59.Unprogramaen econtienelassiguientesinstrucciones:
#include<stdio.h>
inti,ji
longix;
shortSi
unsignedu;
floatx;
doubledx;
charc¡
Escribirunafunción scanfquesatisfagacadaunodelossiguientespuntos,suponiendoquetodos
losenterosseleeráncomocantidadesdecimales.
a)Introducirlosvaloresde i,j,xydxsuponiendoquecadacantidadenteranoexcedelos
cuatrocaracteres,lacantidadencomaflotantenoexcedelosochocaracteres
yla cantidaden
dobleprecisiónnoexcedelos
15caracteres.
b)Introducirlosvalores dei,ix,j,xyusuponiendoquecadacantidadenteranoexcedelos
cincocaracteres,elenterolargonotienemásde
12caracteresylacantidad.encomaflotanteno
excedelos
10caracteres.
e)Introducirlosvaloresde
i,uyesuponiendo
qu",cadacantidadenteranotienemásdeseis
caracteres.
ti)Introducirlosvalores dee,x,dxyssuponiendoquelacantidadencomaflotantenoexcede
losnuevecaracteres,la cantidadendobleprecisión
nqexcedelos 16caracteresyelentero
cortonoexcedelosseiscaracteres.

ENTRADAYSALIDA DEDATOS 121
4.60.Unprogramaen econtienelassiguientesinstrucciones:
#inc1ude<stdio.h>
chartexto[80];
Escribirunafunción scanfqueleaunacadenadecaracteresy seleasignealarraydecaracteres
texto.Supongaquelacadenadecaracteresnocontieneningúncarácterdeespaciado.
4.61.ResolverelProblema4.60suponiendoquelacadenadecaracteressólocontieneletrasminúsculas,
espaciosenblancoycaracteresdenuevalínea.
4.62.ResolverelProblema4.60suponiendoquelacadenadecaracteressólocontieneletrasmayúsculas,
dígitos,signosdeldólaryespaciosenblanco.
4.63.ResolverelProblema4.60suponiendoquelacadenadecaracterescontienecualquiercaráctersal­
voelasterisco(supóngaseque elasteriscoseutilizaparaindicarelfinalde lacadena).
4.64.Unprogramaen econtienelassiguientesinstrucciones:
#inc1ude<stdio.h>
chara,b,c;
Supongamosquesedeseaintroducir $yqueseleasignea a,quea bseleasigne *yquea esele
asigne
@.Muestrecómosedebenintroducirlosdatosparacadaunadelassiguientesfunciones
scanf:
a)scanf("%c%c%c",&a,&b,&c);
b)scanf("%c%c%c",&a,&b,&c);
e)scanf("%s%s%s",&a,&b,&c);
d)scanf("%s%s%s",&a,&b,&c);
e)scanf("%ls%ls%ls",&a,&b,&c);
4.65.Unprogramaen econtienelassiguientesinstrucciones:
#inc1ude<stdio.h>
inta,b¡
f10atx,y;
Supongamosquesedeseaintroducir 12yqueleseaasignadoa a,que
-8leseaasignadoa b,
O.011leseaasignadoaxy-2.2x10'leseaasignadoa y.Muestrecómosedeberíanproporcio­
narlosdatosalacomputadoraalejecutarsecadaunadelassiguientesfunciones
scanf:
a)scanf("%d%d%f%f",&a,
b)scanf("%d%d%e%e",&a,
e)scanf("%2d %2d%5f%6e",
d)scanf("%3d %3d%8f%8e",
&b,
&b,
&a,
&a,
&x,&y);
&x,&y);
&b, &x,&y);
&b,&x, &y);
4.66.Unprogramaen econtienelassiguientesinstrucciones:
#inc1ude<stdio.h>
inti,.j/k;

122 PROGRAMACiÓN ENC
Escribirunafunción printfparacadaunodelossiguientesgruposdevariablesoexpresiones.
Supongaquetodaslasvariablesrepresentanenterosdecimales.
a)
i,jyk
b)(i+j},
e)sqrt(i+
(i-k)
j},abs(i-k}
4.67.Unprogramaen econtienelassiguientesinstrucciones:
#include<stdio.h>
inti,j,k¡
Escribirunafunción printfparacadaunodelossiguientesgruposdevariablesoexpresiones.
Supongaquetodaslasvariablesrepresentanenterosdecimales.
a)i,jyk,conunalongituddecampomínimadetrescaracteresporcantidad.
b)( i+j),(i -k),conunalongituddecampomínimadecincocaracteresporcantidad.
c)
sqrt(i+j),abs(i-k),conunalongituddecampomínimadenuevecaracterespara
laprimeracantidad
ysieteparalasegunda.
4.68.Unprogramaen
econtienelassiguientesinstrucciones:
#include<stdio.h>
floatx,y,z',
Escribirunafunción printfparacadaunodelossiguientesgruposdevariablesoexpresiones:
a)x,yyz
b)(x+y),
e)sqrt(x+
(x-z)
y},fabs(x-z}
4.69.Unprogramaen econtienelassiguientesinstrucciones:
#include<stdio.h>
floatx,y,z',
Escribirunafunción printfparacadaunodelossiguientesgruposdevariablesoexpresiones,
utilizandolaconversióntipo
fparacadacantidadencomaflotante:
a)
x,yyz,conunalongituddecampomínimadeseiscaracteresporcantidad.
b)(x+y),(x- z ) ,conunalongituddecampomínimadeochocaracteresporcantidad.
e)
sqrt(x+y),fabs(x-z),Conunalongituddecampomínimade 12caracterespara
laprimeracantidad
ynueveparalasegunda.
4.70.Repetirelproblemaanteriorutilizando
laconversióntipo e.
4.71.Unprogramaen econtienelassiguientesinstrucciones:
#include<stdio.h>
floatx,y,z',

ENTRADAYSALIDA DEDATOS 123
Escribirunafunción printfparacadauno delossiguientesgrupos devariablesoexpresiones,
utilizandolaconversióntipo
fparacadacantidadencomaflotante:
a)x,y yz,conunalongituddecampomínimadeochocaracteresporcantidad,consólo
cuatrocifrasdecimales.
b)(x+y),(x - z ) ,conunalongitud decampomínima denueve caracteresporcantidad,
contrescifrasdecimales.
e)sqrt(x+y),fabs(x-z),conunalongituddecampomínimade 12caracterespara
laprimeracantidad
y10paralasegunda.Presentarunmáximo decuatrocifrasdecimalesen
cadacantidad.
4.72.Unprogramaen econtienelassiguientesinstrucciones:
#inelude<stdio.h>
floatx,y,z¡
Escribirunafunción printfparacadauno delossiguientesgruposdevariablesoexpresiones,
utilizandolaconversióntipoeparacadacantidadencomaflotante:
a)x,yyz,conunalongituddecampomínimade 12caracteresporcantidad,concuatro
cifrasdecimales.
b)(x+y),(x-z),conunalongitud decampomínimade 14caracteresporcantidad,con
cincocifrasdecimales.
e)
sqrt(x+y),fabs(x-Z),conunalongituddecampomínima de12caracterespara
laprimeracantidad
y15paralasegunda.Presentarunmáximodesietecifrasdecimalesen
cadacantidad.
4.73.Unprogramaen econtienelassiguientesinstrucciones:
#inelude<stdio.h>
inta=0177,b=055,e=Oxa8,d=Oxiff;
Escribirunafunción printfparacadaunodelossiguientesgruposdevariablesoexpresiones:
a)a,b,eyd
b)(a+b),(e-d)
4.74.Unprogramaen econtienelassiguientesinstrucciones:
#inelude<stdio.h>
inti,ji
longix¡
unsignedu¡
floatx;
doubledx;
char
di
Escribirunafunción printfparacadaunodelossiguientesgruposdevaríables.Supongaque
todoslosenterossedeseanpresentarcomocantidadesdecimales.

124 PROGRAMACiÓN ENC
a)i,
b)i,
j,xydx
ix,j /XYti
e)i,u
ti)e,x,
ye
dxeix
4.75.Unprogramaen econtienelassiguientesinstrucciones:
#include<stdio.h>
inti,ji
longix¡
unsignedU¡
floatx;
doubledx;
chare;
Escribirunafunción print fparacadaunadelassiguientessituaciones,suponiendoquetodos
losenterossedeseanpresentarcomocantidadesdecimales.
a)Escribirlosvaloresde i,j,xydxsuponiendoquecadacantidadenteratieneunalongitudde
campominimadecuatrocaracteres
ycadacantidadencoma flotantesepresentaennotación
exponencialconuntotal
dealmenos14caracteresynomásdeochocifrasdecimales.
b)Repetira),visualizandocadacantidadenunalínea.
e)Escribirlosvaloresde
i,ix,j,xyusuponiendoquecadacantidadenteratendráunalongi­
tud
decampominima decincocaracteres,elenterolargotendráunalongituddecampominima
de
12caracteresyla cantidadencoma flotantetienealmenos 10caracteresconunmáximode
cincocifrasdecimales.Noincluirelexponente.
ti)Repetire),visualízandolastresprimerascantidadesenunalínea,seguidasdeunalíneaen
blanco
ylasotrasdoscantidadesenlalíneasiguiente.
e)Escribirlosvaloresde i,uye,conunalongitud decampominimadeseiscaracteresparacada
cantidadentera.Separarcontresespaciosenblancocadacantidad.
1)Escribirlosvalores dej,uyx.Visualizarlastrescantidadesenterasconunalongitud decampo
minimadecincocaracteres.Presentarla cantidadencoma flotanteutilizandolaconversióntipo
f,conunalongituddecampomínima de11caracteresyunmáximodecuatrocifrasdecimales.
g)Repetir
1),concadadatoajustadoalaizquierdadentro desucampo.
h)Repetir1),apareciendounsigno(tanto +como-)delantedecadadatoconsigno.
i)Repetir1),rellenandoelcampodecadaentidadenteraconceros.
j)Repetir1),apareciendoelvalordexconunpuntodecimal.
4.76.Supongamosque i,jYksonvariablesenteras yqueirepresentaunacantidadoctal, junacan­
tidaddecimal
ykunacantidadhexadecimal.Escribirunafunción
¡;Jrint fadecuadaparacada
unadelassiguientessituaciones.
a)Escribirelvalorde i,jyk,conunalongituddecampominímadeochocaracteresporcada
valor.
b)Repetira),concadadatoajustadoalaizquierda desucampo.
e)Repetir
a),concadadatoprecedidodeceros(Ox,enelcasodelacantidadhexadecimal).
4.77.Unprogramaen econtienelassiguientesdeclaracionesdevariables:
inti
=12345,j=-13579,k=-24680;
longix=123456789;
shortsx=-2222;
unsignedux=5555;

ENTRADAYSALIDADEDATOS 125
Mostrarlasalidaresultantedecadaunadelassiguientesinstrucciones printf:
a)printf("%d%d %d%ld%d%u
ll
,i,j,k,ix,sx,ux);
b)printf("%3d%3d%3d%31d %3d%3u
ll
,i,j ,k,ix,sx,ux);
e)printf("%Sd%Sd%Sd%151d %Sd%8u
ll
Ii,j,k,ix,sx,ux);
ti)printf("%-Sd%-Sd%-Sd %-151d%-Sd %-Su",i,j,k,ix,sx,ux);
e)printf("%+Sd%+Sd%+Sd %+151d%+Sd %8u",i,j,k,ix,sx,ux);
1)printf("%OSd%OSd%OSd %0151d%OSd %OSu",i,j,k,ix,sx,ux);
4.78.Unprogramaenecontienelassiguientesdeclaracionesdevariables:
inti=12345,j=Oxabed9,k=077777;
Mostrarlasalidaresultantedecadaunadelassiguientesinstrucciones printf:
a)printf("%d%x%0
11
,i,j,k);
b)printf("%3d%3x%30
11
Ii,j,k);
e)printf("%Sd%8x%80
11
Iirj,k);
ti)printf("%-Sd%-Sx%-80" Ii,j,k);
e)printf("%+Sd%+Sx%+80
11
,i,j,k);
1)printf("%OSd%#Sx%#So",i,j,k);
4.79.Unprogramaen econtienelassiguientesdeclaracionesdevariables:
floata=2.5,b=0.0005,e=3000.;
Mostrarlasalidaresultantedecadaunadelassiguientesinstrucciones printf:
~printf("%f%f%f",a,b,e);
b)printf("%3f%3f%3f",a,b,e);
e)printf("%Sf%Sf%Sf",a,b,e);
ti)printf("%S.4f%S.4f%8.4f",a,b,e);
e)printf("%S.3f%S.3f%S.3f",a,b,e);
1)printf("%e%e%e",a,b,e);
g)printf("%3e%3e%3e",a,b,e);
h)printf("%12e%12e%12e",a,b,e);
i)printf("%12.4e%12.4e%12.4e",a,b,e);
j)printf("%S.2e%S.2e%S.2e",a,b,e);
k)printf("%-Sf%-Sf%-Sf",a,b,e);
l)printf("%+Sf%+Sf%+Sf",a,b,e);
~)printf("%08f%OSf%OSf",a,b,e);
n)printf("%#Sf%#Sf%#Sf",a,b,e);
o)printf("%g%g%g",a,b,e);
p)printf("%#g%#g%#g",a,b,e);
4.80.Unprograma enecontienelassiguientesdeclaracionesdevariables:
charel;::1A/'.rc2='E','c3=-fe'i
Mostrarlasalidaresultantedecadaunadelassiguientesinstrucciones printf:
a)printf("%e%e%e",el,e2,e3);
b)printf("%e%e%e",el,e2,e3);

126 PROGRAMACiÓN ENC
e)printf("%3e%3e%3e",el,e2,e3);
á)printf("%3e%3e%3e",el,e2,e3);
e)printf("e1=%ee2=%ee3=%e",el,e2,e3);
4.81.Unprogramaen econtienelassiguientesinstrucciones:
#inelude<stdio.h>
ehartexto[8O];
Escribirunafunción printfparavisualizarelcontenidode textodelassiguientesformas:
a)Todoenunalínea.
b)Sólolosochoprimeroscaracteres.
e)Losochoprimeroscaracteres,precedidosdecincoespaciosenblanco.
á)Losochoprimeroscaracteres,seguidosdecincoespaciosenblanco.
4.82.Unprogramaen
econtienelasiguientedeclaracióndearray:
ehartexto[8O];
Supongamosqueselehaasignado lasiguientecadenadecaracteresa texto:
Programarenepuedeserunaactividadenormementecreativa.
Mostrarlasalidaresultantedecadaunadelassiguientesinstrucciones printf:
a)
b)
e)
printf
(n%811,texto)
printf("%18s",texto);
printf("%.18s",texto);
á)
e)
printf("%18.7s",
printf("%-18.7s",
texto);
texto);
4.83.Escribirlasinstrucciones seanfoprintfnecesariasparacadaunodelossiguientespuntos:
a)Generarelmensaje:
Porfavor,introducetunombre:
yqueelusuariointroduzcaen lamismalínea sunombre.Asignarelnombreaunarrayde
caracteresllamado
nombre.
b)Supongamosque xlyx2sonvariablesencomaflotantecuyosvaloresson 8.O Y-2.5,
respectivamente.Visualizarlosvaloresde xlyx2,conlosrótulosadecuados,porejemplo:
xl=8.0 x2=-2.5
c)Supongamosquea y bsonvariablesenteras.Pediralusuarioqueintroduzcaelvalordeestas
dosvariablesymostrardespués
~usuma.Rotularla}alidaadecuadamente.
4.84.Determinardequécaracteresdeconversióndisponeensuversiónde
C.Determinartambiénde
quéindicadoressedisponepara
lasalidadedatos.

CAPíTULO5
PreparaciónyejecucióndeunprogramaenC
Conlovistohastaelmomentohemosaprendidolosuficienteparaescribirprogramascompletos
enC,aunquesencillos.Vamosadetenerbrevementelapresentación
denuevosconceptosy
vamosaprestaralgunaatenciónalaplanificación,escriturayejecucióndeunprogramaenC
completo. Además,trataremosalgunosmétodosparaladetecciónycorrección
delosdiferentes
tiposdeerroresquepuedensurgirenprogramasmalescritos.
DirigiremosnuestraatenciónhaciaelusodeTurboC++versión4.5
deBorlandInternatio­
nal,ejecutándosebajoelentornooperativoWindows(recordarqueC++incluye
unaimple­
mentacióncompletadelestándarANSIC,comovimosenlasección1.5).Sehaceespecial
énfasisenestaversiónconcretadeCdebidoalagranpopularidaddelascomputadorasperso­
nales,subajocos-teytambiénporqueesrepresentativodelautilizacióndeCenmuchasotras
computadoras.
5.1.PLANIFICACIÓN DEUNPROGRAMA ENC
Esesencialqueseencuentretrazadacompletamentelaestrategiadelprogramaenconjuntoan­
tes
decomenzarrealmenteconlosdetalles delaprogramación.Estopermiteconcentrarnosenla
lógicadelprogramaengeneral,sinperdernosenlosdetallessintácticosdelasinstrucciones
reales.Unavezquesehafijadoclaramentelaestrategiadelprogramaenconjunto,podemos
pasaraconsiderarlosdetallesasociadosalasinstruccionesindividualesdelprograma.Esteen­
foqueseconocenormalmentecomoprogramación«descendente»
(<<top-down»).Esteproceso
completosepuederepetirvariasvecesenprogramasgrandes,añadiendoencadaestadomás
detalles
deprogramación.
.
Laorganizacióndescendentedelprogramaseefectúaaldesarrollarunesquemainformal
queconstadefrasesosentenciascompuestasparteencastellanoyparteen
C.Enlosestados
inicialesdeldesarrollodelprogramalacantidaddeCesmínima,utilizandoalgunoselementos
paradefinirloscomponentesprincipalesdelprograma,talescomolascabecerasdelasfuncio­
nes,llamadasafunciones,llavesquedeterminaninstruccionescompuestasypartesdesellten­
ciasdecontrolquedescribenlasestructurasprincipalesdelprograma.
Seintroduceentreestos
elementosmaterialdescriptivoencastellano,frecuentementeenforma
decomentarios.Eles­
quemaresultantesesueledenominarpseudocódigo.
EJEMPLO5.1. Interéscompuesto. Unproblemaquesepresentafrecuentementeenlasfinanzasdo­
mésticaseseldeterminarcuántodineroseacumularáenunacuentaenelbancodespuésdenañossi'se
127

128 PROGRAMACiÓN ENC
depositainicialmenteuna cantidadconocida P,ylacuentaacumulaanualmenteinterésauntantopor
cientoanual
r.Larespuestaaestacuestiónsepuededeterminarmediantelabienconocidafórmula
F=P(l+i)"
endonde Frepresentalacantidadfuturadedinero(incluyendolasumaoriginalP,denominadael princi­
pal)
e ieslarepresentacióndecimaldeltantoporcientodeinterés;estoes,i =r/100(porejemplo,un
interés
der =5%secorrespondeconi =O. O 5).
VeamoscómoorganizarunprogramaenCqueresuelvaesteproblema.Elprogramasebasaráen e!
siguienteesquema:
l.Declararlasvariablesdelprograma requeridas.
2.Leerlosvaloresdelprincipal
(P),eltantoporciento deinterés(r)yelnúmerodeaños (n).
3.Calcularlarepresentacióndecimalde!interésutilizandolafórmula
i=rllaa
4.Determinarla cantidadfutura (F)utilizandolafórmula
F=P(l+i)"
5.EscribirelvalorcalculadodeF.
Veamosacontinuación
elpseudocódigocorrespondiente alesquemaanterior.
/*cálculodelinteréscompuesto*/
main()
{
/*declararlasvariablesdelprograma*/
/*leerlosvaloresdeP,ryn*/
/*calcularelvalordei*/
/*calcularelvalordel'*/
/*escribirelvalorcalculadodeF*/
}
Enprincipio.todosestospasosparecenmuysencillos.Sinembargo,algunodeellosrequieremás
detalleantesdequesepuedaprogramarrealmente.Porejemplo,laentradadedatosseefectuará
defor­
mainteractiva.Estorequeriráalgúntipodediálogo
qu~sepodrágenerar medianteparesdesentencias
printfyscanf,comoseexplicóenelCapítulo4.Además,Cnotieneoperadordepotenciación.Por
tanto,senecesitaalgúndetalleadicionalparaevaluarlafórmula
F=P(1+i)"
Heaquíuna.versiónmásdetalladadelanterioresquema.
/*cálculodel
.interéscompuesto*/
main()
{
/ *declararlasvariablesdecomaflotantep,r,n,iyf*!

PREPARACiÓN YEJECUCiÓNDE UNPROGRAMA ENC 129
/*pedirelvalordep yleersuvalor*/
/*pedirelvalorder yleersuvalor*/
/*pedirelvalordenyleersuvalor*/
/*calculari=r/100*/
/*calcularf=p(l+i)ncomosigue:
f=p*pow((l+i),n)
endondepowesunafuncióndebibliotecaparalapotenciación*/
/*escribirelvalordefconelcorrespondienterótulo*/
}
Esteesquemapuedeincluirmásdetallesdelosrealmentenecesariospara unprogramatansencillo,pero
sirvecomoejemplodelenfoquedescendenteeneldesarrollodeprogramas.
EnlosEjemplos5.2,5.4Y5.5 veremoseldesarrollodetallado ylaimplementacióndeestepro­
grama.
Otrométodoqueavecesseutilizaalplanificarunprogramaen eeselenfoqueascendente
(<<bottom-up»).Estemétodopuedeserútilparaprogramasquehacenunusoimportante demó­
dulos(porejemplofuncionesdefinidasporelusuario).Elenfoqueascendenteconllevaeldesa­
rrollodetalladodeestosmódulosalcomienzodelprocesodeplanificación.Eldesarrollo
detodo
elprogramasebasa,portanto,enlascaracterísticasconocidasdeestosmódulos delosquese
dispone.
Enlaprácticadesuelenutilizarlosdosenfoques:eldescendenteparalaplanificacióndel
programaenconjunto,laascendenteparaeldesarrollo
demódulosantesdelaparteprincipaldel
programayladescendenteconrespectoaldesarrollodecadamóduloindividualmente.
5.2.ESCRITURADEUNPROGRAMA ENC
Unavezdeterminadalaestrategiageneraldelprogramayescritounesquemadelmismo,la
atenciónpasaaldesarrollodetallado
deunprogramaen equefuncione.Enestemomentohe­
mosdeconseguirtraducircadapasodelesquemadelprograma(ocadaporcióndelpseudocódi­
go)aunaomásinstruccionesequivalentesen
C.Estodeberíaserunatarearelativamentesenci­
llauna
vezfijadalaestructurageneraldel
programaconelsuficientedetalle.
Laescrituradeunprogramacompletoen
eesalgomásquedisponerlasdeclaracionese
instruccionesadecuadasen
elordencorrecto
Gonlossignosdepuntuaciónadecuados. Sedebe
prestaratenciónalainclusión
deciertoselementosqueaumentenlalegibilidaddelprogramay
lasalidaresultante.Enestoselementosseincluyeelsecuenciamiento
lógicodelassentencias,el
sangradoadecuado
deéstas,lainclusión decomentariosylageneraciónde·salidarotuladade
formaapropiada.
Laelección
delasinstruccionesdelprogramaysusecuenciamientológicodentrodelmismo
estádeterminadaengranmaneraporlalógicasubyacentedelprograma.Existiránamenudo
variasformasdeconseguirelmismoresultado.Estoesciertoenmayormedidaenprogramas

130 PROGRAMACiÓN ENC
máscomplicadosqueinvolucraneluso desegmentosdeformarepetidaocondicional.Enestos
casoslaformaenqueestáorganizadoelprogramapuedetenerunmayorefectoenlaclaridad
de
ésteyensueficienciaalserejecutado.Portanto,esimportantequeseseleccionenlasinstruc­
cionesysusecuenciamientodelamaneramásefectiva.HablaremosmásdeestoenalCapítulo
6,endondediscutimosloselementosdisponiblesenCparalaejecucióncondicionalyrepetida.
Elsangrado
delasinstruccionesestáíntimamenterelacionadoconelsecuenciamiento delos
grupos
deéstasdentrodelprograma.Mientrasqueelsecuenciamientoafectaalordenenque
efectúanungrupo
deoperaciones,elsangradoindicalaformaenqueseencuentransubordina­
daslasinstruccionesdentro
deungrupo.Además,avecesseutilizanlíneasenblancoparasepa­
rargruposdeinstruccionesrelacionados.Lasventajasdelsangradoy
delaslíneasenblanco
resultanobvias,inclusoenlosprogramassencillospresentadosanteriormenteenestelibro.Lo
seránaúnmásalavezqueveamosprogramasenCconestructurasmáscomplicadas.
Siempresedebenincluircomentariosenunprogramaen
C.Escritosconpropiedad,pueden
proporcionarunavisióngeneraldelalógicadelprogramamuyútil.Tambiénpuedenayudara
determinarlaspartesprincipalesdelprograma,identificarciertoselementosclaveyproporcio­
narotrainformaciónútil.Generalmente,loscomentariosnonecesitanserextensos;sepuede
conseguir,medianteunoscomentariosbrevesybiensituados,hacerclarounprogramaquesin
ellosnolosería.Estoscomentariospuedensermuyútilesparacualquieraqueintenteleery
entenderelprogramayparaelmismoprogramador,yaquelamayoría
delosprogramadores
sueleolvidarlosdetallesdesuspropiosprogramasdespuésdeunciertotiempo.Esto
esespe­
cialmenteciertoenprogramaslargosycomplicados.
Otracaracterísticaimportantedelosprogramasbienescritos
eslageneracióndeunasalida
claraylegible.Existendosfactoresquecontribuyenaestalegibilidad.Elprimeroesrotularlos
datosdesalida,comodiscutimosenelCapítulo
4.Elsegundoeslaapariciónenlasalida de
algunosdelosdatos deentrada,deformaquesepuedaidentificarcadainstanciación(sihaymás
deuna)enlaejecucióndelprograma.Laformaenlaqueestosehagadependedelentornoenel
quesevaya
a.ejecutarelprogramaen C.Enunentornointeractivolosdatosdeentradasevisua­
lizaránnormalmenteenelterminalalmismotiempoqueseintroduzcandurantelaejecucióndel
programa.Portanto,
noseránecesarioquelosdatosdeentradaseescribanotravez.
Cuandoseejecutaunprogramainteractivo,el
usuario(alguiendistintodelprogramador)
puedenosabercómointroducirlosdatosrequeridos.Porejemplo,elusuariopuedenosaberqué
datosintroducir,cuándointroducirloso
.elordenenloquedebehacer.Porconsiguiente,un
programainteractivobienescritodebegenerar
mensajesyrótulosenlosmomentosadecuados
durantelaejecucióndelprogramaparaproporcionarestainformación.
EJEMPLO5.2.Interéscompuesto. Consideremosun
program<tintemctivocorrespondiente<tIesque­
m<tpresent<tdoenelEjemplo5.1.
/*problemasencillodeinteréscompuesto*/
#include<stdio.h>
#include<math.h>
main()
{
floatp,r,n,i,f·,

PREPARACiÓN YEJECUCiÓN DEUNPROGRAMA ENC 131
1*leerdatosdeentrada(mediantepeticionesrotuladas)*1
printf("Porfavor,introducelasumainicial(P):"};
scanf(lI%f
l1
,
printf("Por
scanf("%f
ll
,
printf("Por
scanf(lI%fll,
&p);
favor,
&r};
favor,
&n};
introduceelinterés(r):");
introduceelnümerodeafios(n):
11) ;
}
1*calculari y f*1
i=rIlOO;
f p *pow((1+i),n};
1*escribirlasalida*1
printf("Elvalorfinal(F)es %.2f",f};
Elprogramadeesteejemploeslógicamentemuysimple.Nohemostenido,pues,quepreocupamosde
considerarotrasformasalternativasalsecuenciamientodelasinstrucciones.Sinembargo,podríamosha­
berincluidootroselementosdeseables.Porejemplo,podríamoshaberdeseadoqueelprogramaseejecu­
taserepetidamenteparadiferentes conjuntosdedatosdeentrada.O podríamoshaberprevistodiferentes
errores,advirtiendo
alusuariodelaincorreccióndelosparámetrosdeentrada.EnelCapítulo6veremos
cómosepuedenañadirestasmejoras.
5.3.INTRODUCCIÓN DEUNPROGRAMA
EN
LACOMPUTADORA
Unavezquesehaescritoelprograma,sedebeintroducirenlacomputadoraantesdequese
puedacompilaryejecutar.
EnlasversionesantiguasdeCestoserealizabaescribiendoparael
programaunarchivo
detextolíneaalínea,medianteuneditorounprocesador detextos.
Lamayoria
delasversionesdeC oC++actualesincluyenparaestepropósitoun editorde
pantalla.
Eleditorseencuentraintegradonormalmenteenelentornosoftware.Deestaforma,
paraaccederaleditorsedebeentrarprimeroenelentornodeprogramaciónC oC++.Laforma
dehacerestocambiadeunaimplementación
deC aotra.
Consideremos,
porejemplo,laversión4.5deTurboC++,ejecutándosebajoWindowsen
unacomputadorapersonal,compatibleIBM.ParaentrarenTurboC++,serestauraelgrupo
TurboC++y acontinuaciónsepulsaeliconoTurboC++.
Apareceráunaventanacasivacía
comolamostradaenlaFigura5.1.Laprimeralíneadeestaventana(lacualcontiene
TurboC++
-[nonameqO.cpp])eslabarradeltítulo, ylasegundalínea(quecontieneFi 1 eEdit
Searchview,etc.)esla barradelmenú. Laseleccióndeunelementodelabarradelmenú
haráaparecerun
menúdesplegable, conunaserie deopcionesrelativasalaselección delabarra
delmenú.
Por~jetnplo,el menúFi1eincl\lyeopciol1e~ qllepennitenabrirunnuevoprograma,
recuperarunprogramaexistente,gnardarunprograma,imprimirellistadodeunprograma,osalir
deTurboC++.Trataremosalgunos
deestosmenúsdesplegablesmásadelanteenestecapítulo.

132 PROGRAMACiÓN ENC
Nonnalmenteseutilizaundispositivoapuntador,talcomoun ratón,paraseleccionarun
elementodeunmenú.Estosehacesituandoelcursorsobre
elelementodeseadoyluego«ha­
ciendo
dic»sobreelelemento;esdecir,pulsandounbotóndeldispositivoapuntador.
Elgranespacioenblancopordebajodelabarradelmenúconstituyeel
áreadeedición
dondesepuedeintroducirunnuevoprogramaovisualizarunprogramaexistente.Partesdel
programalistadoenesteáreasepuedenmodificar,borrar,copiarodesplazaraotrapartedel
programa.Algunosdeestoscambiosserealizandirectamenteen
eláreadeedición,mientras
queotrosserealizan
destacando(esdecir,seleccionando)unapartedelprogramayluegoco­
piando,desplazandooborrando
elmaterialdestacadoutilizandolasopcionesdelmenú Edit.
Laselecciónseefectúanonnalmentemanteniendopulsadounbotóndelratónyluegoarrastran­
doelratónatravésdelmaterialaseleccionar.
Las
barrasdedesplazamiento seencuentrandebajoy aladerechadelárea deedición.Las
barras
dedesplazamientopennitenmovemosrápidamenteaotraspartesdelprogramacuandosu
listadoseextiendemásallá
deloslímitesdelapantalla.Deestafonna,podemosdesplazarnos
verticalmenteatravésdellistadodelprogramapulsandoalolargodelabarra
dedesplazamiento
deladerecha,odesplazandoelcuadro
dedesplazamientoarribaoabajo.Defonnaanáloga,
podemosdesplazamoshorizontalmenteatravésdellistadodelprogramapulsandoalolargo
de
labarradedesplazamiento delaparteinferior,oarrastrandoelcuadro dedesplazamientoala
derechao alaizquierda.
Finalmente,laúltimalíneaesla
barradeestado, queindicaelestadoactualdeláreade
ediciónoelpropósitodelaopcióndelmenúseleccionadaactualmente.EnlaFigura
5.1seindi­
caquelaventanadeediciónestáenlamodalidad
insertar,loquesignificaqueeltextopuede
insertarseencualquierpartedentro
delaventana.
. .
___________________~ ~__~_~---' _ _ _ 0 .....::
Figura5.1.

PREPARACiÓN YEJECUCiÓNDE UNPROGRAMA ENC133
Paraintroducirunprogramanuevo enTurboC++,sencillamentesetecleaelprogramaenel
áreadeediciónlíneaalíneaysepulsalatecla
Introalfinaldecadalínea.Paramodificaruna
línea,seutilizaelratónolasteclasdemovimientodelcursor(teclasdeflecha)parasituarel
cursoralcomienzodeláreaaeditar.Acontinuaciónseutilizanlasteclas
Ret ro ee so y
Suprimirparaborrarloscaracteresnodeseados.Tambiénsepuedeninsertarcaracteresadi­
cionales,siesnecesario.
Sepueden
borrarunaomáslíneassimplementedestacándolasyluegoseleccionando Cut
delmenúEdit,opulsandolatecla Suprimir.Sepuededesplazarunbloquedelíneasdeuna
posiciónaotrausandolasopciones
CutyPastedelmenúEdit.Deformaanáloga,sepuede
copiarunbloquedelíneasdeunaposiciónaotrausandolasopciones CopyyPastedelmenú
Edit.EnelManualdelUsuariodeTurboC++encontraráinstruccionesdeediciónadicionales.
Unavezintroducidoelprograma,antesdeejecutarloesconvenienteguardarloendisco.Estose
realizaenTurboC++seleccionandolaopción
SaveAsdelmenúFile,suministrandoaconti­
nuaciónunnombredeprograma,porejemplo
INTEREST.C(laextensiónCseañadiráautomáti­
camentesinoseincluyeningunaextensióncomopartedelnombredelarchivo.)Unavezqueel
programahasidoguardadoyselehadadounnombre,puedeserguardadodenuevomásadelante
(porejemplo,conlosúltimoscambiosrealizados),simplementeseleccionando
SavedelmenúFile.
Unprogramaque hasidoguardadopuedeserreeditadoposteriormenteseleccionando Open
enelmenúFile,yluegotecleandoelnombredelprogramaoseleccionandoelnombredeuna
listadeprogramasalmacenados.
Encualquiermomentosepuedeobtener unlistadoimpresodel
programaactual(unacopiaenpapel)seleccionando
PrintdelmenúFile.
EJEMPLO 5.3.Interéscompuesto. Supongamosquehemosintroducidoelprograma delinterés
compuestomostrado
enelEjemplo5.2 enunacomputadorapersonalcompatible IBM,utilizando
Turbo
C++.Trasrealizarlascorreccionespertinentes, lapantallaserásimilaralamostrada enlaFigu­
ra5.2.Acontinuaciónsepuedeguardarelprogramaseleccionando SaveAsdelmenúFile,comose
muestraenlaFigura5.3.(Ambasfigurasenpáginasiguiente.)
AlseleccionarSaveAsapareceráuncuadro dediálogosolicitandoelnombredelprogramaa guar­
dar.Respondamosintroduciendo elnombredelprogramaINTEREST.C.Acontinuación,sepuedecon­
cluirlasesiónseleccionandoExitdelmenúFile.
5.4.COMPILACIÓN YEJECUCIÓNDELPROGRAMA
Unavezqueelprogramahasidointroducido,corregidoyguardado,sepuedecompilaryejecu­
tarseleccionando
Rundelmenú Debug.Seabreunanuevaventanayserealizaunintentode
compilarelprogramaactual.Sielprogramanosecompilacorrectamente,aparecerá
enuna
ventanadiferenteunlistadodemensajesdeerror.Cada mensajedeerrorindicaelnúmerode
la
líneadondesedetectóelerror,asícomoeltipodeerror.Sinembargo,sielprogramasecompila
conéxito,seempezaráaejecutarinmediatamenteenunanuevaventana,pidiendolosdatosde
entrada,presentando
lasalida,etc.
EJEMPLO5.4.Interéscompuesto. Supongail1()s
quev()lvewos.aentrare
l1
Turp().C-j-+itrasconcluirla
sesióndescrita
enelEjemplo5.3.Empezamos
cargandoelprogramaanterior, INTEREST.C,enlame­
moriadelacomputadora,seleccionando OpenenelmenúFile.Acontinuaciónseleccionamos Runen
elmenúDebug,comosemuestraenlaFigura5.4.

134 PROGRAMACiÓN ENC
/*Problemasencillodeinteréscompuesto*/
#include<stdio.h>
#include<math.h>
main()
fIcatp,r,n,i,f;
/*leerdatadeentradamediantepeticionesrotuladas*/
printf("Porfavorintroducelasumainicial(P),");
seanf(","f",&p);
printf(Porfavor,introduceelinterés(r),"};
scanf("%f".&r);
printf(Porfavor.introduceelnúmerodeaflas(n):");
seanf("'!;f",&n);
J*calculariyf*/
i"r(100~
f=p*pow((l+i},n);
/*escribirlasalida"1
printf("Elvalorfinal(F)es:%.2f",f);
Figura5.2.
Problema* /ClrlI-Ks
SearchYlew .eroJectD.ebug1001.Qp1Ions~ndQW .tIelp
"'--;Save:=:.:c:lliI::...-i
#i
r
frlnt,.
maPrtntersetup...
1c:tturbocoots.c
/*leerdatadeentradamediantepeticionesrotuladas"1
printf("Porfavorintroducelasumainicial(P):");
scanf("%f",&p);
printf(Porfavor,introduceelinterés(r):");
scanf("%f",&r);
printf(Porfavor,introduceelnúmerodeaños(n):");
scanf("%f",&n);
/*calculariyf*/
i'=r/100;
f'=P*pow((1+i),n);
/*escribirlasalida*/
printf("Elvalorfinal(F)es:%.2f",f};
Figura5.3.

PREPARACiÓN YEJECUCiÓN DEUNPROGRAMA ENC 135
J*ProblemasencillodeinteIracelnto F7
#include<stdio.h>
#include<math.h>
main()
ToggtebreatpolntF5
(1ndG"xüCl.ltlonpo!nt
EauseprQgram
Termlmrtcpr(){~ratn (.'trH-F2
Add'lelatch... Cb1+FS
floatp,r,n,i,f; Mdl;lreakpOjnt_
(*leerdatadeentrada,Evalua:telMo<ftfy...ClrHF7adas*/
jnspe<:L
printf("porfavorintrod );
scanf("%f",&p); llji1dsvmbollablú..
printf(Porfavor,introduceelinterés(r):")i
scanf("%f",&r);
printf(Porfavor,introduceelnúmerodeafias(n):"JI
scanf("%f".&n);
/*calculariyf*/
i=r/lOO;
f=P*pow{(l+il,n);
/*escribirlasalida*/
printf("Elvalarfinal(F)es:%.2f",fl;
Figura5.4.
Elprogramasecompilacouéxitoeiumediatamenteempiezaaejecutarse.Sobrelaveutauaorigiual
quecontieneellistadodelprograma,apareceunanuevaventana quemuestraeldiálogodeentrada/salida.
Ésta
esmostradaenlaFigura5.5paralosvaloresdeP=1000,r=6yn=20.Estosvaloreshan sido
introducidospor elusuarioenrespuestaa laspeticionesdeentrada.
Unavezintroducidalaúltima cantidad
(n=2O),elprogramareanuda suejecución,generandola
salida
finalmostradaenlaFigura5.6.Deestaforma,vernosqueparalascantidadesdeentradadadas,se
obtieneunvalordeF=3207.14.
5.5.MENSAJESDEERROR
Loserroresdeprogramaciónsuelenpermanecerocultoshastaquesehace unintentodecompila­
ciónoejecucióndelprograma.Lapresencia
deerroressintácticos(ogramaticales)seharápatente
rápidamentetrasejecutarlaorden
Run,yaqueestoserroresimpidenqueelprogramaseacompi­
ladooejecutadoconéxito.Algunoserroresparticularmentefrecuentesdeestetiposonvariables
inapropiadamentedeclaradas,referenciarunavariablenodeclarada,puntuaciónincorrecta,etc.
Lamayoríadeloscompiladoresde egeneraránmensajesdeerrorcuandosedetectenerro­
ressintácticosduranteelprocesodecompilación.Estosmensajesdeerrornosiempresonclaros
ensusignificadoypuedequenoidentifiquencorrectamentelalocalizacióndelerror(aunque
intentanhacerlo).Apesardeello,suelenservirdegranayudaen
laidentificaciónylocalización
aproximadadeloserrores.
Si
unprogramacontienevarioserrores sintácticos,puedequenosedetectentodosen la
primerapasadadelcompilador.Puede, portanto,ser
neceSilriocorregiralgunoserroressintácti­
cosantesdequesepuedanlocalizarotros.Esteprocesopuederepetirsevariasvecesantesde
identificarYcorregirtodosloserroressintácticos.

136 PROGRAMACiÓN ENC
#include
lIinclude
main()
Porfavor,introducelasumainicial(p):1000
porfavor.introduceelinterés(r),6
floatp,rPorfavor,introduceelnúmerode·años(n)'20
/*leerda
printf("Po
seanf("%f"
printf(Por
seanf("'!;f"
printf(Por
seanf("%f"
/ *ea1eu1allllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
i=rI100;
f=P*pow(ll+i),n);
J*escribirlasalida*/
printf("Elvalorfinal(F)es:%.2f",El;
Figura5.5.
#include<stdio.h>
#include<math.h>
main()
floatp,
Porfavor,introducelasumainicial(P):1000
porfavor,introduceel·int·erés(r):6"
Po"rfavor,introduceelnúmerodeañ·ós(n):20
/*leerdElvalorfinal(F)es:3207.14
printE("P
seanf("%f'
printf{Po
seanf("%f'
printf(Po
seanf("%f'
/ *calcul'lllllllllllllllllllllllllllllllllllllillllllilllllllllllllllllllllll
i=r/lJ
f.=p*pow((l.¡.i),n);
/*escribirlasalida.*/
printf("Elvalorfinal(F)es:%2f",f)¡
Figura5.6.

PREPARACiÓN YEJECUCiÓN DEUNPROGRAMA ENC 137
EJEMPLO5.5. Erroressintácticos.Heaquiotraversióndelprograma deinteréscompuestopresenta­
doenlosEjemplos5.2a5.4.
1*problemasencillodeinteréscompuesto*1
#include<stdio.h>
include<math.h>
main()
{
floatPIr,n,i,fi
1*leerdatosdeentrada(mediantepeticionesrotuladas)*1
printf("Porfavor,introducelasumainicial(P)11)i
scanf(H%fll,&p);
printf("Porfavor,introduceelinterés(r):);
scanf(n%f
ll
I&r);
printf("Porfavor,introduceelnúmerodeaños(n):n ) ;
scanf(lI%f",&n)
1*calculariyf*1
i=r/lOO;
f=p*pow«1+i),n);
1*escribirlasalida1*
}
printf("Elvalorfinal(F)es%.2f",f);
Estaversióndelprogramacontienecincoerroressintácticosdiferentes.Sonlossiguientes:
1.Lasegundainstrucción includenocomienzaconunsigno#.
2.Lacadenadecontroldelasegundainstrucción printfnotienelascomillasdecierre.
3.Laúltimainstruccións c
anfnofinalizaconunpuntoycoma.
4.Lainstruccióndeasignacióndefnotienelosparéntesisemparejados.
5.Elúltimocomentariofinalizadeformaincorrecta(terminacon
I*enlugarde *1).
Cuandoseintentacompilarelprograma(bienseleccionandolaopción Rundelmenú Debugobien
seleccionando
CoIllpiledel.
J.l)~~ÚProject),seobtien~n enu~aventanllde mensllj~~ apartelosmensa-
jes
deerrormostradpsen
lafignra5.7....•..•.•.•.•..\ . •..•..•..•••....//•..••.•.•.•..
Elprimermensajehacereferenciaalsigno#quefaltaenlalínea~(la ~umeració~delas líneasincluye
laslíneasvacías).Elsegundomensaje4enotalafaltadeunascomillas (").alfinalde)asegundasentencia
printf(línea15),yeltercermensajeindicalatertI)inacióninapropiadadelúltimocOlne~tario (línea25).
Observequelosmensajesdeerrorsonmuycrípticp~(a4emásde e~tareninglés). Esportantonecesarioalgo
deingenioparadeterminarloquesignifican.
Trasidentificarycprre~ir c0ll.'e~tamente e~tostreserr(Jre~, ~einte~ta .otravezcompilarelprograma.El
resultadoeselnue"oconjU11t04eJ.l)ensajes4~ errprmostradoenlaFigufll5.K
Elprimermensajedeerrorindicaquefaltaunpuntoycomaalfinaldelaúltimainstrucción scanf(lo
querealmenteocu,rreenlalínea 18ynoenla22).Elsegnndomensajeindicaquefaltaelparéntesisizquierdo

138 PROGRAMACiÓN ENC
Figura5.7.
enlasegundainstruccióndeasignación(línea23).Lasdosadvertenciassiguientesyeltercermensajede
errorsonconsecuenciadeestemismo'error.
Cuandosecorrigenestosdoserrores,elprograma
secompilacorrectamenteycomienzaaejecutarse,
comosemuestraenlaFigura5.5.
Hayquetenerpresentequelosmensajesdeerrorylasadvertenciasvarían
deunaversiónde eaotra.
Algunoscompiladorespuedengenerarmensajesmáslargosomásinformativosquelosmostradoseneste
ejemplo,aunquelosmostradosaquísonmuytípicos.
Otrotipocomún deerroreseselerrorde ejecución.Loserroresdeejecuciónocurrendurante
laejecucióndelprograma,despuésdeunacompilaciónefectuadaconéxito.Porejemplo,algu­
noserrores
deejecucióncomunessonel «overflow»o«underflow»numérico (excederelmayor
omenOrnúmeropermitidoquesepuedealmacenarenla computadora),división
pOrcero,inten­
tarcalcularellogaritmoolaraízcuadradadeunnúmeronegativo,etc.Normalmenteenestas
situacionessegeneraránmensajesdeerrorqueharánfácilladetecciónycorrección
delosmis­
mos.Estosmensajessesuelenllamarde
ejecuciónparadistinguirlosdelosde compilacióndes­
critosanteriormente.
EJEMPLO5.6.Raícesrealesde uuaecuacióucuadrática.Supongamosquequeremoscalcularlas
raícesrealesdelaecuacióncuadrátíca
ax'+bx+c=O
EIl'OOINTRE5n.C
23:Too"'"par"-OJ'incaDlo'pow'inIunclionlllllÍn
WarningINTRE5n.C23:Po_.....01~.beloredelinitioninfUflC\ionlllllÍn
WarningINTRE5n.C23:e-/l¡lonoeffeclinfulHllion~
EROOINTRE5n.C23:5lelemenlmiooing;infUflC\ionmein
WarningINTRE5Tl.C28:FUfIC\ion_ retumev_inIunclionlllllÍn
Figura5.8;

PREPARACiÓN YEJECUCiÓN DEUNPROGRAMA ENC 139
utilizandolafórmula
-b±eb'_4ac)1I2
x=
2a
PresentamosacontinuaciónelprogramaenCquerealizaráestoscálculos.
/*raíces realesdeunaecuacióncuadrática*/
#include<stdio.h>
#include<math.h>
main()
{
floata,bre,dixl,x2¡
/*leerdatosdeentrada*/
printf("a= " )i
scanf(lI%f
ll
/&a);
printf("b=
11) ;
scanf("%f",&b);
printf("c=
Il) ;
scanf(ll%f
ll
,&c);
/*efectuarloscálculos*/
d=sqrt(b*b-4 *a *c);
xl=(-b+d)/(2* a);
x2=(-b-d)/(2*a);
/*escribirsalida*/
}
printf("xl=%e x2;%e",xlIx2);
Esteprograrnflnotieneningúnerrorsintáctico,peroesincapazdemanejarvaloresnegativospara
b'-4ac.Esmás,seencontrarándificultadesnuméricassilavariableatiene unvalornuméricomuy
pequeñoomuygrande,osia=O.Paracadaunodeestoserroressegenerará
unmensajedeerrorseparado.
Supongamos,porejemplo,queelprogramaseejecutaconTurbo
C++conlossiguientesvaloresde
entrada:
a=l.O b=2.0 c=3.0
Elprogramasecolllpilasinningunadificultad
..SineIllbargo,cuflndoseejecut~elprograma objetose
generaelsiguientemensajedeerror,despuésdequesehayanintroducidolosvaloresdeentrada.
sqrt:DOMAINerror

140 PROGRAMACiÓN ENC
Seinterrumpeentonceslaejecución delprograma,yaquenopuedecontinuarapartir deestepunto.La
Figura5.9ilustraelaspectodelapantallaenTurboC++.
Análogamente,supongamos queseejecutaelprogramaconlossiguientesvalores deentrada:
a=lE-30 b=lE+IO c=lE+36
Elsistemaahoragenerará elsiguientemensajedeerror:
FloatingPoint:Overflow
cuandoseintentaejecutar elprograma.LaFigura5.10muestra elaspectodelapantallaenTurboC++.
5.6.TÉCNICASDEDEPURACIÓN
Hemosvistoqueloserroressintácticosydeejecuciónsuelenconllevarlageneracióndemensa­
jesdeerroralcompilaroejecutarelprograma.Loserroressintácticossonrelativamentefáciles
deencontrarycorregir,auncuandolosmensajesdeerrornoseanclaros.Loserroresdeejecución,
porotrolado,sonmuchomásinsidiosos.Cuandoocurre unerrordeejecución,debemosenprimer
lugardeterminar
sulocalización(dóndeocurre)enelprograma.Unavezidentificadalalocali­
zacióndelerrordeejecución,sedebedeterminar
lacausadelerror (porqué ocurre).Elcono­
cimientodedóndeocurreelerrorayudaamenudoenelreconocimientoycorreccióndelerror.
Muyrelacionadosconloserroresdeejecuciónseencuentranloserrores
lógicos.Elprogra­
maseejecutaenestoscasosdeformacorrecta,efectuandoloqueelprogramadordesea,pero
#include<stdio.h>
#include
<math.h~
main()
floata,b,e,d,xl,x2
/*leerdatadeentrada/
printf("a"'J;
seanf("%f",&a)¡
printf("b=");
seanf("%f",&b};
printf("c"");
seanf("%f',&c·);
,I
,2
,.
~TURBOQROOTSxXE
• sqrtDQMAINerror
-
/*efectuarloscálculos*/
d=sqrt(b*b - 4*a*e);
xl=(-b+d)/(2*al·;
x2=(-b-dlI(2*al;
/*escribirlasalida*/
printf("xl=%e x2='lis",xl,x2);
Figura5.9.

#include<stdio.h>
#include<math.h>
main()
floata,b,e,d,xl,x2;
/*leerdatadeentrada*
PREPARACiÓN YEJECUCiÓN DEUNPROGRAMA ENC 141
mTURBOC\ROOTS~EXE
=le~3e
=lele
=1'1136
• AoatlngPolntOverffow
-
printf("a=");
scanf{"%f",&a);
printf("b=");
seanf("'!;f",&b)¡
printf("·c="}i
Seanf ("%f",1<e ) ; .I11IIII11IIII11IIII11IIII11IIII11IIII11IIII11IIII11IIII11IIII11IIII11IIII11IIIII1II_
/*efectuarloscálculos,IIIJ
d=sqrt(b*b - 4*a*el;
xl=(-b+d)/(2*al;
x2=(-b-dlI(2*al;
/*escribirlasalida*/
printf("xl=%e x2•%e',xl,x2)¡
Figura5.10.
éstehasuministradoalacomputadoraunasinstruccionesquenosonlógicamentecorrectas.Los
erroreslógicospuedensermuydifícilesdedetectar,puestoquelasalidaresultante
deunprogra­
malógicamenteincorrectopuedeparecerqueestálibre
deerrores.Esmás,loserroreslógicos
sonamenudodifíciles
delocalizarauncuandoseconozcasuexistencia(porejemplo,cuando
losresultadoscalculadosseanobviamenteincorrectos).
Afortunadamente,haymétodosdisponiblesparaencontrarlalocalización
deloserroresdeeje­
cuciónyerroreslógicos
deunprograma.Atalesmétodosselesdenomina técnicasdedepuración.
Acontinuaciónsedescribenalgunasdelastécnicas dedepuraciónmáscomúmnenteutilizadas.
Aislamientodel
error
Elaislamientodelerroresútilparalocalizarunerrorqueapareceen unmensajedeerror.Sino
seconocelalocalizacióngeneraldelerror,éstasepuedeencontrarfrecuentementealborraruna
partedelprogramaconcaráctertemporalyvolveraejecutaracontinuaciónelprogramapara
versielerrordesaparece.Elborradotemporalserealizarodeandolasinstruccionesconmarcas
decomentarios
(1*y*/),convirtiéndolasencomentarios.Sidesapareceelmensajedeerror,la
parteborradadelprogramacontienelacausadelerror.
Unatécnicamuyrelacionadaconsisteeninsertarvariassentencias
printftalescomo
printf("Depuraci6n-lineal");
printf("Depuraci6n-linea2");
etc.

142 PROGRAMACiÓN ENC
endiferenteslugaresdelprograma.Cuandoseejecutaelprograma,losmensajesdedepuración
indicaránlalocalizaciónaproximadadelerror.Portanto,
lacausadelerrorestaráenalgúnlugar
entrelaúltimainstrucción
printfcuyomensajeapareció,ylaprimerainstrucción printf
cuyomensajenoapareció.
Seguimientodelatrazadeejecución
Elseguimientodelatrazadeejecuciónimplicaelusodeinstrucciones printfparavisualizar
losvaloresasignadosaciertasvariablesclave,oparavisualizarlosvaloresquesecalculanin­
ternamenteendiferenteslugaresdelprograma.Estainformaciónsirveparadiversospropósitos.
Porejemplo,verificaquelosvaloresactualmenteasignadosaciertasvariablesson(onoson)
realmentelosvaloresquedeberíanestarasignados.Noesraroelencontrarquelosvaloresasig­
nadosactualmentesondiferentesdelosesperados.Además,estainformaciónpermitemonitori­
zarelprogresodeloscálculoscuandoseejecutaelprograma.Enmuchassituacionessepodrá
localizarelsitioparticulardondeseproducenlosfallosdebidoaquelosvaloresgeneradosserán
obviamenteincorrectos.
EJEMPLO5.7.Depuraciónde unprograma.Consideremosdenuevoelprogramadecálculodelas
raíces realesdeunaecuacióncuadrática,originalmentemostrado 'enelEjemplo5.6.Vimosqueelprogra­
mageneraelerrordeejecución
FloatingPoint:Overflow
cuandoseejecutaconlosvaloresdeentradaa=-lE-3D,b=lElOyc=lE36.Aplicaremosahora
aislamiento
delerrorytécnicasdedepuraciónparadeterminarlacausa delerror.
Esrazonablesuponer queelerrorsegeneraenunadelastresinstruccionesdeasignaciónsiguientesa
laúltimainstruccións c
anf.Portanto,eliminemostemporalmenteestastresinstruccionescolocando
delimitadores
decomentarios,como semuestraen,ellistadosiguiente.
/*raicesrealesdeunaecuacióncuadrática*/
#includecstdio.h>
#includecmath.h>
main()
{
/*leerdatosdeentrada*
printf
(11a ==");
scanf("%f",&a);
printf(tlb=ti)i
scanf("%f".&b);
printf(11e=")i
scanf("%f",&c);
/*efectuarloscálculos*/

PREPARACiÓN YEJECUCiÓN DEUNPROGRAMA ENC 143
/*********************aislamientodelerror****************
d=sqrt(b*b-4*a*e);
xl=(-b+d)/(2* a)
x2=(-b-d)/(2* a)
*******************finaislamientodelerror***************/
/*escribirsalida*/
}
printf("xl=%e x2 %e
1l
1xl,x2)
Cuandoseejecute elprogramamodificadoconlostresvaloresdeentradaelmensajedeerrornoaparecerá
(aunquelosvaloresvisualizadospara
xlyx2notendránsentido).Portanto,estáclaroquelacausadel
errorseencuentraenunadeestastresinstrucciones.
Eliminaremosacontinuaciónlosdelimitadoresdecomentarios,peroprecederemoscadainstrucciónde
asignaciónconunainstrucción
printf,comosemuestraacontinuación.
/*raíces realesdeunaecuacióncuadrática*/
#include<stdio.h>
#include<math.h>
main()
{
floata,b,e,d,xl,x2¡
/*leerdatosdeentrada*/
printf("a=
scanf("%f
ll
,
printf("b=
scanf("%f",
printf("c=
scanf(lI%fll,
11) ;
&a);
11)i
&b);
11)i
&c);
/*efectuarloscálculos*/
printf("Depuración-Línea1" ) ;/*instruccióndedepuracióntemporal*/
d=sqrt(b*b-4*a*c);
printf("Depuración-Línea2
ll
) ;/*instruccióndedepuracióntemporal*/
xl=(-b+d)/(2*a);
printf("Depuración-Línea3");/*instruccióndedepuracióntemporal*/
x2=(-b-d)/(2*a)
/*escribirsalida*/
}
printf("xl =%e x2=%e
11
,xl,x2);

144 PROGRAMACiÓN ENC
Cuandoseejecutaelprograma,usandounavezmáslosmismosvaloresdeentrada,aparecenlostres
mensajes
dedepuración;estoes,
Depuración-Línea1
Depuración-Línea2
Depuración-Línea3
Concluimospuesque elerrorde«overflow»ocurrióenlaúltimainstrucción deasignación,puestoque
dichainstrucciónvaacontinuacióndelatercerainstrucción
printf.
Normalmentepodríamosterminaraquínuestrosesfuerzosdedepuración.Sinembargo,paracomple­
tardichastécnicasvamosaeliminarestastresinstruccionesdedepuración
ylasvamosareemplazarcon
otrasinstrucciones
printf(estoes,tresínstruccionesde seguimientodelatrazadeejecución). La
instrucciónsentencia
printfvisualizarálosvaloresde a,byc,lasegundavisualizaráelvalor de(-b
+d)Ylaúltimaelvalorde (-b -d),comosemuestraacontinuación.(Observelaubicacióndelas
tresinstrucciones
printf,traselcálculodedperoantesdelcálculode xlyx2.Observetambiénlos
formatostipoeenlasinstrucciones
printf.)
/*raíces realesdeunaecuacióncuadrática*/
#include<stdio.h>
#include<math.h>
main()
{
float
a,b,e,dixl,x2¡
/*leerdatosdeentrada*/
printf("a=
11) ;
scanf(lI%f
ll
/&a);
printf("b=
11)i
scanf("%fU f&b);
printf("c=
n)i
scanf(lI%f
ll
I&c);
/*efectuarloscálculos*/
d=sqrt(b*b-4* a*c);
/*instruccionesdeseguimientodelatrazadeejecución*/
printf("a=%e b=%ec=%e d=%e" ,a,b,eld);
printf("-b+d=%e
U
,
(-b+d)) ;
printf("-b-d=%e 11I(-b-d)) ;
xl=(-b+d)/
x2=(-bd)/
(2*a);
(2*a);
}
/*escribirsalida*/
printf("xl=%e x2=%e
l
',xl,x2);

PREPARACiÓN YEJECUCiÓN DEUNPROGRAMA ENC 145
Laejecucióndeesteprogramageneralasiguientesalida:
a~1.000000e-30 b~1.000000e+l0
-b+ d O.OOOOOOe+OO
-b- d ~-2.000000e+l0
e1.000000e+36d~1.000000e+l0
Apartirdeestosvalorespodemosdeterminarqueelvalorde x2debeser
x2~(-b-d)I(2*a)~(-2.000000e+l0)I(2.1.000000e-30) ~
~-1.000000e+40
Elvalorresultante, -1.OOOOOOe +4O,excede(entamaño) alnúmerodecomaflotantemásgrandeque
sepuedealmacenarenlamemoriadelacomputadora(versección2.4).Portantoseproduceel
desbordamientou«overflow».
LamayoríadeloscompiladoresdeCactualesincluyenun depuradorinteractivo, elcual
permiteestablecer
valoresdeinspecciónypuntosdeinterrupción,yposibilitala ejecuciónpaso
apaso,
instrucciónainstrucción.Losvaloresdeseguimientoseutilizanhabitualmentejuntoa
lospuntosdeparadaoconlaejecuciónpasoapaso,proporcionandounamonitorizacióndetalla­
dadelprogramamientrasésteseejecuta.Estascaracterísticassonmásflexiblesyconvenientes
quelastécnicasdeaislamientodelerrorydeseguimientodelatrazadeejecucióndescritas
anteriormente.Acontinuacióndescribimosconmásdetalledichascaracterísticas.
Valoresdeinspección
Un
valordeinspeccióneselvalordeunavariableoexpresiónquesevisualizacontinuamente
durante
laejecucióndelprograma.Portantp,sepuedenverloscambiosproducidosenunvalor
deinspeccióncuandoocurrencomorespuestaalalógicadelprograma.Almonitorizarunos
pocosvalores.deinspecciónseleccionadosdeformaadecuada,podemosdeterminaramenudo
dóndeelprogramaempiezaagenerarvaloresincorrectosonoesperados.
En
TurboC++sepuedendefinirvaloresdeinspecciónseleccionando AddWatchdelmenú
Debug(verFigura5.4másatrásenestecapítulo),yespecificandoacontinuaciónunaomás
variablesoexpresionesenelcuadro
?ediálogocO]'fespondiente.Sevisualizaránlosvaloresde
inspecciónenunaventanadiferentecuandoseejecl.lteelprograma.
Puntosdeinterrupción
Un
puntodeinterrupción esunpuntoquedetienetemporalmente laejecucióndeunprograma.
Alejecutarelprograma,éstesedetendrátemporalmenteenelpuntodeinterrupción,
antesde
ejecutarlailJ.strucción. Sepuedereanudaracontinuaciónlaejecuciónhastaelsiguientepunto
deinterrupción.Lospuntos
deinterrupciónseutilizanjuntoconlosvalores deinspección,ob­
servandoestosúltimosencadapuntodeparadadurantelaejecucióndelprograma.
Para
establec~rull puntodeinte]'fUpciónenTurboCH,seseleccionaA~dBreakpoint
delmenúDebug(verFigura5.4) ysesuministralainformaciónrequeridaenelcuadrodediálogo
resultante.Otambién,seseleccionaunalíneaparticulardelprogramaysepulsalateclade
función
F5paramarcarlacomounpuntode
interrupCión.Dichopuntode.interrupciónsepuede

146 PROGRAMACiÓN ENC
desactivarmásadelantevolviendoapulsarF5.(LatecladefunciónF5actúacomoun«conmu­
tador»enestecontexto,puestoquealpulsarlaseactivaodesactivaelpuntodeinterrupción).
Ejecuciónpasoa paso
Laejecuciónpasoapaso significaejecutarunainstrucción encadamomento,normalmente
pulsandounatecladefunciónparaejecutardichainstrucción.
EnTurboC++,porejemplo,la
ejecuciónpasoapasosepuedeefectuarpulsandoolatecladefunción
F7obienFa.(Faejecuta
lasfuncionessubordinadasdeunavez,mientrasque
F7lasejecutapasoapaso.)Alejecutar
pasoapasounprogramacompleto,sepuededeterminarquéinstruccionesproducenresultados
erróneosogeneranmensajesdeerror.
Laejecuciónpasoapasoseutilizafrecuentementeconlosvaloresdeinspección,permitiendo
rastrear
lahistoriacompletade unprogramacuandoésteseejecuta.Deestaforma,sepueden
observarcambiosenlosvaloresdeinspeccióncuandoéstosocurren.Estonospermitedetermi­
narlasinstruccionesquegeneranresultadoserróneos.
EJEMPLO5.8.Depuraciónconundepuradorinteractivo.Consideremos denuevoelprogramapre­
sentadoenlosEjemplos5.6y5.7,decálculodelasraícesdeunaecuacióncuadrática.Utilizaremosahora
eldepuradorinteractivo deTurboC++paradeterminarlacausa delerrorcuando seejecutaelprograma
conlosvaloresdeentradaa =lE-30,b=lElOyc=lE36.
LaFigura5.11muestraelprogramadentro delaventanadeedición deTurboC++.Sehanselecciona­
dotresvaloresdeinspecciónparalascantidades- b+d,-b-dY2*a.Cadavalordeinspecciónfueselec­
cionadoeligiendo
AddWatchdelmenúDebug. EnlaventanaWatch,sobreellistadodelprograma,se
encuentranlosvaloresdeinspección.
~include <stdio.h>
~include <math.h>
main()
floata,b,e,d,xl,x2;
/*leerdatadeentrada
printf("a=");
seanf("%f",&a);
printf("b=");
seanf("%f",&b);
printf("c'""J;
scanf("%f",&0);
1*·efectuar.1·05cálculos*/
d'"sqrt(b" b-4" a "e):
xl'"(-b+d)/(2"al;
x2'"(-b-d)/(2*a);
/*escribirlasa.lida*/
printf("xl'"%e x2 %e",xl,x2);
Figura5.11.

PREPARACiÓN YEJECUCiÓN DEUNPROGRAMA ENC 147
Sehadefinidoademásunpuntodeinterrupción enlaprimerainstruccióndeasignaclOn,esdecir,
d=sqrt(b*b 4*a*c).Elpuntodeinterrupciónsehadefinidosituandoelcursorsobrela
instruccióndeseada
ypulsandoacontinuaciónlateclaF 5.EnlaFigura5.11semuestradestacadoelpunto
deinterrupción.
ObservequelaFigura5.11muestraelestadodelprograma
antesdecomenzarsuejecución.Ésta
eslarazónporlaqueapareceelmensaje <Noprocessrunning>aliadodecadavalordeinspección.
Unavezquecomienzalaejecucióndelprograma(alseleccionar
Rundelmenú Debug),seintrodu­
cenlosvaloresde
a,byeportecladoycontinúalaejecuciónhastaelsiguientepuntodeinterrupción.El
programasedetienetemporalmente,comosemuestra
en
laFigura5.12.Observequetodavíanoseha
ejecutadolaprimerainstruccióndeasignación,demaneraque
dnotieneaúnunvalorasignado. Portanto,
losdosprimerosvaloresdeinspecciónestánaúnsindefinir.Sinembargo,elúltimovalordeinspecciónse
obtienedirectamentedelosdatosdeentrada.Suvalor,
2e -3O,semuestraenlaventanadeinspecciónde
laFigura5.12.
Podemosreanudarlaejecución,continuandohastaelfinaldelprograma,seleccionandodenuevo
Run
delmenú Debug.Sinembargo,ensulugarvamosaejecutarpasoapasoelprogramapulsandolateclade
función
F8dosveces.LaFigura5.13muestraelestadodelprogramaenestepunto.Observequeelpunto
deinterrupciónpenuanecedestacado.Además,tambiénestádestacadalatercerainstruccióndeasigna­
ción(esdecir,
x2= ( -b-d)I(2*a).Estaúltimaeslasiguienteinstrucciónaejecutar.
Enlaventanadeinspecciónpodemosverahoralosvaloresactualesdetodaslasvariablesdeinspec­
ción.Fácilmenteseobservaqueelvalorasignadoa
x2,elcualeselcocienteentreelsegundo ytercer
valordeinspección,producirá
undesbordamiento.Deestemodo, sireanudamoslaejecucióndelprogra­
ma,bienseleccionando
Rundelmenú Debugobienmediantelaejecuciónpasoapaso,apareceráel
mensajede«overflow»mostradoenlaFigura5.10.
Algunasvecesnosepuedelocalizarunerror,aunutilizandolastécnicasdedepuraciónmás
sofisticadas.Entalescasos,losprogramadoresprincipiantesseinclinanamenudoasospechar
/*raícesrealesdeuna
ecuacióndesegundogrado*I
~include <stdio.h>
~include <math.h>
roaín()
floata,b,c,d,xl,x2;
/*leerdatadeentrada
printf("a="JI
seanf("'!;f",&a);
printfl"b=")¡
seanf("'!;fu,&b);
printf("c=");
seanf("'!;fu,&c);
/*efectuarloscálculos*/
d=sqrt{b*b - 4*a*el;
xl=(-b+dlI(2*al;
x2=(-b-d)/(2.*a);
/*escribirlasalida*/
printf("xl=%8 x2 %e",xl,x2)¡
Figura5.12.

148 PROGRAMACiÓN ENC
/*raieesrealesdeunaecuacióndesegundogrado*/
#include<stdio.h>
#include<math.h>
main()
floata,b,C,d,xl,x2;
/*leerdatadeentrada*1
printf("a=");
scanf("%f",&a);
printf("b="JI
scanf{"%f",&b);
printf("c~");
scanf("%f",&c};
1*efectuarloscálculos*/
d _sqrt{b*b - 4*a"el;
xl•(-h+dII(2"a);
x2=(-b-dII(2"al;
1*escribirlasalida*/
printf{"xl=%e :-:2=%e",xl,x2);
Figura5.13.
queelproblemaestámásallá desucontrol,comounerrordelhardwareounerrordelcompila­
dor.Sinembargo,elproblemacasisiempreresultaserunsutilerrordelalógicadelprograma.
Entalessituaciones,debemosresistirlatentación
deecharlelasculpasalacomputadorayno
buscarelescurridizoerrordeprogramación.Aunqueloserroresdelascomputadorasocurren
rarasveces, éstosnormalmenteproducenresultadosmuypeculiares,talescomo
elbloqueodela
computadoraovisualización
decaracteresaleatprioseininteligibles.
Finalmente,hemos
dereconocerquealprogramarnonosescaparemoscasinunca decome­
teralgunoserroreslógicos,pormuycuidadososqueseamos.Debemosportantoanticiparla
necesidaddealgunadepuraciónlógicacuandoescribamosprogramasrealesysignificativos.
5.1.¿Quéseentiendeporprogramación«descendente»?¿Cuálessonsusventajas?¿Cómose
efectúa?
5.2.¿Quéeselpseudocódigo?¿Quéventajastienesuutilizaciónalplanificarunnuevopro­
grama?
5.3.¿QuéSeentiendeporprogramación«ascendente»?¿Enquésediferencia
delaprograma­
cióndescerrdente?
5.4.¿Quélibertadtieneunprogramadoralsecuenciarlógicamentelasinstruccionesenun
programaen
C?Explicarlo.

PREPARACiÓN YEJECUCiÓN DEUNPROGRAMA ENC149
5.5.
¿PorquésesangranalgunasinstruccionesenunprogramaenC?¿Esabsolutamentenece­
sarioelsangrado
deestaslíneas?
5.6.¿QuérazonesexistenparaincluircomentariosenunprogramaenC?¿Quéextensiónde­
bentenerestoscomentarios?
5.7.Citardosfactoresquecontribuyanalageneracióndedatos
desalidadeformaclaray
legible.
5.8.¿Quéinformación deutilidadproporcionanlosrótulos?
5.9.¿Cómoseintroduceunprogramaenlacomputadoraenlamayoría
delosentornosde
programaciónenCactuales?
5.10.¿Quéeslaextensióndelnombre deunprograma?
5.11.¿Quéesunerrorsintáctico?Citaralgunoserroressintácticoscomunes.
5.12.¿Quéesunerrordeejecución?Citaralgunoserrores deejecucióncomunes.
5.13.¿Enquésediferencianloserroressintácticosdelosdeejecución?
5.14.¿Quéesunerrorlógico?¿Enquésediferencianloserroreslógicosdelossintácticosylos
deejecución?
5.15.¿Quésonlosmensajes deerror?
5.16.¿Quédiferenciahayentrelosmensajesdeerrordecompilaciónydeejecución?Citar
algunassituacionesenlasquesegenerecadatipo
demensajedeerror.
5.17.¿Quéseentiendeporaislamientodelerror?¿Paraquésirve?¿Cómoseefectúa?
5.18.¿Quéseentiende porinspeccióndelatrazadeejecución?¿Paraquésirve?¿Cómose
realiza?
5.19.¿Quéesundepuradorinteractivo?¿Dequécaracterísticasespecialesdisponeundepu­
rador?
5.20.¿Quésonlosvalores deinspección?¿Paraquéseutilizan?¿Cómosedefinen entérminos
generales?
5.21.¿Quésonlospuntos deinterrupción?¿Paraquéseutilizan?¿Cómosedefinenentérminos
generales?
5.22.¿Enquéconsistelaejecuciónpasoapaso?¿Paraquéseutiliza?¿Cómoseefectúaen
términosgenerales?
5.23.Describircómosepuedenutilizarlosvaloresdeinspecciónconlospuntos deinterrupción
ylaejecuciónpasoapasoparamonitorizarelavanceenlaejecución
deunprograma.
Lassiguientescuestiones estánmásrelacionadasconlacomprensióndelcapitulorealmente queconla
resolucióndeproblemas.
5.24.Obtenerrespuestasa lassiguientespreguntasrelativasa lascomputadoraspersonalesdelaescuela
uoficina.
a)¿Dequéequipamientosedisponeexactamente(impresoras,dispositivos dememoriaau­
xiliar,etc.)?
b)¿Dequésistemasoperativossedispone?

150 PROGRAMACiÓN ENC
c)¿Cómo sepuedengrabar,visualizarytransferirarchivos(programas)deundispositivodeme­
moriaaotro?
d)¿Cuáles elcosteaproximado deunacomputadorapersonal?
5.25.Obtenerrespuestasalassiguientespreguntasrelativas alcompiladordeC delaescuelauoficina.
a)¿DequéversióndeC sedispone?¿Quésistemaoperativorequiere?
b)¿Cómoseaccede alcompiladorde C?¿CómoseaccedeaunprogramaenCunavezactivado
elcompilador?¿Cómo
sevisualizaunprograma?¿Cómosegraba?
c)¿Cómoseefectúanlasfuncionesdeediciónusuales(insertar,borrar,etc.)?
d)¿Cómosecompilayejecutaunprogramaen C?
e)¿Incluyeelcompiladorundepuradorinteractivo?Encasoafirmativo,¿quécaracterísticasso­
portaeldepurador?¿Cuálessonlascaracterísticasmáscomúmnenteutilizadas?
1)¿Cuáleselcostedelcompiladorde C?
5.26.EnelEjemplo1.6sepresentaunprogramaenCparacalcular eláreadeuncírculo,dado suradio.
Introduciresteprogramaenlacomputadorayhacerlasmodificacionesnecesarias,talescomo
#include<stdio.h>.Asegurarsedecorregircualquiererrortipográfico.Listarelprograma
unavezquesehayaalmacenadoenlacomputadora.Cuandoseestésegurodesucorrección,com­
pilarelprogramayejecutaracontinuaciónelprogramaobjetointroduciendodiferentesvalores
delradio.Verificarquelasrespuestas calculadassoncorrectascomparándolasconlascalculadasa
mano.
5.27.Introducir,compilaryejecutarlosprogramasenCdados enlosEjemplos1.7a1.13.Verificarque
seejecutancorrectamenteconlaversiónparticular
deC.(Sicualquieradelosprogramas nofun­
ciona,intentardeterminarporqué.)
5.28.RepetirelProblema5.27paraalgunos delosprogramasdadosenelProblema1.31.
5.30.Escribirunprogramacompleto enCparacadaunodelospuntossiguientes.Introducircadaprogra­
maenlacomputadora,asegurándosedehabercorregidocualquiererrortipográfico.Guardarel
programacuandoestemosseguros
dehaberlointroducidocorrectamente,ycompilarloyejecutarlo
acontinuación.Asegurarse
deincluirrótulosparatodaslasentradas,yetiquetartodalasalida.
a)Escribir¡ HOLA!alcomienzodeunalínea.
b)Hacerquelacomputadoraescriba
HOLA,
¿COMOTELLAMAS?
enunalínea.Elusuariointroduciráacontinuaciónsunombre.Lacomputadoraescribedos
líneasenblancoy acontinuación
BIENVENIDO
(nombre)
¡SEAMOSAMIGOS!
endoslíneasconsecutivas.Utiliceunvectordecaracterespararepresentarelnombredelusua­
río.Supongaqueelnombrecontienememosde20caracteres.

PREPARACiÓN YEJECUCiÓN DEUNPROGRAMA ENC 151
e)ConvertirunatemperaturaleidaengradosFahrenheitagradosCelsiusutilizandolafórmula
e~(5/9)x(F-32)
Comprobarelprogramaconlossiguientesvalores: 68,150,212, O,-22,-200(grados
Fahrenheit).
d)Determinarcuántodinero(endólares)hayenunahuchaquecontienevariosmediosdólares,
cuartos,dimes,niquelesypeniques.Utilizarlossiguientesvaloresparacomprobarelprogra­
ma:
11mediosdólares,7cuartos, 3dimes,12niquelesy 17peniques.(Respuesta:8,32dóla­
res).
e)Calcularelvolumenyeláreadeunaesferautilizandolasfórmulas
v=4m
3
/3
A=41tr'
Comprobarelprogramautilizandolossiguientesvaloresdelradio: 1,6,12,2,0,2.
1)Calcularlamasadeaire dennneumáticodeautomóvilutilizandolafórmula
PV=0.37m(T+460)
endonde:
P
~presión,librasporpulgadacuadrada(psi)
V=volumen,piescúbicos
m=masadeaire,libras
T=temperatnra,gradosFahrenheit
Elneumáticocontienedospiescúbicos
deaire.Supóngasequelapresiónes 32psialatempe­
raturaambiente.
g)Introducirunapalabra
decincoletrasenlacomputadora,codificaracontinuaciónlapalabra
letraaletrarestando
30delvalornuméricoque seutilizapararepresentarcadaletra.Portanto,
siseestáutilizandoeljuegodecaracteres
ASCn,laletraa(queserepresentaconelvalor97)
setransformaráene(representadaporelvalor67),etc.
Escribirlaversióncodificadadelapalabra.Comprobarelprogramaconlassiguientespala­
bras:negro,rosas,Japón,Cebra.
h)Leerunapalabradecincoletrasquesehayacodificadodelaformaindicadaenelapartado
anterior.Decodificarlapalabrayescribirlapalabradecodificada.
i)Leerunalíneadetextocompletaycodificarlautilizandoelmétododescritoanteriormente.
Visualizarlalíneacompletadetextoenlaformacodificada.Decodificaracontinuaciónel
textoyescribirlo(visualizareltextocomoaparecióoriginalmente)utilizandoelmétododescri­
toenelapartado
h).
j)Leerunalíneadetextoquecontengaletrasmayúsculasyminúsculas.Escribireltextocon
letrasmayúsculasyminúsculasintercambiadasyelresto
deloscaracteresintactos. (Sugeren­
cia:
Utilizareloperador condicional?:ylasfunciones debibliotecaislower,tolowery
toupper.)

CAPíTULO6
Instruccionesdecontrol
Enlamayoría delosprogramasenCquehemosencontradohastaelmomento,lasinstrucciones
seejecutabanenelmismoordenenqueaparecíanenelprograma.Cadainstrucciónseejecutaba
unaúnicavez.Losprogramasquesesuelenescribirenlaprácticanosontansencilloscomo
éstos,yaquelosquehemosvistonoincluyenningúntipo
deelementosdecontrollógico.En
particular,enestosprogramasnoaparecencomprobaciones
decondicionesqueseanverdaderas
ofalsasniaparecelaejecuciónrepetida
degruposindividuales deinstruccionesdeformaselec­
tiva.Lamayoríadelosprogramas
deinterésprácticohacenusointensodeestoselementos.
Porejemplo,muchosprogramasrequierenqueseefectúeunacomprobaciónlógicaenalgún
puntoconcreto
delosmismos.Acontinuaciónserealizaráalgunaacciónquedependerádelresul­
tadodeltestlógico.Estoseconocecomo
ejecucióncondicional. Existetambiénunaclaseespecial
deejecucióncondicional,llamada
selección,enlaqueseseleccionaungrupodeinstrucciones
entrevariosgruposdisponibles.Además,losprogramaspuedenrequerirqueungrupo
deinstruc­
ciones
seejecuterepetidamente,hastaquesesatisfagaalgunacondiciónlógica.Estoseconocepor
elnombrede
bucle.Avecesseconoceporadelantadoelnúmero derepeticionesrequeridas;y
otrasveces
elcálculocontinúaindefinidamentehastaquelacondiciónlógicasehaceverdadera.
Sepuedenrealizartodasestasoperacionesutilizandodiversasinstruccionesdecontrolinclui­
dasen
C.Veremoscómohacerestoenestecapítulo.Eluso deestasinstruccionesnosabrirálas
puertasaproblemas
deprogramaciónmuchomásamplioseinteresantesquelosvistoshastaahora.
6.1.INTRODUCCIÓN
Antesdeconsiderarcondetallelasinstruccionesdecontrol delasquesedisponeenC,revise­
mosalgunosconceptospresentadosenlosCapítulos2 y 3quesedebenutilizarenconjunción
conestasinstrucciones.Comprenderestosconceptosesfundamentalparaloquesigue.
Primeronecesitaremosformarexpresioneslógicasqueseránverdaderasofalsas.Parahacer
estopodemosutilizarloscuatrooperadoresrelacionales,
<,
<:=,>,>=,ylosdosoperadores de
igualdad,==y!=(versección3.3).
EJEMPLO6.1. Acontinuaciónsemuestranvariasexpresioneslógicas.
cont<=100
sqrt(a+b+c)>0.005
153

154 PROGRAMACiÓN ENC
respuesta==O
balance>=maximo
carl<'T'
letra!=IX'
Lascuatroprimerasexpresionesinvolucranoperandosnuméricos. Susignificadodeberesultarfácilmente
comprensible.
Enlaquintaexpresión,
car1sesuponequeesunavariable detipocarácter.Estaexpresiónserá
verdaderasielcarácterrepresentadopor
car1seencuentraantes delaTeneljuegodecaracteres,esto
es,sielvalornuméricoqueseutilizaparacodificarelcarácteresmenorqueelvalornuméricoutilizado
paracodificarlaletra
T.
Laúltimaexpresiónhaceuso delavariabledetipocarácter letra.Estaexpresiónseráverdaderasi
elcarácterrepresentadopor1
etraesalgúnotroquenoseax.
Ademásdelosoperadoresrelacionalesydeigualdad,eposeedosconectivaslógicas (tam­
biénllamadasoperadoreslógicos), &&(y)YII(O),Yeloperadorunariodenegación!(ver
sección3.3).Lasconectivaslógicasseutilizanparacombinarexpresioneslógicas,formándose
asíexpresionesmáscomplejas.Eloperadordenegaciónseutilizaparainvertirelvalordeuna
expresiónlógica(porejemplo,de verdaderoafalso).
EJEMPLO6.2.Acontinuaciónsemuestranalgunasexpresioneslógicasqueilustranlautilización
de
conectivaslógicasy deloperador denegación.
(cont<=100)&&(car1!='*')
(balance<1000.O)11(estado=='R')
(respuesta<O)11((respuesta>5.O)&&(respuesta<=10.O))
!((pagos>=1000.0)&&(estado=='s'))
Observequeenestosejemplos car1yestadosesuponenvariablesdetipocarácter.Lasotrasvaria­
blessesuponennuméricas(enterasoencomaflotante).
Yaquelosoperadoresrelacionalesydeigualdadtienenmayorprecedenciaquelosoperadoreslógi­
cos,algunosdelosparéntesisnosonnecesariosenlasexpresionesanteriores(ver
Tabl¡l3.1enlasección
3:5).Portanto,podríamoshaberescritoestasexpresionescornosigue:
cont<=100&&car1!='*'
balance<1000.011estado=='R'
respuesta< O11respuesta>5.0&&respuesta<=10.0
!(pagos>=1000.0&&estado
",='s')
Sinembargo,sueleserunabuenaideaincluirparéntesissipuedehaberdudaenlaprecedenciadelos
operadores.Estoesparticularmenteciertoenexpresionesrelativamentecomplicadas,talcornolaexpre­
siónterceradelasanteriores.

INSTRUCCIONES DECONTROL 155
Eloperadorcondicional?:tambiénhaceusodeunaexpresiónqueesverdaderaofalsa(ver
sección3.5).Seseleccionaunvalorenfuncióndelresultadodeestaexpresiónlógica.Esteope­
radoresequivalentea
laestructuraif-then-elsesencilla(versección6.6).
EJEMPLO6.3. Supongamosqueestadoesunavariabledetipocaráctery balanceunavariableen
comaflotante.Deseamosasignarelcarácter Caestadosibalancetieneelvalorcero,y Osibalan­
cetieneunvalormayor quecero.Estosepuedehacerescribiendo
estado=(balance==O)?'c''O'
Finalmente,recordemosqueexistentresclasesdiferentesdeinstruccionesen C:instruccio­
nesdeexpresión,instruccionescompuestas
einstruccionesdecontrol (versección2.8). Una
instruccióndeexpresiónconsiste enunaexpresiónseguidadeunpuntoycoma(versección
2.7).
Unainstruccióncompuestaconsisteenunasecuenciadedosomásinstruccionesconsecu­
tivasencerradasentrellaves({y }
).Lasinstruccionesincluidasenlasllavespuedenserinstruc­
cionesdeexpresión,otrasinstruccionescompuestasoinstruccionesdecontrol.
Lamayoríade
lasinstruccionesdecontrolcontieneninstruccionesdeexpresiónoinstruccionescompuestas,
incluyendolasinstruccionescompuestasanidadas.
EJEMPLO6.4. Acontinuaciónsemuestraunainstruccióncompuesta queseutilizóenelEjemplo3.31.
{
intminuscfmayusci
minusc=getchar( ) ;
mayusc=toupper(minusc);
putchar(mayusc);
}
Heaquíunainstruccióncompuesta máscomplicada:
{
floatsum=o,sumsq O,sumsqrt
;O,Xi
}
scanf(U%f
ll
l&x);
while(x!=O){
suro+=Xi
sumsq+=x*x¡
sumsqrt+=sqrt(x);
scanf("%f",&x);
}
Esteúltimoejemplocontieneunainstruccióncompuestaanidada enotra.

156 PROGRAMACiÓN ENC
Lasinstruccionesdecontrolpresentadasenestecapítulohacenusofrecuentedeexpresiones
lógicaseinstruccionescompuestas.Tambiénseutilizan
operadoresdeasignación, talescomo
elutilizadoenelejemploanterior
(+=).
6.2.EJECUCIÓNCONDICIONAL: LAINSTRUCCIÓNif-else
Lainstruccióni f - e 1 s eseutilizapararealizarunacomprobaciónlógica yacontinuaciónlle­
varacabounadedosposiblesacciones,dependiendodelresultadodelacomprobación(deque
seaverdaderaofalsa).
Laparte
elsedelainstrucciónif-elseesopcional.Portanto,lasinstruccionessepue­
denescribir,en
suformageneralmássimple,
if(expresión)instrucción
Laexpresiónsedebeencontrarentreparéntesis,comose haindicado.Deestaforma,la
instrucciónseejecutarásólosila expresióntieneunvalornonulo(si expresiónes
verdadera).Sila
expresióntieneelvalorcero(si expresiónesfalsa),entoncesseignora­
rála
instrucción.
Lainstrucciónpuedesersimpleocompuesta. Enlaprácticasueleser unainstrucción
compuestaquepuedeincluirotrasinstruccionesdecontrol.
EJEMPLO6.5. Acontinuaciónsemuestranvariasinstruccionesi frepresentativas.
if(x<O)printf("%f",x);
if(debito>O)
credito=O;
if(x<=3.0){
Y=3*pow(x,2);
printf("%f",y);
}
if((balance<1000.)11(estado
printf("%f",balance);
if((a>=O)&&(b<=5)){
xmid=(a+b)!2;
ymid=sqrt(xmid);
}
'R') )
Laprimerainstrucciónhace que
séimprima(visualice)elvalor delavariableencomaflotantex sisu
valoresnegativo.Enlasegundainstrucción, seasignaelvalorceroacreditosielvalordedebitoes
mayorquecero.Latercerainstruccióninvolucraunainstruccióncompuesta enlaqueseevalúay y a
continuación
sevisualiza,sielvalordexnoexcedede3.Enlacuartainstruccióntenemosunaexpresión
lógicacompleja,
quehaceque elvalordebalancesevisualicesi suvaloresmenorde1000osi
estadotieneasignadoelvalor 'R'.

INSTRUCCIONES DECONTROL 157
Laúltimainstruccióninvolucraunaexpresiónlógicacomplejayunainstruccióncompuesta.Alas
variables
xmideymidselesasignarán,pues,valoresapropiadossólosielvaloractualde aesno
negativo
yelvaloractualdebnoexcede de5.
Laformageneraldeunainstrucciónifqueincluyelacláusulae 1sees
if(expresión)instrucción1elseinstrucción2
Silaexpresióntieneunvalornonulo(siexpresiónesverdadera),entoncesseejecu­
taráinstrucción1.Enotrocaso(expresiónesfalsa),se ejecutaráinstrucción2.
EJEMPLO6.6. Acontinuaciónpresentarnosvariosejemploscornomuestradeluso delainstrucción
if
-elsecompleta.
if(estado=='8')
tasa=0.20*pago;
else
tasa=0.14*pago;
if(debito>O){
printf("cuentanº%destáennúmerosrojosn/no_cuenta);
credito=O;
}
else
credito=10OO.O;
if(x<=3)
Y=3*pow(x,2);
else
y=2*pOW((x-3),2);
printf{"%f",balance);
if(circulo)(
scanf("%f",&radio);
area=3.14159*radio*radio;
printf("Areadelcirculo=%f",area);
}
else(
scanf("%f%f",&longitud,&anchura);
area=longitud*anchura;
printf("Areadelrectángulo=%f",area);
}
Enelprimerejemploelvalorde tasasedeterminadedosformasposibles,dependiendo delcarácterque
selehayaasignadoalavariable
estado.Observeelpuntoycomaalfinaldecadainstrucción,especial­
menteenlaprimera
(tasa
=0.2O*pago;).Unaformamásconcisadehacerlomismoesla
siguiente:
tasa
=(estado=='S')?(0.20*pago)
sibienesteestilonoquedatanclaro.
(0.14*pago);

158 PROGRAMACiÓN ENC
Elsegundoejemploexaminaelestadodedébitodeunacuenta. Sielvalordedebitoesmayorque
cero,sevisualizaunmensajeyellímitedecréditoseestableceencero;encualquierotrocaso,ellímitede
créditoseestableceen
10OO.o.Eneltercerejemplosecalcula elvalordeydedosfonnasdistintas,
dependiendodesielvalordex
esmayoro noque3.
Elcuartoejemplomuestracómosepuedecalcularunárea
dedosfigurasgeométricas.Sia c irculo
seleasignaunvalornonulo,seleeelradiodelcírculo,secalculaeláreayluegosevisualiza.Perosiel
valorde
circuloescero,entonces seleenlalongitudylaanchuradeunrectángulo,secalculaeláreay
luegosevisualiza.Encadacaso,serotulaeltipo
defigurageométricajuntoalvalordeláreacorrespondiente.
Esposibleanidar(incluir)instruccionesif-elseunadentrodeotra.Estasanidaciones
puedentomarformasdiferentes.Laformamásgeneral
deanidamientodoble es
ifelife2sl
elses2
elseife3s3
elses4
endondeel,e2ye3representanexpresioneslógicas ysl,s2,s3ys4instrucciones.Enesta
situaciónseejecutaráunainstrucción
if-elsecompletasi elesnonula(verdadera), ys
ejecutaráotrainstrucción
if-elsesielescero(falsa).Esposible,porsupuesto,que sl,
s2,s3ys4contenganotrasinstrucciones ifelse.Tendríamosenestecaso unanida­
mientomúltiple.
Algunasotrasformas
deanidamientodobleson
ifelsl
elseife2s2
ifelsl
elseife2s2
elses3
ifelife2sl
elses2
elses3
ifelife2sl
elses2
Enlostresprimeroscasoslaasociaciónentrelascláusulase 1s eysusexpresionescorrespon­
dientes
esclara.Sinembargo,enelúltimocasonoquedaclaroquéexpresión (e1oe2)tieneaso­
ciadalacláusula
else.Larespuestaes e2.Lareglaaaplicaresquelacláusula elsesiemprese
encuentra
asociadaalifnoaparejado(sin else)precedentemáscercano.Elsangradodelas
líneasdebesugeriresto,aunquenoesésteelfactordecisivo.Portanto,elúltimOejemploes
equivalentea
ifel{
ife2slelses2
}

INSTRUCCIONES DECONTROL 159
Siquisiéramosasociarlacláusula elseaelenlugardea e2,podríamoshacerestoescribiendo
ifel{
ife2sl
}
elses2
Estetipodeanidamientosedebeutilizarconcuidado,convistasaevitarposiblesambigüedades.
Enalgunassituacionespuederesultarinteresanteanidarmúltiplesinstrucciones
if -e 1se,
paracrearunasituaciónenlaqueseseleccionaráunaentrevariasacciones. Porejemplo,la
formageneraldecuatroinstrucciones
if -e 1s eanidadassepuedeescribirasí:
ifelsl
elseife2s2
elseife3s3
elseife4s4
elses5
Cuandoseencuentre unaexpresiónlógicaconvalornocero(verdadera),seejecutarálacorrespon­
dienteinstrucción
ynoseevaluaránelrestodelasinstrucciones if -e 1 se.Deestaforma,el
controlsetransfierefueradetodalaanidaciónunavezqueseencuentreunacondiciónverdadera.
Lacláusulae 1 s efinalseaplicarásólosiningunadelasexpresionesesverdadera.Sepuede
utilizarlamismaparaproporcionarunacondiciónporomisiónounmensajedeerror.
EJEMPLO6.7. Acontinuaciónsemuestraunejemplodetresinstruccionesif-elseanidadas.
((hora>=O.)&&(hora<12.))
ifprintf("BuenosDías");
((hora>=12.)&&(hora<18.))
elseifprintf("BuenasTardes");
((hora>=18.)&&(hora<24.))
elseifprintf("BuenasNoches");
elseprintf("Horanoválida");
Esteejemplohacequesevisualiceunmensajediferenteadistintas horasdeldía.Concretamente,sevisua­
lizará
BuenosDíassihoratieneunvalorentreOy 12;sevisualizaráBuenasTardessihora
tieneunvalorentre 12y18;YsevisualizaráBuenasNoches.sihoratieneunvalorentre 18y24.
Sihoratieneunvalormenor quecero,omayoroiguala 24,sevisualizaráunmensajedeerror("Hora
noválida").
6.3.BUCLES: LAINSTRUCCIÓNwhile
Lainstrucciónwhi1eseutilizaparagenerarbucles,enloscualesungrupodeinstruccionesse
ejecutadeformarepetida,hastaquesesatisfacealgunacondición.
Laformageneralde
lainstrucciónwhilees
while(expresión)instrucción

160 PROGRAMACiÓN ENC
Lainstrucciónseejecutarárepetidamente,mientraselvalordeexpresiónseaverdadero
(mientrasexpresióntengaunvalornonulo).Estainstrucciónpuedesersimpleocom­
puesta,aunquesuelesercompuesta.Debeincluiralgúnelementoquealtereelvalorde
expresión,proporcionandoasílacondicióndesalidadelbucle.
EJEMPLO6.8.Cantidadesenterasconsecntivas. Supongamosquequerernosvisualizarlosdígí­
tos
O,1,2,...
,9,apareciendocadaunoencadalínea.Estosepuedehacerconelsiguienteprograma.
#inc1ude<stdio.h>
main()
{
/*visualizarlosnúmerosdelOal9*/
intdigito=O;
}
while
}
(digito<=9)
printf("%d",
++digitoi
(
digito);
Inicialmenteseleasignaa
digitoelvalorO.Elbuclewhilevisualizaacontinuación elvaloractualde
digito,incrementasuvaloren1 yrepiteelciclohastaqueelvalorde digitoseamayorque9.El
efectototalesqueelcuerpodelbucleserepetirá
10veces,generándose 10líneasconsecutivasdesalida.
Cadalíneacontendráunnúmero,comenzandoporO yacabandoen9.Portanto,cuandoseejecuteel
programa,segeneralasiguientesalida.
O
1
2
3
4
5
6
7
8
9
Esteprogramasepuedeescribirdeformamásconcisacomosepresentaacontinuación.
#include<stdio.h>
main()
{
/*visualizarlosnúmerosdelOal9*/
intdigito=O;
while(digito<=9)
printf("%d",digito++);
}
Cuandoseejecute,esteprogramagenerarálamismasalidaque.elprimero.

INSTRUCCIONES DECONTROL 161
Enalgunosbuclesenparticular,seconoceapriorielnúmerodepasadasatravésdel bucle.
Elejemploanteriormuestraunbucledeestetipo. Sinembargo,enotrasocasiones noseconoce
poradelantadoelnúmerodepasadasatravésdelbucle.Ensulugar,larepeticióncontinúade
formaindefinida,hastaquesesatisfagaunacondiciónlógicaespecificada.Paraestesegundo
tipode buclesesbastanteadecuadalainstrucciónwhi1e.
EJEMPLO6.9.Conversión deminúsculasamayúsculas. Enesteejemploseleeunalineadetexto
enminúsculascarácteracarácter
ysealmacenanloscaracteresenunarrayllamado letras.Elprogra­
macontinúaleyendocaractereshastaqueseleauncarácterdefindelinea
(EOL).Acontinuaciónse
transformanloscaracteresamayúsculas,utilizandolafuncióndebiblioteca
toupper,yseescriben.
Seutilizandosinstrucciones whi1eporseparado.Laprimeraleeeltextointroducidoporteclado.
Obsesrvequenoseconoce
apriorielnúmerodepasadasatravésdeestebucle.Elsegundobucle while
realizalaconversiónyescribe eltextotransformado.Efectuaráunnúmeroconocidodepasadas,dadoque
elnúmerodecaracteresaescribirvienedeterminadoalcontarelnúmero depasadasatravésdelprimer
bucle.
Acontinuaciónsemuestraelprogramacompleto.
/*convertirunalíneadetextodeminúsculasamayúsculas*/
#include<stdio.h>
#include<ctype.h>
#defineEOL''
main()
{
charletras[80],
intaux,cont
=O;
/*leereltextoenminúsculas*/
while((letras[cont]=getchar())!=EOL)++cont,
aux=cont¡
/*escribireltextoenmayúsculas*/
cont=O,
while(cont<aux){
putchar(toupper(letras[cont])),
++cont¡
}
}
Observeque conttieneasignadoinicialmenteelvalorcero.Suvalorseincrementaen1encadapasada
porelprimerbucle.Elvalorfinalde
cont,alconcluirelprimerbucle,seasignaentoncesa aux.Elvalor
deauxdeterminaelnúmerodepasadasporelsegundobucle.
Elprimerbucle
while,estoes,
while((letras[cont]=getchar())!=EOL)++cont;
estáescritodeformamuyconcisa.Estebucledeunasolainstrucciónesequivalentealsiguiente:

162 PROGRAMACIÓN ENC
letras[cont]=getchar();
while(letras[cont]!=EOL) (
cont=cont+1;
letras[cont]=getchar();
}
Estaúltimaformaresultarámásfamiliaraaquelloslectoresquehayanutilizadootroslenguajesdeprogra­
macióndealtonivel,comoPascaloBASIC.Lasdosformassoncorrectas,sibienlaprimeraesmás
representativadelestilodeprogramacióntípicoen
C.
Cuandoseejecutaelprograma,cualquierlíneadetextoqueseintroduzcasevisualizaráacontinua­
ciónenmayúsculas.Supongamos,porejemplo,queseintroducelasiguientelíneadetexto:
tumiradamerecuerdaelfulgordelaaurora...
Lacomputadoraresponderáescribiendo
TUMIRADAMERECUERDAELFULGORDELAAURORA...
EJEMPLO6.10. Mediadeunalistadenúmeros.Utilicemosahoraunainstruccíón whileparacal­
cularlamediadeunalista
dennúmeros.Basaremosnuestraestrategiaenelusodeunasumaparcialque
inicialmenteseaigualacero,actualizandoestevalorcadavezqueseintroduzcaunnúmeroenlacompu­
tadora.Portanto,elproblemasugieredeformamuynaturalelusode unbucle.
Loscálculosseefectuarán
delasiguientemanera.
1.Asignarelvalorde1 alavariableentera cont.Estavariableseutilizarácomocontadoren el
bucle.
2.AsignarelvalordeO alavariableencoma flotante suma.
3.Leerelvalordelavariableentera n.
4.Realizarlossiguientespasos deformarepetidamientras contnoseamayorque n.
a)Leerunnúmerodelalista.Cadanúmerosealmacenaráenlavariableencomaflotante X.
b)Añadirelvalordexalactual desuma.
e)Incrementaren1 elvalordecont.
5.Dividirpornelvalorde sumaparaobtenereldeseadodelamedia.
6.Escribirelvalorcalculadodelamedia.
Presentamosacontinuaciónelprogramaen
C.Nótesequelasoperacionesdeentradavanacompaña­
das
derótulosquepidenalusuariolainformaciónrequerida.
!*calcularlamediadennúmeros*!
#include<stdio.h>
main()
{
intn,cont =:;1¡
floatx,media,suma=O;

INSTRUCCIONES DECONTROL 163
/*inicializaryleerelvalorden*/
printf(t1¿Cuantosnúmeros? 11);
scanf(U%dH I&n)i
/*leerlosnúmeros*/
while(cont<=n){
printf(" x=ti)i
scanf(ll%fll/&x)¡
suma+=Xi
++cont¡
}
/*calcularlamediayescribirlarespuesta*/
media=suma/ni
printf(,rLamediaes%f",media);
}
Observequeelbucle whi1 econtiene unainstruccióncompuestaque,entreotrascosas,seocupade
incrementarelvalorde
cont.Estoharáquelaexpresiónlógica
cont<=n
sehagafalsaenalgúnmomento,finalizándoseconelloelbucle.Observetambiénqueelbuclenose
ejecutarániunasolavezsi
elvalordenesmenorque1(locualporsupuestocareceriadesentido).
Supongamosahoraqueelprograma
seutilizaparaprocesarunalistaconlossiguientesseisvalores: 1,
2,3,4,5,6.Laejecucióndelprogramaconllevaráelsiguientediálogointeractivo.(Observequelas
respuestasdelusuarioestánsubrayadas.)
¿Cuantosnúmeros?
Q
x=1.
x=2-
x=1
x "'-
x=.2-
x=Q
Lamediaes3.500000
6.4.MÁSSOBREBUCLES:LAINSTRUCCIÓN dowhile
Cuandoseconstruyeunbucleutilizandolainstrucción whiledescritaenlasección6.3,la
comprobaciónparalacontinuacióndelbucleserealizaal
comienzodecadapasada.Sinembar­
go,avecesesdeseabledisponerdeunbucleenelqueserealicelacomprobación
aljinaldecada
pasada.
Estosepuedehacermediantelainstrucción do-while.
Laformageneraldelainstrucción do-whilees
doinstrucciónwhile(expresión)

164 PROGRAMACiÓN ENe
Lainstrucciónseejecutarárepetidamente,mientrasqueelvalordeexpresiónseaver­
dadero(esdecir,distinto decero).Observequeinstrucciónsiempreseejecutaráalmenos
unavez,yaquelacomprobacióndelacondiciónderepeticiónnoserealizahastaelfinaldela
primerapasadaporelbucle.Lainstrucciónpuedesersimpleo compuesta,aunqueenla
mayoríadelasvecesserácompuesta.Debeincluiralgúnelementoquealtereel valordeex­
presiónparaqueelbucletengaunfinal.
Paralamayoríadelasaplicacionesesmásnaturalcomprobarlacondiciónalcomienzodel
buclequealfinal.Porestarazón,lainstruccióndo-whi1 eseutilizaconmenorfrecuencia
quelainstrucciónwhiledescritaenlasección6.3.Comoilustracióndelusodelainstrucción
do while,repetimosacontinuaciónlosejemplosdeprogramaciónmostradosenlasec­
ción6.3,utilizandolainstruccióndo-whileparalosbuclescondicionales.
EJEMPLO 6.11. Cantidadesenterasconsecntivas.EnelEjemplo6.8vimosdosprogramas
completosqueutilizabanlainstrucción
whileparavisualizarlosnúmeros O,1,2,...,9.Heaquí
otroprogramaquerealiza
lomismoutilizandolainstrucción do-whi1eenlugar delainstrucción
whi1e.
#include<stdio.h>
main()/*visualizarlosnúmerosdelOal9* /
{
intdigito=O;
do
printf("%d",digito++);
while(digito<=9);
}
Comoenelejemploanterior,seleasignainicialmentea digitoelvalorO.Elbucledo-while
visualizaelvaloractualde digito,incrementandosuvaloren 1,y acontinuacióncompruebasielvalor
actualde
digitoesmayorque9. Siesasí,elbuclefinaliza;enotrocaso,continúaelbucle,utilizando
elnuevovalorde digita.Observequelacomprobaciónsellevaacaboalfinaldecada pasadaporel
bucle.Elefectoglobalesqueelbucleserepite
10veces,generándose 10lineasdesalida.Cadalínea
apareceráexactamentecomosepresentóenelEjemplo6.8.
SicomparamosesteprogramaconelsegundopresentadoenelEjemplo6.8,veremosqueambospro­
gramastienenaproximadamenteelmismoniveldecomplejidad.Ninguna
delasestructurasdebuclecon­
dicionales
(whileodo-while)parecemejorquelaotra.
EJEMPLO6.12. Conversióndeminúsculasamayúsculas.Reescribamosahoraelprogramapresen­
tadoenelEjemplo6.9,queconvertíauntextodeminúsculasamayúsculas,reemplazandolosdosbucles
whileporbuclesdo-while.Comoenelprogramaanterior,leeremosprimerounalíneadetextoen
minúsculascarácteracarácter,almacenaremosloscaracteresenunaformaciónllamada
letrasylo
escribiremosacontinuaciónenmayúsculasutilizandolafuncióndebiblioteca
toupper.Utilizaremos
unainstrucción
do-whileparaleerlalíneadetextocarácter acarácteryotrainstrucción do
whi1 eparaconvertirloscaracteresamayúsculasyescribirlos.
Heaquíelprogramaen
C.

INSTRUCCIONES DECONTROL 165
/*convertirunalíneadetextodeminúsculasamayúsculas*/
#include<stdio.h>
#include<ctype.h>
#defineEOL''
main()
{
charletras[8O];
intaux,cont ;;:;-1;
/*leereltexto
do++cont;while
aux ;;:;cont¡
enminúsculas*/
((letras[cont]=getchar())!=EOL);
}
/*escribireltextoenmayúsculas*/
cont=O;
do(
putchar(toupper(letras[cont]));
++cont¡
}while(cont<aux);
Denuevo vemosdostiposdiferentes debucles,aunqueambosseescribancomobucles do-whi­
le.Enparticular,elnúmerodepasadasporelprimerbuclenoesconocidoapriori,peroelsegundobucle
ejecutaunnúmeroconocidodepasadas,determinadoporelvalorasignadoa
aux.
Observeque elprimerbucle,esdecir
do++cont;while((letras[cont]=getchar())!=EOL);
essimpleyconciso,peroelsegundobucle,
do(
putchar(toupper(letras[cont]));
++cont;
}while(cont<aux);
esalgomáscomplejo.Ambosbuclessecorrespondenconlos whilepresentadosenelEjemplo6.9.
Observe,sinembargo,queelprimerbucledeesteprogramacomienzaconunvalorde
-1asignadoa
cont,mientrasque elvalorinicialde conteraOenelEjemplo6.9.
Cuandoseejecutaelprograma,secomportadelamismaformaqueeldelEjemplo6.9.
Antesdedejaresteejemplo,mencionarqueelúltimobuclesepodriahaberescrito
deformamás
concisaasí:
do
putchar(toupper(letras[cont++]));
while(cont<aux);
Estopuedepareceruntantoextrañoalosrecién iniciados,aunqueescaracteristicodelestilodeprograma­
cióncomúnmenteusadoporlosprogramadoresdeCmásexperimentados.

166 PROGRAMACiÓN ENC
EJEMPLO6.13. Mediadeunalistadenúmeros. SepuedereescribirfácilmenteelprogramadelEjem­
plo6.10
defonnaqueilustre elusodelainstruccióndo-while.Lalógicaserálamisma,exceptoque
lacompobaciónparadetenninarsi
sehanintroducidolosnnúmeros enlacomputadoranoseharáhastael
finaldelbucleenlugardealprincipio.Portanto,
elprogramasiempreharáalmenosunapasadaatravés
delbucle,auncuandoa nse
lehayaasignadoelvalorde O(locualnotendríasentido).
Heaquilaversiónmodificadadelprograma.
/*calcularlamediadennúmeros*/
#include<stdio.h>
main()
{
intTI,cont=1;
floatx,media,suma=O;
/*inicializaryleerelvalorden*/
printf
(n¿Cuantosnúmeros?H);
scanf(lI%d",&n)i
/*leerlosnúmeros*/
do{
printf("X=11);
scanf(lI%fll,&x);
suma+=X;
++cont¡
}while(cont<=n);
/*calcularlamediayescribirlarespuesta*/
media=suma/ni
printf("Lamediaes%f",media);
}
Cuandoseejecutaelprograma,secomportadelamismafonnaquelaauteriorversiónpresentadaenel
Ejemplo6.10.
6.5.MÁSAÚNSOBRE BUCLES:LAINSTRUCCIÓN for
Lainstrucciónforeslatercerayquizáslamásfrecuentementeusadadelasinstruccionespara
crearbuclesenC.Estainstrucciónincluyeunaexpresiónqueespecificaelvalorinicialdeun
índice,otraexpresiónquedeterminacuándosecontinúaonoelbucleyunaterceraexpresión
quepermitequeelíndicesemodifiquealfinaldecadapasada.
Laformageneraldelainstrucciónfores
for(expresión
1;expresión2;expresión3)instrucción
endondeexpres~on 1seutilizaparainicializaralgúnparámetro(denominadoíndice)que
controlalarepeticióndelbucle,expresión2representaunacondiciónquedebesersatisfecha

INSTRUCCIONES DECONTROL 167
paraquesecontinúelaejecucióndelbucle yexpresión3seutilizaparamodificarelvalor
delparámetroinicialmenteasignadopor
expresión1.Típicamente,expresión1esuna
expresióndeasignación,
expresión2unaexpresiónlógica yexpresión3unaexpresión
unariaounaexpresióndeasignación.
Cuandoseejecutalainstrucción
for,seevalúaexpresión2ysecompruebaantesde
cadapasadaporelbucle,
yalfinaldecadapasadaseevalúa expresión3.Portanto,la
instrucción
faresequivalentea
expresión1;
while(expresión2){
instrucción
expresión3;
}
Laejecuciónrepetidadelbuclecontinuarámientraselvalorde
expres~on 2noseacero,
estoes,mientraslacondiciónlógicarepresentadapor
expresión2seacierta.
Lainstrucciónfor,10mismoquelasinstrucciones whileydo while,sepuede
utilizarpararealizarrepeticionesdondenoseconozca
apriorielnúmerodepasadas porelbucle.
Sinembargo,debidoaloselementosincorporadosen
lainstrucciónfor,éstaesparticularmente
adecuadaparabuclesdondeseconozca
apriorielnúmerodepasadas.Comoreglapráctica,los
bucles
whileseutilizangeneralmentecuando noseconoceapriorielnúmerodepasadas, y
losbuclesfarseutilizangeneralmentecuando síseconoceapriorielnúmerodepasadas.
EJEMPLO6.14. Cantidadesenterasconsecntivas. Yahemosvistodiferentesversiones deunprogra­
maenequevisualizalosnúmerosO,1,2,...,9,unoencadalínea(verEjemplos 6.8y6.11).Heaquiotro
programa
quehacelomismo.Ahora,sinembargo, seutilizalainstrucción forenlugardelasinstruccio­
neswhi1eydo-whi1e,comoenlosejemplosanteriores.
#inc1ude<stdio.h>
main()
{
/*visualizarlosnúmerosdelOal9*/
intdigito=O;
for(digito=O;digito<=9;++digito)
printf("%d",digito);
}
Laprimeralínea delainstrucciónforcontienetresexpresiones,encerradasentreparéntesis.Lapri­
meraexpresiónasigna
unvalorinicialOalavariableentera digita;lasegundaexpresiónestablece que
elbucleserepetirámientras queelvaloractualdedigitonoseamayorque9alcomienzodecadapasa­
da;ylaterceraexpresión,incrementa en1elvalordedigitoencadapasadapor elbucle.Lafunción
printfincluidaenelbucleforproducelasalidadeseada, comosevioenelEjemplo6.8.
Desdeelpuntodevistasintácticonoesnecesarioqueseencuentrenpresenteslastresexpre­
siones
enlainstrucciónfor,aunquedebenaparecerlospuntos ycomas.Sinembargo,sedeben

168 PROGRAMACiÓN ENC
entenderclaramentelasconsecuenciasdeestaomisión.Sepuedenomitirlasexpresionesprime­
raytercerasiseinicializay/oalteraelindicedealgunaotraforma.Sin embargo,siseomitela
segundaexpresión,seasumiráqueéstatieneunvalorpermanentede1(cierta);portanto,el
buclecontinuaráejecutándoserepetidamentedeformaindefinidaamenosquesefinaliceme­
diantealgúnotromecanismo,talcomounainstrucciónbreakoreturn(versecciones6.8
y7.2).
Encualquiercaso,lamayoríadelasaplicacionesdelainstrucciónforincluyenlastres
expresIOnes.
EJEMPLO6.15. Variacióndecantidades enterasconsecutivas.Veamosotroejemplo deunprograma
enCquegeneralosenterosconsecutivos
O,1,2'00"9,cadauno deellosenunalínea.Utilizaremosahora
unainstrucción
forenlaquedosdelastresexpresionessehanomitido.
#include<stdio.h>
main()
{
/*visualizarlosnúmerosdelOal9*/
intdigito=O;
}
for(;digito<=9;
printf("%d",
)
digito++);
EstaversióndelprogramaesmásoscuraquelaquesemostróenelEjemplo 6.14,yportantomenos
deseable.
NóteselasimilitudentreesteprogramayelsegundoprogramadelEjemplo6.8,queutilizalainstruc­
ción
while.
EJEMPLO6.16. Conversióndeminúsculasamayúsculas.PresentamosdenuevounprogramaenC
queconvierteuntextodeminúsculasamayúsculas.Yahemosvistootrosprogramasquehacenesto,en
losEjemplos
6.9y6.12.Enésteharemosusodelainstrucción forenlugardelasinstrucciones while
ydo-while.
Comoenloscasosanteriores,primeroseleeráunalíneadetextoenminúsculascarácteracarácter,se
almacenaránloscaracteresenunarrayllamada
letrasyseescribiráacontinuaciónenmayúsculas
utilizandolafuncióndebiblioteca
toupper.Senecesitandosbucles:unoparaleeryalmacenarlos
caracteresenminúsculas,elotroparavisualizarloscaracteresenmayúsculas.Observequesehaceusode
unainstrucciónf
orparaconstruirunbucleenelqueelnúmerodepasadasnoesconocido apriori.
Heaquíelprogramacompletoen C.
/*convertirunalíneadetextodeminúsculasamayúsculas*/
#include<stdio.h>
#include<ctype.h>
#defineEOL''
main()
{
charletras[ 8O]
;
intaux,cont;

INSTRUCCIONES DECONTROL 169
/*leereltextoenminúsculas*/
for(cont=O;(letras[cont]=getchar())!=EOL;++cont)
aux=cont;
/*escribireltextoenmayúsculas*/
for(cont=O;cont<aux;++cont)
putchar(toupper(letras[cont]));
}
SisecomparaesteprogramaconloscorrespondientesdelosEjemplos 6.9y6.12,sepnedeapreciar
quelosbuclessonmásconcisosalusarlainstrucciónf o rqueconlasinstruccioneswh i 1 e
O
do-while.
EJEMPLO6.17. Mediadeunalistade números.ModifiquemosahoraelprogramadadoenelEjem­
plo
6.10,quecalculalamediadeunalistadennúmeros,deformaqueelbucleserealicemedianteuna
instrucción
foroLalógicaseráesencialmentelamisma,aunquealgunosdelospasosserealizaránen
ordenligeramentediferente.Enparticular:
1.Asignarelvalor Oalavariableencomaflotante suma.
2.Leerelvalordelavariableentera n.
3.Asignarelvalor1 alavariable entera cont,endondecontesuníndicequecuentaelnúmerode
pasadasporelbucle.
4.Realizarlossiguientespasosrepetidamente,mientrasqueelvalorde
contnoseamayorque n.
a)Leerunodelosnúmerosdelalista.Cadanúmerosealmacenaráenlavariableencomaflo­
tante
x.
b)Añadirelvalordexalvaloractualde suma.
e)Incrementaren1elvalorde cont.
5.Dividirelvalorde sumapornparaobtenerlamediadeseada.
6.Escribirelvalorcalculadodelamedia.
Presentamosacontinuaciónelprogramaen
C.Observequelospasos3 y 4seencuentrancombinados
enlainstrucción
for,yquelospasos3 y4(e)serealizanambosenlaprimeralinea(expresionesprimera
ytercera,respectivamente).Observetambiénquelasoperacionesdeentradaseencuentrantodasacompa­
ñadasdemensajesquepidenalusuariolainformacióndeseada.
/*calcularlamediadennúmeros*/
#include<stdio.h>
main()
{
intn,cont=1;
floatX,media,suma=O;
/*inicializaryleerelvalorden*/
printf
("¿Cuantosnúmeros?l!)¡
scanf("%d
ll
l&n)¡

170 PROGRAMACiÓN ENC
/*leerlosnúmeros*/
for(cont=1;cont<=n;++cont){
printf("X=")i
scanf(lI%f"I&x)i
suma+=Xi
}
/*calcularlamediayescribirlarespuesta*/
media=suma/n;
printf("Lamediaes%f",media);
}
ComparandoesteprogramaconloscorrespondientespresentadosenlosEjemplos 6.10y6.13,vemos
denuevounamayorconcisiónenelbuclecuandoseutilizalainstrucción forenlugardelasinstruccio­
nes
whileodo-while.Sinembargo,ahoralainstrucción foresencierto.modomáscomplica­
daqueenlosejemplosanteriores.Enparticular,observequelaparte
instruccióndelbucleesahorauna
instruccióncompuesta.Además,debemosasignardeformaexplícitaunvaloriniciala surnaantesde
lainstrucción
for.
Cuandoseejecutaelprograma,generalamismasalidaquelasanterioresversionesdelosEjem­
plos
6.10y6.13.
6.6.ESTRUCTURAS DECONTROLANIDADAS
Losbucles,aligualquelas instruccionesifelse,sepuedenanidar,unodentrodeotro.
Losbuclesinternoyexternononecesitansergeneradosporelmismotipode estructuradecon­
trol.Sinembargo,esesencialqueunbucleseencuentrecompletamenteincluidodentrodelotro.
Además,cadabucledebesercontroladoporuníndicediferente.
Esmás,lasestructurasdecontrolanidadaspuedeninvolucrartantobuclescomoinstruccio­
nesif e 1 se.Deestemodo,unbuclepuedeestarincluidodentrodeunainstrucción
if-else,yunainstrucciónif-elsepuedeestarincluidaenunbucle.Lasestructuras
anidadaspuedensertodolocomplejasqueserequiera,adaptándosealalógicadelprograma.
EJEMPLO6.18.Repeticiónde lamediade unalistadenúmeros.Supongamosquequeremoscalcu­
larlamedia
devariaslistasconsecutivas denúmeros.Siconocemosporadelantado elnúmerodelistasde
lasquevamosacalcularlasmedias,podemosusarunainstrucción
fo rparacontrolarelnúmerodeveces
queelbucleinterno(elcualcalculalamedia)sevaaejecutar.Elcálculodelamediasepuederealizar
utilizandocualquieradelostresmétodospresentadosanteriormenteenlosEjemplos
6.10,6.13 y6.17
(utilizandounainstrucción
"(hile,do-whileoforjo
Tomemos,porejemplo,lainstrucción forparacalcularlamedia,comoenelEjemplo6.17.Procede­
remos,portanto,delasiguienteforma:
1.Leerelvalorde nlistas,unacantidadenteraqueindicaelnúmero delistasquesevanapro­
cesar.
2.Leerrepetidamenteunalistadenúmerosydeterminarsumedia.Estoes,calcularlamediadeuna
lista
denúmerosparacadavalorsucesivode contlista,desde1hasta nlistas.Seguirlos
pasosdadosen
elEjemplo6.14paracalcularcadamedia.

INSTRUCCIONES DECONTROL 171
Heaquíelprogramaen C.
/*calcularlamediadevariaslistasdenúmeros*/
#include<stdio.h>
main()
{
intn,cont,nlistas,contlista¡
floatX,media,suma;
/*leerelnúmerodelistas*/
printf("¿Cuantaslistas?");
scanf(U%d"/&nlistas)¡
/ *bucleexterno(procesarcadalistadenúmeros)* /
for(contlista=1;contlista<=nlistas;++contlista){
}
/*inicializaryleerelvalorden*/
suma ;:::O;
printf("Listanúmero%d¿Cuantos números?
scanf(lI%d
ll
,&n)¡
/*leerlosnúmeros*/
for(cont=1;cont<=n;++cont){
printf (11X=11)i
scanf(lI%fll,&x);
suma+=Xi
} /*findelbucleinterno*/
/*calcularlamediayescribirlarespuesta*/
.media ;:::suma/ni
printf("Lamediaes%f",media);
} /*findelbucleexterno*/
contlista);
Esteprogramacontienevarioselementosinteresantes.Primero,contienedosinstrucciones
for,una
dentrodeotra.Cadainstrucción
forincluyeunainstruccióncompuesta,queconstadevariasinstruccio­
nesindividualesencerradasentrellaves.
Seutilizauníndicecliferenteencadainstrucción for(losíndi­
cesson
contlistaycont,respectivamente).
Observeque sumasedebeinicializarahoradentro
del.bucleexternoynoenladeclaración..Esto
permiteque
sumaseapuestaacerocadavezqueseintroduceunnuevoconjuntodedat()s(esdecir,al
comienzodecadapasadaatravésdelbucleexterno).
Lasoperacionesdeentradaseencuentrantodasacompañadas
delapresentaciónderótulosymensa­
jes,indicandoalusuarioquédatossonrequeridos.Deestaforma,vemosparesde
funcionesprintfy
scanfenvarioslugaresalolargodelprograma.Dosdelasfunciones printfcontienenvarioscarac­
teresde
nueva1ínea,paracontrolarelespaciamientodelaslíneasdesalida.Estohacequelasalida
asociadaacadaconjuntodedatos(cadapasadaporelbucleexterno)seidentifiqueconfacilidad.
Finahnente,observequeelprogramaestáorganizadoensegmentosseparadosfácilmenteidentifica­
bles,concadasegmentoprecedidoporunalíneaenblancoyuncomentario.

172 PROGRAMACiÓN ENC
Cuandoseejecutadprogramaintroduciendotresconjuntossencillosdedatos,segeneraelsiguiente
diálogo.Comodecostumbre,lasrespuestasdelusuarioalosrótulosseencuentransubrayadas.
¿Cuantaslistas?
~
Listanúmero1
¿Cuantosnúmeros?i
x=1.5
x=2....:....2.
x=6.2
x=3.0
Lamediaes3.300000
Listanúmero2
¿Cuantosnúmeros? ~
x=i
x=-2
x=1-
Lamediaes3.000000
Listanúmero3
¿Cuantosnúmeros?2
x=5.4
x=8.O
x=2.2
x=1.7
x=-3.9
Lamediaes2.680000
EJEMPLO6.19. Conversióndevariaslíneasdetextoamayúsculas.Esteejemploilustralautilización
dedostiposdistintos debucles,unoanidadodentrodelotro.Ampliaremoslosprogramas deconversiónde
minúsculasamayúsculaspresentadosenlosEjemplos6.9,6.12y6.16paraquevarias líneasdetextoen
minúsculasseconviertanamayúsculas,realizándoselaconversiónlíneaalínea.Enotraspalabras,leeremos
unalínea
detextoenminúsculas,lavisualizaremosenmayúsculasy acontinuaciónprocesaremosotralínea,
yasísucesivamente.Estocontinuaráhastaquesedetecteunalíneacuyoprimercarácterseaunasterisco.
Utílizaremosbuclesanidadosparallevaracaboelproceso.Elbucleexternoseutílizaráparaprocesar
varias líneasdetexto.
Ésteincluirádosbuclesinternosseparados.Elprimerodeellosleeunalíneade
textoyelsegundovisualizaeltextoconvertidoenmayúsculas.Observequeestosdosbuclesinternosno
estánanídadosentre
sí.Utílicemos,porejemplo,unainstrnccíón whi1eparaelbucleexternoyuna
instrnccíón
forparacadaunodelosbuclesínternos.
Entérminosgenerales,elprocesoseráelsiguiente:
l.Realízarrepetídamentecadaunodelossiguientespasos,paracadalíneadetexto,mientras el
primercarácterde lalíneanoseaunasterisco.
a)Leerunalíneadetexto
yasignarcadacarácteracadaelementodeunarraydecaracteres
letras.Sedefinirálalineacomounasucesióndecaracteresterminadosporunamarcafin
delínea(nuevalínea).

INSTRUCCIONES DECONTROL 173
b)Asignarlacuentadecaracteres(incluyendoelcarácterdefindelínea)a aux.
e)Escribirlalíneaenmayúsculas,utilizandolafuncióndebiblioteca toupperpararealizarla
conversión.Escribiracontinuacióndoscaracteresdenuevalínea
deformaquelasiguiente
línea
deentradaseencuentreseparada delasalidaactualporunalíneaenblanco.
2.Unavezquesehadetectadounasteriscocomoprimercarácterdeunanuevalínea,escribir
Has­
ta_luegoyterminarelproceso.
Heaquí
elprogramaen ecompleto.
/*convertirvariaslíneasdetextodeminúsculas
amayúsculas.Continuarlaconversiónhastaque
primercarácterdeunalíneaseaunasterisco(*)*/
#include<stdio.h>
#include<ctype.h>
#defineEOL''
main()
{
charletras[80];
intauxtconti
while((letras[O]=getchar())!='*'){
/*leerlíneadetexto*/
for(cont
=O;(letras[cont]=getchar())!=EOL;++cont)
aux ;:::cont¡
/*escribirlalíneadetexto*/
for(cont=O;cont<aux;++cont)
putchar(toupper(letras[cont]));
printf("");
} /*findelbucleexterno*/
printf(
lI
Hastaluego11)i
}
Acontinuaciónsemuestraunasesióninteractivatípica,parailustrarlaejecucióndelprograma.Ob­
servequeeltextodeentradaproporcionadoporelusuarioseencuentrasubrayado,comodecostumbre.
Milgraciasderramandopasoporestossotosconpresura
~~ ~
MILGRACIAS DERRAMANDO PASOPORESTOSSOTOS CONPRESURA
EnunlugardelaManchadecuyonombrenoguieroacordarme~~ ~
ENUNLUGARDELAMANCHA DECUYONOMBRE NOQUIEROACORDARME
*
Hastaluego
Debequedarclaroqueladecisióndeutilizarunainstrucción whi1 eparaelbucleexternoeinstruc­
ciones
forparalosbuclesinternosesarbitraria.Sepodríanhaberutilizadootrasestructurasparalos
bucles.

174 PROGRAMACiÓN ENC
Muchosprogramasinvolucrantantorepeticióncomoejecucióncondicional.Frecuentemente
seanidandiferentesestructurasdecontrol,unasdentrodeotras,comomostramosenlostres
ejemplossiguientes.
EJEMPLO6.20.Codificación deunacadenade caracteres.EscribamosunprogramasencilloenC
queleaunasecuenciadecaracteresASCIIyescribaensulugarunasecuencia
decaracterescodificados.
Siuncarácteresunaletraodígíto, loreemplazaremosporelsiguientecarácterenelconjunto decaracte­
res,exceptoZqueseráreemplazadopor
A,zpora y 9por O.Portanto,1setransformaen2, eenD,p
enq,etc.Cualquiercarácterquenosealetraodígitosereemplazaráporunpunto(.).
Elprocesocomenzaráporlalecturadeloscaracteres.Seutilizarálafunción
scanfparaestefin.Se
introducirányalmacenarántodosloscaractereshasta elcarácterdenuevalínea
(),perosinincluiréste,
enunarrayde
80elementosdetipocarácterllamado1 inea.
Acontinuaciónsecodificarányvisualizaránloscaracteresindividualmentedentro deunbucleforo
Elbucleprocesarácadaunodeloscaracteresde
lineahastaencontrar elcarácterdeescape\ O,que
indicaelfinaldelasecuencia
decaracteres.(Recuérdesequelasecuencia deescape\ Oseañadeautomá­
ticamente
alfinaldecadacadena decaracteres.)Dentrodelbucleseincluyenvariasinstruccionesi f ­
e 1 s eanidadaspararealizarlacodificaciónadecuada.
Sevisualizarácadacaráctercodificadoutilizando
lafunción
putchar.
AcontinuaciónsemuestraelprogramaenCcompleto.
/*leerunacadenadecaracteres,reemplazaracontinuación
cadacarácterporuncaráctercodificadocorrespondiente*/
#include<stdio.h>
main()
{
char1inea[8O];
intcont¡
/*leerlacadenacompleta*/
printf("Introducirdebajounalíneadetexto:");
scanf(11%
[""] 11Ilinea);
/*codificarcadacarácterye'scribirlo*/
for(cont=O;linea[cont]!='\0';++cont){
if(((linea[cont]>='O')&&(linea[cont]< '9'))11
((linea[cont]>='A')&&(linea[cont]<'Z'))11
((linea[cont]>='a')&&(linea[cont]<'z')))
putchar(linea[cont]+1);
elseif(linea[cont]--'9')putchar('O');
elseif(linea[cont]--'Z')putchar('A');
elseif(linea[cont]--'z')putchar('a');
elseputchar(".");
}
}

INSTRUCCIONES DECONTROL 175
Laejecucióndeesteprogramagenera elsiguientediálogoamodo deilustración.Sehasubrayadode
nuevolaentradaproporcionadaporelusuario.
Introducirdebajounalíneadetexto:
TheWhiteHouse.1600PennsylvaniaAvenue.Washington.De
Uif.Xijuf.Ipvtf..2711.Qfootzmwbojb.Bwfovf..Xbtijohupo..ED
EJEMPLO6.21.Cálculosrepetidosdel interéscompuestocondeteccióudeerror. EnelEjem­
plo5.2vimosunprogramaenCquerealizabacálculossimplesdelinteréscompuesto,comoseindicaba
enelEjemplo5.1.Sinembargo,esteprograma
nopermitialaejecuciónrepetida(varioscálculossucesi­
vos,utilizandodiferentesconjuntosdedatos
deentradaparacadaunodeellos),nicontemplabaladetec­
cióndeerroresenlosdatosdeentrada.Nosocuparemosacontinuacióndeañadirestoselementosal
programaanterior.
Incluiremosloscálculosanterioresenunainstrucción
whi1e,queseejecutarámientraselvalorin­
troducidodelasumainicial(p)seapositivo.Portanto,laintroduccióndelvalorceropara
Pseinterpretará
comocondicióndeparada.Incluiremosunmensajeenelqueseexpliquelaformadepararcuandosepida
elvalorde
P.
Además,incluiremosuna deteccióndeerrores quecompruebesielvalordecadaentradaesnegativo,
yaqueunvalornegativo
notienesentidoyseinterpretarácomounerror.Cadacomprobaciónserealizará
enunainstrucción
if.Sisedetectaunerror(unvalornegativo),sepresentaráunmensajepidiendoal
usuarioqueintroduzcadenuevoeldato.
Reaquíelprogramaen
C.
/*problemasencillodeinteréscompuesto*/
#include<stdio.h>
#include<math.h>
main()
{
floatP,r,n,i
lfi
/*leeelvalordelasumainicial*/
printf("Porfavor,introducelasumainicial(P)");
printf("(Parafinalizarelprograma,introducirOcomovalor):");
scanf
("%fllI&p)i
if(p<O) {
printf("ERROR - inténtelodenuevo,porfavor:");
scanf("%f",&p);
}
while(p>O) {/*bucleprincipal*/
/*leerlosrestantesdatosdeentrada*/
printf("Porfavor,introduceelinterés(r)");
scanf(U%f
ll
,&r)¡

176 PROGRAMACiÓN ENC
if(r<O){
printf("ERROR - Inténtelodenuevo,porfavor:");
scanf(ll%f
ll
l&r);
}
printf("Porfavor,introduceelnúmerodeaños(n)" );
scanf(tl%fllI&n);
if(n<O) {
printf("ERROR - Inténtelodenuevo,porfavor:");
scanf(lI%f
l1
,&n)i
}
1*calculariyf*1
i=r/l00;
f=p*pow((1+i),n);
1*escribirsalida*1
printf("Elvalorfinal(F)es:%.2f",f);
1*leerlasumainicialparalasiguientespasada*1
printf("Porfavor,introducelasumainicial(P)");
printf("(Parafinalizarelprograma,introducirOcomovalor):");
scanf("%f",&p);
if(p<O) {
printf("ERROR -inténtelodenuevo,porfavor:");
scanf(ll%f",&p)¡
}
} 1*findelbucleprincipal*1
}
Acontinuaciónsemuestraunasesióninteractivatípica.Observedenuevoquesehansubrayadolasres­
puestasdelusuario.
Porfavor,introducelasumainicial(P)
(Parafinalizarelprograma,introducirOcomovalor):1000
Porfavor,introduceelinterés(r):Q
Porfavor,introduceelnúmerodeaños(n)20
Elvalorfinal(F)es:3207.14
Porfavor,introducelasumainicial(P)
(Parafinalizarelprograma,introducirOcomovalor):5000
Porfavor,introduceelinterés(r):-7.5
ERROR-Inténtalodenuevo,porfavor:7.5

INSTRUCCIONES DECONTROL 177
Porfavor,introduceelnúmerodeaños(n)12
Elvalorfinal(F)es:11908.90
Porfavor,introducelasumainicial(P)
(Parafinalizarelprograma,introducirOcomovalor):Q
Observequesehan proporcionadodosconjuntosdedatos.Elprimerconjuntoescompletamentecorrecto,
resultandounvalorfuturode
3207.14(comoenelEjemplo5.4).Enelsegundoconjuntodedatosse
introduceinicialmenteunvalornegativodeltantoporcientodeinterés
(r).Estoesdetectadocomoerror,
presentandoacontinuaciónunmensajede
errOrysolicitandootrovalor.Unavezquesehaproporcionado
elvalorcorrecto,elrestodelaejecucióncontinúacomoeradeesperar.
Despuésdequesehayaprocesadoelsegundoconjunto
dedatos,elusuariointroduceelvalor Opara
lasumainicialenrespuestaalmensaje.Estohacequeterminelaejecucióndelprograma.
Debequedarclaroqueladeteccióndeerroresutilizadadeesteprogramaselimitaalaintroducción
de
cantidadesencomaflotantenegativascomodatosdeentrada.Otrotipodeerrorocurriríasiseintrodujese
unaletraounsignodepuntuaciónenuna
delascantidadesdeentradarequeridas.Estoproduciráunerror
deentradaenlafunción
scanf.Cadacompiladortrataesteerrordeformadiferente,impidiendouna
deteccióndeerroresgeneralysencilla.
Elsiguienteprogramaesdenaturalezamáscomprensible.Incluyelamayoríadeloselemen­
tosdeprogramaciónquehemostratadoconanterioridadenestelibro.
EJEMPLO6.22.Soluciónde unaecuaciónalgebraica.Paraloslectoresmásaficionadosalasmate­
máticas,esteejemploilustracómosepuedenutilizarlascomputadoraspararesolverecuacionesalgebrai­
cas,incluidasaquellasquenosepuedenresolverutilizandométodosmásdirectos.Consideremos,por
ejemplo,laecuación
x
5
+3x'
-10=O.
Estaecuaciónnosepuedetransformardeformaqueobtengamosunasoluciónexactapara x.Sin embargo,
sepuededeterminarlasoluciónmedianteunprocedimientorepetidodepruebayerror(procedimiento
iterativo)querefinasucesivamenteunvalorinicialsupuesto.
Comenzaremosporreescribirlaecuación
delaformasiguiente:
x=(10- 3X')1!5
Nuestroprocedimientoempezaráporsuponerunvalorde x,sustituirestevalorenlapartederechadela
últimaecuacióny acontinuacióncalcularunnuevovalorde
x.Siestevalornuevoesigual(omuypróxi­
mo)alvaloranterior,esquehemosobtenidolasolucióndelaecuación.Deotraformasesustituiráeste
nuevovalorenlapartederechadelaecuaciónysevolveráaobtenerotrovalorde
x,yasísucesivamente.
Continuaráesteprocedimientohastaquelosvaloressucesivosdexseanlosuficientementepróximos
(estoes,hastaqueelcómputo
converja)ohastaqueseexcedaunnúmeroespecificadodeiteraciones.La
últimacondiciónseocupadeimpedirquecontinúenloscálculosindefinidamenteen
elcasodequelos
resultadosobtenidosnoconverjan.
Paravercómofuncionaelmétodo,supongamosunvalorinicialdex
=1.O.Sustituyendoestevalor
enlapartederechadelaecuaciónobtenemos:
x=[10-3(1.0)']°·'=1.47577

178 PROGRAMACiÓN ENC
Acontinuaciónsustituimosestenuevovalorenlaecuación,obteniendo
x~[10- 3(1.47577)']°2=1.28225
Continuandoesteprocedimiento,seobtiene
x~[lO-3(1.28225)2]0' =1.38344
x~[lO- 3(1.38344)']°2=1.33613
yasisucesivamente.Observequelosvaloresconsecutivosdexparecenconvergeralarespuestafinal.
Eléxitodelmétododependedelvalorinicialtomadopara
x.Siestevaloresdemasiadograndeen
valorabsoluto,lacantidadentrecorchetesseránegativa,ynosepuedeelevarunacantidadnegativaaun
exponentefraccionario.Portanto,debemoscomprobar
sielvalorde 10 3x
2
esnegativoantesde
sustituirelvalordexporeldelapartederechadelaecuación.
Convistasalaescrituradelprograma,definamoslossiguientessimbolos:
cont
valor
raíz
test
error
indicador=
uncontadordeiteraciones (contseincrementaráen1encadaiteración)
elvalordexsustituido
enlapartederechadelaecuación
elnuevovalorcalculadodex
lacantidad
(10-
3x')
elvalorabsolutodeladiferenciaentre raizyvalor
unavariableenteraqueindicalacontinuaciónonodelaiteración
Continuaremosloscálculoshastaquesesatisfagaunadelassiguientescondiciones:
1.Elvalorde erroresmenorque O. OOO01,encuyocasohabremosobtenidounasoluciónsatis­
factoria.
2.Se
hanrealizadocincuentaiteraciones (cont=5O).
3.Lavariabletesttienevalornegativo,encuyocasonopuedencontinuarloscálculos.
Controlemoseldesarrollodeloscálculosescribiendocadavalorsucesivoder a i
z.
Ahorapodemosescribirelsiguienteesquemadelprograma.
1.Porconveniencia,definirlasconstantessimbólicas VERDADEROyFALSO.
2.Declarartodaslasvariableseinicializarlasvariablesenteras indicadorycont(asignarVER­
DADEROaindicadoryOacont).
3.Leerelvalorinicialde valor.
4.Llevaracaboelsiguienteprocedimientoiterativomientras indicadorseaVERDADERO.
a)Incrementarelvalor de'conten1.
b)AsignarFALSOaindicadorsielnuevovalorde contesiguala 5 O.Estoindicalaúltima
pasada
porelbucle.
e)Examinar.elvalorde
test.Sisuvalorespositivo,procedercomosigue.
i)Calcularunnuevovalorpara raiz;escribirelvaloractualde
C(:mt,seguidodelvalor
actualde
raiz.
ii)Evaluarerror,queeselvalorabsolutodeladiferenciaentre raizyvalor.Sieste
valoresmayorque
O. OOO01,asignarelvaloractualde raizavalorycontinuarcon
lassiguienteiteración.Deotraforma,escribirlosvaloresactualesde
raizycont,y
ponerindicadoraFALSO.Elvaloractualde raizseconsiderarálasolucióndeseada.

INSTRUCCIONES DECONTROL 179
ti)Sielvaloractualde testnoespositivo,nosepuedeseguirconloscálculos.Portanto,
escribirunmensajedeerrorapropiado(porejemplo
Númerosfueraderango)y
establecer
indicadoraFALSO.
5.Despuésdecompletar
elpaso4,escribirunmensajedeerroradecuado(porejemplo Conver­
gencianoobtenida)siconttieneelvalorde 50yelvalorde erroresmayorque
0.00001.
Expresemosahoraelguióndelprogramaenlaformadepseudocódigoconvistasasimplificarla
transformacióndelesquemaaprogramaen
C.
#includearchivos
#defineconstantessimbólicas
main()
{
/*declaracióneinicializacióndevariables*/
/*leerparámetrosdeentrada*/
while(indicador){
/ *incrementarcont*/
/*asignaraindicadorFALSOsicont
=50*/
/*evaluartest*/
if(test>O){
/*evaluarraiz*/
/*visualizarcontyraiz*/
/*evaluarerror*/
if(error>0.00001)valor=raiz;
else{
/*asignaraindicadorFALSO*/
/*visualizarlarespuestafinal(raizyc6nt)*/
}
}
else{
/*asignaraindicadorFALSO*/
/*númerosfueraderango-escribirmensajedeerror*/
}
}/*findewhile*/
if((cont--50)&&(error>0.00001))
/ *convergencianoobtenida
-escribirmensajedeerror* /
}

180 PROGRAMACiÓN ENC
Heaquíelprogramaen ecompleto.
/*determinarlasraícesdeunaecuaciónalgebraica
utilizandounprocedimientoiterativo*/
#include<stdio.h>
#include<math.h>
#defineVERDADERO 1
#defineFALSOO
main()
{
intindicador=VERDADERO,cont=O;
floatvalor,raiz,test,error¡
/*leerparámetrosdeentrada*/
printf("Valorinicial:");
scanf("%f",&valor};
while(indicador){ /*comienzabucleprincipal*/
++cont¡
if(cont 50)indicador=FALSO;
test=10.-3.*valor*valor;
if(test>O) { /*otraiteración*/
raiz=pow(test,0.2);
printf("lteraciónnúmero:%2d",cont);
printf(11 x=%7.Sf
ll
Iraiz);
error=fabs(raiz-valor};
if(error>0.00001)valor=raiz;/*repetirelcálculo*/
else{ /*visualizarlarespuestafinal*/
indicador=FALSO;
printf("Raíz= %7.5f",raiz);
printf(" Nºdeiteraciones=%2d",cont);
}
}
else{ /*mensajedeerror*/
indicador=FALSO; ");
printf("Númerosfueraderango-");
printf("intentaconotrovalorinicial!·);
}
}
if((cont==50)&&(error>0.00001)}/*otromensajedeerror*/
printf("Convergencia noobtenidatras50iteraciones"};
}
Observequeelprogramacontíeneunaínstruccíón whileyvaríasínstruccíonesifelse.Se
podríahaberutílízadofácílmenteunaínstruccíán
forenlugardelaínstruccíón while.Observetam­
bíénlaexístencíadeínstruccíones
if -e 1seanídadasenlamítaddelprograma.

INSTRUCCIONES DECONTROL 181
Acontinuaciónsemuestralasalidaquesegeneraparaunvalorinicialdex =1,conlarespuestadel
usuariosubrayada.Nótesequeloscálculoshanconvergidoalasoluciónx
=1.35195despuésde 16
iteraciones.Lasalidamuestralossucesivosvalores dexacercándosemásymás,conduciendoalasolu­
ciónfinal.
Valorinicial:
1-
Iteraciónnúmero: 1 x=1.47577
Iteraciónnúmero: 2 x=1.28225
Iteraciónnúmero: 3 x=1.38344
Iteraciónnúmero: 4 x=1.33613
Iteraciónnúmero: 5 x=1.35951
Iteraciónnúmero: 6 x=1.34826
Iteraciónnúmero: 7 x=1.35375
Iteraciónnúmero: 8 x=1.35109
Iteraciónnúmero: 9 x=1.35238
Iteraciónnúmero:10 x=1.35175
Iteraciónnúmero:11 x=1.35206
Iteraciónnúmero:12 x=1.35191
Iteraciónnúmero:13 x=1.35198
Iteraciónnúmero:14 x=1.35196
Iteración.número:15 x=1.35196
Iteraciónnúmero:16 x=1.35195
Raíz=1.35195 Nºdeiteraciones=16
Supongamosahoraqueseintroducecomovalorinicialx =10.Estevalorgeneraunnúmerode
testnegativoenlaprimeraiteración.Portanto,lasalidatieneelaspectosiguiente.
Valorinicial:1Q
Númerosfueraderango-intentaconotrovalorinicial
Esinteresanteverquéocurrecuandosevuelveatomarcomovalorinicialx =1,peroelmáximo
númerodeiteracionescambiade5 O a
10.Intenteestoyobserveelresultado.
Hayquedecirqueexistenotrosmuchosmétodositerativosparalaresolucióndeecuacionesalgebrai­
cas.Lamayoríaconvergendeformamásrápidaqueelmétododescritoanteriormente(requierenmenos
iteracionesparaconseguirunasolución),aunqueimplicanmayorcomplejidadmatemática.
6.7.LAINSTRUCCIÓN switch
Lainstrucciónswitchhacequeseseleccioneungrupodeinstruccionesentrevariosgrupos
disponibles.
Laselecciónsebasaenelvalor deunaexpresiónqueseincluyeenlainstrucción
switch.
Laformageneraldelainstrucción switches
switch(expresión)instrucción
endondeexpresióndevuelveunvalorentero.Tengaencuentaque expresióntambién
puedeserdetipo
char,yaqueloscaracteresindividualestienenvaloresenteros.

182 PROGRAMACiÓN ENC
Lainstrucciónincluidaesgeneralmenteunainstruccióncompuestaqueespecificaop­
cionesposiblesaseguir.Cadaopciónseexpresacomoungrupo
deunaomásinstrucciones
individualesdentro
delainstrucciónglobalincluida.
Paracadaopción,laprimerainstruccióndentrodelgrupodebeserprecedidaporunaomás
etiquetas«case» (tambiénllamadas prefijos).Lasetiquetascaseidentificanlosdiferentesgru­
pos
deinstrucciones(lasdistintasopciones)ydistinguenunasdeotras.Lasetiquetasc a s ede­
benser,portanto,únicasdentro
deunainstrucciónswitchdada.
Cadagrupo
deinstruccionesseescribe deformageneral:
caseexpresión:
instrucción1
instrucción2
instrucciónn
oenelcaso devariasetiquetascase,
caseexpresión1
caseexpresión2
caseexpresiónm
instrucción1
instrucción2
instrucciónn
endondeexpresión1,expresión2,. .,
expres~ onmrepresentanexpre­
sionesconstantesdevaloresenteros.Normalmente,cadaunadeestasexpresionesseescribiráo
biencomoconstanteenteraocomoconstante
decarácter.Cada instrucciónindividualque
siguealasetiquetasc a s epuedesersimpleocompuesta.
Cuandoseejecutalainstrucción
switch,seevalúala expresiónysetransfiereelcon­
troldirectamentealgrupodeinstruccionescuyaetiqueta
casetengaelmismovalorqueel de
expresión.Siningunodelosvalores delasetiquetascasecoincideconelvalorde expre­
sión,entoncesnoseseleccionaráninguno delosgruposdelainstrucción switch.Eneste
casosetransfiereelcontroldirectamentealainstrucciónqueseencuentrea
contil}uacióndela
instrucción
switch.
EJEMPLO6.23. Presentamosacontinuación unainstrucciónswitchsencilla.Enesteejemplo,supo­
nemosqueeleccionesunavariabledetipocharo
switch(eleccion=getchar()) {
case'r':
case
'R/:
printf("ROJO");
break;

INSTRUCCIONES DECONTROL 183
case'b':
case'B':
printf("BLANCO");
break;
casela':
caselA':
printf(11AZUL")i
}
Portanto,sepresentaráROJOsieleccionrepresentaroR,sepresentaráBLANCOsieleccion
representaboB,yAZULsielecciontieneelvalor aoA.Nosevisualizaránada sielecciontiene
asignadoalgúnotrocarácter.
Observequecadagrupo
deinstruccionestienedosetiquetasc a s eparacontemplarmayúsculasy
minúsculas.Observetambiénquecadauno
delosdosprimerosgruposacabaconlainstrucción break
(versección6.8).Lainstrucción breakhaceque setransfieraelcontrolfuera delainstrucciónswitch,
evitandoque seejecutemás deungrupodeinstrucciones.
Unodelosgruposdeinstruccionesse puedeetiquetarcomodefa u 1t.Estegruposeselec­
cionarásiningunadelasetiquetascasecoincideconelvalordeexpresíón.(Éstaes una
formaconvenientede generarunmensajedeerrorenrutinasde correccióndeerrores.)Elgrupo
defaultpuedeaparecerencualquierlugardentrode lainstrucciónswitch(nonecesitaser
emplazadoalfinal). Siningunadelasetiquetascasecoincideconelvalordeexpresíóny
noseencuentraelgrupo default(comoenelejemploanterior), lainstrucciónswitchno
haránada.
EJEMPLO6.24. Heaquíunavariación delainstrucciónswitchpresentadaenelEjemplo 6.23.
switch(eleccion=toupper(getchar())){
case'R
/
:
printf("ROJO");
break;
case'B':
printf("BLANCO");
break;
case/A':
printf("AZUL");
break;
de.fault:
printf("ERROR");
}
Lainstrucciónswitchcontieneahoraungrupo default(queconstadeunasolainstrucción),elcual
generaunmensaje
deerrorsiningunadelasetiquetascasecoincidecon expresión.

184 PROGRAMACiÓN ENC
Cadaunodelostresprimerosgruposdeinstruccionestieneahoraunasolaetiqueta case.Eneste
ejemplosenecesitanetiquetas
casemúltiples,yaquelafuncióndebiblioteca toupperhacequetodos
loscaracteresqueserecibanseconviertanamayúsculas.Portanto,
e1eccionsiempretendráasignada
unaletramayúscula.
EJEMPLO6.25.Heaquíotratípicainstrucción switch.Enesteejemplo, sesuponeque indicador
esunavariableentera,ysesuponequex e ysonvariablesencomaflotante.
switch(indicador){
case-1:
y=fabs(x);
break;
caseO:
y
=sqrt(x);
break;
case1:
y=x;
break;
case2:
case3:
y=2*(x-1);
break;
defau1t:
y=O;
}
Enesteejemploseleasignaráa yalgúnvalorrelacionadoconxsi indicadoresiguala -1,O,1,2
o3.Larelaciónexactaentrey y xdependerádelvalorparticularde
indicador.Siindicadorrepre­
sentaalgúnotrovalor,entoncesseleasignaráa yelvalor
O.
Observequelasetiquetas casesonnuméricasenesteejemplo.Observetambiénqueelcuartogrupo
deinstruccionestienedosetiquetas
case,mientrasquecadaunodelosotrosgrupossólotiene
Ijllaeti­
queta
case.Yfinalmenteobservequeenestainstrucción switchseincluyeungrupoporomisión(que
constadeunasolainstrucción).
Deformapráctica,lainstrucciónswitchsepuedevercomounaalternativaalusodeins­
truccionesif-elsequecompruebenigualdades.Entalessituaciones,utilizarlainstrucción
switchespornormageneralmuchomásconveniente.
EJEMPLO6.26.Cálculodeladepreciación. Consideremoscómocalcularladepreciaciónanualpara
algunosobjetossusceptiblesaello,talescomounedificio,unamáquina,etc.Haytresmétodoscomún­
menteusadosparaelcálculodeladepreciación,quesesuelenllamarmétodode
línearecta, métodode
balancedoblementedeclinante, yelmétodode lasumadelosdigitosdelosaños. Deseamosescribirun
programaenCquenospermitaseleccionaralgunosdeestosmétodosparacadaconjuntodecálculos.

INSTRUCCIONES DECONTROL 185
Elprocesocomenzaráleyendoelvalororiginal(sindepreciar)delobjeto,lavidadelobjeto(elnúmero
deañosenlosquesedepreciará)yunenteroqueindiquequémétodoseutilizará.Acontinuaciónse
calcularáladepreciaciónanualyelvalorremanente(nodepreciado)delobjeto,yseescribiráparacadaaño.
Elmétodo
delínearecta eselmásfácil deutilizar.Enestemétodoelvalororiginaldelobjetose
divideporsuvida(númerototaldeaños).Elcocienteresultanteserála cantidadenque
elobjetosedepre­
ciaanualmente.Porejemplo,siunobjetode8000dólaressedepreciaendiezaños,entoncesladeprecia­
ciónanualserá8OOO
/10=8 OOdólares.Portanto,elvalordelobjetohabrádisminuidoen800dólares
cadaaño.Nótesequeladepreciaciónanualeslamismacadaañocuandoseutilizaestemétodo.
Cuandoseutilizaelmétodode
balancedoblementedeclinante, elvalordelobjetodisminuyecadaaño
enun
porcentajeconstante.Portanto,laverdaderacantidaddepreciada,endólares,variarádeunañoal
siguiente.Paraobtenerelfactordedepreciación,dividimosdosporlavidadelobjeto.Estefactor
semul­
tiplicaporelvalordelobjeto
alcomienzodecadaaño (ynoelvalororiginaldelobjeto)paraobtenerla
depreciaciónanual.
Supongamos,porejemplo,quedeseamosdepreciarunobjetode8000dólaresendiezaños,utilizando
elmétodo.delbalancedoblementedeclinante.Elfactordedepreciaciónserá
2/10=0.2.Portanto,la
depreciaciónelprimerañoseráO. 2 O x 8OOO
=16OOdólares.Ladepreciacióndelsegundoañoserá
O.
2O x (8OOO 16OO)=O.2O x640O=1280dólares;ladepreciacióndelterceraño
seráO
.20x5120=1024dólares,yasisucesivamente.
Enelmétodode
lasumadelosdígitosdelosaños, elvalordelobjetoirádisminuyendoenunporcen­
tajequees
diferentecadaaño.Elfactordedepreciaciónseráunafraccióncuyodenominadoreslasumade
losdígitos
de1 an,endondenrepresentalavidadelobjeto.Si,porejemplo,consideramosuntiempo de
vidadediezaños,eldenominadorserá 1+2+3+ + 10=55.Paraelprimerañoel
numeradorserá
n,paraelsegundoañoserá (n-1),paraelterceraño (n-2),yasísucesivamente.
Ladepreciaciónanualseobtienemultiplicandoelfactordedepreciaciónporelvalororiginaldelobjeto.
Paravercómofuncionaelmétododelasuma
delosdígitosdelosaños,depreciemos denuevoun
objetode8000dólaresendiezaños.Ladepreciacióndelprimerañoserá
(10/55)x8OOO=1454.55
dólares;elsegundoañoserá (9/55)*8OOO=13O9 .O9dólares,yasísucesivamente.
Definamosahoralossiguientessímbolos,quenospermitiránescribirelprograma.
val=elvalorencursodelobjeto
aux=elvalororiginaldelobjeto(elvalororiginalde val)
deprec=ladepreciaciónanual
n
=elnúmerodeañosporlosquesedepreciaráelobjeto
anual=uncontadorquetomarávaloresde 1an
e1eccion=unenteroqueindicaquémétodosehadeutilizar
Presentamosacontinuaciónelguióndelprogramaen
C.
1.Declarartodaslasvariableseinicializarlavariableentera eleceiona O(enrealidad,podemos
asignarcualquiervalordistintode4 a
eleccion).
2.Repetirtodoslospasossiguientessielvalorde eleceionnoesiguala4.
a)Leerelvalorde eleccion,queindicaeltipodecálculoquesellevaráacabo.Estevalor
sólopuedeser1,
2,3 o4.(Cualquierotrovalorseconsideraráunerror.)
b)Sielecciontieneasignadoelvalor de1,2 o3,leerlosvaloresde valyn.
c)Dependiendodelvalorasiguadoa eleccion,saltaralaparteadecuadadelprogramay
realizarloscálculosindicados.Enparticular,
i)Si
elecciontieneasignadoelvalorde 1,2 o3,calcularladepreciaciónanualyel
nuevovalordelobjetoañoaaño,utilizandoelmétodoapropiadosegúnindiqueelvalor
de
eleccion.Escribirlosresultadossegúnsevayancalculando,añoaaño.

186 PROGRAMACiÓN ENC
ii)Sielecciontieneasignado elvalor4,escribir elmensaje«Hastaluego» yfinalizarel
programasaliendodelbucle while.
iii)Sielecciontieneasignadounvalordistinto de1,2,3 o4,escribir unmensajede
erroreiniciarunanuevapasadapor elbucle.
Expresemosahoraesteesquemaenforma
depseudocódigo.
#includearchivos
main()
{
/*declaracióneinicializacióndevariables*/
while(eleccion
!=4){
/*generarmenúyleerelección*/
if(eleccion>=1&&eleccion<=3)
/*leervalyn*/
switch(eleccion){
case1:/*métododelínearecta*/
/*escribirtítulo*/
/*calculardepreciación*/
/*paracadaaño:
calcularunnuevovalor
escribiraño,depreciaciónyvalor*/
case2: /*métododebalancedoblementedeclinante*/
/*escribirtítulo*/
/*paracadaaño:
calculardepreciación
calcularunnuevovalor
escribiraño
ldepreciaciónyvalor*/
case3:/*métododelasumadelosdígitosdelosaños*/
/*escribirtítulo*/
/*copiarvalororiginal*/
/*paracadaaño:
calculardepreciación
calcularunnuevovalor
escribiraño,depreciaciónyvalor*/

case4,
INSTRUCCIONES DECONTROL 187
/*findeloscálculos*/
/*escribirmensaje"Hastaluego"*/
/*escribirtítulo*/
default:/*generarmensajedeerror*/
/*escribirmensajedeerror*/
}
}
}
Lamayorpartedelpseudocódigoesdefácilcomprensión,aunquehaylugarparaalgunoscomenta­
rios.Primero,vemosqueseutilizaunainstrucción
whilepararepetirelconjuntocompletodecálculos.
Dentrodeestebucleglobalseutilizaunainstrucción
switchparaseleccionarelmétodoconcretode
cálculodeladepreciación.Cadamétodoutilizaunainstrucción
forpararealizarloscálculosrequeridos.
LlegadosaestepuntonoesdificilescribirelprogramafinalenC,comosemuestraacontinuación.
/*calcularladepreciaciónutilizandounodetresmétodosdiferentes*/
#include<stdio.h>
main()
{
int
n,anual,eleccion=O;
floatval,aux,depreci
while(eleccion!=4){
/*leerdatosdeentrada*/
printf("Método: (l-LR2-BDD 3-SDA4-Fin)");
scanf(11%d 11I&eleccion)i
if(eleccion>=1 &&eleccion<=3) {
printf(I1Valororiginal:11)i
scanf(lI%f
ll
,&val)¡
printf(IlNúmerodeaños:n)i
scanf(11%du,&n)i
}
switch(eleccion){
case1 /*métododelalínearecta*}
printf("Métododelalínearecta");
deprec=val/n;
for(anual=1;anual<=n;++anual){
val- =deprec;

188 PROGRAMACiÓN ENC
printf("Findeaño%2d",
printf( "Depreciación:
printf("Valoractual:
}
break:
anual):
%7 . 2f",deprec):
%8.2f",val):
case2: 1*métododebalancedoblementedeclinante*1
anual);
%7 . 2
f",deprec):
%8.2f",val):
printf("Métododebalancedoblementedeclinante"):
for(anual=1:anual<=n:++anual){
deprec=2*val/n:
val
-=deprec:
printf(
lI
Findeaño%2d
ll
l
printf("Depreciación:
printf("Valoractual:
}
break:
case3: 1*métododelasumadelosdígitosdelosaños*1
printf("Métododelasumadelosdígitos"):
printf("delosaños"):
aux=val;
for(anual=1:anual<=n:++anual){
deprec=(n-anual+1)*aux1(n*(n+1)12):
val-=deprec:
printf("Findeaño%2d",anual):
printf("Depreciación:%7.2f",deprec):
printf("Valoractual:%8.2f",val):
}
break:
case4: 1*findeloscálculos*1
printf("Hastaluegoyquetengaunbuendía");
break:
default: 1*generarmensajedeerror*1
printf("Entradadedatosincorrecta"):
printf("-repiteporfavor"):
} 1*findeswitch*1
} 1*findewhile*1
}
Laformaderealizarloscálculoscorrespondientesalmétododela sumadelosdígitosdelosaños
puederesultaralgooscura. Enparticular,eltérmíno (n-anual+1)enelnumeradorrequierealguna
explícación.Estacautídadseutilíza
paracontardecrecientemente(den a 1)míentrasanualavanza
crecientemente(de1 an).Estosvaloresdeclinautessonrequeridos porelmétododelasumadelos
dígítosdelosaños.Porsupuesto,podríamoshaberutílizado
enlugardeestounbuclecon uncontadorque
decreciese,estoes,
for(anual=n:anual>=1:--anual)

INSTRUCCIONES DECONTROL 189
peroentonceshabríamosnecesitadoelcorrespondientebucleconcontadorcrecientequeescribieselos
resultadoscalculadosanualmente.Tambiéneltérmino
(n*(n+1)/2)queapareceeneldenominadores
unafórmulaparalasumadelosnprimerosdígitos,estoes,1
+2+ + n.
Elprogramaestádiseñadoparaejecutarsedeformainteractiva,conmensajesquesolicitanlosdatosde
entradacorrespondientes.Observequeelprogramageneraun
menúconcuatroopciones,paracalcularla
depreciaciónutilizandounodelostresmétodosoterminarlaejecucióndelprograma.Lacomputadora
continuaráaceptandonuevosconjuntosdedatosdeentrada
yrealizaráloscálculosapropiadosparacada
unodeellos,hastaqueseseleccionelaopción4 delmenú.Elprogramageneraráautomáticamenteun
mensaje
deerroryvolveráalmenúsiseintroducealgúnvalordistinto de1,2,3 o 4
enrespuestaala
opcióndelmenú.
Semuestraacontinuaciónunasesiónrepresentativadelfuncionamientodelprograma.Sehadeprecia­
dounobjetode8000dólaresporunperíododediezañosutilizandocadaunodelostresmétodos.Tam­
biénsepresentalarespuestaconelmensajedeerroraunaintroducciónincorrectadedatosenlaselección
deopciónenelmenú.Finalmente,elcálculoterminacomoconsecuenciadelaúltimaopciónseleccionada
enelmenú.
Método:(l-LR2-BDD 3-SDA4-Fin)1
Valororiginal:8000
Númerodeaños:
1.Q.
Métododelínearecta
Findeaño1Depreciación:800.00Valoractual:7200.00
Findeaño2Depreciación:800.00Valoractual:6400.00
Findeaño3Depreciación:800.00Valoractual:5600.00
Findeaño4Depreciación:800.00Valoractual:4800.00
Findeaño5Depreciación:800.00Valoractual:4000.00
Findeaño6Depreciación:800.00Valoractual:3200.00
Findeaño7Depreciación:800.00Valoractual:2400.00
Findeaño8Depreciación:800.00Valoractual:1600.00
Findeaño9Depreciación:800.00Valoractual:800.00
Findeaño10Depreciación:800.00Valoractual: 0.00
Método:(1-LR2-BDD 3-SDA4-Fin)2-
Valororiginal:8000
Númerodeaños:1.Q.
Métododebalancedoblementedeclinante
Findeaño1Depreciación:1600.00Valoractual:6400.00
Findeaño2Depreciación:1280.00Valoractual:5120.00
Findeaño3Depreciación:1024.00Valoractual:4096.00
Findeaño4Depreciación:819.20Valoractual:3276.80
Findeañ'o5Depreciación:655.36Valoractual:2621.44
Findeaño6Depreciación:524.29Valoractual:2097.15
Findeaño7Depreciación:419.43Valoractual:1677.72
Findeaño8Depreciación:335.54Valoractual:1342.18
Findeaño-9Depreciación:268.44Valoractual:1073.74
Findeaño10Depreciación:214.75Valoractual:858.99

190 PROGRAMACiÓN ENC
Método:(l-LR2-BDD 3-SDA4-Fin).:1.
Valororiginal:8000
Númerodeaños:lQ
Métododelasumadelosdígitosdeíosaños
Findeaño1
Findeaño2
Findeaño3
Findeaño4
Findeaño5
Findeaño6
Findeaño7
Findeaño8
Findeaño9
Findeaño10
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
1454.55
1309.09
1163.64
1018.18
872.73
727.27
581.82
436.36
290.91
145.45
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
6545.45
5236.36
4072.73
3054.55
2181.82
1454.55
872.73
436.36
145.45
0.00
Método:(l-LR2-BDD 3-SDA
4-Fin).2.
Entradadedatosincorrecta-repite,porfavor
Método:(l-LR2-BDD 3-SDA4-Fin)4.
Hastaluegoyquetengaunbuendía
Observequeelmétodo debalancedoblementedeclinante yeldelasumadelosdígitos delosaños
proporcionanunagrandepreciaciónanualdurantelosprimerosaños,perounamuchomenordurantelos
últimosdeltiempodevidadelobjeto.Vemostambiénqueelobjetotieneunvalorceroalfinaldesu
tiempodevidacuandoseutilizaelmétododelínearecta
yeldelasumadelosdígitosdelosaños,pero
quedaunvalorresidualsindepreciarcuandoseusaelmétododelbalancedoblementedeclinante.
6.8.LAINSTRUCCIÓN break
Lainstrucciónbreakseutilizaparaterminarlaejecución debuclesosalir deunainstrucción
switch.Sepuedeutilizardentrodeunainstrucción while,do-while,foroswitch.
Lainstrucciónbreaksepuedeescribirsencillamentedelasiguienteforma:
break;
sincontenerningunaotraexpresiónoinstrucción.
Yahemosvistoenalgunosejemploselusodelainstrucción
breakdentrodeunains­
trucción
switch,enlasección6.7. Lainstrucciónbreakseocupadetransferirelcontrol
fueradelainstrucción
switchcompleta,alaprimerainstrucciónquese.encuentreacontinua­
cióndeella.
EJEMPLO6.27. Consideremosdenuevolainstrucción switchpresentadainicialmenteenelEjem­
plo6.24.

INSTRUCCIONES DECONTROL 191
switch(eleccion=toupper(getchar()) ) {
caseTRI:
printf("ROJO");
break;
case'B':
printf("BLANCO");
break;
case'A':
printf("AZUL");
break;
default:
printf("ERROR");
break;
}
Observequecadagrupodeinstruccionesfinalizaconunainstrucción break,conelfm detransferirel
controlfueradelainstrucción
switch.Lainstrucciónbreakesnecesariadentrodecadaunodelostres
primerosgruposconelfindeevitarlaejecucióndelossiguientesgruposdeinstrucciones.Elúltimogrupo
norequiereunainstrucción
break,yaqueelcontrolsetransferiráfuera delainstrucciónswitchauto­
máticamentedespuésdelaejecucióndelúltimogrupodeinstrucciones.Sinembargo,lainclusióndela
últimainstrucción
breakesunacostumbrepropiadeunbuenestilodeprogramación,convistasaque
estéyapresenteenelcasodequeseañadanotrosgruposdeinstruccionesposteriormente.
Siseincluyeunainstrucción breakenunbucle while,do-whileofor,entoncesse
transfiereelcontrolfueradelbucleenelmomentoenqueseencuentrelainstrucción
break.
Estoproporcionaunaformaconveniente determinarunbuclecuandosedetectaunerroroalgu­
naotracondiciónirregular.
EJEMPLO6.28. Heaquíalgunasmuestrasdebuclesquecontieneninstrucciones break.Encada
situación,elbuclecontinuarásuejecuciónmientraselvaloractualdelavariableencomaflotantexnosea
mayorque
10O.Sinembargo,sesaldrádelbuclesisedetectaunvalordexnegativo.
Primeroconsideremosunbucle
whi1e.
scanf(lI%fll
r&x);
while(x<=100){
if(x<O) {
printf("ERROR-VALORNEGATIVO DE X");
break;
}
/*procesarelvalornonegativodex*/
SCél.nf(U%.fU
J&x)¡.
}

192 PROGRAMACiÓN ENC
Consideremosahora unbucledo-whilequehacelomismo.
do{
scanf("%f
ll
,&x)¡
if(x<O) {
printf("ERROR-VALORNEGATIVO DEX");
break;
}
/*procesarelvalornonegativodex*/
}while(x<=100);
Finalmente,heaquíunbucleforsemejante.
for(eont=1;x<=100;++eont){
scanf(lI%f
ll
l&x);
if(x<O) {
printf("ERROR-VALORNEGATIVO DEX");
break;
}
/*procesarelvalornonegativodex*/
}
Enelcasodevariasinstrucciones while,do-while,foroswitchanidadas,una
instrucción
breakcausarálatransferenciadecontrolfueradelainstrucciónmásinterna enla
queseencuentre,peronofueradelasinstruccionesexternas.
Yahemosvistounamuestrade
esto
enelEjemplo6.26, endondeseencuentraunainstrucción switchdentrodeunainstruc­
ción
while.Semuestraotroejemploacontinuación.
EJEMPLO6.29. Consideremoselsiguienteesquema deunbuclewhileincluidoenuno foro
for(eont=O;eont<=n;++eont){
while(e=getehar()!='') {
if(e='*')break;
}
}
Silavariabledecarácteretieneasignadounasterisco (*),entonceselbuclewhileterminará.Sin
embae
go,continuarálaejecución delbuclefor.Portanto,si elvalordeeontesmenorqilencuandosesalga
delbuclewhile,lacomputadoraincrementará eontyharáotrapasadaatravés delbucleforo

INSTRUCCIONES DECONTROL 193
6.9.LAINSTRUCCIÓN Continue
Lainstruccióncontinueseutilizapara saltarseelrestodelapasadaactualatravésdeunbucle.
Elbucle
noterminacuandoseencuentraunainstrucción continue.Sencillamentenoseejecutan
lasinstruccionesqueseencuentranacontinuación
enelmismoysesaltadirectamentea lasi­
guientepasadaatravésdelbucle.(Observeestadiferenciaimportanteentre
continueybreak.)
Lainstruccióncontinuesepuedeincluirdentrode unainstrucciónwhile,do
whileoforoSimplementeseescribeasí:
continue;
sínincluirotrasinstruccionesoexpresiones.
EJEMPLO6.30. Heaquíalguuasmuestras debuclesquecontieneninstrucciones continue.
Primeroconsideraremos unbucledo-whi1e.
do{
scanf("%f",&x);
if(x<O) {
printf("ERROR-VALORNEGATIVO DEX");
continu8;
};
/*procesarelvalornonegativodex*/
}while(x<=100);
Heaquíunbucleforsemejante.
for(cont=1;x<=100;++cont){
scanf("%f",&x);
if(x<O) {
printf("ERROR-VALORNEGATIVO DEX");
continue;
}
/*procesarelvalornonegativodex*/
}
Encadacaso noseejecutarálaparteenla queseprocesaelvaloractual dexsiéste esnegativo.Se
continuaráenestecasoconlasiguientepasada delbucle.
Esinteresantecompararestasinstrucciones decontrolconlasmostradasen elEjemplo6.28,que
hacenuso
delainstrucciónbreakenlugardelacontinue.(¿Porquénoseincluyeenesteejemplo
unamodificación
delbuclewhilequeapareceenelEjemplo6.28?)

194 PROGRAMACiÓN ENC
EJEMPLO6.31. Mediadeunalistadenúmerosnonegativos. EnelEjemplo6.17vimosunprogra­
maenCqueutilizabaunbucle
forparacalcularlamedia deunalistadennúmeros.Modifiquemoseste
programaparaqueprocesesolamentelosnúmerosnonegativos.
Elprogramaanteriorrequieredospequeñoscambiosparaquesecomportedeestaforma.Primero,el
bucle
fordebeincluirunainstrucción ifquedeterminesicadavalorde xesononegativo.Segundo,
necesitamosuncontadorespecial
(nmedia)paradeterminarcuántosnúmerosnonegativossehanproce­
sado.Estecontadorapareceráeneldenominadorcuandosecalculelamedia(lamediasecalcularáasi:
media=suma/nmedia).
Presentamosacontinuaciónelprogramaen C.Esinteresantecompararloconelqueapareceenel
Ejemplo6.17.
/*calcularlamediadelosnúmerosnonegativosdeunalistaden
números*/
#include<stdio.h>
main( )
{
intn,cont,nmedia=O;
floatx,media,suma=O;
/*inicializaryleerelvalorden*/
printf(l!¿Cuantosnúmeros? 11);
scanf(ll%dUJ&n);
/*leerlosnúmeros*/
for(cont=1;cont<=n;++cont){
printf("X=
11)i
scanf(lI%f
1l
1&x)¡
if(x<O)continue;
suma+=Xi
++nmedia¡
}
/*calcularlamediayescribirlarespuesta*/
media=suma/nmedia;
printf("Lamediaes%f",media);
}
Cuandoseejecutaelprogramaconvaloresnonegativosde x,secomportaexactamenteigualquela
anteriorversióndelEjemplo6.17.Sin embargo,cuandoseasignana
xvaloresnegativos,éstossonigno­
radosalcalcularlamedia.
Mostramosacontinuaciónunasesióninteractivaamododeejemplo.Como
decostumbre,lasres·
puestasdelusuarioseencuentransubrayadas.
¿Cuantosnúmeros?
Q
x=1
x=-1
x=2-
x=.::1.

INSTRUCCIONES DECONTROL 195
x=~
x==..l
Lamediaes2.000000
Éstaeslamediadelosnúmerospositivos.Observeque sisehubiesenconsideradotodoslosnúmerosla
mediahabríasídocero.
6.10.ELOPERADOR COMA
Introducimosahorael operadorcoma(,),queseutiliza principalmenteenlainstrucciónforo
Esteoperadorpermiteque aparezcandosexpresionesensituacionesendondesólo seutilizaría
unaexpresión.Porejemplo,es posibleescribir
for(expresiónla,expresiónlb;expresión2;expresión3)instrucción
endondeexpresiónlayexpresiónlbsondosexpresiones,separadas poreloperador
coma,endondenormalmentesóloaparecería unaexpresión(expresión1).Estasexpresio­
nesseocupandeinicializardosíndices,típicamente, que'seutilizansimultáneamentedentrodel
buclefor.
Análogamentesepuedeutilizarenunainstrucciónforeloperadorcomadelasiguiente
forma:
for(expresiónl;expresión2;expresión3a,expresión3b)instrucción
Aquíexpresión3ayexpresión3b,separadasporeloperadorcoma,aparecen enlugar
delaexpresiónúnicahabitual.Laformafrecuentedeutilizarlasdosexpresioneses paraalterar
(incrementarodecrementar)los dosíndicesqueseestánutilizandosimultáneamentedentrodel
bucle.Porejemplo,uníndicepodríairseincrementando mientraselotrodecrece.
EJEMPLO6.32.Búsquedadepalíndromos. Unpalíndromoesunapalabraounafrasequeselee de
lamismaformahaciadelantequehaciaatrás.Porejemplo,laspalabras alayraparsonpalíndromos.
También
loeslafrasedábalearrozalazorraelabad, sinotenemospresentesespaciosenblanco,signos
depuntuaciónyelacento de«dábale».
EscribamosunprogramaenCqueleaunalínea
detextoquecontengaunapalabraounafraseydeter­
mine
siesonounpalíndromo.Parahaceresto,compararemoselprimercarácterconelúltimo,elsegundo
caráctercon
elpenúltimo,yasísucesivamente,hastaquehayamosalcanzadoelpuntomediodeltexto.Las
comparacionesennuestroprogramaincluiránlossignos
depuntuaciónylosespaciosenblanco.
Conelfin
deesbozarelesquemadelprograma,definamoslassiguientesvariables:
letras
aux
cont
unarraydecaracteresde80elementos.Estoselementosseránloscaracteres dela
línea
detexto.
unavariableenteraqueindicaráelnúmero
decaracteresasignadosa letras,
sinincluirelcarácter deescape\0delfinal.
unavariableenteraque
seutilizarácomoíndicealmovemoshaciadelanteen
letras.

196 PROGRAMACiÓN ENC
contr
indicador
bucle
unavariableenteraqueseutilizacornoíndicealmovernoshaciaatrásen letras.
unavariableenteraqueseutilizaráparaindicarunacondición deverdadero/falso.
Lacondiciónverdaderoindicaráquesehaencontradounpalíndromo.
unavariableenteracuyovaloressiempreigual
al,apareciendo,portanto,siem­
precornoverdadera.Laintención
deestoescontinuarlaejecucióndelbucleprin­
cipalhastaqueunadeterminadacondiciónindiquesufin.
Podernosescribirahoraelsiguienteesquema:
1.Definirlasconstantessimbólicas EOL(<<endofline»ofindelínea), VERDADERO yFALSO.
2.Declarartodaslasvariableseinicializar bucle(asignarVERDADERO abucle).
3.Comenzarelbucleprincipal.
a)AsignarVERDADERO aindicador,anticipandoelhallazgodeunpalíndromo.
b)Leerlalíneadetextocarácteracarácteryalmacenarlaen letras.
e)ComprobarsilostresprimeroscaracteresdelalíneaenmayúsculassonF,1 Y N,respectiva­
mente.Siesasí,salirdelbucleprincipalyfinalizarlaejecucióndelprograma.
d)Asignara auxelvalorfinalde contmenos1.Estevalorindicaráelnúmerodecaracteres
quetienelalíneadetexto,sinincluirelcarácterdeescapefinal\
O.
e)Compararcadacarácterdelaprimeramitadde letrasconelcorrespondienteenlasegunda
mitad.Siseencuentraalgunafaltadecoincidencia,asignar
FALSOaindicadorysalirdel
bucle(másinterno)decomparación.
1)SiindicadoresVERDADERO, escribirunmensajequeinformedelhallazgode unpalín­
dromo.Deotraforma,escribirunmensajeenelqueseinformedequenosehaencontrado
ningúnpalíndromo.
4.Repetirelpaso3(hacerotrapasadaporelbucleexterior),procesandootralíneadetexto.
Heaquíelpseudocódigocorrespondiente.
#includearchivos
#defineconstantessimbólicas
main()
{
1*declarareinicializarvariables*1
while(bucle){
indicador=VERDADERO; 1*anticiparpalíndromo*1
1*
leerunalíneadetextoyalmacenarlaenletras*1
1*salirdelbuclewhilesilostresprimeroscaracteres
deletrassonFIN(comprobarlosenmayúsculas)*1
1*
asignarelnúmerodecaracteresdeltextoaaux*1
for«cont=
(++cont,
0
1contr=aux);
--contr)) {
cont<=(aux-1)12;

INSTRUCCIONES DECONTROL 197
if(letras[cont]!=letras[contr]) {
indicador=FALSO;
/*noesunpalíndromo-salirdelbuclefor*/
}
}
/*escribirunmensajeindicandosiletrascontieneo
nounpalíndromo*/
}
}
Elprogramautilizaeloperadorcomaenunainstrucción forparacompararcadacarácterdelaprime­
ramitad
deletrasconelcaráctercorrespondientedelasegundamitad.Portanto,mientras contva
tomandovaloresdeOa(aux-1)/2,contrlohacedeauxa(aux/2)+l.Observeque
serealizaladivisiónentera(obteniéndoseelcocientetruncado)paraestablecerestosvaloreslímite.
Observetambiénquehaydosoperadorescomadentrodelainstrucción
foroCadaoperadorcomay
susoperandosasociadosseencuentranentreparéntesis.Estonoesnecesario,perorecalcaelhecho
deque
cada
pardeoperandosformanunargumentodentrodelainstrucción foro
Acontinuaciónsemuestraelprogramaen ecompleto.
/*buscarunpalíndromo*/
#include<stdio.h>
#include<ctype.h>
#defineEOL ''
#defineVERDADERO 1
#defineFALSO O
main()
{
charletras[8O]
;
intaux,cont,contr,indicador,bucle=VERDADERO;
/*bucleprincipal*/
while(bucle) {
indicador=VERDADERO;
/*leereltexto*/
printf("Introduceunapalabraofrasedebajo:") ;
for(cont=O;(letras,[cont]=getchar())! =EOL;++cont)
if((toupper(letras[O])
(toupper(letras[l])
(toupper(letras[2])
aux ;:;:cont-1;
/*realizarlabúsqueda*/
,F')&&
,I')&&
'N'))break;

198 PROGRAMACiÓN ENC
for((cont~
(++cont,
O,contr
--contr))
aux)i
{
cont<=aux/2i
if(letras[cont]!~letras[contr]){
indicador~FALSO;
break;
}
}
/*escribirmensaje*/
for(cont
~O;cont<~aux;++cont)
putchar(letras[cont]);
if(indicador)printf("ESunpalíndromo");
elseprintf("NOESunpalíndromo");
}
}
Acontinuación
semuestraunasesióninteractivatípica,detallándoselasalidageneradacuandoseeje­
cutaelprograma.Comosehahechohasta
elmomento,lasrespuestasdelusuarioseencuentransubrayadas.
Introduceunapalabraofrasedebajo:
RAPAZ
RAPAZNOESunpalíndromo
Introduceunapalabraofrasedebajo:
RAPAR
RAPARESunpalíndromo
Introduceunapalabraofrasedebajo:
salas
salasESunpalíndromo
Introduceunapalabraofrasedebajo:
DABALEARROZ
~LA ZORRAELABAD
DABALEARROZALAZORRAELABADNOESunpalíndromo
Introduceunapalabraofrasedebajo:
DABALEARROZALAZORRAELABAD
DABALEARROZALAZORRAELABADESunpalíndromo
Introduceunapalabraofrasedebajo:
FIN
Recuerdequeeloperadorcomaaceptadosexpresionescomooperandos.Estasexpresiones
seevaluarándeizquierdaaderecha.Ensituaciones
querequierenlaevaluacióndelaexpresión

INSTRUCCIONES DECONTROL 199
enconjunto(laexpresiónformadaporlosdosoperandosyeloperadorcoma),eltipoyelvalor
de
laexpresiónenconjuntoserándeterminadasporeloperandodeladerecha.
DentrodelconjuntodeoperadoresdeC,eloperadorcomatienelaprecedenciamenorde
todos.
Portanto,eloperadorcomaseencuentrasolodentrodesugrupodeprecedencia,por
debajodelgrupodeprecedenciaintegradoporlosdistintosoperadoresdeasignación(verApén­
diceC).Suasociatividadesdeizquierdaaderecha.
6.11.LAINSTRUCCIÓN goto
Lainstruccióngotoseutilizaparaalterarlasecuencia deejecuciónnormaldelprograma,trans­
firiéndoseelcontrolaotrapartedeél.Ensuformageneral,lainstrucción
gotoseescribe
gotoetiqueta;
endondeetiquetaesunidentificadorqueseutilizapararotularlainstruccióna laquese
transferiráelcontrol.
Sepuedetransferirelcontrolacualquierotrainstruccióndelprograma.(Parasermáspreci­
sos,sepuedetransferirelcontrolacualquierlugardentrode
lafunciónactual.Introduciremos y
trataremoslasfuncionesenelcapítulosiguiente.)Lainstrucciónporlaquesecontinuará la
ejecucióndebeencontrarseetiquetada, ylaetiquetadebeirseguidadedospuntos(:).Portanto,
lainstrucciónetiquetadaaparecerádela siguienteforma:
etiqueta:instrucción
Cadainstrucciónetiquetadadentrodeunprograma(másconcretamente,dentrodelafunciónac­
tual)debetenerunaúnicaetiqueta;esdecir,dosinstruccionesnopuedentener
lamismaetiqueta.
EJEMPLO6.33. Elsiguienteesquema deprogramamuestra cómosepuedeutilizarlainstmccióngoto
paratransferirelcontrolfuera deunbuclesisedaunacondicióninesperada.
/*bucleprincipal*/
scanf
("%flll&x);
while(x<=100) {
if(x<O)gotaerror;
scanf("%f",&x);
}
/*rutinadedeteccióndeerror*/
error: {
printf("ERROR -VALORNEGATIVO DEX");
}

200 PROGRAMACiÓN ENC
Enesteejemplosetransfiereelcontrolfuera delbuclewhile,alainstruccióncompuesta conetiqueta
error,sisedetectaunvalornegativo delavariablex.
Sepodríahaberhecho lomismoutilizandolainstrucción break,comosevioenelEjemplo6.28.De
hechoespreferibleelusodelainstrucciónbreak.Lautilizacióndelainstruccióngotasepresentaaquí
atítulomeramenteilustrativo.
Todosloslenguajesdepropósitogeneralpopularesposeenlainstrucción
gota,aunqueac­
tualmentetodaslastécnicasdeprogramacióninstanaevitarsuutilización.
Enalgunosdelos
lenguajesmásantiguos,comoFortranoBASIC,lainstrucción
gotaseutilizacongranprofu­
sión.Lasaplicacionesmáscomunessonlassiguientes:
1.Ejecutarcondicionalmenteinstruccionesogruposdeinstruccionesbajodeterminadascir­
cunstancias.
2.Saltaralfinde
unbucleendeterminadascondiciones,noejecutándose, portanto,elresto
delbucleen
lapasadaactual.
3.Finalizartotalmentelaejecucióndeunbuclebajodeterminadascondiciones.
LoselementosestructuradosdelCpermitenrealizartodasestasoperacionessinrecurrira
la instrucción
gota.Porejemplo,laejecucióncondicionalsepuederealizarmediantelains­
trucción
if e 1 se;saltaralfinalde unbuclesepuederealizarmediante lainstrucción
continue;yterminarlaejecuciónde unbuclemediantela instrucción break.Espreferible
lautilizacióndeesoselementosestructuradosaldelainstrucción
gotaporqueelusode gota
tiendeafavorecer(oalmenos,anodisminuir)quesedisperselalógicasubyacenteportodoel
programa,mientrasqueloselementosestructuradosdeCrequierenquetodoelprogramase
escribaenunaformaordenadaysecuencial.Porestarazón,
lautilizaciónde lainstruccióngota
sedebeevitar,comonormageneral,dentrodelosprogramas enC.
Sinembargo,avecessepresentansituacionesdeformaesporádica enlasquelainstrucción
gotapuedesermuyútil.Consideremos, porejemplo,unasituación enlaquesenecesitasalirde
unbucledoblementeanidadoaldetectardeterminadacondición.Estosepuedehacermediantedos
instrucciones
if
-break,unadentrodecadabucle,aunqueestoes untantoenrevesado.Una
soluciónmejorenestecasoparticularpodríaserclutilizarunainstrucción
gotaparatransferir
elcontrolfueradeambosbuclesdeunavez.Esteprocedimientoseilustra
enelejemplosiguiente.
EJEMPLO6.34.Conversión devariaslíneasdetextoamayúsculas.ElEjemplo6.19presentaun
programaqueconviertevariaslíneas detextoamayúsculas,procesandounalínea detextocada vez,hastaque
elprimercarácter deunalíneaseaunasterisco(*).Modifiquemosahora elprogramaparadetectaruna
con-dición
deparada,indicadaporlapresencia dedossignosdedólarconsecutivos($$)encualquier
parteden-tro
deunalíneadetexto.Siseencnentralacondición deparada,elprogramaimprimirálalínea
detextoconlossignosdedólarincluidos,seguida deunmensajeadecuado. Enesemomentoterminarála
ejecución
delprograma.
Lalógica
delprogramaserálamismaqueladadaenelEjemplo6.19,peroañadiremosunbucleparacom­
probarsiseencuentranlosdossignosdedólarconsecutivos.Portanto,elprogramaprocederá comosigue.
1.Asignarunvalorinicialde1alíndicedelbuclemásexterno(contlineas).
2.Efectuarlossiguientespasos deformarepetida,paralassucesivaslíneas detexto,mientras el
primercarácter delalíneanoseaunasterisco.
a)Leerunalínea detextoyasignar loscaracteresa loselementosdelarraydecaracteres1 e­
tras.Unalíneasedefinirácomounasucesióndecaracteresterminadaporunaindicación de
finaldelalínea(uncarácterdenuevalínea).

INSTRUCCIONES DECONTROL 201
b)Asignarlacuenta decaracteres,incluidoeldenuevalinea,a a ux.
e)Escribirlalineaenmayúsculas,utilizandolafuncióndebiblioteca toupperpararealizarla
conversión.Escribiracontinuacióndoscaracteres
denuevalinea(paraquelasiguientelinea
deentradaseencuentreseparadadelasalidaactualporunalineaenblanco)eincrementarel
contadordelíneas
(contlineas).
á)Buscarentodosloscaracteresdelalinealapresenciadedossignosdedólarconsecutivos.Si
sedetectan,escribirunmensajeinformando
deladeteccióndelacondicióndeparada ysaltar
alfinaldelprograma.
3.Unavezquesehadetectadounasteriscoalcomienzodeunalinea,escribir«Hastaluego»,
y
terminarlaejecución.
Heaquíelprogramacompletoen
C.
/*convertirvariaslíneasdetextoamayúsculas
Continuarlaconversiónhastaqueelprimercarácterdeuna
líneaseaunasterisco(*).Finalizarelprogramasise
encuentrandentrodeunalíneadossignosdedólar($$).*/
#include<stdio.h>
#include<ctype.h>
#defineEOL''
main()
{
charletras[80]
;
intaux,cont,contlineas=1;
while((letras[O]=getchar())!= '*'){
/*leerlalíneadetexto*/
for(cont=1;(letras[cont]=getchar())!=EOL;++cont)
aux=cont¡
/*escribirlalíneadetexto*/
for(cont=O;cont<aux;++cont)
putchar(toupper(letras[cont]));
printf("");
++contlineasi
}
/*comprobarlacondicióndesalida*/
for(cont=1;cont<aux;++cont)
if(letras[cont-1]=='$'&&letras[contl
printf("CONDICION DESALIDADETECTADA ­
printf("FINDEEJECUCION");
gotofin;
}
}
fin:printf("Hastaluego");
, $ , )
11)i
(

202 PROGRAMACiÓN ENC
Esinteresantecompararesteprograma conelcorrespondientepresentadoanteriormente enelEjem­
plo
6.19.Elprogramaactualcontiene unbucleforadicionaldentro delbuclewhile,alfinal.Estebucle
f orexamina
paresconsecutivosdecaracteres,buscando lacondicióndeparada($$),despuésdehaber
escritolalíneacompleta
enmayúsculas.Siseencuentraunacondicióndeparada,entonces setransfiereel
controla lainstrucciónprintffinal(<<Hasta1uego»)quesehaetiquetadoahora confin.Obser­
vequeestatransferencia decontrolcausaunasalida delbucleforactualydelbucleexteriorwhile
desdelainstrucciónif.
Ellectorpuedeejecutaresteprograma yutilizarlasdoscondiciones,la
determinaciónnormal (un
asteriscoalcomienzodeunalínea)yladeparada.Compárense losresultadosobtenidos conlasalida
mostrada
enelEjemplo6.19.
6.1.
6.2.
6.3.
6.4.
6.5.
6.6.
6.7.
6.8.
6.9.
6.10.
6.11.
6.12.
6.13.
6.14.
6.15.
6.16.
6.17.¿Quéesejecucióncondicional?
¿Quéesselección?
¿Quéesunbucle?Describirdosformasdiferentesdeconstruir
unbucle.
Citartodaslasreglasrelacionadasconlautilizacióndeloscuatrooperadoresrelaciona­
les,losdosoperadoresdeigualdad,lasdosconectivaslógicas
yeloperadorunariode
negación.¿Quétiposdeoperandosseutilizanconcadaoperador?
¿Cómoseinterpretanlasvariables
yconstantesdetipocaráctercuandoseutilizancomo
operandosdeunoperadorrelacional?
¿Enquédifierenlasinstruccionesdeexpresióndelasinstruccionescompuestas?Mencio­
narlasreglasasociadasacadauna.
¿Cuáleselpropósitodela instruccióni f - e
1se?
Describirlasdosformasdiferentesdelainstruccióni f - else.¿Enquésediferencian?
Compararelusodela instruccióni f - e
1s econeldeloperador ? : .¿Dequéformase
puedeutilizareloperador
?:enlugardeunainstruccióni f - e 1se?
Citarlasreglassintácticasasociadasconlainstrucción if-else.
¿Cómoseinterpretanlasinstruccionesi f e 1s eanidadas?Enparticular,¿cómose
interpreta lasiguiente?
ifelife2sl
elses2
¿Quéexpresiónlógicaseencuentraasociadaalacláusulae 1se?
¿Quéocurrecuandoseencuentraunaexpresiónconvalornonulodentrodeungrupode
instrucciones
if-elseanidadas?
¿Cuáleslafinalidaddela instrucción
while?¿Cuándoesevaluada laexpresiónlógica?
¿Cuáleselmínimonúmerodevecesquesepuedeejecutarunbucle
while?
¿Cómofinalizalaejecuciónde unbuclewhile?
Hacerunarelacióndelasreglassintácticasasociadasalaínstrucción while.
¿Cuáleslafinalidaddelainstrucción do-while?¿Enquédifierede lainstrucción
while?
¿Cuáleselmínimonúmerodevecesquesepuedeejecutar unbucledo while?
Compararloconunbucle whileyexplicarlasrazones porlasquesediferencian.

INSTRUCCIONES DECONTROL 203
6.18.Mencionarlasreglassintácticasasociadasconlainstrucción do-while.Compararlas
conlasdelainstrucción
while.
6.19.¿Cuáleslafinalidaddelainstrucciónf or?¿Enquésedistinguedelasinstrucciones
whileydo
-while?
6.20.¿Cuántasvecesseejecutaráunbucle for?Compararloconlosbucles whiley
do-while.
6.21.¿Cuáleslafinalidaddelíndicedeunainstrucción for?
6.22.¿Sepuede omitiralgunadelastres.expresionesinicialesenunainstrucción for?Sies
así,¿cuálessonlasconsecuencias decadaomisión?
6.23.Citarlasreglassintácticasasociadasconlainstrucción
foro
6.24.¿Quéreglasseaplicanalosbuclesanidados?¿Sepuedeanidaruntipo debucleenotro de
tipodistinto?
6.25.¿Sepuedenincluirbuclesenlasinstruccionesi f
-e 1 se?¿Einstrucciones
if-elseenlosbucles?
6.26.¿Cuáleslafinalidaddelainstrucción
switch?¿Enquédifiereestainstruccióndelas
otrasdescritasenestecapítulo?
6.27.¿Quésonlasetiquetas«case»(oprefijos«case»)?¿Quétipodeexpresionessedeben
utilizarpararepresentarunaetiqueta«case»?
6.28.Mencionarlasreglassintácticasasociadasaluso
delainstrucciónswitch.¿Puedenes­
tarasociadasvariasetiquetas«case»aunúnicogrupo
deinstrucciones?
6.29.¿Quéocurrecuandoelvalor
delaexpresiónenlainstrucción switchcoincideconel de
unadelasetiquetas?¿Quéocurrecuandoelvalor deestaexpresiónnocoincideconel
deningunadelasetiquetas?
6.30.¿Sepuededefinirunaopciónporomisióndentro
deunainstrucciónswitch?Siesasí,
¿cómosedebeetiquetarlaopciónporomisión?
6.31.Compararlautilización
delainstrucciónswitchconladeinstruccionesif-else
anidadas.¿Cuálesmásconveniente?
6.32.¿Cuáleslafinalidaddelainstrucción
break?¿Dentrodequéinstruccionesdecontrolse
puedeincluirlainstrucción
break?
6.33.Supóngasequeunainstrucción breakseencuentraincluidaenlamásinterna deuna
seriedeinstruccionesdecontrolanidadas.¿Quéocurrecuandoseejecutalainstrucción
break?
6.34.¿Cuáleselpropósito delainstruccióncontinue?¿Dentrodequéinstruccionesdecon­
trolsepuedeincluirlainstrucción
continue?Compararlaconlainstrucción break.
6.35.¿Cuáleslafinalidaddeloperadorcoma?¿Dentro dequéinstruccionesdecontrolsuele
aparecereloperadorcoma?
6.36.Ensituacionesquerequierenlaevaluacióndeunaexpresiónquecontieneeloperador
coma,¿quéoperandodeterminaráeltipo
yelvalordetodalaexpresión(laexpresiónala
izquierdao aladerechadelacoma)?
6.37.¿CuáleslaprecedenciadeloperadorcomarespectoalosotrosoperadoresdeC?
6.38.¿Cuáleslafinalidaddelainstrucción
gota?¿Cómoseidentificalainstrucciónetiqueta-
daasociadaaella?
.
6.39.¿Existealgunarestricciónrespectoallugaralquesepuedetransferirelcontroldentrode
unprogramaen
C?
6.40.Relacionarlasreglassintácticasasociadasalainstrucción gota.

204 PROGRAMACiÓN ENC
6.41.Compararlasintaxisrelacionadaconlasetiquetasde lasinstrucciones(correspondientes
a
goto)yladelasetiquetas «case»(prefijos«case»).
6.42.¿Porquésedebeevitarelusodelainstruccióngoto?¿Enquéocasionespuedeserútil
estainstrucción?¿Quétipodeusossedebenevitaryporqué?Discutirlocondetalle.
6.43.Explicarquéocurrecuandoseejecutalasiguienteinstrucción.
if(abs(x)<xmin)x
=(x>O)?xmin:-xmin;
¿Eséstaunainstruccióncompuesta?¿Seencuentraincluidaenestainstrucciónunainstrucción
compuesta?
6.44.Identificartodaslasinstruccionescompuestasqueaparecenenelsiguientefragmentodeprograma.
{
suma
=O;
do{
scanf(lI%dUI
if(i<O)
&i);
{
i
;;;-i¡
++indicador¡
}
suma+=i¡
}while(i!=O);
}
6.45.Escribirunbuclequecalculelasumadecadatercerentero,comenzandopor i=2(esdecir,calcu­
larlasumade2
+5+8+11+.•.)paratodoslosvaloresdeimenoresque 10O.Escribir
elbucledetresformasdiferentes:
a)Utilizandounainstrucción whi1e.
b)Utilizandounainstrucción do-whi1e.
e)Utilizandounainstrucción for.
6.46.RepetirelProblema6.45calculandolasumadecadaenteron-ésimo,comenzandoporelvalor
asignadoa
neoro(esdecir,i=nCOffi,ncorn+n,neoro+2*n,ncom+3*n,yasí
sucesivamente).Continuarelprocesoparatodoslosvaloresdeiquenoseanmayoresque nfin.
6.47.Escribirunbuclequeexaminecadacarácterenunarray decaracteresllamado textoyescribael
equivalente
ASCn(elvalornumérico)decadacarácter.Supóngasequeseespecificapor
adelantadoelnúmerodecaractere.sdelarrayenlavariableentera
n.Escribirelbucledetresfor­
masdiferentes:
a)Utilizandouna instrucción while.
b)Utilizandouna instrucción do-whi1e.
e)Utilizandouna instrucción foro

INSTRUCCIONES DECONTROL 205
6.48.RepetirelProblema6.47suponiendoquenoseespecificaporadelantadoelnúmerodecaracteres
delarray.Laejecucióndelbucledeberepetirsehastaqueseencuentreunasterisco
(*).Escribirel
bucledetresformasdiferentes,comoantes.
6.49.GeneralizarelProblema6.45parageneraruna seriedebucles,dondecadabuclehadecalcularla
sumadelosenterosj-ésimos,endonde
jseencuentraentre2 y 13.Comenzarcadabuclecon i=2
eincrementar
ienjunidadeshastaque ialcanceelmayorvalorposiblemenorque 10O.(En
otraspalabras,elprimerbuclecalcularálasuma2
+4+6+ + 98;elsegundobucle
lasuma2
+5+8+...+98;eltercerolasuma2 +6+10+ + 98,Yasí
sucesivamente.Elúltimobuclecalcularálasuma2
+15+2 8+...+93.)Elprograma
debeescribírelvalordecadasumacompleta.
Utilizarbuclesanidadospararesolveresteproblema.Calcularcadasumaenelbucleinteriory
hacerqueelbucleexteriorseocupedecontrolarelvalorde
jutilizadoencadapasadaporelbucle
interior.Utilizarunainstrucción
forparaelbucleexterior,yparaelbucleinteriorutilizarcada
unadelastresinstruccionesderepetición
while,do-whileyfor.Redactarunasolución
porseparadoparacadatipode
bucleinterior.
6.50.Escribirunbuclequegenereenteros detresentres,comenzandopor i=2hastaelvalormáximo
menorque
10O.Calcularlasumadelosenterosgeneradosqueseandivisiblespor5.Utilizardos
métodosdistintosparacomprobarestoúltimo:
a)Utilizareloperadorcondicional (?:).
b)Utilizarunainstrucción if-else.
6.51.GeneralizarelProblema6.50paraquegenerelosenterosn-ésimos,comenzandopor ncom(esto
es,
i=ncom,ncom+n,ncom+2*n,ncom+3*n,etc.).Continuarelprocesoparatodos
losvaloresde
imenoresque nfin.Calcularlasuma delosenterosqueseandivisiblespork,en
dondekrepresentacualquierenteropositivo.
6.52.Escribirunbuclequeexaminecadacarácterdeunarraydecaracteresllamado textoydetermine
cuántosdeloscaracteressonletras,cuántossondígitos,cuántoscaracteresdeespaciadoycuántos
sonotrostiposdecaracteres(porejemplocaracteresdepuntuación).Supongaque
textocontiene
8Ocaracteres.
6.53.Escribirunbuclequeexaminecadacarácterdeunarraydecaracteresllamado textoydetermine
cuántosdeloscaracteressonvocalesycuántossonconsonantes.
(Sugerencia:Determinarprimero
cuandouncarácteresletray,siesasí,determinareltipodeletra.)Supongaque
textocontiene
8Ocaracteres.
6.54.Escribirunainstrucción switchqueexamineelvalordeunavariableenterallamada indica­
doryescribaunodelossiguientesmensajesdependiendo desuvalor:
a)CALOR,siindicadortieneelvalor1
b)TEMPLADO,siindicadortieneelvalor2
e)
FRIa,siindicadortieneelvalor3
el)FUERADERANGO, siindicadortieneelvalor4
6.55.Escribirunainstrucción switchqueexamineelvalordeunavariable detipocarácterllamada
coloryescribaunodelossiguientesmensajesdependiendodesuvalor:
a)ROJO,sicolortieneasignado roR,
b)VERDE,sicolortieneasignadov o V,
e)AZUL,sicolortieneasignado aoA,
el)NEGRO,sicolortieneasiguadocualquierotrocarácter.

206 PROGRAMACiÓN ENC
6.56.Escribirunaestructuradecontrolqueexamineelvalor deunavariableencomaflotantellamada
tempyescribaunodelossiguientesmensajesdependiendodesuvalor:
a)HIELO,sielvalor detempesmenorque O.
b)AGUA,sielvalor detempseencuentraentre Oy10O.
e)VAPOR,sielvalor detempesmayorque 10O.
¿Sepuedeutilizarunainstrucción switchenesteproblema?
6.57.Escribirunbucle forquelealoscaracteresdeunarraydecaracteresllamado textoylosescriba
ensentidoopuestoenotroarrayllamado
inverso.Supongaquelaformación textocontiene
8
Ocaracteres.Utilizareloperadorcomadentrodelainstrucción foro
6.58.Describirlasalidaquegenerarácadaunodelossiguientesprogramas
el'C.
a)#include<stdio.h>
main( )
{
inti=O/x=Di
while(i<20) {
if(i%5--O) {
X+=i¡
printf("%dx);
}
++i¡
}
printf("x=%d",x);
}
b)#include<stdio.h>
main( )
{
inti=01X=Di
do{
if(i%5==O) {
X++¡
printf("%d"x);
}
++i¡
}while(i<20);
printf(lIx=%d",x)¡
}

e)#include<stdio.h>
main( )
{
inti =o,x =o,
INSTRUCCIONES DECONTROL 207
for(i=1;i <10;i*=2){
x++¡
printf(l1%d 11Ix)i
}
printf("x=%d",x),
}
d)#include<stdio.h>
main( )
{
inti= O,x= O,
for( i= 1·i <la,++i) {,
if( i% 2--1 )
X+=ii
else
x--¡
printf("%d x},
}
printf("x =%dn,x);
}
e)#include<stdio.h>
main( )
{
inti =O,x =O,
for(i=1,i <la,++i){
if(i%2==1)
X
+=ii
else
x--;
printf("%dx);
continue;
}
printf("x =%d",x),
}

208 PROGRAMACiÓN ENC
f)#include<stdio.h>
main()
{
inti~O,x ~O;
for(i~1;i <10;++i){
if(i%2~~1)
X+=i¡
else
x--¡
printf("%d x);
break;
}
printf(l!x=%dll,Xli
}
g)#include<stdio.h>
main()
{
intiIjIX=O;
f9r(i~O;i < 5;++i)
for(j~O;j <i;+ + j ) {
x+~(i+j -1);
printf(lI%d11,x);
}
printf(lIx=%d",x);
}
h)#include<stdio.h>
main()
{
inti1j,x=O;
for(i~O;i < 5;++i)
for(j~O;j<i;++j) {
x+~(i+j -1);
printf("%dn,x);
break;
}
}
printf(TIx =%d
n
Ix)i
,

i)#inc1ude<stdio.h>
main()
{
inti /j,X O;
for(i=O;i <5;. ++i){
for(j=O;j <i;++j)
X+=(i+j -1);
printf("%d",x);
break;
}
printf("x=%d",x);
}
j)#inc1ude<stdio.h>
main( )
{
inti,j /k,X;:;;O;
INSTRUCCIONES DECONTROL 209
for(i=O;i <5;++i)
for(j=O;j <i;++j){
k=(i+j -1);
if(k%2==O)
X+=k¡
e1se
if(k%3==O)
X+=k -2;
printf('I%d 1"x);
}
printf("x=%d",x);
}
k)#inc1ude<stdio.h>
main()
{
inti,j /kIX=Oi
for(i=O;i <5;++i)
for(j=O;j <i;++j){
switch(i+ j -1){

210 PROGRAMACiÓN ENC
case-1:
caseO:
X+=1;
break;
case1:
case2:
case3:
x+=2;
break;
default:
x+=3;
}
printf(ll%d x);
}
printf("x=%d",x);
}
1)#include<stdio.h>
main()
{
inti /jIkfX=O;
for(i=O;i <5;++i)
for(j=O;j < i;++j){
switch(i+ j -1){
case-1:
caseO:
x+=1;
break;
case1:
case2:
case3 :
X+=2·,
default:
x+=3;
}
printf("%dx);
}
printf("x =%d",x);
}

INSTRUCCIONES DECONTROL 211
6.59.ModificarlosprogramasdadosenlosEjemplos6.9,6.12Y6.16paraquecadaprogramahagalo
siguiente:
a)Leerunalínea detextoenmayúsculas,almacenarlaenunarrayadecuadoyescribirlaaconti­
nnaciónenminúsculas.
b)Leerunalíneadetextoenmayúsculasyminúsculas,almacenarlaenunarrayadecuadoy a
continuaciónescribirlaconlasmayúsculasylasminúsculasintercambiadas,todoslosdígitos
reemplazadosporcerosyelresto
deloscaracteressustituidosporasteriscos (*).
6.60.CompilaryejecutarlosprogramasdadosenlosEjemplos6.10,6.13y6.17utilizandolosdiez
númerossiguientes:
27.5,13.4,53.8,29.2,74.5,87.0,39.9,47.7,8.1,63.2
6.61.Compilaryejecutarelprogramadadoen
elEjemplo6.31utilizandolosdieznúmerossiguientes:
27.5,-13.4,53.8,-29.2,74.5,87.0,39.9,-47.7,
-8.1,63.2
Compararlosresultadoscalculadosconlosobtenidosenelúltimoproblema.
6.62.ModificarelprogramadadoenelEjemplo6.10deformaquenoseespecifiqueporadelantadoel
tamañodelalistadenúmeros.Continuarlaejecucióndelbucle(leyendounnuevovalor
dex y
añadiéndoloa
suma)hastaqueseintroduzcaelvalorcero.Portanto,x =Oindicarálacondición
defin.
6.63.RepetirelProblema6.62paraelprogramadelEjemplo6.17.
6.64.ReescribirelprogramadedepreciacióndadoenelEjemplo6.26utilizandolainstrucción
if
elseenlugardelainstrucción switch.Comprobarelprogramaconlosdatosdadosenel
Ejem­
plo6.26.¿Quéversiónseprefiere?¿Porqué?
6.65.Laecuación
x'+3x'-1O=O
quesepresentóenelEjemplo6.22,sepuedereescribirdelaforma
x=[(10
-x')/3]1!2
ReescribirelprogramadelEjemplo6.22utilizandolaecuación enestaúltimaforma.Ejecutar
elprogramaycompararlosresultadoscalculadosconlosqueaparecen
enelEjemplo6.22.¿Por
quésondiferenteslosresultados?(¿Generansiemprelascomputadoras respuestascorrectas?)
6.66.ModificarelprogramadelEjemplo6.22,quecalculalasraícesdeunaecuaciónalgebraica,
reem­
plazandolainstrucción whileporunado-while.¿Quéestructuraseadaptamejoraestetipo
deproblema?
6.67.ModificarelprogramadelEjemplo6.22,quecalculalasraícesdeunaecuaciónalgebraica,reem­
plazandolainstrucción whileporunaforo.CompararelusodelasÍ1i.strucciones for,whiley
do-while.¿Quéversiónseprefiere?¿Porqué?

212 PROGRAMACiÓN ENC
6.68.AñadirunarutinadedeteccióndeerroressemejantealadelEjemplo6.21alprogramadecálculo
deladepreciacióndelEjemplo6.26.Larutinadebegenerarmensajesdeerrorseguidosdeuna
nuevapeticióndeentradadelosdatoscuandosedetecteunvalornopositivo.
6.69.EscribirunprogramacompletoenCparacadaunodelosproblemasque sepresentanacontinua­
ción.Utilizareltipodeinstruccióndecontrolmásnaturalencadacaso.Comenzarconunesquema
detallado;reescribirloenformadepseudocódigo
sieltraducirlodirectamentea Cnoesinmediato.
Asegurarsedeutilizar
unbuenestilodeprogramación(comentarios,sangrados,etc.).
a)Calcularla mediaponderada deunalistade nnúmeros,utilizandolafórmula
dondelas
fsonlospesosdecadacantidadyhandeserfraccionarios,esdecir:
O-:>/,<1yJ,+j,+...+1,,=I
Comprobarelprogramaconlossiguientesdatos:
i
=I
2
3
4
5
6
7
8
9
la
f=0.06
0.08
0.08
0.10
0.10
0.10
0.12
0.12
0.12
0.12
x=27.5
13.4
53.8
29.2
74.5
87.0
39.9
47.7
8.1
63.2
b)Calcularelproductodeunalistadennúmeros.Comprobarelprogramautilizandoelsiguiente
conjuntodeseisdatos:6,2,12,3,5,0,18,8,7,1,12,8.
c)Calcularla
mediageométrica deunalistadenúmeros,utilizandolafórmula
Comprobarelprogramautilizandolosvaloresdexdados
enlaparteb).Compararlosresulta­
dosobtenidosconlamediaaritméticadelosmismosdatos.¿Quémediaesmayor?
d)Determinarlasraícesdelaecuacióndesegundogrado
ax
2
+bx+c=0
utilizandolafórmula
- b±
W-4ac)1I2
x=-------
2a
(VerEjemplo5.6).Permitirlaposibilidaddequealgunadelasconstantestengaelvalorceroy
quelacantidadb
2
-4ac seamenoroigualacero.Comprobarelprogramautilizandolossi­
guientesconjuntosdedatos:

0=2
3
1
O
3
2
b=6
3
3
12
6
-4
e=1
O
1
-3
3
3
INSTRUCCIONES DECONTROL 213
e)LosnúmerosdeFibonacci sonlosmiembrosdeunainteresantesecuencia enlaquecadanú­
meroesigualala
sumadelosdosnúmerosanteriores. Enotraspalabras,
endonde
F,eseli-ésimonúmerodeFibonacci.LosdosprimerosnúmerosdeFibonaccison,
pordefinición,iguales
al,esdecir:
Portanto,
F=F+F=1+1=2
, 2 1
F=F+F=2+l=3
4 , 2
F=F+F=3+2=5
, 4 ,
yasísucesivamente.
Escribir
unprogramaenCquedeterminelos nprimerosnúmerosdeFibonacci.Comprobar
elprogramacon
n=7,n=10,n=17Yn=23.
1)Unnúmeroprimo esunacantidadenteraqueesdivisible(sinresto)sólo por1yporsímismo.
Porejemplo,7es
unnúmeroprimo,pero6no 10es.
Calcular
ypresentarunalistaconlos nprimerosnúmerosprimos. (Sugerencia:unnúmero,
nseránúmeroprimosilosrestosdelasecuaciones n/2, n/3, n/4,..., nl/
2
sontodosnonulos.)
Comprobarelprogramahaciendoquecalculelos100primerosnúmerosprimos.
g)Escribirunprogramainteractivoquelea unvalorenteropositivo ydeterminelosiguiente:
i)Sielenteroes
unnúmeroprimo.
ii)Sielenteroes
unnúmerodeFibonacci.
Escribirel
programadeformaqueseejecuterepetidamente, hastaqueseintroduzcacomo
valordeentrada
uncero.Comprobarelprograma convariosenteros.
h)Calcularlasumadelosprimeros nnúmerosimpares (1+3+5+'"+2n-1).Comprobarelpro­
gramaconlasumadelos100primerosnúmerosimpares(nótesequeelúltimoenteroserá199).
i)Sepuedecalcularelsenode xdeformaaproximadasumandolos nprimerostérminosdela
serieinfmita
sen
x=x-x'/3!+x'/5!
-x'/7!+'"
endondexseexpresaenradianes.(Nota:1tradianes=180°).

214 PROGRAMACiÓN ENC
EscribirunprogramaenCqueleaelvalor dexycalculesuseno.Escribir elprogramade
dosformasdiferentes:
i)Sumarlos nprimerostérminos,endonde nesunenteropositivoqueseintroduceademás
delvalorde
x.
ii)Continuarsumandotérminosdelaseriehastaqueelvalordeltérminosiguienteseamenor
(envalorabsoluto)quelO".
Comprobarelprogramapara
x=1,x=2 Yx=
-3.Escribirencadacasoelnúmerodetérminos
utilizadosparaconseguirlarespuestafinal.
j)Supongamosqueseconsigueunpréstamo dePdólaresdeunbanco,conelreconocimientode
quesedevolverán
Adólarescadameshastaquesehayacompletadolacantidadtotalprestada.
Partedelpagomensualseránintereses,calculadoscomoel
iporcientodelacantidadaúnno
pagada.Elrestodelpagoserviráparareducirla cantidadadeudada.
EscribirunprógramaenCquedeterminelasiguienteinformación:
i)Lacantidaddeinteréspagadopormes.
ii)Lacantidad
dedineroaplicadoalareduccióndeladeudatotalcadames.
iii)Lacantidadtotaldeinteresesquesellevapagadaalfinaldecadames.
iv)Lacantidaddedeudaaúnnopagadaalfinal
decadames.
v)Elnúmerodepagosmensualesnecesariosparadevolverelpréstamo.
vi)Lacuantíadelúltímopago(yaquepuedesermenorque
A).
Comprobarenelprogramautilizandolossíguientesdatos: P
=$40000;A=$2000;i=1%
mensual.
k)Losestudiantesdeunaclaseconsiguieronlassiguientespuntuacionesenseisexámenes deun
cursodeprogramaciónen
C.
Nombre Puntuaciones
Adrián 45 80 80 95 55 75
Antonio 60 50 70 75 55 80
Carmen 40 30 10 45 60
55
Félix O 5 5 O 10 5
Guillermo90 85
lOO 95 90 90
José 95 90 80 95
85 80
Lidia 35 50
55 65 45 70
Maruja 75 60
75 60 70 80
Pedro
85 75 60 85 90 100
Raúl 50 60 50 35 65 70
Rosa 70 60 75 70 55
75
Sonia 10 25 35 20 30 10
Víctor 25 40 65 75 85 95
Zoraida 65 80 70
lOO 60 95
EscribirunprogramainteractivoenCqueaceptecomoentradacadanombredeestudiante
ysuspuntuaciones,determinelanotamediadecadaestudianteyescribaacontinuaciónel
nombredelestudiante,lasnotasdelosexámenesylamediacalculada.

INSTRUCCIONES DECONTROL 215
1)Modificarelprogramaescritoenelapartado k)paraquecalculelamediadandodistintopesoa
cadaexamen.Suponer,porejemplo,quecadauno
delosprimeroscuatroexámenescontribuye
conel
15porcientodelanotafinal,yquecadauno delosdosúltimoscontribuyeconel20por
ciento.
m)Ampliarelprogramaescritoenelapartadoanteriorparaquecalculeademáslanotamediadela
clase.
n)EscribirunprogramaenCquepermitaquesepuedautilizarlacomputadoracomounacalcula­
doranormal.Considerarsólolasoperacionesaritméticasbásicas(suma,resta,multiplicacióny
división).Incluirunamemoriaenlaque
sepuedaalmacenarunnúmero.
o)Generarlasiguiente«pirámide»dedigitosutilizandobuclesanidados.
l
232
34543
4567654
567898765
67890109876
7890123210987
890123454321098
90123456765432109
0123456789876543210
Noescribirsimplementediezcadenas devariosdigitos.Conseguirunafórmulapara generar
losdigitoscorrespondientes paracadalínea.
p)Generarunagráfica delafunción
y=e-O·
lt
sen0.51
enunaimpresorautilizandounasterisco (*)paracadapuntoqueaparezcaenlagráfica.Hacer
quelagráficasedesarrolleverticalmente,conunpunto (unasterisco)porlínea.
(Sugerencia:
Cadalíneaimpresadebeconsistirenunasteriscoprecedidoporelnúmeroadecuadodeespa­
ciosenblanco.Determinarlaposicióndelasteriscoredondeandoelvalorde
yalenteromás
cercanoyutilizandounaescalaadecuadaalnúmerodecaracteresporlínea.)
q)EscribirunprogramainteractivoenCquepaseuna cantidadenterapositivaanumeraciónro­
mana(porejemplo
12seconvierteenXII, 14enXIV,etc.).Diseñarelprogramaparaquese
ejecuterepetidamente,hastaqueseintroduzcacero.
r)EscribirunprogramainteractivoenCqueconviertaunafechaintroducidadelaforma
rnm-dd-aa(porejemplo:4-12-99)enunenteroqueindiqueelnúmero dediasapartirdel l
deenero
de1980.Sielañonoessuperiora1999(esdecir,si aa
:s;99),sepuedenutilizarlas
siguientesrelaciones:

216 PROGRAMACiÓN ENC
i)Eldíadelañoencursosepuededeterminaraproximadamentemediante
dia=(int)(30.42*(mm-1))+dd
ii)Si mm==2(febrero),incrementarelvalorde diaen1.
iii)Simm>2ymm<8(marzo,abril,mayo,junioojulio), decrementarelvalorde dia
en1.
iv)Siaa%4==OYmm>2(añobisiesto), incrementarelvalordediaen1.
v)Incrementarelvalorde diaen1461porcadaciclocompletodecuatroañosapartir
del1-1-80.
vi)
Incrementardiaen365porcadaañocompletoapartirdelúltimociclocompletode
cuatroaños,ysumarentoncesl(porelañobisiestomásreciente).
Comprobarelprogramaconlafechaactual,ocualquierotrodía aelegir.
s)Ampliarelapartado r)parapermitirañosdelcalendarioporencimadelaño1999(elEjem­
plo10.28presentaunasoluciónparaunaversiónmásavanzadadeesteproblema).

CAPíTULO7
Funciones
YahemosvistoqueenCseutilizanfuncionesdebibliotecaconelfinderealizarunciertonúme­
rodeoperacionesocálculos
deusocomún(versección3.6).Sinembargo,Cpermitetambiénal
programadordefinirsuspropiasfuncionesquerealicendeterminadastareas.Estecapítulosecentra
enlacreaciónyutilizacióndeestasfuncionesdefinidasporelprogramador.
Eluso
defuncionesdefinidasporelprogramadorpermitedividirunprogramagrandeenun
ciertonúmero
decomponentesmáspequeñas,teniendocadauna deellasunpropósitoúnicoe
identificable.Portanto,unprogramaenCsepuede
modularizarmedianteelusointeligente de
lasfunciones.(Cnoincluyeotrasformasdedesarrollomodulardeprogramas,comolosprocedi­
mientosenPascalolassubrutinasenFortran.)
Hayvariasventajasdeestaformadedesarrollomodular
delosprogramas.Porejemplo,mu­
chosprogramasrequierenqueseaccedarepetidamenteaungrupódeterminadodeinstrucciones
desdevariaspartes distintasdelprograma.Lasinstruccionesrepetidassepuedenincluirdentro
deunasolafunción,alaquesepuedeaccedercuandoseanecesario.Además,sepuedetransferir
unconjunto
dedatosdiferentealafuncióncadavezqueseaccedeaella.Portanto, elusode
funcionesevita lanecesidadderepetirlasmismasinstruccionesdeformaredundante.
Igualmenteimportanteesla claridadlógica resultantedeladescomposicióndeunprograma
envariasfuncionesconcisas,representandocadafunciónalgunapartebiendefinidadelproble­
maglobal.Estosprogramassonmásfáciles
deescribiry dedepurar,ysuestructuralógicaesmás
fácildeentenderquela
deaquellosprogramasquecarecen deestetipodeestructuras.Estoes
especialmenteciertoenprogramasgrandesycomplicados.LamayoríadelosprogramasenCse
modularizan
deestamanera,auncuandonoimpliquenlaejecuciónrepetidadelasmismastareas.
Dehecho,ladescomposicióndeunprogramaenmódulosindividualesseconsiderageneralmen­
teparteimportantedelabuenaprácticadelaprogramación.
Lautilizacióndefuncionespermitetambiénalprogramadorconstruiruna bibliotecaamedi­
daderutinasdeusofrecuenteo derutinasqueseocupendelmanejodeelementosdependientes
delsistema.Cadarutinasepuedeprogramarcomounafunciónporseparadoyalmacenarenun
archivodebibliotecaespecial.Siunprogramarequiereunadeterminadarutina,sepuedeañadir
lacorrespondientefuncióndebibliotecaalprogramaduranteelprocesodecompilación.Por
tanto,muchosprogramasdistintospuedenutilizarunamismafunción.Estoevitalareescritura
delcódigodelasfunciones.Ademásfavorece
la
portabilidad,yaquesepuedenescribirprogra­
massinprestaratenciónalascaracterísticasdependientesdelsistema.
Enestecapítuloveremos cómosedefinenlasfuncionesycómosepuedeaccederaellas
desdediferentespartesdeunprogramaen
C.Veremostambiéncómosepuedepasarinformación
aunafunción.Trataremoslautilización
deprototiposdefunciones,recomendadaporelestándar
217

218 PROGRAMACiÓN ENC
ANSIactual.Yfinalmente,discutiremosunaimportanteeinteresantetécnicadeprogramación
conocidacomo
recursividad,enlaqueunafunciónpuedeaccederasimismadeformarepetida.
7.1.INTRODUCCIÓN
Unafunciónesunsegmentodeprogramaquerealizadeterminadastareasbiendefinidas.Todo
programaenCconstadeunaomásfunciones(versección1.5).Unadeestasfuncionestieneque
llamarse
main.Laejecucióndelprogramasiemprecomenzará porlasinstruccionescontenidas
en
main.Sepuedensubordinarfuncionesadicionalesa main,yposiblementeunasaotras.
Si
unprogramacontienevariasfunciones,susdefiniciones puedenaparecerencualquier
orden,perodebenserindependientesunasdeotras.Estoes,unadefinicióndeunafunciónno
puedeestarincluidaenotra.
Cuandose
accedeaunafuncióndesdealgunadeterminadapartedelprograma(cuandose
«llama»aunafunción),seejecutanlasinstruccionesdequeconsta.Sepuedeaccedera
una
mismafuncióndesdevarioslugaresdistintosdelprograma. Unavezquesehacompletadola
ejecucióndeunafunción,sedevuelveelcontrolalpuntodesdeelqueseaccedióaella.
Generalmente,
unafunciónprocesará lainformaciónque leespasadadesdeelpuntodel
programa
endondeseaccedeaella ydevolveráunsolovalor.Lainformaciónselepasaala
función medianteunosidentificadoresespecialesllamados
argumentos(tambiéndenominados
parámetros)yesdevueltapormediode lainstrucciónreturn.Sinembargo,algunasfunciones
aceptaninformaciónperonodevuelvennada(porejemplo,
lafuncióndebiblioteca printf),
mientrasqueotras funciones(lafuncióndebibliotecas canf)devuelvenvariosvalores.
EJEMPLO7.1.Conversióndeuncarácterdeminúsculaamayúscula. EnelEjemplo3.31vimosun
sencilloprograma
enCqueleiaunsolocarácter,loconvertíaenmayúsculautilizandolafunción debi­
blioteca
toupperyloescribía.Consideremosahora unprogramasimilar,aunquedefiniremosnuestra
propiafuociónpararealizarlaconversión
deminúsculaamayúscula.
Nuestropropósito
alhaceresto esilustrarlosprincipaleselementosinvolucrados enelusodefuncio­
nes.Portanto,
ellectordebeconcentrarseenlalógicageneraldelprograma ynopreocuparsedelos
detalles
decadainstrucciónconcreta.
Reaquíelprogramacompleto.
/*convertiruncarácterenminúsculaamayúscula
utilizandounafuncióndefinidaporelprogramador*/
#include<stdio.h>
charminusc_a_mayusc(charcl)
{
charc2;
/*definicióndelafunción*/
c2;;;(el>=la'&&el<= lZ')?('A'+el-la')el;
return(c2);
}

FUNCIONES 219
main()
{
charrninusc,rnaYUSCi
printf(11PorfavorIintroduceunaletraminúscula:");
scanf(lI%c",&minusc)¡
mayusc =minusc_a_mayusc(rninusc);
printf("Lamayúsculaequivalentees%c", mayusc);
}
Esteprogramaconsta dedosfunciones,lafunción mainrequeridaylafuncióndefinidaporelprogra­
madorminusc_a_mayusc,queconvierteunaminúsculaamayúscula.Nótese queminusc_a_mayusc
efectúalatransformaciónreal delcarácter.Estafuncióntransformaúnicamentelasletras enminúsculas;
elresto
deloscaracteressedevuelvenintactos.Através delargumentoclsetransfierealafunciónuna
letraenminúscula,y
sedevuelvelamayúsculacorrespondiente, c2,alapartedelprogramaquehizola
llamada(main),mediantelainstrucción
return.
Consideremosahoralafunción main,queestáacontinuación delafunciónminusc_a_mayusc.
Estafunciónleeuncarácter(quepuedesero nounaletraenminúscula)y seloasignaalavariable detipo
carácter
minusc.Entoncesmainllamaa minusc_a_mayusc,letransfiereelcarácterenminúscula
(minusc)yrecibeelcarácterequivalente enmayúscula(mayusc). Seescribeacontinuaciónelcarácter
enmayúsculayfinaliza elprograma.Nótese quelasvariablesminuscymayuscenmainsecorrespon­
dencon
lasvariablesclyc2dentro deminusc_a_mayusc,respectivamente.
Enelrestodelcapítuloconsideraremoslasreglasasociadasconlasdefinicionesdelasfun­
cionesylosaccesosaéstas.
7.2.DEFINICIÓNDEUNAFUNCIÓN
Ladefinicióndeunafuncióntienedoscomponentesprincipales:la primeralínea (incluyendo
las
declaracionesdelosargumentos)yelcuerpodelafunción.
Laprimeralíneadeladefiniciónde unafuncióncontiene laespecificacióndeltipodevalor
devuelto
porlafunción,seguidodelnombredelafuncióny(opcionalmente)unconjuntode
argumentos,separadosporcomasyencerradosentreparéntesis.Cadaargumentovieneprecedi­
do
porsudeclaracióndetipo.Si ladefinicióndelafunciónnoincluyeningúnargumentohay
queincluirdetrásdelnombredelafunciónunpardeparéntesisvacíos.
Entérminosgenerales, laprimeralíneasepuedeescribirasí:
tipo-de-datonombre(tipo1arg1,tipo2arg2,. . .,tiponargn)
endondetipo-de-datorepresentaeltipodedatosdelvalorquedevuelve lafuncióny nom­
bJ;eelnombredelafunción,y tipo1,tipo2,...,tiponrepresentanlostiposdedatosde
losargumentos
arg1,arg2,...,argn.Lostiposdedatossesuponenenteroscuandonose
indicanexplícitamente.Sinembargo,
laomisióndelostiposdedatosseconsidera unamala
prácticadeprogramación,auncuandoéstosseanenteros.
Losargumentossedenominan
argumentosformales, yaquerepresentanlosnombresdelos
elementosquesetransfierena
lafuncióndesdelapartedelprogramaquehace lallamada.Tam-

220 PROGRAMACiÓN ENC
biénsellaman parámetrosoparámetrosformales. (Losargumentoscorrespondientesenla refe­
rencia
alafunciónsedenominan argumentosreales, yaquedefinenlainformaciónquereal­
mentesetransfiere.Algunosautoresllaman
argumentossimplementealosargumentosreales,o
parámetrosreales.) Losidentificadoresutilizadoscomoargumentosformalesson«locales»,en
elsentidodequenosonreconocidosfueradelafunción.Portanto,losnombresdelosargumen­
tosformalesnotienenporquécoincidirconlosnombresdelosargumentosrealesenlapartedel
programaquehace
lallamada.Sinembargo,cadaargumentoformaldebeserdelmismo tipode
datosqueeldatoquerecibedesdeelpuntodellamada.
Elrestodeladefinicióndelafunciónesunainstruccióncompuestaquedefinelasacciones
quedeberealizarésta.Sesuelellamaraestainstruccióncompuesta
cuerpodelafunción.Como
cualquierotrainstruccióncompuesta,puedecontenerinstruccionesdeexpresión,otrasinstruc­
cionescompuestas,instruccionesdecontrol,etc.Debeincluirunaomásinstrucciones
return
paradevolverunvaloralpuntodellamada.
Unafunciónpuedeaccederaotrasfunciones. Dehecho,puedeaccederasímisma(este
procesoseconocecomo
recursividadysetrataenlasección7.6).
EJEMPLO7.2. Consideremoslafunción minuse_a_mayuse,incluidaenelEjemplo7.1.
eharminuse_a_mayuse(eharel)
{
ehare2;
/*funcióndeconversión
definidaporelprogramador*/
c2=(el>='a'&&el<='z')?('A'+el-'a')el;
return(e2);
}
Laprimeralíneacontiene elnombredelafunciónminuse_a_mayuse,seguidodelargumentofor­
malel,queseencuentraentreparéntesis. Elnombredefunción vieneprecedidopor eltipodedatoehar,
quedescribeelelementodevueltoporla función.Además,elargumentoformal e1vieneprecedidopor el
tipodedatoehar.Esteúltimotipo dedato,queseincluyedentro delpardeparéntesis,serefiereal
argumentofonual. Elargumentofonual, el,representaelcarácterenminúsculaquesetransfiereala
función
desdeelpuntodellamada.
Elcuerpodelafuncióncomienza enlasegundalínea, conladeclaracióndelavariablelocal detipo
carácter
e2.(Observeladiferenciaentre elargumentoformal elylavariablelocal e2.)Acontinuación
deladeclaracióndee2seencuentraunainstrucción quecompruebasielrepresentaunaletraminúscula
yrealizaentonceslaconversión.
Sedevuelveelcarácteroriginalintactosi noesunaletraminúscula.
Finalmente,lainstrucción
return(veracontinuación)hace quesedevuelvaelcarácterconvertido al
puntodellamadaalafunción.
Sedevuelveinformacióndesdelafunciónhastaelpuntodelprogramadesdedondesellamó
mediantela instrucción
return.Lainstrucciónreturntambiénhacequesedevuelvaelcon­
trolalpuntodellamada.
Entérminosgeneralessepuedeescribir lainstrucciónreturndelasiguienteforma:
'returnexpresión;

FUNCIONES 221
Sedevuelveelvalorde expresiónalpuntodellamada,comoenelEjemplo7.2. Laexpresiónes
opcional.Siseomitela
expresión,lainstrucciónreturnsimplementedevuelveelcontrolal
puntodelprogramadesdedondesellamóa
lafunción,sinningunatransferenciadeinformación.
Sólosepuedeincluirunaexpresión
enlainstrucciónreturn.Portanto,unafunciónsólo
puededevolverunvaloralpuntodellamadamediante
lainstrucciónreturn.
Unadefinicióndefunciónpuedeincluirvariasinstrucciones return,conteniendocadauna
deellas
unaexpresióndistinta.Lasfuncionesqueincluyenvariasbifurcaciones
suelenrequerir
variasinstrucciones
return.
EJEMPLO7.3. Heaquilafunciónminusc_a_mayuscdelosEjemplos7.1y7.2,conalgunasvaria­
ciones.
charminusc_a_mayusc(charcl)
{
if(el>='a'&&el<= lZ')
return('A'+el-la
/
)
i
else
return(cl);
}
/*funcióndeconversión
definidaporelprogramador*/
Estafunciónutilizalainstruccióni f - e 1s eenlugardeloperadorcondicional. Esmenoscompacta
quelaversiónanterior,peropuederesultar demásfácilcomprensión.Porotraparte,estafunción no
necesitalavariablelocalc2.
Nótesequelafuncióncontienedosinstruccionesreturn.Laprimeradevuelveunaexpresiónquerepres­
entalamayúsculacorrespondientealaminúsculadada;lasegundadevuelveelcarácteroriginal,sincambios.
Lainstrucciónreturnpuedefaltar enladefinicióndeunafunción,aunqueestoseconside­
rageneralmentecomounamalaprácticadeprogramación.Si
unafunción alcanzaelfinaldel
bloquesinencontrarseunainstrucción
return,sedevuelveelcontrolalpuntodellamadasin
devolverseningunainformación.Serecomiendaenestoscasos
unainstrucciónreturnvacía
(sinexpresión),parahacermásclara
lalógicade lafunciónyhacermáscómodaslasmodifica­
cionesfuturasde
lafunción.
EJEMPLO7.4. Lasiguientefunciónaceptadoscantidadesenterasydetermina elvalormayor,quese
escribeacontinuación. Lafunciónnodevuelveningunainformación alpuntodellamada.
maximo(intx,inty)
{
intz;
/ *determinarelmáximode
doscantidadesenteras*/
z
;(x>;y)?x :y;
printf("Valormáximo;%d",z);
return¡
}

222 PROGRAMACiÓN ENC
Observequesehaincluidounainstrucción returnvacíacomoprácticadebuenaprogramación. De
todasformas,lafunciónactuaríaigualsilainstrucción returnnoseencontrarapresente.
EJEMPLO7.5. Elfaetorialdeunenteropositivo sedefinecomo n!=Ix2x3x...x n.Portanto,
2!=Ix2=2;3!=Ix2x3=6;4!=Ix2x3x4=24;Yasísucesivamente.
Lafunciónquesemuestraacontinuacióncalculaelfactorialde unenteropositivodado,n.Sedevuel­
veelfactorialcomounenterolargo,yaqueelfactorialcrece
muyrápidamentealhacerlon.(porejemplo,
8!=40320.Estevalor,expresadocomounenteroordinario,puedesermuygrandeparaalgunascomputa­
doras.)
longintfactorial(intn)
{
inti;
longintprod=1;
if(n>1)
for(i
=2;i<=ni++i)
prod*=i¡
return(prod);
}
/*calcularelfactorialden*/
Observelaespecificacióndetipo longintqueseincluyeenlaprimeralíneadeladefinicióndela
función.Tambiénsedeclaralavariablelocal
prodcomoenterolargodentrodelafunción.Observeque
a
prodseleasignaunvalorinicialde 1,aunquesuvalorserecalculaenelbucle for.Elvalorfinalde
prod,queesdevueltoporlafunción,representaelvalordeseadodelfactorialde n.
Sieltipodedatosespecificadoenlaprimeralineaesinconsistenteconlaexpresiónque
apareceenlainstrucciónreturn,elcompiladorintentaráconvertirlacantidadrepresentada
porlaexpresiónaltipodedatosespecificadoenlaprimeralinea.Elresultadodeestopuedeser
unerrordecompilaciónounapérdidaparcialdedatos(porejemplo,debidoaltruncamiento).
Encualquiercaso,sedebenevitarinconsistenciasdeestetipo.
EJEMPLO7.6. LasiguientedefinicióndefunciónesidénticaaladelEjemplo7.5,exceptoenlaprime­
ralínea,enlaquenoapareceespecificacióndetipoparaelvalordevuelto porlafunción.
factorial(intn)
{
inti¡
longintprod=1;
if(n>1)
for(i=2;i<=n;++i)
prod*=i;
return(prod);
}
/*calcularelfactorialden*/

FUNCIONES 223
Lafuncióndevolveráunacantidadenteraordinaria,yaque nohayunadeclaraciónexplícitadetipode
datosenlaprimeralíneadeladefinicióndelafunción.Sinembargo,la cantidadquesevaadevolver
(prod)sedeclaracomoenterolargodentro delafunción.Elresultado deestainconsistenciapuedeserun
error.(Algunoscompiladoresgeneraránunmensajedeerrorydetendránenesepuntolacompilación.)Sin
embargo,sepuedeevitarelproblemaañadiendouna declaración
detipolongintenlaprimeralíneade
ladefinicióndelafunción, comoenelEjemplo7.5.
Sepuedeutilizarlapalabrareservada voidcomoespecificador detipocuandosedefine
unafunciónquenodevuelvenada.
Lapresenciadeestapalabrareservadanoesobligatoria,
peroesunabuenaprácticadeprogramación.
EJEMPLO7.7.Consideremos denuevolafunciónqueapareceenelEjemplo7.4,queacepta doscan­
tidadesenterasyescribelamayordelasdos.Recordarqueestafunciónnodevuelvenadaalpunto
de
llamada.Portanto,lafunciónsepuedeescribirasi:
voidmaximo(intx,inty)
{
intz;
/*determinarelmáximode
doscantidadesenteras*/
z=(x>=y)?x :y;
printf("Valormáximo=%d",z);
return;
}
EstafunciónesidénticaalaincluidaenelEjemplo7.4,exceptoenquesehaañadidolapalabrareservada
vaidenlaprimeralínea,indicandoquelafunciónnodevuelvenada.
7.3.ACCESOAUNAFUNCIÓN
Sepuedeacceder(llamar)aunafunciónespecificandosunombre,seguidodeunalista deargu­
mentosencerradosentreparéntesis
yseparadosporcomas. Silallamadaa lafunciónnorequiere
ningúnargumento,sedebeescribiracontinuacióndelnombre
delafunciónunpar deparén­
tesisvacíos.
Lallamadaalafunciónpuedeformarparte deuna expresiónsimple(comopor
ejemplounainstruccióndeasignación)opuedeserunodelosoperandosde
unaexpresiónmás
compleja.
Losargumentosqueaparecenenlallamadaalafunciónsedenominanargumentosreales,en
contrasteconlosargumentosformalesqueaparecenenlaprimeralíneadeladefinición
dela
función.(Tambiénsellamansimplementeargumentos,oparámetrosreales.)Enunallamada
normalaunafunción,habráunargumentorealporcadaargumentoformal.Losargumentos
realespuedenserconstantes,variablessimples,oexpresionesmáscomplejas.Noobstante,cada
argumentorealdebeserdelmismotipo
dedatosqueelargumentoformalcorrespondiente.Re­
cordarqueelvalordecadaargumentorealestransferidoalafunción
yasignadoalcorrespon­
dienteargumentoformal.

224 PROGRAMACiÓN ENC
Silafuncióndevuelveunvalor,el accesoalafunciónsesueleescribiramenudocomouna
instruccióndeasignación;estoes,
y=polinomio(x);
Esteaccesoalafunciónhacequealavariableyseleasigneel valordevueltoporla[unción.
Porotrolado,si la[unciónnodevuelvenada,elaccesoa la[unciónseescribeporseparado,
comoen,
visualizar(a,b,e);
Esteaccesoalafunciónhacequeseproceseninternamente(sevisualicen)losvaloresde a,by
edentrodelafunción.
EJEMPLO7.8. ConsideremosdenuevoelprogramaquepresentamosoriginalmenteenelEjemplo7.1,
queleeuncaráctery
loconviertedeminúsculaamayúsculautilizandounafuncióndefinidaporelprogra­
mador,yluegoescribe
elequivalenteenmayúscula.
/*convertiruncarácterenminúsculaamayúscula
utilizandounafuncióndefinidaporelprogramador*/
#include<stdio.h>
charminusc_a_mayusc(charcl) /*definicióndelafunción*/
{
charc2;
c2
;;;;;(el>='a/&&el<=IZ1)?('A'+el-'a')el;
return(c2);
}
voidmain(void)
{
charminusc
1mayusc;
printf(nPorfavorIintroduceunaletraminúscula:n);
scanf(11%c111&minusc)i
rnayusc=rninusc_a_mayusc(minusc)i
printf("Lamayúsculaequivalentees%e",mayusc);
}
definidaporelprogramador
deasignación
mayus e=
alafnnción
laexpresión
sólounallamada
esunapartede
Enesteprograma,mai ncontiene
minusc_a_mayusc.Lallamada
minusc_a_mayuse(minusc).
Lallamadaa 'lafuncióncontieneunargumentoreal,lavariabledetipocarácter minusc.Observeque
elargumentoformalcorrespondiente,c
1,dentrodeladefinicióndelafunciónestambiénunavariablede
tipocarácter.

FUNCIONES 225
Cuandoseaccedealafunción,setransfiere elvalordeminuscalafunción.Estevalores represen­
tadoporc 1dentrodelafunción.Acontinuaciónsedeterminaelvalor
delamayúsculacorrespondiente,
c2,ysedevuelvealpunto dellamada,endondeseasignaalavariabledetipocarácter mayusc.
Observequesepuedencombinarlasdosúltimasinstruccionesde maindelaformasiguiente:
printf("LamayÚsculaequivalentees%c", minusc_a_mayusc(minusc)) ;
Ahoralallamadaa
minusc_a_mayuscesunargumentorealdelafunción debibliotecaprintf.
Observetambiénqueya nosenecesitalavariable mayusc.
Finalmente,observelaformaenqueseescribelaprimeralíneade main,estoes,voidmain(void).
EstoestápermitidoenelestándarANSI,aunquealgunoscompiladores
noaceptenvoidcomotipode
retomo.Enconsecuencia,muchosautores(ymuchosprogramadores)escribenlaprimeralíneade
main
comomain(void)osimplementemain().Usaremosestaúltimaopciónenelrestodellibro.
Puedehaberdiversasllamadasalamismafuncióndesdevarioslugaresdeunprograma.Los
argumentosrealespuedenserdistintosdeunallamadaaotra.Entodocaso,dentrodecadalla­
madaaunafunciónlosargumentosrealesdebencorresponderseconlosargumentosformales
deladefinicióndelafunción;esdecir,elnúmero deargumentosrealesdebeserelmismoque
elnúmerodeargumentosformales
ycadaargumentorealdebeserdelmismotipodedatosque
elcorrespondienteargumentoformal.
EJEMPLO7.9. Mayordetrescantidadesenteras.Elsiguienteprogramadeterminalamayor detres
cantidadesenteras.Esteprogramautilizaunafunciónquedeterminalamayor
dedoscantidadesenteras.
LafunciónessemejantealadefinidaenelEjemplo7.4,salvoquelafunción
deesteejemplodevuelveel
valormayoralpuntodellamadaenlugardevisualizarlo.
Laestrategiaglobalesdeterminarlamayordelasdosprimerascantidadesycompararlaacontinua­
ciónconlatercera.Lacantidadmayorseescribeenlaparteprincipaldelprograma.
/*determinarlamayordetrescantidadesenteras*/
#include<stdio.h>
intmaximo(intx,inty)
{
intz;
z=(x>=y)?xy;
return(z);
}
main()
{
/*determinarlamayordedos
cantidadesenteras*/
/*leerlascantidadesenteras*/
printf("a =");
scanf(ll%dll,&a)i
printf("b =");

226 PROGRAMACiÓN ENC
scanf("%d",&b);
printf(11c =11);
scanf("%d",&c);
/*calcularyvisualizarelvalormáximo*/
d=maximo(a,b);
printf("máximo =%d",maximo(c,d));
}
Seaccedealafunción maximodesdedoslugaresdiferentes enmain.Enlaprimerallamadaa
maximo,
losargumentosreales sonlasvariablesa yb,mientras queenlasegundallamada losargumen­
tossonc y d(d esunavariabletemporal querepresentaelvalor máximodea yb).
Observe
quelasdosinstruccionesqueaccedenamaximo, esdecir,
d
=maximo(a,b);
printf("máximo =%d",maximo(c,dI);
sepuedenreemplazarporlainstrucción
printf("máximo =%d",maximo(c,maximo(a,b)));
Enestainstruccióuvemos queunadelasllamadasamaximo esunargumentopara laotrallamada.Es
decir,puedenincluirselasllamadas,unadentro deotra,y nosenecesitalavariableintermediad. Se
permitetenerllamadasafuncionesincluidasdentro deotras,aunqueenalgunoscasoslalógicasubyacen­
tepuederesultarmenosclara.Portanto, engeneraldeberíanserevitadasporlosprogramadores quese
estániníciando.
7.4.PROTOTIPOSDEFUNCIONES
Enlosprogramasdeestecapítuloexaminadosconanterioridad, lafuncióndefinidaporelpro­
gramadorsiempre
haprecedidoamain.Deestemodo,alcompilarelprograma,lafunción
definidaporelprogramadorestaríadefinidaantesdelprimeraccesoalafunción.Sinembargo,
muchosprogramadoresprefierenunenfoque«descendente»,enelque
mainapareceantesdela
definicióndefuncióndefinida
porelprogramador.Entalessituacioneselaccesoalafunción
(dentrode
main)precederíaladefiniciónde lafunción.Estopuedeconfundiralcompilador,a
menosquesealerteprimeroalcompiladordelhechodequelafunciónaaccedersedefinirámás
adelanteenelprograma.Paraestafinalidadseutilizanlos
prototiposdefunciones.
Losprototiposdefuncionesnormalmenteseescribenalcomienzodelprograma,delantede
todaslasfuncionesdefinidasporelprogramador(incluida
main).Laformageneraldeunpro­
totipodefunciónes:
tipo-de-datosnombre(tipo1arg
1,tipo2arg2,...,tiponargn);
endondetipo-de-datosrepresentaeltipodedatosdelelementodevueltoporlafunción,
nombrerepresentaelnombredelafunción, ytipo1,tipo2,...,tiponrepresentanlos
tiposdedatosdelosargumentos
arg1,arg2,...,argn.Observeque unprototipode

FUNCIONES 227
funciónessimilaralaprimeralínea deunadefinicióndefunción(sibienunprototipo defun­
ciónfinalizaconunpuntoycoma).
No
esnecesariodeclararenningúnlugardelprogramalosnombres delosargumentosdeun
prototipo
defunción,puestoqueéstossonnombresdeargumentos«ficticios»quesólosereco­
nocendentrodelprototipo.Dehechosepuedenomitirlosnombresdelosargumentos(aunque
no
esunabuenaideahacerlo);sinembargo,los tiposdedatos delosargumentossonesenciales.
Enlapráctica,normalmenteseincluyenlosnombres
delosargumentosyéstosfrecuente­
mentecoincidenconlosnombres
delosargumentosrealesqueaparecenenalguna delasllama­
dasalafunción.Lostipos
dedatosdelosargumentosrealessedebenadecuaralostiposde
datosdelosargumentosenelprototipo.
Losprototipos
defuncionesnosonobligatoriosen C.Sinembargo,sonaconsejables,yaque
facilitanlacomprobación
deerroresulteriorentrelasllamadasaunafunciónyladefiniciónde
funcióncorrespondiente.
EJEMPLO7.10. Cálculodefactoriales.Heaquíunprogramacompleto enequecalculaelfactorial
deunacantidadenterapositiva.Elprogramautiliza
lafunciónfactorial,definidaenelEjemplo7.5.
Observeque ladefinicióndelafunciónprecedea main,aligualque enlosanterioresejemplosdeprogra­
masde'estecapitulo.
/*calcularelfactorialdeunacantidadentera*/
#include<stdio.h>
longintfactorial(intn)
/*calcularelfactorialden*/
{
inti;
longintprod=1;
if(n>1)
for(i=2;i<=n;++i)
prod*=i;
return(prod);
}
main()
{
intDi
/*leerlacantidadentera*/
printf(l!n=11);
scanf("%d",&n);
/*calcularyvisualizarelfactorial*/
printf("n! =%ld",factorial(n)) ;
}

228 PROGRAMACiÓN ENC
Lafuncióndefinidapor elprogramador(factorial)utilizaunargumentoentero(n)ydosvariables
locales-unenteroordinario (i)yunenterolargo (prod)-.Puestoquelafuncióndevuelveunentero
largo,ladeclaración
detipolongintapareceenlaprimeralineadeladefinición delafunción.
Acontinuación
sepresentaotraversióndelprograma,escritadescendentemente(esdecir, mainapa­
recedelantede
factorial).Observelapresenciadelprototipodelafunciónalcomienzodelprograma.
Elprototipodelafunciónindicaquesedefinirá,posteriormenteenelprograma,unafunciónllamada
factorial,queaceptaunacantidadenteraydevuelveunenterolargo.
/*calcularelfactorialdeunacantidadentera*/
#include<stdio.h>
longintfactorial(intni;
main()
{
intni
/*prototipodefunción*/
/*leerlacantidadentera*/
printf(lIn =
11)i
scanf(lI%dll1&n);
/*calcularyvisualizarelfactorial*/
printf("n! =%ld",factorial(n)) ;
}
longintfactorial(intn)
/*calcularelfactorialden*/
{
intii
longintprod=1;
if(n>1)
for(i=2;i<=n;++i)
prod*=i;
return(prod);
}
Lasllamadasalasfuncionespuedenabarcarvariosnivelesenunprograma.Estoes,la
funciónApuedellamaralafunciónB,lacualpuedellamaralafuncióne,etc.También,lafun­
ciónApuedellamardirectamentealafuncióne,yasísucesivamente.
EJEMPLO7.11.Simulacióndennjuego deazar(juegode dados«Craps»).Ésteesuninteresante
problemadeprogramaciónqueincluyevariasllamadasafuncionesadiferentesniveles.
Serequierenfun­
cionesdebiblioteca
yfuncionesdefinidasporelprogramador.

FUNCIONES 229
Existeunpopularjuego dedadosllamado«Craps»enelqueselanzanlosdadosunavezomáshasta
queseganaosepierde.Eljuego
sepuedesimularenunacomputadorasustituyendoellanzamientorealde
losdadosconlageneración
denúmerosaleatorios.
Haydosformas
deganar.Puedelanzarlosdadosyobtenerunapuntuaciónde7 u 11;opuedeobtener
4,5,6,8,9 OlOenlaprimeratiradayconseguirdenuevolamismapuntuaciónenalgunadelassiguien­
testiradasantesdeobtenerun7.Existentambiéndosformasdeperder.Puedelanzarlosdadosunavezy
obtener
2,3 o12;opuedeobtener4,5,6,8,9 o lOenlaprimeratiradayobtenerun7enunatirada
posteriorantesderepetirlapuntuaciónoriginal.
Desarrollaremoseljuegointeractivamente,deformaquesesimuleunatiradadedadoscadavezque
sepulselatecla
Intro.Apareceráentoncesunmensajeinformandodelresultadodecadalanzamiento.
Alfinal
decadajuegosepreguntarásisedeseacontinuarjugandoono.
Nuestroprogramarequeriráungeneradordenúmerosaleatoriosqueproduzcaenterosdistribuidos
uniformementeentre1 y6.(Por
uniformementedistribuidos entendemosquecadaenteroentre1 y 6tiene
lamismaprobabilidaddeaparecer.)LamayoríadelasversionesdeCincluyenungeneradordenúmeros
aleatoriosentresusfuncionesdebiblioteca.Estosgeneradoresdenúmerosaleatoriossuelendevolver
típicamenteunnúmeroencomaflotanteuniformementedistribuidoentreO y
1,ounacantidadentera
uniformementedistribuidaentreO yalgúnvalorenteromuygrande.
Utilizaremosunafunción
debibliotecallamadar and,quedevuelveunenterouniformementedis­
tribuidoentreO y 2
15
-1(estoes,entreO y 32767).Convertiremosentoncescadacantidadenteraalea­
toriaenunnúmeroencomaflotante
x,queseencontraráentreO y O. 99999....Parahacerestoes­
cribimos
x
=rand()/32768.0
Observequeeldenominadorsehaescritocornoconstanteencomaflotante.Estohaceque elcociente,y
portanto
x,seaencomaflotante.
Laexpresión
(int)(6*x)
seráunenterotrnncado,convaloruniformemcntedistribuidoentreOy5.Portanto,obtenemoselresulta­
dodeseadosimplementeañadiendo1;estoes,
n
=1+(int)(6*x)
Estevalorrepresentaráelresultadodellanzamientodeundado.Sirepetirnosesteprocesounasegunda
vezysumamoslosresultados,obtenernoselresultadodelanzardosdados.
Lasiguientefunciónutilizalaestrategiadescritaanteriormenteparasimularlatiradadeunpar
dedados.
inttirada(void)/*simulaellanzamientodeunpardedados* /
{
f10atxl,x2;
intnl,n2¡
/*númerosencomaflotantealeatoriosentreO y 1*/
/*enterosaleatoriosentre1 y 6*/
xl=rand()
x2=rand()
/32768.0;
/32768.0;

230 PROGRAMACiÓN ENC
nI=1+
n2=1+
(int)
(int)
(6*xl);/*simulaprimerdado*/
(6*x2);/*simulasegundodado*/
return(nl+n2);
}
/*lapuntuacióneslasumadelosdosdados*/
Lafuncióndevuelveelresultadodecadatirada(unacantidadenteraconvalorentre2 y12).Observeque
esteresultadofinal
noestaráuniformementedistribuido,aunquelosvaloresde nIyn2loestén.
Definamosahoraotrafunciónllamada
juego,quesimulauna jugadacompleta.Portanto,losdados
selanzarántantasvecescomoseanecesario
paradeterminarsisepierdeosegana.Estafunciónaccederá
a
tirada.Todaslasreglasdeljuegoestánpresentesenestafunción.
Podemosescribirelpseudocódigode
juegocomosigue.
voidjuego(void)
(
/*simularunajugadacompleta*/
intpuntosl,puntos2;
/*informaralusuariodecómotirarlosdados*/
/*inicializarelgeneradordenúmerosaleatorios*/
puntosl=tirada();
switch(puntosl){
case7:
case11:
/*escribirunmensajeindicandoquesehaganadoenla
pri­
meratirada* /
case2:
case3:
case12:
/ *escribirunmensajeindicandoquesehaperdidoenla
primeratirada*/
case4 :
case5 :
case6 :
case8 :
case9 :
case10:
do(
/*instruiralusuariodecómolanzarlosdadosdenuevo*/
puntos2=tirada();
}while(puntos2!=puntosl&&puntos2!=7);
if(puntos2==puntosl)
/*escribirunmensajeindicandoquesehaganado*/

FUNCIONES 231
else
/*escribirunmensajeindicandoquesehaperdido*/
}
return;
}
Larutinamaincontrolarálaejecucióndeljuego.Estarutinaconstará deunbuclewhilequeconten­
drálaentrada/salidainteractiva
ylallamadaa juego.Portanto,podemosescribirelpseudocódigo de
maincomosigue.
main()
{
/*declaraciones*/
/*inicializarelgeneradordenúmerosaleatorios*/
/*generarunmensajedebienvenida*/
while/*eljugadordeseaseguirjugando*/) {
jugar( )
;
/*preguntaraljugadorsideseacontinuar*/
}
/*generarmensajededespedida*/
}
Lafuncióndebiblioteca srandseutilizaparainicializarelgenerador denúmerosaleatorios.Esta
funciónrequiereunenteropositivo,llamado
semi11a,queestablecelasecuenciadenúmerosaleatorios
generadosporrandoSegeneraráunasecuenciadenúmerosaleatoriosdiferenteparacadasemilla.Por
comodidad,podemosincluirunvalordelasemillacomoconstantesimbólicadentrodelprograma.(Siel
programaseejecutarepetidamenteconlamismasemilla,segenerarácadavezlamismasecuenciade
númerosaleatorios.Estopuedeservir
deayudaaldepurarelprograma.)
Heaquí
elprogramacompletoen C.
/*simulacióndeljuegodedados"Craps"*/
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#defineSEMILLA12345
voidjuego(void);
inttirada(void);
main()
/*prototipodefunción*/
/*prototipodefunción*/

232 PROGRAMACiÓN ENC
{
charrespuesta= fS';
printf("BienvenidoaljuegoCRAPS");
printf("Paralanzarlosdados.pulsaIntro");
srand(SEMILLA);1*inicializaelgeneradordenúmerosaleatorios*1
1*bucleprincipal*1
while(toupper(respuesta)!='N'){
juego();
printf("¿Deseasjugardenuevo?(SIN)");
scanf(11%c 11/&respuesta);
printf(lI")i
}
printf("Adiós,quelopasesbien");
}
voidjuego(void)
{
1*simularunajugadacompleta*1
intpuntosl,puntos2;
charnada;
printf("Porfavorlanzalosdados . " ) ;
scanf(11%cnI&nada)i
printf("");
puntos1=tirada();
printf("%2d",puntos1);
switch(puntos1){
case7:1*sehaganadoenlaprimeratirada*I
case11:
printf("
break;
¡Felicidades!GANASTEenlaprimeratirada");
case2:1*sehaperdidoenlaprimeratirada*1
case3:
case12:
printf("-¡Losiento!-PERDISTEenlaprimeratirada");
break;
case4:1*serequierenotrastiradas*I
case5:
case6:
case8:
case9:
case10:

FUNCIONES 233
do{
printf(11-Lanzalosdadosdenuevo .11);
scanf("%c
ll
,&nada);
puntos2=tir'ada(),
printf("%2d",puntos2),
}while(puntos2!=puntosl&&puntos2! =7),
if(puntos2==puntosl)
printf("-GANASporigualartuprimerapuntuación"),
else
printf("-PIERDES pornoigualartuprimerapuntuación"),
break,
}
return¡
.}
inttirada(void)
(
/*simulaellanzamientodeunpardedados*/
floatxl,x2;/*númerosencomaflotantealeatoriosentreOy 1*/
intni/n2;
xl=rand()/32768.0,
x2=rand()/32768.0,
ni=1+(int)(6*xl);/*simulaprimerdado*/
n2=1+(int)( 6*x2);/*simulasegundodado*/
return(nl+n2),/*lapuntuacióneslasumadelosdosdados*/
}
Observeque mainllamaa srandyjuego.Selepasaunargumentoa srand(elvalorde
semilla),peronoselepasaningúnargumentoa juego.Observetambiénque juegollarnaatira­
dadesdedoslugaresdiferentes,y tiradallamaa randdesdedoslugaresdiferentes.Nosepasan
argumentosdesde
juegoatirada,nidesdetiradaarand.Sinembargo,randdevuelveunentero
aleatorioa
tirada,ytiradadevuelveelvalordeunaexpresiónentera(elresultadodeunatiradade
losdados)a
juego.Nóteseque juegonodevuelveningunainformacióna main.
Dentrode juegohaydosreferenciasalafunción scanf,cadaunadelascualesleeunvalorde
lavariable
nada.Sedebeentenderque nadanoseutilizarealmenteenelprograma.Lapresenciadela
función
scanftienelaúnicafinalidaddegenerarunaesperaenlaejecucióndelprogramahastaquese
pulselatecla
Intro(parasimularunanuevatiradadelosdados).
Esteprogramadebeejecutarseenunentornointeractivo,talcomounacomputadorapersonal.Se
muestraacontinuaciónunatípicasesióninteractiva.Porclaridad,sehansubrayadolasrespuestasdel
usuario.
BienvenidoaljuegoCRAPS
Paralanzarlosdados,pulsaIntro(Intro)
Porfavorlanzalosdados

234 PROGRAMACiÓN ENC
6 -Lanzalosdadosdenuevo
10-Lanzalosdadosdenuevo
7 -PIERDES pornoigualartuprimerapuntuación
¿Deseasjugardenuevo?(S/N)§
Porfavorlanzalosdados
7 -¡Felicidades!GANASTEenlaprimeratirada
¿Deseasjugardenuevo?(S/N)§
Porfavorlanzalosdados
11-¡Felicidades!GANASTEenlaprimeratirada
¿Deseasjugardenuevo?(S/N)§
Porfavorlanzalosdados
8 -Lanzalosdadosdenuevo
5 -Lanzalosdadosdenuevo
7 -PIERDES pornoigualartuprimerapuntuación
¿Deseasjugardenuevo?(S/N)§
Porfavorlanzalosdados
6 -Lanzalosdadosdenuevo
4 -Lanzalosdadosdenuevo
6 -GANASporigualartuprimerapuntuación
¿Deseasjugardenuevo?(S/N)§
Porfavorlanzalosdados.
3 -¡LO
siento!-PERDISTE enlaprimeratirada
¿Deseasjugardenuevo?(S/N)
TI
Adiós,quelopasesbien

FUNCIONES 235
7.5.PASODEARGUMENTOS AUNAFUNCIÓN
Cuandoselepasaunvalorsimplea unafunciónmedianteunargumentoreal,secopiaelvalor
delargumentorealalafunción.Portanto,sepuedemodificarelvalordelargumentoformal
dentro
delafunción,pero elvalordelargumentoreal enlarutinaqueefectúa lallamadano
cambiará.Esteprocedimientoparapasarelvalordeunargumentoaunafunciónsedenomina
pasoporvalor.
EJEMPLO7.12. HeaquíunsencilloprogramaenCquecontieneunafunciónquemodificaelvalor de
suargumento.
#include<stdio.h>
voidmodificar(inta);
main()
{
inta=2;
/*prototipodefunción*/
printf("a=%d(desdemain,antesdellamaralafunción)",a);
modificar(a);
printf("a =%d(desdemain,despuésdellamaralafunción)",a);
}
voidmodificar(inta)
{
a*=3;
printf("a=%d(desdelafunción,modificandovalor)",a);
return¡
}
Sevisualizaelvalororiginal dea(a=2)cuandocomienzalaejecución demain.Estevalorsepasaala
función
modificar,endondesemultiplicapor3 ysevisualizaelnuevovalor.Observequees elvalor
alteradodelargumentoformalel quesevisualizaenlafunción.Finalmente,elvalordeaen main(el
argumentoreal)sevuelveavisualizar,después
dehabersedevueltoelcontrola maindesdemodificar.
Cuandoseejecutaelprograma,segeneralasiguientesalida:
a
=2(desdemain,antesdellamaralafunción)
a=6(desdelafunción,modificandoelvalor)
a=2(desdemain,despuésdellamaralafunción)
Estosresultadosmuestranqueanosehamodificadodentrodemain,aunquesehayamodifica­
doelvalorcorrespondientedeaenmodificar.
Pasarunargumentoporvalortienesusventajaseinconvenientes.Algopositivoesqueper­
mitequepuedaproporcionarsecomoargumentorealunaexpresiónenlugardenecesariamente

236 PROGRAMACiÓN ENC
unavariable.Esmás,sielargumentorealesunasimplevariable,se protegesuvalordeposibles
alteracionesporpartedelafunción.Porotraparte,impidequese transfierainformacióndesde
lafunciónhastaelpuntodellamadamediantelosargumentos.Portanto,elpasoporvalorimpli­
caquelatransferenciadeinformaciónsólopuedarealizarse enunsentido.
EJEMPLO7.13.Cálculodedepreciación. ConsideremosunavariacióndelprogramadelEjemplo
6.26.Elobjetivofinalescalcularladepreciaciónenfuncióndeltiempoutilizandouno
delostresmétodos
comúnmenteusados.Reescribiremosaboraelprogramaparaqueseutiliceunafunciónporseparadopara
cadamétodo.Estonospermiteorganizarloscomponenteslógicosdelprogramadeunaformamásclara.
Además,pasaremosunbloquedeinstruccionesrepetidasdesalidaaunafunción,eliminandoasíuna
ciertaprogramaciónredundantedelaversiónoriginaldelprograma.
Tambiénaumentaremoslageneralidaddelprogramadealgúnmodo,yaquepermitiremos
quesepue­
danhacerdistintoscálculos
deladepreciaciónconlosmismosdatos deentrada.Sepreguntaráalusuario
alfinaldecadaconjunto
decálculossideseaquesevuelvaarealizarotronuevoconjuntodecálculos.Si
larespuestaessí,selepreguntaráalusuariosideseaintroducirnuevosdatosono.
Heaquílanuevaversióndelprograma,escritadescendentemente.
/*calcularladepreciaciónutilizandounodetresmétodosdiferentes*/
#include<stdio.h>
#include<ctype.h>
voidlr(floatval,intn);
voidbdd(floatval,intnI;
voidsda(floatval,intnI;
voidescribir_salida(intanual,
main()
{
/*prototipodefunción*/
/*prototipodefunción*/
/*prototipodefunción*/
floatdepreciacion,floatvalor);
/*prototipodefunción*/
intTIIeleccion
==O;
floatval;
charrespl='S',~esp2 =/S';
while(toupper(respl)! ='N'){
/*leerdatosdeentrada*/
i f(toupper(resp2)!='N'){
printf("Valororiginal:");
scanf(l1%f
ll
,&val)¡
printf("Númerodeaños:11);
scanf(l1%d
ll
,&n);
}
printf("Método:(l-LR2-.BDD3-SDA)");
scanf(11%d 111&eleccion)i
switch(eleccion){

case1:/*métododelínearecta*/
FUNCIONES 237
printf("Método delínearecta");
1r(val,n);
break;
case2:/*métododebalancedoblementedeclinante*/
printf("Métododebalancedoblementedeclinante");
bdd(val,n);
break;
case3:/*métododelasumadelosdígitosdelosaños*/
printf("Métododelasumadelosdígitosdelosaños");
sda(val,n);
}
printf("¿Más cálculos?(S/N)");
scanf("%18ni&respl);
if(toupper(resp1)!='N')(
printf("¿Introducirunnuevoconjuntodedatos?(S/N)");
scanf(11%18n/&resp2);
}
}
printf("Hastaluegoyquetengaunbuendía");
}
voidlr(floatval,intn)
{
floatdeprec;
intanual;
/*métododelínearecta*/
deprec
=val/ni
for(anual=1;anual.<=n;++anual)(
val-=deprec;
escribir_salida(anual,deprec,val);
}
return¡
}
voidbdd(floatval,intn)/*métododebalancedoblementedeclinante*/
{
floatdeprec;
intanual;

238 PROGRAMACiÓN ENC
for(anual=1;anual<=n;++anual){
deprec=2*val/n;
val-=deprec;
escribir_salida(anual,deprec,val);
}
return;
}
voidsda(floatval,intn)/*métododelasumadelosdígitosde
losaños*/
{
floataux,deprec;
intanual;
aux=val;
for(anual=1;anual<=n;++anual){
deprec=(n-anual+l)*aux/(n*(n+l)/2);
val-=deprec;
escribir_salida(anual,deprec,val);
}
return;
}
voidescribir_salida(intanual,floatdepreciacion,floatvalor)
/*escribirlosdatosdesalida*/
{
}
printf("Findeaño%2d",
printf("Depreciación:
printf( "Valoractual:
return;
anual);
%7.2f",depreciacion);
%8.2f",valor);
Observequeaúnseemplealainstrucción switch,comoenelEjemplo6.26,
aunquIYahorahaysólo
tresopcionesenlugardecuatro.(Laopcióncuarta,quefinalizaba
laejecuciónenlaversiónanterior,se
manejaahoramedianteeldiálogointeractivoalfinal
deloscálculos.)Seproporcionaahoraunafunción
porseparadoparacadatipodecálculos.Enparticular,loscálculosdelmétodo
delínearectaseefectúan
dentrodelafunción
lr,losdelmétododelbalancedoblementedeclinantedentro debdd,ylosdela
sumadelosdígitosdelosañosdentrode
sda.Cadauna deestasfuncionesincluyelosargumentosforma­
les
valyn,querepresentanelvalororiginaldelobjetoysutiempodevida,respectivamente.Observe
queelvalorde
valesalteradodentrodecadafunción,aunqueelvalororiginalasignadoa valpermane­
cesinalteracióndentrode
main.Esestoloqnepermiterepetirelconjuntodecálculosconelmismovalor
deentrada.
Laúltima
fuhción,escribir'-.-sa.lida,haceqnelosresultadosdecadaconjuntodecálculosse
escribanañoaaño.Seaccedeaestafuncióndesde
lr,bddysda.Encadallamadaa
escribir_salida,elvalormodificadodevalsetransfierecomoargumentoreal,juntoconelañoen
curso
(anual)yladepreciacióndelañoencurso (deprec).Observequeestascantidadessonllamadas
valor,anualydepreciación,respectivamente,dentrode escribir_salida.

Acontinuaciónsemuestraunejemplodesesióninteractivaconesteprograma.
Valororiginal:8000
Númerodeaños:10
Método:(l-LR2-BDD3-SDA).1
Métododelínearecta
FUNCIONES 239
Findeaño1
Findeaño2
Findeaño3
Findeaño4
Findeaño5
Findeaño6
Findeaño7
Findeaño8
Findeaño9
Findeaño10
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
800.00
800.00
800.00
800.00
800.00
800.00
800.00
800.00
800.00
800.00
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractua.1:
Valoractual:
Valoractual:
7200.00
6400.00
5600.00
4800.00
4000.00
3200.00
2400.00
1600.00
800.00
0.00
¿Máscálculos?(S/N)
g
¿Introducirunnuevoconjuntodedatos?TI
Método:(l-LR2-BDD3-SDA) .2.
Métododebalancedoblementedeclinante
Findeaño1
Findeaño2
Findeaño3
Findeaño4
Findeaño5
Findeaño6
Findeaño7
Findeaño8
Findeaño9
Findeaño10
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
1600.00
1280.00
1024.00
819.20
655.36
524.29
419.43
335.54
268.44
214.75
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
6400.00
5120.00
4096.00
3276.80
2621.44
2097.15
1677.72
1342.18
1073.74
858.99
¿Máscálculos?(S/N)
g
¿Introducirunnuevoconjuntodedatos?TI
Método:(l-LR2-BDD3-SDA)].
Métododelasumadelosdígitosdelosaños
Findeaño
Findeaño
Findeaño
Findeaño
Findeaño
Findeaño
1
2
3
4
5
6
DepreciacIón:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
Depreciación:
1454.55 1309.09
1163.64 1018.18
872.73
727.27
ValoraCtual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
Valoractual:
6545.45
5236.36
4072.73
3054.55
2181.82
1454.55

240 PROGRAMACiÓN ENC
Findeaño7Depreciación:581.82Valoractual:
Findeaño8Depreciación:436.36Valoractual:
Findeaño9Depreciación:290.91Valoractual:
Findeaño10Depreciación:145.45Valoractual:
872.73
436.36
145.45
0.00
¿Máscálculos?(SIN).§.
¿Introducirunnuevoconjuntodedatos?.§.
Valororiginal:5000
Númerodeaños:~
Método:(l-LR2-BDD3-SDA)1.
Métododelínearecta
Findeaño1Depreciación:1250.00Valoractual:
Findeaño2Depreciación:1250.00Valoractual:
Findeaño3Depreciación:1250.00Valoractual:
Findeaño4Depreciación:1250.00Valoractual:
3750.00
2500.00
1250.00
0.00
¿Máscálculos?(SIN).§.
¿Introducirunnuevoconjuntodedatos?n
Método:(l-LR2-BDD3-SDA)2.
Métododebalancedoblementedeclinante
Findeaño1Depreciación:2500.00Valoractual:
Findeaño2Depreciación:1250.00Valoractual:
Findeaño3Depreciación:625.00Valoractual:
Findeaño4Depreciación:312.50Valoractual:
2500.00
1250.00
625.00
312.50
¿Máscálculos?(SIN)n
Hastaluegoyquetengaunbuendía
Observequesehanprocesadodosconjuntosdiferentes dedatosdeentrada.Ladepreciaciónpara elprimer
conjuntosecalculautilizandolostresmétodos,
yparaelsegundoconjuntoutilizandosólolosdosprimeros.
Portanto,noesnecesarioreintroducirlosdatosdeentradaparasimplementerecalcularladepreciación
utilizandounmétododiferente.
Losargumentosarraysepasandeformadiferentequeloselementosconunúnicovalor.Si
seespecificaelnombredeunarraycomoargumentoreal,nosehaceunacopiaparalafunción
deloselementosdelarray.Enlugar
deesto,loquesehaceespasaralafunciónla posicióndel
array(laposicióndelprimerelemento).Siseaccedeaunelementodelarraydentrodelafun­
ción,elaccesoharáreferenciaalaposicióndeeseelementodelarrayconrelaciónalaposición
delprimerelemento.
portanto,cualquieralteracióndeunelementodelarraydentro delafun­
ciónafectaráa
larutinaquehizolallamada. DiscutiremosestoconmásdetalleenelCapítulo 9,
cuandotratemosformalmente
.losarrays.

FUNCIONES 241
Tambiénsepuedenpasarcomoargumentosaunafunción otrostiposdeestructuras dedatos.
Discutiremoslatransferenciadetalesargumentosencapítulosposteriores,cuandoseintroduz­
canestructuras
dedatosadicionales.
7.6.RECURSIVIDAD
Sellamarecursividadaunprocesomedianteelqueunafunciónsellamaasímismadeforma
repetida,hastaquesesatisfacealgunacondicióndeterminada.Elprocesoseutilizaparacálculos
repetitivosenlosquecadaacciónsedeterminaenfuncióndeunresultadoanterior.
Sepueden
escribirenestaformamuchosproblemasiterativos(repetitivos).
Sedebencumplirdoscondicionesparaqueunproblemasepuedaresolverrecursivamente.
Primero,elproblemasedebeescribirenformarecursiva,
ysegundo,laespecificacióndelproble­
madebeincluirunacondicióndefin.Supongamos,porejemplo,quedeseamoscalcularelfactorial
deunacantidad enterapositiva.Expresaríamosnormalmenteelproblemaasí:
n!=1 x 2 x 3 x
x...x
n,endondeneselenteropositivoespecificado(verEjemplo7.5).Sinembargo,podemos
tambiénexpresarelproblemadeotraforma,escribiendo
n!=nx(n-l)!Éstaeslaforma
recursiva,enlaquelaaccióndeseada(elcálculo
den!)seexpresaentérminos deunresultado
anterior[elvalor
de(n-1)!,quesesuponeconocido].Tambiénsabemosque l!=1pordefini­
ción.Estaúltimaexpresiónproporcionaunacondicióndefinparaelprocesoresursivo.
EJEMPLO7.14.Cálculodefactoriales. EnelEjemplo7.10vimosdosversionesdeunprogramaque
calculabaelfactorial
deunacantidaddada,utilizandounafunciónnorecursivaqueseocupabaderealizar
loscálculosensí.Heaquíunprogramaquerealizaelmísmocálculo
deformarecursiva.
/*calcularelfactorialdeunacantidadenterautilizandorecursi­
vidad* /
#include<stdio.h>
longintfactorial(intn);
main()
{
intni
/*prototipodefunción*/
/*leerlacantidadentera*/
printf(IIn=U);
scanf("%d",&n);
/*calcularyvisualizarelfactorial*/
printf("n!=%ld",factorial(n));
}

242 PROGRAMACiÓN ENC
longintfactorial(intn)
{
/*calcularelfactorial*/
if(n<=1)
return(1);
else
return(n*factorial(n-1));
}
Lapartemaindelprogramasimplementeleelacantidadentera nyllamaacontinuaciónalafunción
factorial.(Recuerdequeutilizamosenteroslargosparaestecálculoporquelosfactorialessoncanti­
dadesenterasmuygrandes,aunparavalorespequeñosde
n.)Lafunciónfactorialsellamaasímisma
recursivamente,conunargumentoreal
(n-1)quedecreceencadallamadasucesiva.Lasllamadasrecur­
sivasterminancuandoelvalordelargumentorealsehaceiguala
1.
Observequeestaformade lafunciónfactorialesmássencillaquelamostradaen elEjem­
plo7.10.Lacorrespondenciaentre estafunciónyladefiniciónoriginaldelproblema,entérminosrecursi­
vos,deberesultarinmediata.Enparticular,observeque
lainstrucciónif -e1s eincluyeunacondición
determinaciónquesecumplecuandoelvalorde
nesmenoroiguala 1.(Tengaencuentaqueelvalorde
nnuncaserámenorque 1,amenosqueseintroduzcaenlacomputadoraunvalorinicialinadecuado.)
Cuandoseejecutaelprograma,seaccedealafunción
factorialrepetidamente,unavezen main
y(n-1)veces.desdedentrodeellamisma,aunque lapersonaqueutiliceelprogramanosedarácuentade
esto.Sólosevisualizará
larespuestafinal,porejemplo,
n
=JJl
n!=3628800
Cuandoseejecutaunprogramarecursivo,lasllamadasrecursivasnoseejecutaninmediata­
mente.Loquesehaceescolocarlasenunapilahastaqueseencuentralacondicióndetermina­
cióndelarecursividad*.Entoncesseejecutanlasllamadasalafunciónenordeninversoa
comosegeneraron,comosisefueran«sacando»delapila.Portanto,cuandoseevalúaun
factorialrecursivamente,lasllamadasalasfuncionessegeneraránenelsiguienteorden.
n!=nx(n-l)!
(n-l)!=(n-l)x(n-2)!
(n-2)!
=(n-2)x(n-3)!
2!=2xl!
*Unapilaesunaestructura«lasí-in,first-out»(últimoen entrar,primeroensalir)en laquelosdatossucesivos
se«colocanencima» delosanteriores.Losdatosse«sacan»despuésenordeninverso delapila,comoindicala
designación«last-in,first-out».

FUNCIONES 243
Losvaloresrealessedevolveránenordeninverso, esdecir,
1!= 1
2!=2x1!=2x1=2
3!= 3 x2!= 3 x 2 = 6
4!= 4 x3!= 4 x 6 =24
n!=nx(n-1)!=...
Elordeninverso deejecuciónesunacaracterísticatípicadetodaslasfuncionesrecursivas.
Siunafunciónrecursivacontienevariableslocales,secrearáunconjunto
diferentedevaria­
bleslocalesdurantecadallamada.Losnombres
delasvariableslocalesserán,porsupuesto,siem­
prelosmismos,comosehayandeclaradoenlafunción.Sinembargo,lasvariablesrepresentarán
unconjuntodiferente
devalorescadavezqueseejecutelafunción.Cadaconjunto devaloresse
almacenaráenlapila;asísepodrádisponer
deellascuandoelprocesorecursivose«deshaga»,es
decir,cuandolasllamadasalafunciónse«saquen»delapila
yseejecuten.
EJEMPLO7.15.Escriturainversa. Elsiguienteprogramaleeunalíneadetextocarácteracarácter y
escribeloscaracteresenordeninverso.Elprogramautilizarecursividadpara laescriturainversa.
/*leerunalíneadetextoyescribirlaenordeninversoutilizando
recursividad* /
#include<stdio.h>
#defineEOLN''
voidinverso(void);
main()
(
/*prototipodefunción*/
printf("Introduceunalíneadetextodebajo");
inverso();
}
voidinverso(void)
/*leerunalíneadecaracteresyescribirlaen
ord~ninverso*/
{
char'ci
if((c=getchar(»)!=EOLN)inverso();
putchar(c);
return¡
}

244 PROGRAMACiÓN ENC
Lafunciónmainenesteprogramasimplemente seocupadepresentarunrótulo yllamaralafunción
inverso,iniciandoelprocesorecursivo.Lafunciónrecursiva inversoprocedeentoncesaleercarac­
tereshastaqueseencuentrelacondiciónfinaldelínea
().Cadallamadaaestafunciónhacequese
introduzcaenlapilaunnuevocarácter(unvalornuevode
c).Unavezqueseencuentraelfinaldelalínea,
sesacanloscaracteresdelapila
ysevisualizanenlaforma <<1ast-in,first-out»(últimoenentrar,primero
ensalir).Deestaforma,loscaracteressevisualizandeformainversaacomoseintrodujeron.
Supongamosqueseejecutaelprograma
yseintroducelasiguientelínea:
Tumiradamerecuerdaelfulgordelaaurora
Lasalidacorrespondienteserá
aroruaaledroglufleadreuceremadarimuT
Algunasvecessepuedeescribirrecursivamenteundeterminadoprocesorepetitivodeforma
muyconcisa,aunquelalógicasubyacentepuederesultardedifícilcomprensión.
EJEMPLO7.16.LasTorresdeHanoi. LasTorresdeHanoi sonunconocidojuegodeniños,quese
juegacontrespivotes
yunciertonúmerodediscosdediferentestamaños.Losdiscostienenunagujeroen
elcentro,conloquesepuedenapilarencualquieradelospivotes.Inicialmente,losdiscosseamontonan
enelpivotedelaizquierda
portamañodecreciente,esdecir,elmásgrandeabajo yelmáspequeñoarriba,
comoseilustraenlaFigura7.1.
Elobjetodeljuegoesconseguirllevarlosdiscosdelpivotemásalaizquierdaaldemásaladerecha,
sincolocarnuncaundiscosobreotromáspequeño.Sólosepuedemover
undiscocadavez, ycadadisco
debeencontrarsesiempreenunodelospivotes.
II
I
2I
I
3I
I
4 I
I
Izquierda
-
Centro
Figura7.1.
.
-
Derecha
I

FUNCIONES 245
Laestrategiageneralaseguiresconsiderarunodelospivotescomoorigenyelotrocomodestino.El
tercerpivoteseutilizaráparaalmacenamientoauxiliar,conloquepodremosmoverlosdiscossinponer
ningunosobreotromáspequeño.Supongamosquehayndiscos,numeradosdelmáspequeñoalmás
grande,comoenlaFigura7
..1.Silosdiscosseencuentranapiladosinicialmenteenelpivoteizquierdo,el
problemademoverlosndiscosalpivotederechosepuedeformulardelasiguienteformarecursiva:
1.Moverlos n-ldiscossuperioresdelpivoteizquierdoaldelcentro.
2.Movereln-ésimodisco(elmásgrande)alpivotedeladerecha.
3.Moverlos
n-ldiscosdelpivotedelcentroaldeladerecha.
Elproblemasepuederesolverdeestamaneraparacualquiervalorde
nmayorqueO
(n~Orepresentala
condicióndefin).
Convistasalaredaccióndelprograma,primeroetiquetaremoslospivotes,deformaqueelpivote
izquierdoserepresentará
porl,eldelcentro poreyelderechopor D.Construiremosentoncesunafun­
ciónrecursivallamada
transferirquetransferirándiscosdeunpivoteaotro.Refirámonosalos
pivotesorigen,destinoydealmacenamientotemporalconlasvariables
desde,haciaytemp,respec­
tivamente.Comoresultadodeesto,siasignamoselcarácter
ladesde,D ahaciayeatemp,estare­
mosespecificandoelmovimientode
ndiscosdelpivoteizquierdoalderecho,utilizandoelpivotedel
centroparaalmacenamientointermedio.
Conestanotación,laestructuradelafunciónserá:
voidtransferir(intn,chardesde,charhacia,chartemp)
/* n=númerodediscos
desde=origen
hacia=destino
temp=almacenamientotemporal*/
{
if(n>O){
/*movern-ldiscosdesdesuorigenhastaelpivotetemporal*/
/*movereln-ésimodiscodesdesuorigenhastasudestino*/
/*movern-ldiscosdesdeelpivotetemporalhastasudestino*/
}
}
Latransferenciadelos n-ldiscossepuederealizarmedianteunallamadarecursivaa transferir.
Portanto,podemosescribir
transferir(n-l,desde,temp,hacia);
paralaprimeratransferencia,y
transferir(n-l,temp,hacia,desde);
paralasegunda.(Observe elordendelosargumentosencadallamada.)Elmovimientodeldiscon-ésimo
delorigenaldestinosimplementerequiereescribirlosvaloresencursode
desdeyhacia.Lafunción
completasepuedeescribircomosigue:

246 PROGRAMACiÓN ENC
voidtransferir(intn,chardesde,charhacia,chartemp)
/*transferirndiscosdeunpivoteaotro*/
/* n
~númerodediscos
desde
~origen
hacia
~destino
temp
~almacenamientotemporal*/
{
if(n>O){
/*movern-ldiscosdesdesu
transferir(n-l,desde,temp,
origenhastaelpivotetemporal*/
hacia);
}
/*movereln-ésimodiscodesdesuorigenhastasudestino*/
printf("Moverdisco%ddesde%chasta%c",n,desde,hacia);
/*movern-ldiscosdesdeelpivotetemporalhastasudestino*/
transferir(n-l,temp,hacia,desde);
}
return¡
Elañadirlaparte maindelprogramaesyaunacuestiónsencilla,simplemente sedebeleerelvalor
den einiciarloscálculosllamandoa transferir.Enestaprimerallamadaa lafunciónlosparámetros
reales
seespecificancomoconstantes decarácter,estoes,
transferir(n,/1','D','e');
Estallamadaafunciónespecificalatransferencia dendiscosdelpivote delaizquierda(elorigen) aldela
derecha(eldestino),utilizandoelpivotedelcentroparaalmacenamientoauxiliar.
Heaquíelprogramacompleto.
/*lasTORRESDEHANOI-resoluciónutilizandorecursividad*/
#include<stdio.h>
voidtransferir(intn,chardesde,charhacia,chartemp);
/*prototipodefunción*/
main()
{
intn;
printf("BienvenidoalasTORRESDEHANOI");
printf
(11¿Cuantosdiscos?11);
scanf("%d",&n);
printf("");
transferir(n
r/1'I'D',le');
}
voidtransferir(intn,chardesde,charhacia,chartemp)

FUNCIONES 247
/*transferirndiscosdeunpivoteaotro*/
/*n =númerodediscos
desde=origen
haciadestino
temp=almacenamientotemporal*/
{
if(n>O){
/*movern-ldiscosdesdesuorigenhastaelpivotetemporal*/
transferir(n-l,desde,temp,hacia);
/*movereln-ésimodiscodesdesuorigenhastasudestino*/
printf("Moverdisco%ddesde%chasta%c",n,desde,hacia);
/*movern-ldiscosdesdeelpivotetemporalhastasudestino*/
transferir(n-l,temp,hacia,desde);
}
return;
}
Debequedarclaroquelafunción t ransferi rrecibeunconjuntodiferente devaloresdesusargu­
mentoscadavezquesellamaalafunción.Esteconjunto
devaloressealmacenaráenlapiladeformaque
cadaconjuntoesindependientedelosotros.Durantelaejecucióndelprogramasesacanasudebido
tiempodelapila.Eslacapacidaddealmacenar
yrecuperarestosconjuntosindependientesdevalores lo
quepermitequefuncioneelprocesorecursivo.
Cuando
seejecutaelprogramaparaelcasoenque n=3,seobtienelasiguientesalida:
BienvenidoalasTORRES DERANOI
¿Cuantosdiscos?
.3-
Moverdisco1desdeIhastaD
Moverdisco2desdeIhastaC
Moverdisco1desdeDhastaC
Moverdisco3desdeIhastaD
Moverdisco1desdeChastaI
Moverdisco2desdeChastaD
Moverdisco1desdeIhastaD
Estudiardetenidamenteestosmovimientosparacomprobarquelasoluciónescorrecta.Lalógicadel
programaescomplicadaapesar
desuaparentesencillez.
VeremosotroejemplodeprogramaciónqueutilizalarecursividadenelCapítulo11,cuando
tratemoslaslistasenlazadas.
Eluso
delarecursividadnoesnecesariamentelamejoraproximaciónaunproblema,aunque
ladefinicióndelproblemasearecursiva.Unaimplementaciónnorecursivapuedesermásefi­
ciente,encuantoautilizacióndememoria
yvelocidaddeejecución.Comoconclusión,eluso de
larecursividadpuedeinvolucraruncompromisoentresimplicidad yrendimiento.Cadaproble­
masedebejuzgarindividualmenteteniendoencuentasuscaracterísticasespecíficas.

248 PROGRAMACiÓN ENC
7.1.
7.2.
7.3.
7.4.
7.5.
7.6.
7.7.
7.8.
7.9.
7.10.
7.11.
7.12.
7.13.
7.14.
7.15.
7.16.
7.17.
7.18.
7.19.
7.20.
7.21.
7.22.
¿Quéesunafunción?¿Serequierelautilización defuncionesalescribirunprogramaenC?
Citartresventajasdelautilización
defunciones.
¿Quéseentiendeporunallamadaaunafunción?¿Desdequépartesdeunprogramase
puedellamaraunafunción?
¿Quésonlosargumentos?¿Cuál
essupropósito?¿Quéotrotérminoseutilizaavecesen
lugar
deargumento?
¿Cuál
eslafinalidaddela
instrucCiónreturn?
¿CuálessonlasdosprincipalescomponentesdeunadefinicióndefunCión?
¿Cómoseescribelaprimeralínea deunadefinicióndefunción?¿Cuáleselpropósitode
cadaelementoocadagrupodeelementos?
¿Quésonlosargumentosformales?¿Quésonlosargumentosreales?¿Cuál
eslarelación
entreambostiposdeargumentos?
Citarotrostérminosqueseutilizanenlugar
deargumentoformal yargumentoreal.
¿Puedencoincidirlosnombresdelosargumentosformalesdentrodeunafunciónconlos
nombresdeotrasvariablesdefinidasfueradelafunción?Explicarlo.
¿Puedencoincidirlosnombresdelosargumentosformalesdentrodeunafunciónconlos
nombres
deotrasvariablesdefinidasdentrodelafunción?Explicarlo ycompararlares­
puestaconlaúltimapregunta.
Citarlasreglas relacionadasconelusodelainstrucción
return.¿Sepuedenincluir
variasexpresionesenuna
instrucCiónreturn?¿Sepuedenincluirvariasinstrucciones
returnenunafunción?
¿Quérelacióndebeexistirentreeltipo
dedatosqueaparecealcomienzodelaprimera
línea
deladefinicióndeunafunciónyelvalordevueltoporlainstrucción return?
¿Porquésepuedeincluirunainstrucción returnenunafunciónquenodevuelvenin­
gúnvalor?
¿Cuáleslafinalidaddelapalabrareservada
vaid?¿Dóndeseutilizaestapalabra
reservada?
Citarlasreglasrelacionadasconlallamadaafunciones.¿Quérelacióndebeexistirentre
losargumentosreales
ylosformalescorrespondientesen ladefinicióndelafunción?¿Es­
tánsujetosalasmismasrestriccioneslosargumentosrealesquelosformales?
¿Sepuedellamaraunafuncióndesdemásdeunlugarenunprograma?
¿Quésonlosprototiposdefunciones?¿Cuálessupropósito?¿Dóndesecolocannormal­
mentelosprototipos
defuncionesenunprograma?
Citarlasreglasasociadasconlosprototipos
defunciones.¿Cuáleslafinalidad decada
elementoogrupo
deelementos?
¿Cómoseespecificanlostiposdedatosdelosargumentosenunprototipo
defunción?
¿Quésentidotieneelincluirlostiposdedatos
delosargumentosenunprototipo defunción?
Cuandoseaccedeaunafunción,¿debencoincidirlosnombresdelosargumentosreales
conlosnombresdelosargumentosenelcorrespondienteprototipodefunción?
Suponerquelafunción
Flllamaalafunción F2dentrodeunprogramaen C.¿Tiene
importanciaelordenenelquesedefinanlasfunciones?Explicarlo.

FUNCIONES 249
7.23.Describirlafonnaenquelosargumentosrealespasaninfonnaciónaunafunción.¿Qué
nombreseasociaaesteproceso?¿Cuálessonlasventajaseinconvenientes
depasarlos
argumentos
deestamanera?
7.24.¿Quédiferenciashayentrepasarunarrayaunafunciónypasarundatosimpleauna
función?
7.25.Suponerquesepasaunarrayaunafuncióncomoargumento.Sidentro
delafunciónse
alteraelvalor
deunelementodelarray,¿sereconoceráestecambioenlapartedelpro­
gramaquellamóalafunción?
7.26.¿Quéeslarecursividad?¿Quéventajastienehaceruso
deella?
7.27.Explicarporquéalgunosprogramaspuedenserresueltosconosinrecursividad.
7.28.¿Quéesunapila?¿Enquéordenseañadeyeliminainfonnacióndelapila?
7.29.Explicarloquesucedecuandoseejecutaunprogramaquecontienellamadasrecursivas,
enténninosdelainfonnaciónañadidaoeliminadadelapila.
7.30.Cuandoseejecutaunprogramaquecontienellamadasrecursivas,¿cómoseinterpretan
lasvariableslocalesdentrodeunafunciónrecursiva?
7.31.Siseprogramarecursivamenteunprocesoiterativo,¿seránecesariamentemáseficiente
elprogramaqueelcorrespondienteaunaversiónnorecursiva?
7.32.Explicar
elsignificadodecadaunodelossiguientesprototipos defunciones.
a)intf(inta);
b)doublef(doublea,intb);
e)voidf(longa,shortb,unsignede);
d)eharf(void);
e)unsignedf(unsigneda,unsignedb);
7.33.Cada unadelassiguienteslíneas eslaprimeralínea deunadefinicióndefunción.Explicarel
significadodecadauna.
ofloatf(floata,floatb)
b)longf(longa)
e)voidf(inta)
d)eharf(void)
7.34.Escribir unallamadaafunción(accesoafunción)apropiadaparacadaunadelassiguientesfunciones.
a)floatformula(floatx)
{
floaty;
y=3*x -1;
return(y);
}

250 PROGRAMACiÓN ENC
~voideseribe(inta,intb)
(
inte;
e=sqrt(a*a+b*b);
printf("e=%i",e);
}
7.35.Escribirlaprimeralíneadeladefinicióndelafunción,incluyendolasdeclaracionesdelosargu­
mentosformales,paracadaunadelassituacionesquesedescribenacontinuación.
a)Unafunciónllamada muestrageneraydevuelveunacantidadentera.
b)Unafunciónllamada raizaceptadosargumentosenterosydevuelveunresultado encoma
flotante.
c)Unafunciónllamada convertiraceptauncarácterydevuelveuncarácter.
el)Unafunciónllamada transferiraceptaunenterolargoydevuelveuncarácter.
e)Unafunciónllamada inversaaceptauncarácterydevuelveunenterolargo.
1)Unafunciónllamada procesaraceptaunenteroydoscantidades encomaflotante(eneste
orden)ydevuelveunacantidad
endobleprecisión.
g)Unafunciónllamada valoraceptadoscantidades endobleprecisiónyunenterocorto(en
esteorden).Lascantidadesdeentradaseprocesanparagenerarunvalordedobleprecisiónque
seescribecomoresultadofinal.
7.36.Escribirprototiposdefuncionesadecuadosparacadaunodelosesquemasquesemuestranacon­
tinuación.
a)main( )
(
inta,b,c;
e=funel(a,b);
}
intfunel(intx,inty)
(
intZi
z
;;;; .I
return(z);
}
b)main()
{
doublea,b,e;
e=funel(a,b);
}

doublefunel(doublex,doubley)
{
doublez;
z=..f
return(z);
}
elmain()
{
inta¡
floatb;
longinte;
e=fune1(a,b);
}
longintfune1(intx,floaty)
{
longintZi
Z=..i
return(z);
}
el)main()
{
doublea,b,e,d;
e=fune1(a,b);
d=fune2(a+b,a+e);
}
doublefune1(doublex,doubley)
{
doublez;
z=10*fune2(x,y);
return(z);
}
doublefune2(doublex,doubley)
{
doublez;
FUNCIONES 251
z= . .,
return(z);
}

252 PROGRAMACiÓN ENC
7.37.Describirlasalidageneradaporcadaunodelossiguientesprogramas:
a)#include<stdio.h>
intfuncl(intcont);
main()
{
inta,cont¡
for(cont~1;cont<~5;++cont)(
a ~funcl(cont);
printf("%d",a);
}
}
intfuncl(intx);
{
intYi
y=x*Xi
return(y);
}
b)Escribirelprogramaanteriordealgunaformamásconcisa.
e)#include<stdio.h>
intfuncl(intn);
main( )
{
intn
~la;
printf("%d",funcl(n)) ;
}
intfuncl(intni;
{
if(n>O)return(n+funcl(n-1));
}
ti)#include<stdio.h>
intfuncl(intn);
main( )
{
intn ~10;
printf("%d",funcl(n)) ;
}

FUNCIONES 253
intfuncl(intn);
{
if(n>O)return(n+funcl(n-2));
}
7.38.Expresarcadaunadelassiguientesfórmulasdeformarecursiva:
a)y~(Xl+X,+'"+X")
b)Y =I -X+x'/2-x
3
/6+.0/24+...+(-I)"x"/n!
e)p=r.¡;*f,*...*J;J
7.39.Escribirunafunciónquecalcule ypresentelasraices realesde laecuacióndesegundogrado
ax'+bx+e=O
utilizandolafórmula
- b±(b'-4aeJl/'
X~-------
2a
Suponerque a,by esonargumentosencomaflotanteconvaloresdadosyque XlyqueX,son
variablesencomaflotante.Suponertambiénque
b'>4*a*e,deformaquelasraicescalculadasson
siemprereales.
7.40.Escribir
unprogramacompletoenCquecalcule
lasraícesdelaecuacióndesegundogrado
ax'+bx+e~O
utilizandolafórmulacuadráticaquesedescribióenelproblemaanterior.Leerloscoeficientesa, b
yeenlafunciónmain.Accederacontinuaciónalafunciónescritaparaelproblemaanteriorpara
conseguir
lasolucióndeseada.Finalmente,escribirlosvaloresdeloscoeficientes,seguidosdelos
valorescalculadosde
XlyX,.Asegurarsedeque lasalidaaparececonrótulosclaros.
Comprobarelprogramaconlossiguientesdatos:
ª
2
3
I
Q
6
3
3
1
O
1
7.41.ModificarlafunciónescritaparaelProblema7.39deformaquesecalculen todaslasraícesdela
ecuacióndesegundogrado
ax'+bx+e=O

254 PROGRAMACiÓN ENC
habiendodadolosvaloresde a,byc.Observarquelasraicesestaránrepetidas(sólohabráunaraiz
real)si
b'=4*a*c.Además,lasraicesseráncomplejassi b
2
<4*a*c.Enestecasolaparterealde
cadaraízesiguala
-b/(2*a)
ylaspartesimaginariassecalculancon
endonde
irepresenta(-1)1/2.
7.42.Modificar elprogramaenCescritoparaelProblema7.40 deformaquesecalculen todaslasraíces
delaecuación
desegundogrado
a.x
2
+bx+c=0
utilizandolafunciónescritaenelProblema7.41.Asegurarse dequetodalasalidaseacompaña de
rótulosclaros.Comprobarelprogramautilizandolossiguientesdatos:
ª
º
!2
2 6 l
3 3 O
1 3 1
O 12 -3
3 6 3
2-4 3
7.43.Escribirunafunciónquepermitaelevarunnúmeroencomaflotanteaunapotenciaentera.Enotras
palabras,deseamosevaluarlafórmula
y=x
n
endondeyyxsonvariablesencomaflotante ynunavariableentera.
7.44.EscribirunprogramacompletoenCquelealosvalores
dexyn,evalúelafórmula
y=x
n
utilizandolafunciónescritaenelProblema7.43 yescribaacontinuaciónelresultado.Comprobar
elprogramautilizandolossiguientesdatos:
.I ll. .I ll.
2 3 1.53
212
1.510
2-5 1.5
-5
-3 3 0.2 3
-3 7 0.25
-3 -5 0.2-5
7.45.AmpliarlafunciónescritaparaelProblema7.43paraquesepuedan elevarvalorespositivos dexa
cualquierpotencia,enteraoencomaflotante. (Sugerencia:utilizarlafórmula
y=xN=e<nlnx)
Recordarincluirunacomprobacióndequeelvalorde xseaadecuado.)

FUNCIONES 255
Incluirestafunciónen elprogramaescritoparaelProblema7.44.Comprobarelprogramauti­
lizandolosdatosdadosenelProblema7.44Ylossiguientesdatosadicionales:
K II K II
20.2 1.50.2
2
-0.8 1.5-0.8-30.2 0.20.2
-3-0.8 0.2-0.8
0.20.0
7.46.Modificarelprogramaparacalcularlasolucióndeunaecuaciónalgebraica,dadoenelEjemplo
6.22,deformaquecadaiteración
serealiceenunafunción.Compilaryejecutarelprogramapara
asegurarsedequefuncionacorrectamente.
7.47.ModificarelprogramadelEjemplo6.17parahacerlamedia deunalistadenúmeros,deformaque
hagausodefuncionesparaleernúmerosydevolversusuma.Comprobarelprogramautilizando
lossiguientesdieznúmeros:
27.5 87.0
13.4 39.9
53.8 47.7
29.2 8.1
74.5 63.2
7.48.ModificarelprogramadelEjemplo5.2paracalcularelinteréscompuestodeformaqueloscálcu­
losserealicenen
unafuncióndefinidaporelprogramador.Escribirlafuncióndeformatalquelos
valoresde
P,rynsepasencomoargumentosysedevuelvaelvalorcalculadode F.Comprobarel
programautilizandolossiguientesdatos:
E. 1:- II
1000 6 20
1000 6.25 20
333.33 8.75 20
333.33 8.75 22.5
7.49.Paracadaunodelossiguientesproblemas,escribirunprogramacompletoenCqueincluyauna
funciónrecursiva.
a)LospolinomiosdeLegendresepuedencalcularmediantelasfórmulas Po=1,PI=X,
P,=[(2n-I)/n]xP'_I-[en-I)ln]P,_,
endonden=2,3,4,oo.,yxesunnúmeroencomaflotanteentre -1y1.(Advertirquelos
coeficientesdelospolinomiosdeLegendresoncantidadesencomaflotante.)
Generarlos
nprimerospolinomios.Losvaloresde nyxdebenserparámetrosdeentrada.
b)Determinarlasuma dennúmerosencomaflotante[verProblema 7.38(a)].Leerunnuevo
número
encadallamadaaunafunciónrecursiva.

256 PROGRAMACiÓN ENe
e)Evaluarlos nprimerostérminosdelasseriesespecificadasenelProblema 7.38(b).Introducirn
comoparámetro deentrada.
d)Determinarelproductode nnúmerosencomaflotante[verProblema 7.38(c)].Leerunnuevo
númerodurantecadallamadaaunafunciónrecursiva.
AlfinaldelCapitulo8sepuedenencontrarotrosproblemasdeprogramaciónreferentesaluso
de
funciones.

CAPíTULO8
Estructuradeunprograma
Estecapítuloconsideravariostemasasociadosconlaestructura deprogramasqueconstan de
másdeunafunción.Trataremosenprimerlugarladiferenciaentrevariables«locales»queson
reconocidassolamentedentrodeunafunción,yvariables«globales»quesonreconocidasendos
omásfunciones.Enestecapítuloseverácómodefiniryutilizarvariablesglobales.
Además,seconsideraelproblema
delaretencióndeinformaciónestáticaodinámicame­
dianteunavariablelocal.Unavariablelocalnormalmentenoconservasuvalorunavezqueel
controldelprogramasehatransferidofuera
desufuncióndedefinición.Sinembargo,aveces
interesaquealgunasvariablesretengansusvalores
demodoquesepuedavolvermástardeala
funciónyreanudarelcómputo.
Finalmente,puederesultarinteresantedesarrollarunprogramamultifuncióngrandeentérmi­
nosdevariosarchivosindependientes,conunnúmeropequeño
defunciones(quizásunasola)
definidasdentrodecadaarchivo.Entalesprogramaslasfuncionesindividualespuedenserdefi­
nidasyaccedidaslocalmentedentrodeunarchivo,oglobalmentedentrodemúltiplesarchivos.
Estoessimilaraladefiniciónyeluso
devariableslocalesversusglobalesenunprogramamul­
tifuncióndeunúnicoarchivo.
8.1.TIPOSDEALMACENAMIENTO
Yasehamencionadoquehaydosformasdiferentesdecaracterizarvariables: porsutipo
dedatos
yportipodealmacenamiento (versección2.6).Eltipodedatosserefierealtipode
informaciónrepresentadaporunavariable,porejemplo,unnúmeroentero,unnúmeroenco­
maflotante,uncarácter,etc.Eltipo
dealmacenamientoserefierealapermanenciadelavaria­
bley asu
ámbitodentrodelprograma,queeslapartedelprogramaenlaquesereconocela
variable.
Haycuatroespecificacionesdiferentes
detipodealmacenamientoen C:automática,externa,
estática
yregistro.Estánidentificadasporlassiguientespalabrasreservadas autu,extern,
staticyregister,respectivamente.Enestecapítulosetrataránlostiposdealmacena­
miento
automático,externo yestático.Eltipodealmacenamientoregistrosediscuteenlasec­
ción13.1.
Avecessepuedeestablecereltipo
dealmacenamientoasociadoaunavariablesimplemente
porlaposicióndesudeclaraciónenelprograma.Enotrassituaciones,sinembargo,lapalabra
reservadaqueespecificauntipoparticular
dealmacenamientosetienequecolocaralcomienzo
deladeclaración
delavariable.
257

258 PROGRAMACiÓN ENC
EJEMPLO8.1.
Acontinuaciónsemuestranvariasdeclaracionestípicas devariablesqueincluyenla
especificacióndeuntipodealmacenamiento.
autointa,b,c¡
externfloatraizl,raiz2¡
staticintcont=
O;
externcharasterisco;
Laprimeradeclaraciónestablece quea,b ycsonvariablesenterasautomáticas,ylasegunda queraizl
yraiz2sonvariablesencomaflotanteexternas. Laterceradeclaraciónestablece quecontesunava­
riableenteraestática devalorinicial0,yenlaúltimadeclaración seestableceasteriscocomouna
variableexterna
detipocarácter.
Elprocedimientoexactoparaestablecereltipodealmacenamientoparaunavariabledepende
deltipoparticulardealmacenamientoydelamanera
enqueestáorganizadoelprograma(archi­
vosimplefrenteamúltiplesarchivos).Consideraremosestasreglas
enlassiguientessecciones
delcapítulo.
8.2.VARIABLESAUTOMÁTICAS
Lasvariablesautomáticas sedeclaransiempredentrodelafunciónysonlocalesalafunción
dondehansidodeclaradas;esdecir,
suámbitoestáconfinadoaesafunción.Lasvariablesauto­
máticasdefinidas
enfuncionesdiferentesseránindependientesunasdeotras,inclusositienenel
mismonombre.
Cualquiervariabledeclaradadentrode
unafunciónseinterpretacomounavariableautomá­
ticaamenosqueseincluyadentrodeladeclaraciónuntipodistintodealmacenamiento.Esto
incluye
ladeclaracióndeargumentosformales.Todaslasvariablesencontradasenlos ejemplos
deloscapítulosanterioreshansidovariablesautomáticas.
Comolalocalizaciónde
ladeclaraciónde lavariabledentrodelprogramadeterminaeltipo
dealmacenamientoautomático,nosenecesita
lapalabrareservada autoalprincipiodecada
declaracióndevariable.No
hayproblemaparaincluirlaespecificación autodentrodeuna
declaraciónsielprogramadorlodesea,peronormalmentenosehace.
EJEMPLO8.2. Cálculodefactoriales. Consideremosdenuevoelprogramaparacalcularfactoriales,
mostradooriginalmente
enelEjemplo7.10.Dentrodemain,nesunavariableautomática.Dentro de
factorial,iyprod,asícomoelargumentoformaln,sonvariablesautomáticas.
Ladesignación
deltipodealmacenamientoautopodríahaberseincluidoexplícitamente enlasdecla­
raciones
delasvariablessisehubieradeseado. Asíelprogramapodríahaberseescrito comosígue:
/*calcularelfactorialdeunacantidadentera*/
#include<stdio.h>
longintfactorial(intn);

ESTRUCTURA DEUNPROGRAMA 259
main()
{
autointn;
/*leerlacantidadentera*/
printf(l1n II)¡
scanf(lI%d
n
I&n);
/*calcularyvisualizarelfactorial*/
printf("n! =%ld",factorial(n)) ;
}
longintfactorial(autointn)
{
autointi;
autolongintprod=1;
if(n>1)
for(i=2;i<=n;++i)
prod*=i¡
return(prod);
}
/*calcularelfactorial*/
Cualquieradelosmétodosesaceptable.Sinembargo,comoregla,ladesignación autonoseincluyeen
lasdeclaraciones
devariablesoargumentosformales,yaque eseltipodealmacenamientoporomisión.De
estemodo,elprogramadelEjemplo
7.10presentaunestilo deprogramaciónmásusual.
Se
puedenasignarvaloresinicialesalasvariablesautomáticasincluyendolas expresiones
adecuadasdentro deladeclaracióndevariables,comoenelejemploanterior,o porasignación
explícitadeexpresionesencualquierpartedelafunción.Talesvaloressereasignarán cadavez
queseentreenlafunción.Si unavariableautomática noesinicializadadealgunamanera, su
valorinicialseráimpredecible yprobablementeincomprensible.
Unavariableautomática nomantienesuvalorcuando setransfiereelcontrolfuerade la
funciónenqueestádefinida. Portanto,cualquier valorasignadoa unavariableautomáticaden­
tro
deunafunciónseperderáunavezquesesaledelafunción.Si lalógicadel programarequiere
que
unvalorparticularseaasignadoa unavariableautomáticacadavezqueseejecuta lafunción,
ese
valortendráquereasignarsecadavezqueseentre enlafunción(siemprequese accedaala
función).
EJEMPLO8.3.LongitudmediadevariasIíueasdetexto.Escribamosacontinuaciónunprograma
enCqueleavariaslíneas
detextoydetermineelnúmeromedio decaracteres(incluyendopuntuacióny
espaciosenblanco)encadalínea.Estructuraremoselprograma
detalmaneraquecontinúeleyendolíneas
hastaencontrarunalíneavacía(unalíneacuyoprimercaráctersea
).
Utilizaremosunafunción (contlinea)queleeunalíneadetextoycuentaelnúmero decaracteres,
excluyendoelcarácter
denuevalínea ()quemarcael findelalínea.Larutinadesdelaque sellama

260 PROGRAMACiÓN ENC
(main)mantieneunasumaacumulativa,asícomoelnúmerototal delíneasquesehanleído.Lafunciónse
llamarárepetitivamente(leyendounanuevalíneacadavez)hastaque
seencuentreunalíneavacía.El
programadivideentonceselnúmeroacumuladodecaracteresporelnúmerototaldelíneasparaobtenerla
media.
Heaquíelprogramacompleto.
/*leervariaslíneasdetextoydeterminarelnúmeromediodecarac­
teresporlínea*/
#include<stdio.h>
intcontlinea(void)
;
main()
{
intn; /*númerodecaracteresenunalínea*/
intcont=O; /*númerodelíneas*/
intsuma=O; /*númerotot'aldecaracteres*/
floatmedia; /*númeromediodecaracteresporlínea*/
printf("Introducireltextodebajo:");
/*leerunalíneadetextoyactualizarloscontadores*/
while(n=contlinea())>O){
suma+=ni
++cont;
}
media=(float)suma/cont;
printf("Númeromediodecaracteresporlínea:%5.2f",media);
}
intcontlinea(void)
/*leerunalíneadetextoycontarelnúmerodecaracteres*/
{
charlinea[80];
intcont=O;
while«(linea[cont]=getchar())!='')
++cont¡
return(cont);
}
Vemosque maincontienecuatrovariablesautomáticas: n,cont,sumaymedia,mientrasque
contlineacontienedos: lineaycont.(Lineaesunarraydecaracteresde 80elementos
querepresentaelcontenidodeunalínea
detexto.)Tresdeestasvariablestienenasignadoelvalorinicial
cero.

ESTRUCTURA DEUNPROGRAMA 261
Observetambién queconttienediferentesignificadodentro decadafunción.Dentro de
contlinea,contrepresentaelnúmerodecaracteresenunalínea,mientrasqueenmain,contrepre­
senta
elnúmerototaldelíneasquesehanleído.Además,contseponea cerocadavezqueseaccedea
contlinea.Estonoafectaalvalordecontdentrodemain,yaqueunavariableesindependientede
laotra.Estoestaríaclaro silasvariablestuvierannombresdistintos,porejemplo contylineas,o
quizáscaracteresy 1ineas.Sehausadoelmismonombreparalasdosvariablesparailustrar la
independenciadelasvariablesautomáticas enfuncionesdiferentes.
Acontinuacíón
semuestraunasesióninteractivadelaejecucióndelprograma.Comosiempre,las
respuestas
delusuarioestánsubrayadas.
Introducireltextodebajo:
EnunlugardelaManchadecuyo
nombrenoquieroacordarme.
Númeromediodecaracteresporlínea:29.50
Sisedesea,elámbitodeunavariableautomáticapuedesermenorquelafunción.Dehecho,
puedendeclararsevariablesautomáticasdentrodeunainstruccióncompuesta.Conprogramas
pequeñosnosuelenexistirventajasalhaceresto,peropuedeseraconsejableenprogramasma­
yores.
8.3.VARIABLESEXTERNAS(GLOBALES)
Lasvariablesexternas, encontrasteconlasvariablesautomáticas,noestánconfinadasafuncio­
nessimples.Suámbitoseextiendedesdeelpuntodedefinición hastaelrestodelprograma.Por
tanto,generalmenteabarcandosomásfuncionesyfrecuentementetodoelprograma.Amenudo
selesllama
variablesglobales.
Comolasvariablesexternassereconocenglobalmente,sepuedeaccederalasmismasdesde
cualquierfunciónqueseencuentredentrodesuámbito.Mantienenlosvaloresasignadosdentro
deesteámbito.
Portanto,aunavariableexternaselepuedeasignar unvalordentrodeuna
función,yestevalorpuedeusarse(alaccederalavariableexterna)dentrodeotrafunción.
Lautilizaciónde variablesexternasproporciona unmecanismo adecuadodetransferencia
deinformaciónentrefunciones.
Enparticular,podemostransferirinformacióna unafunción
sinusarargumentos.Estoesespecialmenteconvenientecuandounafunciónrequierenume­
rososdatosdeentrada.Esmás,ahoratenemos
unmétodoparatransferirmúltiplesdatosfuera
de
unafunción,porquelainstrucciónreturnsólopuedetransferir undato.(Veremosotro
mododetransferirinformaciónentrefuncionesenelCapítulo10,dondesetratanlospun­
teros.)
Altrabajarconvariablesexternashayquedistinguirentre
definicionesdevariablesexternas
y
declaracionesdevariablesexternas.Una definicióndevariableexternaseescribede lamisma
maneraqueunadeclaracióndeunavariableordinaria.Tienequeaparecerfuera,ynormalmente
antes,delasfuncionesqueaccedenalasvariablesexternas.Unadefinicióndevariableexterna
reservaautomáticamente elespaciodealmacenamientorequeridoen
lamemoriadelacomputa­
dora.Laasignacióndevaloresinicialespuedeincluirse,sisedesea,dentrodeunadefiniciónde
variableexterna(veremosmásdetallessobreestoposteriormente).

262 PROGRAMACiÓN ENC
Noserequiereelespecificadordetipo dealmacenamientoexternenunadefinicióndeuna
variableexterna,porquelasvariablesexternasseidentificanporlalocalización
desudefinición
enelprograma.Dehecho,muchoscompiladoresde
eprohíbenlaaparicióndelespecificador de
tipodealmacenamiento externdentrodeunadefinicióndevariableexterna.Enestelibrosegui­
remosesteconvenio.
Siunafunciónrequiereunavariablequehasidodefinidaantesenelprograma,entonces la
funciónpuedeaccederlibrementealavariableexterna,sinningunadeclaraciónespecialdentro
delafunción.(Recuerde,sinembargo,que cualquieralteracióndelvalordelavariableexterna
dentrodelafunciónseráreconocidodentrodelámbitocompletodelavariableexterna.)
Por
otraparte,siladefinición
defunciónprecedealadefinicióndevariableexterna,entoncesla
funcióntienequeincluiruna
declaraciónparalavariableexterna.Lasdefiniciones defunciones
enunprogramagrandefrecuentementeincluyendeclaracionesdevariablesexternas;
sisonono
necesarias
escuestióndeunabuenapráctica deprogramación.
Una
declaracióndevariableexternatienequecomenzarconelespecificadordetipodealma­
cenamiento
externoElnombredelavariableexternaysutipo dedatostienenquecoincidir
consucorrespondientedefinición
devariableexternaqueaparecefuera delafunción.Nose
reservaráespaciodealmacenamientoparavariablesexternascomoconsecuenciadeunadeclara­
cióndevariableexterna.Esmás,unadeclaración
devariableexterna nopuedeincluirunaasig­
nación
devaloresiniciales.Éstassonlasdiferenciasimportantesentrela definicióndeunavaria­
bleexternayla
declaracióndeunavariableexterna.
EJEMPLO8.4.Búsqueda deuumáximo. Supougamosquequeremosencontrarelvalorparticularde
xquehacemáximalafunción
y=xcos(x)
enelintervalolimitadopor x=Oalaizquierday x=1taladerecha.Necesitaremosconocerconbastante
exactitudelvalormaximizante
dex.Necesitamostambiénqueelesquema debúsquedasearelativamente
eficazenelsentidoquelafunción
y=xcos(x)sedebeevaluar elmenornúmerodevecesposible.
Unaformaobviaderesolveresteproblemaseríagenerarungrannúmero
defuncionesdepruebamuy
próximas(estoes,evaluar
x=O,x=0.0001,x=0.0002,..., x=3.1415Y x=3.1416)Ydeterminarelmayor
deéstosporinspecciónvisual.Estonoseríamuyeficiente,sinembargo,yrequeriríadeintervenciónhuma­
naparaobtenerelresultadofinal.Ensulugar,utilizaremoselsiguiente
esquemadeeliminación,queesun
procedimientocomputacionalaltamenteeficienteparatodaslasfuncionesquesólotienenunmáximo(un
solo«pico»)dentrodelintervalodebúsqueda.
Elcálculoserealizarácomosigue.Empezamoscondospuntosdebúsquedaenelcentrodelintervalo
debúsqueda,marcandounamuypequeñadistanciaentreellos,comosemuestraenlaFigura8.1.
Seemplealasiguientenotación:
a extremoizquierdodelintervalo
xipuntointerior debúsquedaalaizquierda
xd puntointeriordebúsquedaaladerecha
b extremoderechodelintervalo
s
ep distanciaentre xiyxd.
Siseconocena,b y sep,entonceslospuntosinteriorespuedencalcularsecomo

ESTRUCTURA DEUNPROGRAMA 263
xi a+.5*(b-a -sep)
xd=a+.5*(b a+sep)=xi+sep
Evaluemoslafunción y=xcos(x)enxiyxd.Llamemosaestosvalores yieyd,respectiva­
mente.Supongamosque
yiresultasermayorque yd.Entonceselmáximoestáenalgunaparteentrea y
xd.Portanto,seretendrásóloestapartedelintervalodebúsquedaquevadesde x=ahastax=xd.
Ahoranosreferiremosalpuntoviejo xdcomob,puesésteeselextremoderechodelnuevointervalode
búsqueda,ysegeneranotrosdos
nuevospuntosdebúsquedaxiyxd.Estospuntosselocalizaránenel
centrodelnuevointervalodebúsqueda,separadosunadistancia
sep,comosemuestraenlaFigura8.2.
Porotrolado,supongamosahoraqueennuestrointervalo
originaldebúsquedaelvalor deydresulta
mayorque
yi.Estoindicariaquenuestrointervalodebúsquedasehallaentre xiyb.Portanto,renom­
bramoselpuntooriginalmentellamado
xicomoaygeneramosdosnuevospuntos debúsqueda,xiyxd,
enelcentrodelnuevointervalodebúsqueda,como semuestraenlaFigura8.3.
Continuamos generandounnuevopar
depuntosdebúsquedaenelcentro decadanuevointervalo,
comparandolosrespectivosvalores
dey,yeliminandounapartedelintervalo debúsquedahastaqueel
intervalodebúsquedasehacemenorque3
*sep.Llegadoestepunto,nosepuedendistinguirlos
puntosinterioresdeloslímites.Portantofinalizalabúsqueda.
~
~sep
H
a xixd b
Figura8.1.
-1~sep
-----IH,....-----
a xixd
Figura8.2.
b
(anteriormentexd)
-1~sep
I-----HI-----
a
(anteriormentexi)
xixd
Figura8.3.
b

264 PROGRAMACiÓN ENC
Cadavezquehacemosunacomparaciónentre yieyd,eliminamoslapartedelintervalodebúsqueda
quecontiene
elvalormáspequeño dey.Siambosvaloresinterioressonidénticos(locualpuedesuceder
peroesinusual),entonceselprocedimientodebúsquedasedetieneysesuponeque
elmáximotienelugar
enelcentrodelosdosúltimospuntosinternos.
Unavezacabadalabúsqueda,tantoporqueelintervalodebúsquedasehahecholosuficientemente
pequeñooporquelosdospuntosinteriorestienenvaloresidénticos
dey,sepuedecalcularlalocalización
aproximadadelmáximocomo
xmax=0.5*(xi+xd)
Elvalormáximocorrespondiente delafunciónsepuedeobtenercomo xmax*cos(xmax).
Consideremosunesquema deprogramaparaelcasogeneralenquea y bsoncantidadesdeentrada
pero
septieneunvalorfijo deO• OOO1.
1.Asignarunvalor sep=0.0001.
2.Leerlosvaloresdea yb.
3.Repetir
losiguientehastaque yisehagaiguala yd(elmáximoestaráenelpuntomedio),o el
valormásreciente de(b
-a)seamenoroigualque (3*sep):
a)Generarlosdospuntosinteriores, xiyxd.
b)Calcularloscorrespondientesvaloresde y ieyd,ydeterminarcuálesmayor.
e)Reducirelintervalodebúsqueda,eliminandolaparteque nocontengaelvalormayorde y.
4.Evaluarxmaxeymax.
5.Escribirlosvalores dexmaxeymax,yparar.
Paratraducirelesquemaaunprograma,primerosecreaunafuncióndefinidaporelprogramadorpara
evaluarlafunciónmatemática
y=xcos(x).Llamemosaestafunción curva.Estafunciónsepuede
escribirfácilmentecomosemuestraacontinuación:
/*evaluarlafuncióny=x*cos(x)*/
doub1ecurva(doub1ex)
{
return(x*cos(x)) ;
}
Observeque cos(x)esunallamadaaunafuncióndebibliotecade C.
Ahoraconsidéreseelpaso3 delesquemadeprogramaanterior,querealizalareduccióndelintervalo.
Estepasopuedeprogramarsecomounafunción,quellamaremos
reducir.Observe,sinembargo,que
losvaloresrepresentadosporlasvariables
a,b,xi,xd,yieyd,quecambianenelcursodelcómputo,
debensertransferidosa
ydesdeestafuncióny main.Portanto,haremosqueestasvariablesseanexter­
nasysuámbitoincluyatantoa
reducircomoa main.
Lafunciónreducirsepuedeescribircomo
/*rutinadereduccióndelintervalo*/
voidreducir(void)
{
xi=a+O.5*(b
-a-CN8T);
xd=xi+CN8T;

ESTRUCTURA DEUNPROGRAMA 265
yi
~curva(xi);
yd
~curva(xd);
if(yi>Vd) {
b
~xd¡
return¡
}
if(yi<Vd)
a
~Xii
return¡
}
/*retenerelintervaloizquierdo*/
/*retenerelintervaloderecho*/
Observequeelparámetroalcualnoshemosreferidoantescomo sepestárepresentadoahoraporla
constanteCN8T.Observetambiénqueestafunciónnoincluyeningúnargumentoformalynodevuelve
nadaatravésdelainstrucción
return.Todalainformacióntransferidainvolucravariablesexternas.
Ahoraesmuysimpleescribirlaparteprincipaldelprograma,quellamaalasdosfuncionesdefinidas
anteriormente.Aquíestáelprogramacompleto.
/*encontrarelmáximodeunafunciónenunintervaloespecificado*/
#include<stdio.h>
#include<math.h>
#defineCN8T0.0001
doublea,b,xi,yi,xd,yd¡
voidreducir(void);
doublecurva(doublexi);
main( )
{
doublexmax,ymax;
/*variablesglobales*/
/*prototipodefunción*/
/*prototipodefunción*/
/*leerdatosdeentrada(puntosextremosdelintervalo)*/
printf("a
~");
scanf("%lf",&a);
printf ("b~");
scanf(ll%lf
ll
,&b)¡
/ *bucledereduccióndelintervalo* /
do
reducir();
while((yi!~vd)&&((b-a)>3*CN8T);

266 PROGRAMACiÓN ENC
/*calcularxmaxeymaxyescribirlosresultados*/
}
xmax=0.5*(xi+xd);
ymax=curva(xmax);
printf("xmax =%8.6lfymax=%8.61f",xmax,ymax);
/*rutinadereduccióndelintervalo*/
voidreducir(void)
{
xi=a+0.5*
(b-a-CNST);
xd=xi+CNST;
yi=curva(xi);
yd=curva(xd);
if(yi>yd) {
b=xd;
return;
}
if(yi<yd)
/*retenerelintervaloizquierdo*/
/*retenerelintervaloderecho*/
a=xii
return;
}
/*evaluarlafuncióny=x*cos(x)*/
doublecurva(doublex)
{
return(x*cos(x)) ;
}
Lasvariablesa,b,xi,yi,xdeydestándefinidascomovariablesexternascuyoámbitoincluyetodo
elprograma.Observequeestasvariablesestándeclaradasantesdequeempiece
main.
Laejecucióndelprograma,cona =OYb=3.141593,producelasiguientesesióninteractiva.
Lasrespuestasdelusuariosesubrayan,comosiempre.
a=
Q
b3.141593
xmax=0.860394 ymax=0.561096
Portanto,obtenemosla localizaciónyelvalordelmáximodentrodelintervalooriginaldado.
A
lasvariablesexternasselespuedenasignarvaloresinicialescomopartedeladefinición
devariables,perolosvaloresinicialessetienenqueexpresarcomoconstantesenvezdecomo
expresiones.Estosvaloresinicialesseasignaránsólounavez,alcomienzodelprograma.Las
variablesexternasretendránestosvaloresiniciales,amenosquesealterendespuésdurantela
ejecucióndelprograma.

ESTRUCTURA DEUNPROGRAMA 267
Sinoseincluye unvalorinicialenladefinicióndelavariableexterna,seleasignaráautomá­
ticamenteelvalorcero.
Portanto,lasvariablesexternas nuncasedejanbailandoconvalores
inicialesindefinidosyvagos.
Noobstante,es unabuenaprácticadeprogramaciónasignar un
valorinicialexplícitodecerocuandolorequieralalógicadelprograma.
EJEMPLO8.5. Longitudmediadevariaslíneasdetexto. Acontinuaciónsemuestraunamodifica­
ción
delprogramapresentado enelEjemplo8.3,paradeterminarelnúmeromedio decaracteresenvarias
líneas
detexto.Laversiónactualhace usodevariablesexternaspararepresentar elnúmerototal(acumula­
do)decaracteresleídos yelnúmerototal delíneas.
/*leervariaslíneasdetextoydeterminar
elnúmeromediodecaracteresporlínea*/
#include<stdio.h>
intsuma=O;
intlineas=O;
intcontlinea(void);
main()
{
intn;
floatmedia;
/*númerototaldecaracteres*/
/*númerototaldelíneas*/
/*númerodecaracteresenunalínea*/
/*númeromediodecaracteresporlínea*/
printf("Introducireltextodebajo:");
/*leerunalíneadetextoyactualizarloscontadores*/
while((n=contlinea())>O){
suma+=n;
++lineas;
}
media=(float)suma/lineas;
printf("Número mediodecaracteresporlínea:%5.2f",media);
}
/*leerunalíneadetextoycontarelnúmerodecaracteres*/
intcontlinea(void)
{
charlinea[80];
intcont=O;
while((linea[cont]=getchar())!='')
++cont¡
return(cont);
}

268 PROGRAMACiÓN ENC
Observequesumaylineassonvariablesexternas querepresentanelnúmerototal(acumulado)de
caracteresleídosy elnúmerototaldelíneas,respectivamente.A ambasvariablesseleshaasignadoel
valorinicialcero.Estosvaloressemodificansucesivamentedentrodemain,segúnseleenlíneasadicio­
nalesdetexto.
Recuerdetambién quelaversiónanterior delprogramausaba dosvariablesautomáticasdiferentes
llamadascontenpartesdiferentesdelprograma.Enlaversiónactual, sinembargo,lasvariablesque
representanestas mismascantidadestienen nombresdistintos,puesunadelasvariables(1ineas)es
ahoraunavariableexterna.
Debedestacarsequeasumaylineasnohayqueasignarlesexplícitamente elvalorcero,puesto
quelasvariablesexternas siempreseinicializana ceroamenosquesedesignealgúnotrovalor.Seincluye
elvalorexplícitodeinicializaciónceroparaclarificarlalógicadelprograma.
Losarrayspuedendeclararsecomoautomáticosocomoexternos,sibienlosarraysautomá­
ticosnosepuedeninicializar.Veremoscómoseasignanvaloresinicialesaloselementosdeun
arrayenelCapítulo
9.
Finalmente,hayquedestacarqueexistenpeligrosinherenteseneluso devariablesexternas,
porqueunaalteracióndelvalor
delavariableexternadentrodeunafunciónrepercutiráenotras
partesdelprograma.Avecesestopasainadvertidamente,comounefectolateraldealgunaotra
acción.Portanto,existelaposibilidaddequeelvalordelavariableexternacambieinespera­
damente,dandolugaraunerrorsutildeprogramación.Elprogramadorha
dedecidircuidado­
samentequétipo
dealmacenamientoesmásadecuadoparacadasituacióndeprogramaciónpar­
ticular.
8.4.VARIABLESESTÁTICAS
Enestasecciónylasiguientesehaceladistinciónentreunprogramamonoarchivo,enelque
todoelprogramaestácontenidoenunsoloarchivofuente,yunprogramamultiarchivo,donde
lasfuncionesquecomponenelprogramaestánalmacenadasenarchivosfuenteseparados.Las
reglasquerigeneltipodealmacenamientoestáticosondiferentesencadasituación.
Enunprogramamonoarchivo,lasvariablesestáticassedefinendentro
defuncionesindivi­
dualesytienen,portanto,elmismoámbitoquelasvariablesautomáticas;estoes,sonlocalesa
lafunciónenqueestándefinidas.Sinembargo,adiferenciadelasvariablesautomáticas,las
variablesestáticasretienensusvaloresdurantetodalavidadelprograma.Comoconsecuencia,
sisesaledeunafunciónyposteriormentesevuelveaentrar,lasvariables estáticasdefinidas
dentrodeesafunciónretendránsusvaloresprevios.Estacaracterísticapermitealasfunciones
mantenerinformaciónpermanentea
10largodetodalaejecucióndelprograma.
Lasvariablesestáticassedefinendentrodeunafunción
delamismaformaquelasvariables
automáticas,exceptoqueladeclaracióndevariablestienequeempezarconladesignacióndel
tipodealmacenamientos
tatic.Lasvariablesestáticassepuedenutilizardentro deunafun­
cióndelamismamaneraquelasotrasvariables.Sinembargo,nosepuedeaccederaellasfuera
delafunciónenqueestándefinidas.
Noesinusualdefinirvariablesautomáticasoestáticas.conelmismonombrequelasvariables
externas.Entalessituaciones,lasvariableslocalestienenprecedenciasobrelasvariablesexter­
nas,aunquelosvaloresdelasvariablesexternasnoseveránafectadosporlamanipulacióndelas
variableslocales.Portanto,lasvariablesexternasmantienensuindependenciafrentealasvaria-

ESTRUCTURA DEUNPROGRAMA 269
biesautomáticasoestáticas.Lomismoesciertoparavariableslocalesdentrodeunafunciónque
tienenlosmismosnombresdevariableslocalesdentrodeotrafunción.
EJEMPLO8.6. Acontinuaciónsemuestraelesqueletodelaestructuradeunprogramaeneque
incluyevariablespertenecientesavariostiposdiferentes dealmacenamiento.
floata,brC¡
voidficticio(void)
;
main()
{
staticfloata;
}
voidficticio(void)
{
staticinta¡
intb¡
}
Enesteprograma,a,b y csonvariablesexternas encomaflotante.Sinembargo,aestáredefinida como
variableencomaflotanteestáticadentrodemain.Portanto,b y cson lasúnicasvariablesexternas que
sereconocerándentro demain.Observequelavariablelocal estáticaaseráindependientedelavariable
externa
a.
Deigualforma,a y bseredefinencomovariablesenterasdentro def i cticio.Observequeaes
unavariableestática,perob esunavariableautomática.Luegoaretendrá suvalorpreviosi sevuelvea
entrara f i c
ticio;sinembargo,bperderá suvalorsiempre quesetransfieraelcontrolfuera def ic­
ticio.Además,ceslaúnicavariable externaqueseráreconocidadentro def i cticio.
Porsera y blocalesa
ficticio,seránindependientesdelasvariablesexternas a,b yc,ydela
variableestáticaadefinidadentro
demain.Elhechodequea y bseandeclaradas comovariablesenteras
dentro
def i ctici o ycomovariables encomaflotanteencualquierotrositio esirrelevante.
Sepuedenincluirvaloresinicialesenlasdeclaracionesdevariablesestáticas.Lasreglas
asociadasalaasignacióndeestosvaloressonesencialmentelasmismasquelasasociadascon
la
inicializacióndevariablesexternas,aunquelasvariablesestáticassedefinenlocalmentedentro
deunafunción.
Enparticular:
1.Losvaloresinicialestienenqueserexpresadoscomoconstantes,nocomoexpresiones.
2.Losvaloresinicialesseasignanasusrespectivasvariablesalcomienzode
laejecución
delprograma.Lasvariablesretienenestosvaloresa
10largodetoda lavidadelprogra­
ma,amenosqueseasignenvaloresdiferentes
enelcursodelaejecución.
3.Atodaslasvariablesestáticascuyasdeclaracionesnoincluyanvaloresinicialesexplícitos
selesasignaráelvalorcero.Asílasvariablesestáticastendránsiemprevaloresasignados.

270 PROGRAMACiÓN ENC
EJEMPLO8.7.GeneracióndelosnúmerosdeFibonacci.Losnúmeros deFibonacciformanuna
interesantesecuenciaenlaquecadanúmeroesigualalasumadelosdosnúmerosanteriores.Enotras
palabras:
donde
F¡refiereelnúmeroi-ésimo deFibonacci.Losdosprimerosnúmerossoniguales al;estoes,
Portanto,
F,
=F,+F
l=1+1=2
F,=F,+F,=2+1=3
F
~F+F=3+2=5
5 4 ,
yasísucesivamente.
EscribamosunprogramaenCquegenerelosnprimerosnúmerosdeFibonacci,dondenesunvalor
especificadoporelusuario.Enlaparte
maindelprogramaseleeunvalorpara n,yluegoseejecutaun
buclequegenerayescribecadanúmerodeFibonacci.ParacalcularcadanúmerodeFibonacciapartirde
susdosvaloresprecedentesseutilizaráunafunciónllamada
fibonacci.Estafunciónserállamadauna
vezencadapasadaporelbucleprincipal.
Cuandoseentraen
fibonacci,elcálculodelnúmeroactual deFibonacci,J,esmuysimple,supues­
tosconocidoslosdosvaloresprevios.
Sepuedenretenerestosvaloresdeunallamadaalafunciónala
siguientesiselosasignamosalasvariablesestáticas
f1 Yf2,querepresentanF¡_lyF¡_2'respectivamente.
(Podriamos,porsupuesto,haberusadovariablesexternasparaestepropósito,peroesmejorusarvariables
locales,puessóloserequieren
F¡_lyF¡_2dentrodelafunción.)Acontinuaciónsecalculaelnúmerodeseado
deFibonaccicomo
f=fl+f2
yseactualizanlosvaloresde f2 Yf1utilizandolasfórmulas
f2=fl
y
fl=f
Heaquíelprogramacompletoen C.
/*programaparacalcularnúmerosdeFibonaccisucesivos*/
#include<stdio.h>
longintfibonacci(intcont);
main()

ESTRUCTURA DE UNPROGRAMA 271
(
intcont,n;
printf("¿Cuantosn~meros deFibonacci?11);
scanf(U%d"/ &n);
printf("");
for(cont=1;cont<=n;++cont)
printf("i=%2d F =%ld",cont,fibonacci(cont»;
}
longintfibonacci(intcont}
/*calcularunnúmerodeFibonacciusandolasfórmulas
F=1parai<3,yF=F1+F2 parai>=3*/
{
staticlongintf1=1,f2=1;
longintf;
}
f=(cont<3)? 1
f2=fl;
fl=f;
return(f};
f1+f2;
ObservequesehanusadoenteroslargospararepresentarlosnúmerosdeFibonacci.Observetambién
que
f1 Yf2sonvariablesestáticasdevalorinicial1.Estosvaloresinicialesseasignansólounavez,al
comienzo
delaejecucióndelprograma.Lossubsiguientesvaloresseretienensegúnsonasignados,entre
llamadassucesivasalafunción.
Sesobreentiendeque f1yf2sonvariablesestrictamentelocales,aun­
queretengansusvalores
deunallamadaafunciónaotra.
Acontinuaciónsemuestralasalidacorrespondientealvalorn
=3o.Larespuestadelusuarioestá
subrayada,comodecostumbre.
¿CuantosnúmerosdeFibonacci?
.lQ.
i=1 F =1
i
=2 F 1
i
=3 F =2
i
=4 F =3
i
=5 F=5
i= 6 F=8
i=7 F=13
i 8 F=21
i=9 F=34
i=10 F=55
i=11 F=89
i=12 F=144
i=13 F=233

272 PROGRAMACiÓN ENC
i=14 F 377
i=15 F=610
i=16 F=987
i 17 F=1597
i=18 F=2584
i=19 F 4181
i=20 F=6765
i=21 F=10946
i=22 F=17711
i=23 F=28657
i=24 F 46368
i=25 F=75025
i=26 F=121393
i=27 F=196418
i=28 F=317811
i=29 F=514229
i=30 F=832040
Esposibledefinireinicializararraysestáticascomosucedeconvariablesestáticassimples.
Elusodearrayssetrataenelpróximocapítulo.
8.5.PROGRAMAS DEVARIOSARCHIVOS
Unarchivoesunacoleccióndeinformaciónalmacenadacomounaentidadseparadadentro dela
computadoraodeldispositivoauxiliar
dealmacenamiento.Unarchivopuedeserunconjunto de
datos,unprogramafuente,unaparte deunprogramafuente,unprogramaobjeto,etc.Eneste
capítuloconsideraremosqueunarchivoesounprogramacompletoenC ounapartedeun
programaenC,porejemplounaomásfunciones.(VéaseelCapítulo
12paraunadiscusión de
losarchivosdedatosysurelaciónconlosprogramasenC.)
HastaahorahemosrestringidonuestraatenciónaprogramasenCqueestánenteramente
contenidosenunarchivoindividual.Sinembargo,muchosprogramasestáncompuestosporvarios
archivos.Estoesespecialmenteciertoenprogramasqueusanfuncionesgrandes,dondecada
funciónpuedeocuparunarchivoseparado.
O,siexistenmuchasfuncionespequeñasrelacionadas
entresídentrodeunprograma,puedeserdeseablecolocaralgunasfuncionesdentro
decadauno
delosdiversosarchivos.Losarchivosindividualessecompilandeformaseparaday acontinuación
seenlazanparaformarunprogramaobjetoejecutable(versección5.4).Estohacemásfácilla
redacciónyladepuracióndelprograma,puescadaarchivosemantieneconuntamañomanejable.
Losprogramasmultiarchivopermitenunamayorflexibilidadenladefinicióndelámbitode
lasfuncionesydelasvariables.Sinembargo,lasreglasasociadasconlostiposdealmacena­
mientosevuelvenmáscomplicadas,porqueseaplicantantoafuncionescomoavariables,yse
disponedemásopcionesenelusotanto
devariablesexternascomoestáticas.
Funciones
Empecemosconsiderandolasreglasasociadasconlautilización defunciones.Ladefiniciónde
unafuncióndentrodeunprogramamultiarchivopuedesertanto
externacomoestática.Una

ESTRUCTURA DEUNPROGRAMA 273
funciónexternaseráreconocidaalolargo detodoelprograma,mientrasqueunafunciónestáti­
caseráreconocidasólodentrodelarchivoenelquesedefina.Entodocaso,eltipodealmace­
namientoseestablececolocandoeltipoadecuadodeasignacióndetipo
dealmacenamiento(es
decir,
externostatic)alcomienzodeladefinicióndelafunción.Sesuponequelafunción
es
externasinoapareceladesignacióndeltipodealmacenamiento.
Entérminosgenerales,laprimeralínea
deunadefinicióndefunciónsepuedeescribircomo
tipo-de-almacenamientotipo-datosnombre(tipo1arg1,
tipo2arg2, o,tiponargn)
dondetipo-de-almacenamientodenotaeltipo dealmacenamientoasociadoconlafun­
ción,
tipo-datoseltipodedatosdelvalordevueltoporlafunción, nombredenotaelnom-
bredelafunción,
tipo1,tipo2, o,tiponserefierenalostipos delos
argnmentosformalesy
arg
1,arg2, .,argnalosargumentosformales.
Recuerdequeeltipodealmacenamiento,eltipodedatosylosargumentosformalesnonecesitan
estarsiemprepresentesencadadefinición
defunción.
Cuandosedefineunafunciónenunarchivoyseaccedeaellaenotro,esteúltimoarchivo
debeincluiruna
declaracióndefunción.Estadeclaraciónidentificalafuncióncomounafun­
ciónexternacuyadefiniciónapareceenotraparte.Estasdeclaracionessecolocannormalmente
alcomienzodelarchivo,delante
decualquieradelasdefinicionesdefunciones.
Esunabuenaprácticadeprogramaciónempezarladeclaraciónconunespecificador
detipo
dealmacenamiento
externoEsteespecificadordetipo dealmacenamientono esabsolutamen­
tenecesario,puessesuponequelafunción
esexternasinoestápresenteelespecificador detipo
dealmacenamiento.
Entérminosgenerales,una
declaracióndefunciónsepuedeescribircomo
tipo-de-almacenamientotipo-datos
tipoargumento2,
nombre(tipoargumento1,
o,tipoargumenton)
Unadeclaracióndefuncióntambiénsepuedeescribirutilizandoelprototipocompleto defun­
ción(versección7.4)como
tipo-de-almacenamientotipo-datos
tipo2arg2,
nombre(tipo1
o,tipon
arg
1,
argn)
Recuerdequeeltipodealmacenamiento,eltipodedatosylostiposdeargumentosnonecesitan
estarpresentesencadadeclaracióndefunción.
Paraejecutarunprogramamultiarchivo,sedebecompilarcadaarchivoindividual,ylosarchi­
vosobjetoresultantessedebenenlazar.Parahaceresto,normalmentesecombinanlosarchivos
fuenteenun
proyecto.Acontinuaciónse construye(<<build»)elproyecto(esdecir,secompilan
todoslosarchivosfuenteyseenlazanlosarchivosobjetoresultantesenunúnicoprograma
ejecutable).Simásadelantesemodificaalgunosdelosarchivosfuente,
construimos(<<make»)
otroprogramaejecutable(esdecir,compilamoslosnuevosarchivosfuenteyenlazamoslosarchi­
vosobjetoresultantes,conlosarchivosobjetoquenosehanmodificado,enunnuevoprograma
ejecutable).LosdetallesdecómoseefectúaestocambiandeunaversióndeC aotra.
EJEMPLO8.8. Aquísemuestraunprogramasímplequegeneraelmensaje«¡Hola!»desdeunafun­
ción.Elprogramaconstadedosfunciones:mainysalida.,Cadafunciónapareceenunarchivoseparado.

274 PROGRAMACiÓN ENC
Primerarchivo:
/*programasimplemultiarchivoparaescribirIIhola
ll
*/
#include<stdio.h>
externvoidsalida(void);
main()
(
salida()
}
Segundoarchivo:
externvoidsalida(void)
(
printf("¡Hola!");
return¡
}
/*prototipodefunción*/
/*definicióndefunciónexterna*/
Observequea salidaseleasignaeltipo dealmacenamientoextern,puessetienequeaccedera
elladesdeotroarchivodistintodeaquelenelqueestádefinida;portanto,hadeserunafunciónexterna.
Asiseincluyelapalabrareservada
externtantoenla
dechiracióndelafunción(enelprimerarchivo)
comoenladefinición
delafunción(segundoarchivo).Como externeseltipodealmacenamientopor
defecto,sepuedeomitirlapalabrareservada
externtantodeladeclaracióncomo deladefiniciónde
función.Deestemodo,elprogramasepuedeescribircomosigue:
Primerarchivo:
/ *programasimplemultiarchivoparaescribir"hola"* /
#include<stdio.h>
voidsalida(void);
main()
(
salida();
}
Segundoarchivo:
voidsalida(void)
(
/*prototipodefunción*/
/*definicióndefunciónexterna*/
printf("¡Hola!");
return¡
}
ConstruyamosunproyectoTurboC++correspondienteaesteprogramamultiarchivo.Parahacerlo,
introducimosenprimerlugarelcódigofuentedelprimerarchivoy
10guardamosenunarchivollamado

ESTRUCTURA DEUNPROGRAMA 275
ARCHIVO1 .C.Acontinuaciónintroducirnoselcódigofuentedelseguudoarchivoyloguardarnosenun
archivollamado
ARCHIV02.C.EstosdosarchivossemuestranenlaFigura8.4ensendasventanas.
Acontinuaciónseleccionarnoslaopción
NewdelmenúProject,yespecificarnoscornonombredel
proyecto
EXS-S.IDE.Cornoresultado, seabrelaventana Project,aproximadamenteenelcentrode
laFigura8.4.Enestaventanavernosqueelproyectogeneraráunprogramaejecutablellamado
EXS- S .EXE. Esteprogramaejecutableseobtieneapartirdelosdosarchivosfuente, ARCHIVOl. CY
ARCHIVo2.C.
Elprogramayasepuedeejecutarseleccionando Runenelmenú Debug,cornoseexplicóenelCapí­
tulo5(verEjemplo5.4).Enlaventanadesalidasevisualizaelmensajeresultante,¡Hola!,talycorno
muestralaparteinferiorderechade
laFigura8.4.
Siunarchivocontieneuna[unciónestática,seránecesarioincluireltipodealmacenamiento
staticenladeclaraciónoprototipodelafunción.
EJEMPLO8.9.Simulación deunjuegodeazar(juegodedados «Craps»).Éstaesotraversióndel
juegodedados«Craps»,presentadooriginalmenteenelEjemplo7.11.Enestaversiónelprogramaconsta
dedosarchivosseparados.Elprimerarchivocontienelafuoción
main,mientrasqueelseguudocontiene
lasfuociones
juegoytirada.
Primerarchivo:
/*simulacióndeljuegodedados"Craps"*/
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
Figura8.4.

276 PROGRAMACiÓN ENC
#defineSEMILLA 12345
externvoidjuego(void);
main()
{
charrespuesta='S';
1*prototipodefunción*1
printf("BienvenidoaljuegoCRAPS");
printf("Paralanzarlosdados,pulsaIntro");
srand(SEMILLA);1*inicializaelgeneradordenúmerosaleatorios*1
1*bucleprincipal*1
while(toupper(respuesta)!='N') {
juego();
printf("¿Deseasjugardenuevo?(SIN)");
scanf(ll%c",&respuesta)¡
printf(11
ll
),;
}
printf(uAdiós1quelopasesbien11)i
}
Segundoarchivo:
#include<stdio.h>
#include<stdlib.h>
staticinttirada(void);
externvoidjuego(void)
1*prototipodefunción*1
1*definicióndefunciónexterna*1
1*simularunajugadacompleta*1
{
intpuntosl,puntos2;
charnada;
printf("Porfavorlanzalosdados .");
scanf(II%C
Il
I&nada);
printf("");
puntosl=tirada();
printf("%2d",puntosl);
switch(puntosl){
case7:
case11:
1*sehaganadoenlaprimeratirada*1
printf("
break;
¡Felicidades!GANASTEenlaprimeratirada");

case2:
case3:
case12:
ESTRUCTURA DEUNPROGRAMA 277
/*sehaperdidoenlaprimeratirada*/
printf("
break;
¡Losiento!-PERDISTE enlaprimeratirada");
case4 :
case5:
case6 :
case8 :
case9 :
case10:
do
/*serequierenotrastiradas*/
{
printf("-Lanzalosdadosdenuevo .");
scanf("%c",&nada);
puntos2=tirada();
printf("%2d",puntos2);
}while(puntos2! =puntosl&&puntos2!=7);
if(puntos2==puntosl)
printf("-GANASporigualartuprimerapuntuación");
else
printf("-PIERDES pornoigualartuprimerapuntuación");
break;
}
return;
}
/*simulaellanzamientodeunpardedados*/
staticinttirada(void)/*definicióndefunciónestática*/
{
floatxl,x2;
intni,n2¡
/*númerosencomaflotantealeatoriosentre
Oy1*/
/*númerosenterosaleatoriosentre1 y 6*/
xl=rand()
x2=rand()
/32768.0;
/32768.0;
}
nl= 1 +(int)(6*xl);
n2=1+(int)(6*x2)
return(nl+n2);
/*simulaprimerdado*/
/*simulasegundodado*/
/*lapuntuacióneslasumadelosdosdados*/
Observeque juegosedefinecomounafunciónexterna,demodoquesepuedeaccederdesde main
(porquemainyjuegosedefinenenarchivosseparados).Portanto, juegoestádeclaradacomouna

278 PROGRAMACiÓN ENC
funciónexterna enelprimerarchivo.Porotrolado,a tiradasóloseaccededesde juego.Tanto
tiradacomojuegosedefinenenelsegundoarchivo. Asipues,tiradanonecesitaserreconocida
enelprimerarchivo.Podemosdefinir tiradacomofunciónestática,confinando suámbitoalsegundo
archivo.
Observetambién
quecadaarchivotiene unconjuntoseparado deinstrucciones#includeparalos
archivosdecabecerastdio.hystdlib.h.Estoaseguraqueencadaarchivoseincluyanlasdeclara­
cionesnecesariaspara
lasfuncionesdebiblioteca.
Cuandosecompilanyenlazan losarchivosindividuales,y seejecutaelprogramaejecutableresultan­
te,
elprogramagenera undiálogoidéntico almostradoenelEjemplo7.11,comoeradeesperar.
Variables
Enunprogramamultiarchivosepuedendefinirvariablesexternas(globales)enunarchivo y
accederaellasenotro.Denuevoenfatizamos ladistinciónentrela dejinicióndeunavariable
externa
ysusdeclaraciones.Una.dejinición devariableexternapuedeaparecersólo enunarchi­
vo.
S.ulocalizacióndentrodelarchivodebeserexternaacualquierdefinicióndefunción.Gene­
ralmenteapareceráalcomienzodelarchivo,delantedelaprimeradefinicióndefunción.
Lasdefinicionesdevariablesexternaspuedenincluirvaloresiniciales.Cualquiervariable
externaquenotengaasignado
unvalorinicialseinicializaráautomáticamenteacero. Noes
necesarioelespecificadordetipodealmacenamiento
externdentrodeladefinición;dehecho,
muchasversionesdeCprohibenespecíficamente
laaparicióndeesteespecificadordetipode
almacenamientoen
dejinicionesdevariablesexternas.Lasdefinicionesdevariablesexternasse
reconocenporsulocalización
enlosarchivosenqueestándefinidas yenlosqueaparecen.Se­
guiremosesteconvenioenestelibro.
Paraaccederaunavariableexternaenotroarchivo,sedebe
declararprimeroenesearchivo.
Estadeclaraciónpuedeaparecer
encualquierpartedentrodelarchivo.Sinembargo,generalmen­
tesecolocaráalprincipiodelarchivo,delantedelaprimeradefinicióndefunción.
Ladeclara­
ción
debecomenzarconelespecificadordetipodealmacenamiento externoNopueden in­
cluirsevaloresinicialesenlasdeclaracionesdevariablesexternas.
Elvalorasignadoaunavariableexternapuedealterarsedentrodecualquierarchivodonde
sereconozcalavariable.Estoscambiosseránreconocidos
entodoslosotrosarchivosqueestén
dentrodelámbitode
lavariable.Porello,lasvariablesexternasproporcionanlosmediosade­
cuadosparatransferirinformaciónentrearchivos.
EJEMPLO8.10. Acontinuaciónsemuestraelesquema deunprogramaenCdedosarchivosque
utilizavariablesexternas.
Primerarchivo:
inta=1,b=2,c=3;
externvoidfuncl(void);
main()
{
}
/*DEFINICIONdevariableexterna*/
/*DECLARACION defunciónexterna*/
/*DEFINICIONdefunción*/

ESTRUCTURA DEUNPROGRAMA 279
Segundoarchivo:
externinta,b,c;
externvoidfuncl(void)
{
}
/*DECLARACIONdevariablesexternas*/
/*DEFINICIONdefunciónexterna*/
Lasvariablesa,bycsedefinencomoexternasenelprimerarchivo, yselesasigna 1,2 Y 3como
valorinicial,respectivamente.Elprimerarchivotambiéncontieneuna
definicióndelafunción mainy
unadeclaraciónparalafunciónexterna funcl,definidaenotrolugar.Dentrodelsegundoarchivovemos
la
definicióndefunclyunadeclaracióndelasvariablesexternas a,byc.
Observequeelespecificadordetipo
dealmacenamientoexternaparecetantoenla definicióncomo
enla
declaracióndelafunciónexterna func1.Esteespecificadordetipo dealmacenamientoestátam­
biénpresenteenla
declaracióndelasvariablesexternas(enelsegundoarchivo),pero noapareceenla
definicióndelasvariablesexternas(enelprimerarchivo).
Elámbito
dea,byceselprogramacompleto.Portanto,sepuedeaccederaestasvariables yasus
valoresenambosarchivos,tantoen
maincomoen func1.
EJEMPLO8.11.Búsquedade unmáximo.EnelEjemplo8.4sepresentabaunprogramaen eque
determinabaelvalor
dexparaelcuallafunción
y=xcos(x)
sehacíamáximaenunintervaloespecificado.Ahorasepresentaotraversióndeesteprograma,donde
cadaunadelastresfuncionesquecomponenelprogramaestásituadaenunarchivoseparado.
Primerarchivo:
/*encontrarelmáximodeunafunciónenunintervaloespecificado*/
#include<stdio.h>
doublea,b,xi,yi,xd,yd,cnst=0.0001;
/*definicióndevariablesexternas*/
externvoidreducir(void);/ *prototipodefunciónexterna*/
externdoublecurva(doublexi);
/*prototipodefunciónexterna*/
main()
{
doublexmax,ymax;
/*definicióndefunción*/
/ *leerdatosdeentrada(puntosextremosdelintervalo)*/
printf
("a =11)i
scanf("%lf
ll
[&a)¡

280 PROGRAMACiÓN ENC
printf("b=");
scanf("%lf",&b),
/*bucledereduccióndelintervalo*/
do
reducir();
while((yi!=yd)&&((b-a)> 3*cnst));
/*calcularxmaxeyrnaxy escribirlosresultados*/
xmax=0.5*(xi+xd),
yrnax=curva(xmax),
printf("xmax =%8.61f
}
Segundoarchivo:
yrnax=%8.61f",xmax,ymax);
/*rutinadereduccióndelintervalo*/
externdoublea,b,xi,yi
lxd,yd,cnst¡
/*declaracióndevariablesexternas*/
externdoublecurva(doublexi);
/*prototipodefunciónexterna*/
externvoidreducir(void)/*definicióndefunciónexterna*/
{
xi=a+0.5*(b-a-cnst),
xd=xi+cnst;
yi=curva(xi);
yd=curva(xd),
if(yi>yd) {
b=xd¡
return¡
}
if(yi<yd)
a=xi;
return¡
/*retenerelintervaloizquierdo*/
/*retenerelintervaloderecho*/
}
Tercerarchivo:
/*evaluarlafuncióny=x*cos(x)*/
#include<math.h>
externdoublecurva(doublex)
{
return(x*cos(x)) ,
}
/*definicióndefunciónexterna*/

ESTRUCTURA DEUNPROGRAMA 281
Lafunciónexterna reducir,definidaenelsegundoarchivo,estádeclaradaenelprimerarchivo.Por
tanto,suámbitocubrelosdosprimerosarchivos.Igualmente,lafunciónexterna
curva,definidaenel
tercerarchivo,sedeclaraenlosarchivosprimeroysegundo.Luegosuámbitoestodoelprograma.Observe
queelespecificadordetipo
dealmacenamientoexternaparecetantoenlasdefinicionesdefunción
comoenlosprototipos
defunciones.
Consideremosahoralasvariablesexternas
a,b,xi,yi,xd,ydycnst,definidasenelprimer
archivo.Observequea
cnstseleasignavalorinicialenladefinición.Estasvariablesseutilizan, ypor
tantosedeclaran,enelsegundoarchivo,peronoeneltercero.Observequela
declaracióndevariables(en
elsegundoarchivo)incluyeelespecificadordetipodealmacenamiento
extern,peroenla definiciónde
variables(enelprimerarchivo)noseincluyeespecificador detipodealmacenamiento.
Finalmente,observelainstrucción#
inc1ude<math.h>alcomienzodeltercerarchivo.Estains­
trucciónhacequeelarchivodecabecerama
th. hseincluyaen eltercerarchivofuente,dandosoportea
lafuncióndebiblioteca
coso
LosresultadosdelaejecucióndeesteprogramasonidénticosalosmostradosenelEjemplo 8.4.
Enunarchivo,lasvariablesexternassepuedendefinircomoestáticas.Parahacerestose
colocaelespecificadordetipode almacenamientostaticalprincipiodeladefinición.Elám­
bitodeunavariableexternaestáticaserálaparterestantedelarchivoenelcualhasidode­
finida.Noseráreconocidaenningunaotrapartedelprograma(esdecir,enotrosarchivos). El
usodevariablesexternasestáticas dentrodeunarchivopermitequeungrupodevariablesesté
«oculto»alrestodelprograma.Otrasvariablesexternaspuedenestardefinidasconelmismo
nombreenlosarchivosrestantes.(Sinembargo,generalmentenoesunabuenaideautilizar
nombresidénticosdevariables.Estasvariablesconelmismonombrepuedencausarconfusión
enlacomprensióndelalógicadelprograma,aunquenoentraránenconflictosintácticounas con
otras).
EJEMPLO8.12.GeneracióndenúmerosdeFibonacci. Volvamosalproblemadecalcularnúmeros
deFibonacci,queoriginalmenteconsideramosenelEjemplo
8.7.Sisereescribeelprogramacomo
unprogramadedosarchivosutilizandovariablesestáticasexternas,seobtieneelsiguienteprograma
completo.
Primerarchivo:
/*programaparacalcularnúmerosdeFibonaccisucesivos*/
#include<stdio.h>
externlongintfibonacci(intcont);/*prototipodefunciónexter­
na*/
main() /*definicióndefunción* /
{
intcont
lni
printf(11¿CuantosnúmerosdeFibonacci?")i
scanf
(n%dn<,;&n)¡
printf(n 11)i

282 PROGRAMACiÓN ENC
for(cont=1,cont<=
printf('i=%2d
}
n;++cont)
F=%ld',cont,fibonacci(cont)),
Segundoarchivo:
/*calcularunnúmerodeFibonacci(F=lparai<3,yF=F1+F2parai>=3*/
staticlongintf1=1,f2=1,/*definicióndevariablesexter-
nasestáticas* /
longintfibonacci(intcont) /*definicióndefunciónexterna*/
{
longintf,
}
f=(cont<3) ?1
f2=f1;
f1=f;
return(f);
f1+f2;
Enesteprogramalafunciónfibonaccisedefineenelsegundoarchivoy sedeclaraenelprimero;por
ello
suámbitoestodoelprograma.Por otrolado,lasvariablesf1yf2sedefinencomovariablesexter­
nasestáticas.Obsérvese
queladefinicióndevariablesenelsegundoarchivoincluyelaasignación de
valoresiniciales.
Losresultadosqueseobtienensonidénticosa losmostradosenelEjemplo8.7.
8.6.MÁSSOBREFUNCIONESDEBIBLIOTECA
Nuestradiscusiónsobreprogramasmultiarchivopuedeaportarunavisiónadicionalsobreeluso
defuncionesdebiblioteca.Recuerdequelasfuncionesdebiblioteca
sonrutinaspreescritasque
realizanoperacionesocálculosqueseusancomúnmente(versección3.6).Estáncontenidasen
unoovariosarchivosdebibliotecaqueacompañanacadacompiladorde
C.
Duranteelprocesodeconvertirunprogramafuentede eenprogramaobjetoejecutable,el
programafuentecompiladoseenlazaconlos
archivosdebiblioteca paraproducirelprograma
ejecutablefinal.Deestaforma,elprogramafinalseconstruiráapartirdevariosarchivos,aun­
queelprogramafuenteoriginalestécontenidoenunsoloarchivo.Elprogramafuentedebe,por
tanto,incluirlasdeclaracionesparalasfuncionesdebiblioteca,lomismoqueparalasfunciones
definidasporelprogramadorquesedefinenenarchivosseparados.
Unmododeproporcionarlasfuncionesdebibliotecanecesariasconsisteenqueelprogra­
madorlasescribaexplícitamente,comoenlosprogramasmultiarchivomostradosenlaúltima
sección.Estopuederesultartedioso,puesunprogramapequeñopuedehacerusodevariasfun­
cionesdebiblioteca.Deseamossimplificaralmáximoelusodefuncionesdebiblioteca.
eofre­
ceuna'formainteligentedehacerlo,alcolocarlasdeclaracionesdefuncionesdebibliotecane­
cesariasenarchivosfuenteespecialesllamados
archivosdecabecera.
Lamayoríadeloscompiladoresde eincluyenvariosarchivosdecabecera,cadaunodelos
cualescontienedeclaracionesfuncionalmenterelacionadas(verApéndice
H).Porejemplo,
stdio.hesunarchivodecabeceraquecontienedeclaracionespararutinasdeentrada/salida;
math. hcontienedeclaracionesparaciertasfuncionesmatemáticas;yasísucesivamente.Los

ESTRUCTURA DEUNPROGRAMA 283
archivosdecabeceratambiéncontienenotrainformaciónrelacionadaconelusodefuncionesde
biblioteca,talcomolasdefinicionesdeconstantessimbólicas.
Losarchivosdecabeceradebensercombinadosconelprogramafuenteduranteelproceso
decompilación.Estoselogracolocandounaomásinstrucciones#includealcomienzodel
programafuente(oalcomienzodelosarchivosindividualesdelprograma).Hemosestadosi­
guiendoesteprocedimientoentodoslosejemplosdeprogramaciónmostradosenestelibro.
EJEMPLO8.13.
Interéscompuesto.ElEjemplo5.2presentabaoriginalmenteelsiguienteprograma e
paraefectuarcálculossimples deinteréscompuesto.
1*problemasencillodeinteréscompuesto*1
#include<stdio.h>
#include<math.h>
main()
{
floatP,r,n,i,fi
1*leerdatosdeentrada(mediantepeticionesrotuladas)*1
printf("Porfavor,introducelasumainicial(P):
11) ;
scanf(l1%f"I&p);
printf("Porfavor,introduceelinterés(r): 11)i
scanf("%f
ll
,&r);
printf("Porfavor,introduceelnúmerodeaños(n): 11)i
scanf(lI%f
ll
,&n);
1*calculari y f*1
i=r/lDD;
f=p *pow((1+i),n);
1*escribirlasalida*1
printf("Elvalorfinal(F)es:%.2f",f);
}
Esteprogramausadosarchivosdecabecera,s tdio. h Ymath.h.Elprimerarchivodecabeceracontie­
nedeclaracionesparalasfunciones
printfyscanf,mientrasqueelsegundocontienedeclaraciones
paralafunciónpotenciación,pow.
Sepuedereescribiresteprogramaquitandolasinstrucciones# inc1udeyañadiendonuestraspro-
piasdeclaraciones
defuncionescomosigue.
1*problemasencillodeinteréscompuesto*1
externintprintf();I*declaracióndefuncióndebiblioteca*1
externintscanf();1*declaracióndefuncióndebiblioteca*I
externdoublepow(double,double);1*declaración.defuncióndebi-
blioteca*I
main()
{
floatP,rlnIirfi

284 PROGRAMACiÓN ENC
/*leerdatosdeentrada(mediantepeticionesrotuladas)*/
printf("Porfavor,introducelasumainicial(P):");
scanf("%f
l1
,&p);
printf("Porfavor,introduceelinterés(r):");
scanf("%f
ll
,&r);
printf("Porfavor
lintroduceelnúmerodeaños(n): 11) ;
scanf(lI%f"/&n);
/*calculariyf*/
i=rIlOO;
f=p*pow((1+i),n);
/*escribirlasalida*/
printf("Elvalorfinal(F)es:%.2f",f);
}
Estaversióndelprogramasecompiladelamismamanera quelaversiónanterior ygenerarálamisma
salidacuando seejecute.Enlaprácticanosehaceusodeestasdeclaracionesdefuncionessuplementarias
definidasporelprogramador,pues
esmáscomplicadoygenerannuevasfuentes deerror.Esmás,el
procesodecomprobacióndeerroresqueserealizadurante elprocesodecompilaciónesmenoscompleto,
porque
noseespecificanlostiposdeargumentospara lasfuncionesprintfyscanf.(Observequeel
número
deargumentosenprintfyscanfpuedevariar deunallamadadefuncióna otra.Lamaneraen
queseespecificanlostiposdeargumentosbajoesascondiciones vamásalládelámbitodeestadiscusión.)
Laindependenciade laplataforma(esdecir,la independenciadelamáquina) esunaventaja
significativaenesteacercamientoalusodefuncionesdebiblioteca
ydearchivosdecabecera.De
estemodo,lascaracterísticasdependientesdelamáquinapuedenproporcionarsecomofunciones
debiblioteca,comoconstantesdecaracteresocomo
macros(versección14.4)incluidasenlos
archivosdecabecera.UnprogramatípicoenCfuncionaráenmuchascomputadorasdiferentessin
modificaciones,siemprequeseusenlasfuncionesdebibliotecaylosarchivosdecabeceraapropia­
dos.
Laportabilidadresultantedeesteenfoqueeslamayorcontribucióna lapopularidaddel C.
8.1.¿Quésignificadotieneeltipodealmacenamientodeunavariable?
8.2.Nombrarlascuatroespecificacionesdetiposdealmacenamientoincluidasen
C.
8.3.¿Quésignificaelámbitode un.avariabledentrodeunprograma?
8.4.¿Cuáleslafinalidaddeunavariableautomática?¿Cuálessuámbito?
8.5.¿Cómo
sedefmeunavariableautomática?¿Cómoseinicializa?¿Quésucedesiunavaria­
bleautomáticanoseinicializaexplícitamentedentrode
unafunción?
8.6.¿Retieneunavariableautomáticasuvalorunavezqueelcontrolestransferidofuerade
la
funciónenlaquesedefine?
8.7.¿Cuáleslafinalidaddeunavariableexterna?¿Cuálessuámbito?
8.8.Mencionarlasdiferenciasentre
unadefinicióndevariableexternay unadeclaraciónde
variableexterna.

ESTRUCTURA DEUNPROGRAMA 285
8.9.¿Cómosedefineunavariableexterna?¿Cómoseinicializa?¿Quésucedesiunadefini­
ción
devariableexternanoincluyelaasignación deunvalorinicial?Compararlasres­
puestasconlas
devariablesautomáticas.
8.10.Suponerqueunavariableexternasedefinefuera deunafunciónA yseaccedeaella
dentro
deésta.¿Importasilavariableexternasedefineantesodespuésdelafunción?
Explicarlo.
8.11.¿Enquésentidoesmásrestrictivalainicialización deunavariableexternaquela deuna
variableautomática?
8.12.¿Quéseentiendeporefectoslaterales?
8.13.¿Quépeligrosinherenteshayenelusodevariablesexternas?
8.14.¿Cuáleslafinalidad deunavariableestáticaenunprograma deunsoloarchivo?¿Cuáles
suámbito?
8.15.¿Cómosedefineunavariableestáticaenunprogramadeunsoloarchivo?¿Cómose
inicializaunavariableestática?Compararconlasvariablesautomáticas.
8.16.¿Bajoquécircunstanciaspuedeserdeseabletenerunprogramacompuestoporvariosarchivos?
8.17.Compararladefinicióndefuncionesdentro deunprogramamultiarchivoconladefini­
cióndefunciones dentrodeunprogramadeunsoloarchivo.¿Quéopcionesadicionales
estándisponiblesenelcasomultiarchivo?
8.18.Enunprogramamultiarchivo,¿cuál eseltipodealmacenamientoporomisiónparauna
funciónsinoseincluyeexplícitamenteenladefinición?
8.19.¿Cuáleslafinalidad deunafunciónestáticaenunprogramamultiarchivo?
8.20.Compararladefinición devariablesexternasenunprogramamultiarchivoconladefini­
cióndevariablesexternasenunprograma
deunsoloarchivo.¿Quéopcionesadicionales
estándisponiblesenelcasomultiarchivo?
8.21.Compararlasdefiniciones devariablesexternasconlasdeclaracionesdevariablesexter­
nasenunprogramamultiarchivo?¿Cuál
eslafinalidaddecadauna?¿Puedeunadeclara­
ción
devariableexternaincluirlaasignación deunvalorinicial?
8.22.¿Bajoquécircunstanciaspuededefinirseunavariableexternacomoestática?¿Quéventa­
japuedehaberenhaceresto?
8.23.¿Cuáleselámbito deunavariableestáticaexterna?
8.24.¿Cuáleslafinalidaddeunarchivodecabecera?¿Esabsolutamentenecesarioeluso deun
archivodecabecera?
8.25.Describirlasalidageneradaporcadaunodelossiguientesprogramas.
a)#include<stdio.h>
intfuncl(intcont);
main()
{

286 PROGRAMACiÓN ENC
inta,cont¡
for(cont=1;cont<=5;++cont){
a=funcl(cont);
printf("%d lita)¡
}
}
funcl(intx)
{
inty
=O;
y+=Xi
return(y);
}
b)#inc1ude<stdio.h>
intfuncl(intcont);
main()
{
inta,cont;
for(cont=1;cont<=5;++cont){
a=funcl(cont);
printf("%d",a);
}
}
funcl(intx)
{
staticinty=O;
y+=Xi
return(y);
}
e)#inc1ude<stdio.h>
intfuncl(inta);
intfunc2(inta);
main()
{
inta=O,b =1,cont¡
for(cont=1;cont<=5;++cont){
b
+=funcl(a)+func2(a);
printf("%d
",b);
}
}

ESTRUCTURA DE UNPROGRAMA 287
func1(inta)
{
intb;
b=func2(a);
return(b);
}
func2(inta)
{
staticintb=1;
b+=1;
return(b+a);
}
8.26.Escribirlaprimeralineadeladefinicióndefunciónparacadaunadelassiguientessituaciones
descritasacontinuación.
a)Elsegundoarchivodeunprogramacondosarchivoscontieneunafunciónllamadaresolver
queaceptadoscantidadesencomaflotante
ydevuelveunargumentoencomaflotante.La
funciónserállamadaporotrasfuncionesqueestándefinidasenambosarchivos.
b)Elsegundoarchivodeunprogramacondosarchivoscontieneunafunciónllamadaresolver
queaceptadoscantidadesencomaflotante
ydevuelveunargumentoencomaflotante,como
enelproblemaanterior.Elreconocimientodeestafuncióndebeserlocalalsegundoarchivo.
8.27.Añadirlasdeclaracionesdefuncionesrequeridas(osugeridas)paracadaunodelosesquemas
mostradosacontinuación.
a)Ésteesunprogramadedosarchivos.
Primerarchivo:
main()
{
doub1ex,y,Z',
z=func1(x,y);
}
Segundoarchivo'
doub1efunc1(doub1ea,doub1eb)
{
}

288 PROGRAMACiÓN ENC
b)Ésteesunprogramadedosarchivos.
Primerarchivo:
main()
{
doublex,y,
z =func1(x,
}
Segyndoarchivo:
z',
y);
doublefunc1(doublea,doub1eb)
{
doublee;
e =func2(a,b);
}
staticdoublefunc2(doublea,doub1eb)
{
}
8.28.Describirlasalidageneradaporcadaunodelossiguientesprogramas.
a)#include<stdio.h>
inta=3;
intfunc1(intcont);
main()
{
intcont;
for(cont=1;cont<=5;++cont){
a =
func1(cont};
printf("%d",a);
}
}

ESTRUCTURA DEUNPROGRAMA 289
funel(intx)
{
a+=Xi
return(a);
}
b)#inelude<stdio.h>
inta =100,b =200;
intfunel(inta,intb);
main()
{
intcont,e,di
for(eont=1;eont<=5;++eont){
e =
20*(eont-1);
d=4*cont*cont¡
printf("%d%d funel(a,e),funel(b,d));
}
}
funel(intx,inty)
{
return(x-y);
}
e)#inelude<stdio.h>
inta =100,b =200;
intfunel(inte);
main()
{
intcont,C¡
for(eont=1;eont<=5;++eont)(
e=4*cont*cont¡
printf("%d"funel(e));
}
}
funel(intx)
{
inte;
}
e=(x<50)?(a+x)
return(e);
(b-x);

290 PROGRAMACiÓN ENC
d)#inelude<stdio.h>
inta =100,b =200;
intfunel(inteont);
intfune2(inte);
main()
{
intcont;
for(eont=1;
printf("%d
}
funel(intx)
{
inte,di
eont<=5;++eont)
"funel(eont));
e =fune2(x);
d=(e<100)?(a+e)b;
return(d);
}
fune2(intx)
{
statieintprod=1;
prod*=Xi
return(prod);
}
e)#inelude<stdio.h>
intfunel(inta);
intfune2(intb);
main()
{
inta=O,b=1,cont¡
for(eont=1;eont<=5;++eont){
b+=
funel(a+1)+1;
printf("%d",b);
}
}
funel(inta)
{
intb;

ESTRUCTURA DEUNPROGRAMA 291
b =func2(a+1)+1;
return(b);
}
func2(inta)
{
return(a+1);
}
fl#include<stdio.h>
inta =0,b =1;
intfunc1(inta);
intfunc2(intb);
main()
{
intcont;
for(cont=1;cont<=5;++cont){
b+=
func1(a+1)+1;
printf("%d",b);
}
}
func1(inta)
{
intb;
b =func2(a+1)+1;
return(b);
}
func2(inta)
{
return(a+1);
}
g)#include<stdio.h>
inta =0,b =1;
intfunc1(inta);
intfunc2(intb);
main()
{
intcont¡

292 PROGRAMACiÓN ENC
for(cont=1;cont<=5;++cont){
b+=
func1(a+1)+1;
printf(U%d n,b);
}
}
func1(inta)
{
b =func2(a+1)+1;
return(b);
}
func2(inta)
{
return(b+a);
}
h)#inc1ude<stdio.h>
intcont=O;
voidfunc1(void);
main()
{
printf("Porfavor,introduzcaunalíneadetexto");
func1();
,
printf (11%d111cont);
}
voidfunc1(void)
{
charc¡
if((c =getchar())!='') {
++cont;
func1();
}
return;
}
8.29.ElprogramadadoenelEjemplo8.4puedemodificarsefácilmentepara minimizarunafuncióndex.
Esteprocedimientodeminimizaciónnospuedeproporcionarunatécnicaaltamenteeficazpara
calcularlasraícesdeunaecuaciónalgebraicanolineal.Porejemplo,supóngasequequeremos

ESTRUCTURA DEUNPROGRAMA 293
encontrarelvalorconcretodexquehacequeunafunciónfl:x)seaigualacero.Unafuncióntípica
deestetipopuedeser:
fl:x)=x+cos(x)- 1 -sen(x)
Síhacemos
y(x)=
fl:x)',entonceslafunción y(x)serásiemprepositiva,exceptoparaaquellosvalo­
resde
xqueseanraícesdelafuncióndada[paraloscuales
fl:x)yportanto y(x)sonígualesacero].
Portanto,cualquiervalorde
xqueminimicea y(x)esunaraízdela
ecuaciónfl:x)=O.
ModificarelprogramadelEjemplo8.4paraminimizarunafuncióndada.Usarelprograma
paraobtenerlasraícesdelassiguientesecuaciones:
a)x+cos(x)=1+sen(x),
nl2<x<n
b)x'+3x'=10, O <=X<=3(verEjemplo6.21)
8.30.ModificarelprogramadelEjemplo7.11deformaquesesimuleautomáticaynointeractivamente
unasecuenciadeljuegodedados«Craps».Introducirelnúmerototaldejuegoscomovariablede
entrada.Incluirdentro delprograma
uncontadorquedetermineelnúmerototaldevictorias.Utili­
zarelprogramaparasimularunnúmerograndedejuegos(porejemplo1000).Estimarlaprobabi­
lidaddeganarenestejuegodedados.Estevalor,expresadoendecimal,esigualalnúmerode
victoriasdivididoentreelnúmerototaldepartidasjugadas.Silaprobabilidadexcedede0,500,es
favorablealjugador;delocontrarioesfavorablealabanca.
8.31.Reescribircadaunodelossiguientesprogramasdeformaqueincluyaalmenosunafuncióndefini­
daporelprogramador,ademásdelafunciónprincipal.Tengacuidadocon
laeleccióndeargumen­
tosy(siesnecesario)devariablesexternas.
a)Calcularlamediaponderadadeunalistadenúmeros[verProblema 6.69(a)].
b)
Calcularelproductoacumuladodeunalistadenúmeros[verProblema 6.69(b)].
e)Calcularlamediageométricadeunalistadenúmeros[verProblema 6.69(c)].
d)Calcularytabularunalistadenúmerosprimos[verProblema6.69(1)].
e)Calcularelsenode x,usandoelmétododescritoenelProblema 6.69(i).
1)Calcularlospagosdeunpréstamo[verProblema6.69(j)].
g)Determinarlacalificaciónmediaenlosexámenesdecadaestudiantede laclase,comosedes­
cribeenelProblema
6.69(k).
8.32.EscribirunprogramacompletoenCpararesolvercadaunodelosproblemasdescritosacontinua­
ción.Utilizarfuncionesdefinidasporelprogramadordondecorresponda.Compilaryejecutarel
programaconlosdatosdadosenladescripcióndelproblema.
a)SupongaquesedepositaunacantidaddadadedineroAen unalibretadeahorrosalprincipiode
cadaañodurante
naños.Sisepercibe uninterésianual,entonceslacantidadFdedineroque
seacumularátrasnañosvienedada
por
F=A[(1+mOa)+(1+i/lOO)'+(i+i/lOO)'+...+(1+
i/lOO)"]
EscribirunprogramaCenestiloconversacionalquedeterminelosiguiente:

294 PROGRAMACiÓN ENC
i)¿Cuántodineroseacumularádespuésde3 Oañossisedepositan100dólaresalcomienzo
decadaañoyeltipodeinteréscompuesto
esdel6por 100anual?
ii)¿Cuántodinerosedebededepositar
alcomienzodecadaañoparaacumular100000dólares
despuésde3 Oaños,suponiendotambiénuntipodeinteréscompuestodel6por
100anual?
Encadacaso,determinarprimerolacantidaddedinerodesconocida.Luegocrear
unatabla
mostrandolacantidadtotaldedineroqueseacumularáalfinaldecadaaño.Utilizarlafunción
escritaparaelProblema7.43paraobtenerlapotenciación.
b)Modificarelprogramaanteriorparaobtenerinteresestrimestrales envezdeanuales.Comparar
losresultadosobtenidosparaambosproblemas.
Sugerencia:lafórmulaadecuadaes
F=A[(1+i/lOOm)m+(1+i/lOOm)2m+(i+i/lOOm)'m+...+(1+
i/lOOmr]
dondemrepresentaelnúmerodeperiodosdeinterésporaño.
c)Elcostedelahipotecadeunacasasedeterminademodoqueeldeudorpagalamismacantidad
dedineroalmesalainstituciónprestatariaduranteeltiempodehipoteca.Lafraccióndelpago
mensualtotalquesedestinaalosinteresesdeltotalprincipaldelpréstamovaria,sinembargo,
deunmesaotro.Alcomienzodelahipotecalamayoríadelpagomensualsedestinaalpagode
losinteresesysólo
unapequeñafracciónareducirelpagodelpréstamo.Gradualmente,el
principaldelpréstamosereduce,loqueprovocaqueel
pagomensualdeinterésdecrezca.
Comoconsecuencia,eltotaldelpréstamosereducearitmoacelerado.
Normalmente,loscompradoresdecasassabencuántodinerotienenquepedirprestadoyel
tiempoqueserequiereparasupago.Entoncespreguntanaunainstituciónprestatariacuálserá
elpagomensualconelinterésestablecido.Tambiénestánalcorrientedequécantidaddelpago
mensualsedestinaalpagodelosintereses,qnéinteréstotalhanpagadodesdequesolicitaron
elpréstamoycuántoadeudanalfinaldecadames.
Escribir
unprogramaenCquepuedaserusadoporunainstituciónqueprestedineropara
suministrarestainformaciónaunclientepotencial.Suponerqueseespecificanlacantidaddel
préstamo,elinterésanualy
laduracióndelpréstamo. Lacantidadpagadamensualmentese
calculacon:
A=i P(1+
i)"/[(1+i)"-1]
dondeA=pagomensual,dólares
P=cantidadtotaldelpréstamo,dólares
i=interésmensual,expresado endecimal(estoes, 1/2porcientosedebeescribir
0.005)
n=númerototaldepagosmensuales
Elpagomensualdeinteresessepuedecalcularconlafórmula
[=iB
dondeI=pagomensualdeintereses,dólares
B=principalactual,dólares
Elprincipalactualessimplementeiguala
lacantidadoriginal delpréstamo,menoslasumade
lospagospreviosdestinadosalcapitalprincipal.Elpagomensualdestinadoalcapitalprincipal
(estoes,lacantidad
enlacualsereduceelpréstamo)essimplemente
T=A-I
dondeT=pagomensualdestinadoalcapitalprincipal.

ESTRUCTURA DEUNPROGRAMA 295
Utilizarelprogramaparacalcularelcoste deunahipotecade5OOOOdólaresa 25años
conuninterésanualdel8por
10O.Repetirloscálculosparauninterésanualdel 8.5
por
10O.¿Quéimpacto tieneelincrementodelinterésen elO.5por100enelpagototal dela
hipoteca?
d)Elmétodoutilizadoparacalcularelcostedeunahipotecausadoenelproblemaanteriorse
conocecomométodo
decuotafija, yaqueelpagomensualeselmismo.Supóngasequelos
pagosmensualessecalculanporelmétododelinteréssimple.Esdecir,quelamismacantidad
seaplicaparareducirelpréstamocadames.Portanto
Elinterésmensual,sinembargo,dependerádela cantidaddelpago,estoes,
l=iB
Portanto,elpagomensualtotal, A=T+l,decrecerácadamessegúndisminuyeelpago.
EscribirunprogramaenCparacalcularelcostedeunahipotecautilizandoestemétodode
pago.Etiquetarclaramentelasalida.Usarelprogramaparacalcular
elcostedeunahipotecade
5OOOOdólaresa 2 5añosconuninterésanualdel 8por 10O.Compararlosresultadosconlos
obtenidosenelapartado
e).
e)Supongaquesedanunaseriedepuntosdiscretos (x"Y,),(x"
y,),...,(x"Y,)leídosdelacurva
y=f(x),dondexestáacotadaentre x,yx,,Sedeseaaproximareláreaencerradaporlacur­
vadescomponiendolacurvaenunnúmerodepequeñosrectángulosycalculandoelárea
de
estosrectángulos.(Estoseconocecomola regladeltrapecio.) Lafórmulaadecuadaes
Tengaencuentaquelaalturamediadecadarectángulovienedadapor
(y,+Y,+,)/2ylaanchura
decadarectánguloesiguala (x,+!
-x,);i=1,2,...,n-1.
EscribirunprogramaenCqueimplementeestaestrategia,usandounafunciónparaevaluar
lafórmulamatemática
y=f(x).Utilizarelprogramaparacalculareláreabajolacurva y=x'
entreloslímites x=1 Yx=4.Resolveresteproblemaprimerocon 16puntosespaciados,luego
con
61puntosyfinalmentecon3 O1puntos.Observequelaprecisióndelasoluciónmejora
segúnaumentaelnúmerodepuntos.(Larespuestaexactaaesteproblemaes63.
75.)
1)Elproblemaanteriordescribeunmétodoconocidocomola regladeltrapecio paracalcularel
áreaencerradaporunacurva y=f(x),dondeseusanunaseriedevalorestabulados (x"Y,),(x"
Y,),...,(x"y,jparadescribirlacurva.Silosvalorestabulados dexestánequiespaciados,enton­
ceslaecuacióndadaenelproblemaanteriorpuedesimplificarsea
A=(y,+2Y2+2y,+2Y4+...+
2y,_,+y,jhl2
dondehesladistanciaentredosvaloressucesivosde x.
Otratécnicaaplicablecuandohayunnúmeropardeintervalosigualmenteespaciados(un
númeroimpardepuntos)esla
regladeSimpsQn. Laecuaciónparaimplementarlaregla de
Simpsones

296 PROGRAMACiÓN ENC
Paraunvalordado deh,estemétodoproporcionamayorexactitudquelaregladeltrapecio.
(Observeque
elmétodorequierecasilamismacomplejidadcomputacionalquelaregladel
trapecio.)
EscribirunprogramaenCparacalculareláreaencerradaporunacurvausandoambas
técnicas,suponiendounnúmeroimpardepuntosespaciadosporigual.Implementarcadamé­
todoconunafunciónseparadayutilizarotrafunciónparaevaluar
y(x).
Usarelprogramaparacalculareláreaencerradaporlacurva
donde
xvadeOal.Calculareláreausandocadamétodo ycompararlosresultadosconla
respuestacorrectade
A=0.7468241.
g)Otratécnicaadicionalparacalculareláreaencerradaporunacurvaesemplearelmétodode
MonteCarla, quehaceusodenúmerosgeneradosaleatoriamente.Supongaquelacurva
y=j{x)espositivaparacualquiervalor dexentreloslímitessuperioreinferior x=ayx=b.
Seay'elmayorvalorde ydentrodeestoslímites.ElmétododeMonteCarlafuncionaasí:
i)Empezarconuncontadoracero.
ii)Generarunnúmeroaleatorio,
r
x
'
devalorcomprendidoentre ayb.
iii)Evaluar
y(r).
iv)Generarunsegundonúmeroaleatorio, r,devalorcomprendidoentre Oey'.
y
v)Compararr
y
cony(r).Sir
y
esmenoroigualquey(r),entoncesestepuntocaerásobreo
debajodelacurvadada.Entalcasoelcontadorseincrementaen
l.
vi)Repetirlospasosdelii)alv)unnúmerograndedeveces.Cadarepeticiónsedenomina
un
ciclo.
vii)Calcularlafracción Fdepuntosquecaenenobajolacurvatrascompletarunnúmerode
ciclos,dividiendoelvalordelcontadorporelnúmerototaldeciclos.Eláreabajola
curvaseobtienecomo
A=Fy'(b-a).
EscribirunprogramaenCqueimplementeestaestrategia.Usaresteprogramaparacalcu­
lareláreaencerradaporlacurva
y
~e-Xentreloslímites a=OYb=l.Determinarcuántos
ciclossonnecesariosparaobtenerelresultadoconunaprecisióndetrescifrassignificativas.
Comparareltiempo
decálculorequeridoparaesteproblemaconeltiemporequeridoparael
problemaanterior.¿Quémétodoesmejor?
h)Unavariablealeatorianormalmentedistribuida, x,conmedia
!J.ydesviaciónestándareJ,se
puedegenerarconlafórmula
N
2>-NI2
x=f1+o..Jic=-.L!r="~~-
.JN/12
donder.esunnúmeroaleatoriounifOrmementedistribuido'devalorcomprendidoentre Oyl.,
Normalmenteseseleccionaunvalor N=12cuandoseutilizaestafórmula.Labasedelafórmula
esel
teoremadellimitecentral, queestablecequeunconjuntodevaloresmediosdevariables
aleatoriasuniformementedistribuidastiendeaestaruniformementedistribuido.

ESTRUCTURA DEUNPROGRAMA 297
EscribirunprogramaenCquegenereunnúmeroespecificadodevariablesaleatoriasnor­
malmentedistribuidasconunamediayunadesviaciónestándardadas.Suponerque
elnúmero
devariablesaleatorias,lamediayladesviaciónestándarsondatosdeentradadelprograma.
Generarcadavariablealeatoriaconunafunciónqueaceptelamediayladesviaciónestándar
comoargumentos.
i)EscribirunprogramaenCquepermitaaunapersonajugaralastresenrayaconlacomputado­
ra.Escribirelprogramadeformaquelacomputadorapuedasertantoelprimerocomoelse­
gundojugador.Silacomputadoraeselprimerjugador,elprimermovimientosegeneraráal
azar.Mostrarelestadodeljuegotrascadamovimiento.Lacomputadoradebesabercuándo
ganacadajugador.
j)EscribirunprogramacompletoenCqueincluyaunafunciónrecursivaparadeterminarelvalor
deln-ésimonúmero
deFibonacci,
F"dondeF,=F,_¡+F'_2yF¡=F
2
=I(verEjemplo8.7).
Considerarelvalor
dencomoundatodeentrada.

CAPíTULO9
Arrays
I!!ww.._:_m.",..+»",g ,.",,_,W1ilI.,,'",._rni!f}) ;;ti"' '''''!W~__,"'é"'''iilll'''''__''~
Muchasaplicacionesrequierenelprocesamiento demúltiplesdatosquetienencaracterísti­
cascomunes(porejemplo,unconjuntodedatosnuméricos,representadosporxI'
x
2
'•••,
x
n
).En
talessituacionesesamenudoconvenientecolocarlosdatosenunarray,dondetodoscomparten
elmismonombre(porejemplox).Losdatosindividualespuedensercaracteres,enteros,núme­
ros encomaflotante,etc.Sinembargo,todosdebenserdelmismotipo
dedatosyconelmismo
tipodealmacenamiento.
.
Cadaelementodelarray(estoes,cadadatoindividual)esreferenciadomediantelaespecifi­
cacióndelnombredelarrayseguidoporunoomásindices,concadaíndiceencerradoentre
paréntesiscuadrados.Cadaíndicedebeserexpresadocomounenterononegativo.Asíenun
array
denelementos,loselementosdelarraysonx [O],x[1],x[2],...
,x[n-l],
comoseilustraenlaFigura9.1.Elvalor decadaíndicepuedeserexpresadocomounaconstante
entera,unavariableenteraounaexpresiónenteramáscompleja.
x[O] x[l] x[2] x[n-2]x[n-l]
xesun arrayunidimensionalde nelementos
Figura9.1.
Elnúmero de.índicesdeterminanladimensionalidaddelarray. Porejemplo,x [i]re­
ferenciaa
unelementodelarrayunidimensional x.Análogamente,y [ i][j]referenciaa
unelementodelarraybidimensional y.(Sepuedepensarque
unarraybidimensionales
unatabla,dondey [i][j]eselelemento jdelafilai.)Sepuedenformulararraysde
mayordimensión,añadiendoíndicesadicionalesdelamismamanera(porejemplo,
z[i][j][kl).
Recuérdesequeyahemosutilizadoarraysunidimensionalesantesenestelibro,conjunta­
menteconelprocesamientodecadenasdecaracteresylíneasdetexto.Porconsiguiente,los
array'snosonalgocompletamentenuevo,.aunquenuestrasreferencias.anterioresfueroncasua­
les.Ahoraconsideraremoslosarraysconmayordetalle.Enparticularsetratarálamanera
.de
definiryprocesararrays,elpaso dearrays.afuncionesylautilizacióndeformacionesmultidi­
mensionales.Seconsiderarántantoarraysnuméricoscomodecaracteres.Inicialmentenoscen-
299

300 PROGRAMACiÓN ENC
traremosenlosarraysunidimensionales,sibienlosarraysmu1tidimensionalesseconsiderarán
enlasección9.4.
9.1.DEFINICIÓN DEUNARRAY
Losarrayssedefinencomolasvariablesordinarias,acompasandoacadanombre dearray
con
unaespecificacióndetamaño(númerodeelementos).Paraunarrayunidimensional,el
tamañoseespecificaconunaexpresiónenterapositivaencerradaentreparéntesiscuadra­
dos.
Entérminosgenerales,unadefinicióndearrayunidimensionalpuedeexpresarsecomo
tipo-de-almacenamientotipo-datoarray[expresión];
dondetipo-de-almacenamientoserefierealtipo dealmacenamientodelarray, tipo­
datoeseltipo dedatos,
q.rrayeselnombredelarrayy expresiónesunaexpresiónentera
positiva.queindicaelnúmero
deelementosdelarray.El tipo-de-almacenamientoes
opcional;losvaloresporomisiónson automaticparaarraysdefinidosdentrodeunafunción
obloque,y
externparaarraysdefinidosfueradeunafunción.
EJEMPLO9.1.Acontinuaciónsemuestranalgunasdefinicionestípicas dearraysunidimensio­
nales.
intx[100];
chartexto[80];
staticcharmensaje[25];
staticf10atn[12];
Laprimeralíneaestablece quexesunarrayde100elementosenteros,ylasegundadefine texto
comounarrayde8Ocaracteres.Enlaterceralínea sedefinemensajecomounarrayestáticode25
caracteres,mientras quelacuartaestablece quenesunarrayestáticode12elementosencomaflo­
tante.
Algunasveces
esconvenientedefinireltamañodeun arrayentérminosdeunaconstante
simbólica
envezdeunacantidadenterafija.Estohacemásfácilmodificarunprogramaque
utilizaunarray,yaquetodaslasreferenciasaltamañomáximodelarray(porejemplo,enbucles
foroendefinicionesdearrays)puedenseralteradascambiandosimplementeel valordela
constantesimbólica.
EJEMPLO·
9,2.Cónversióndetextoen minúsculasa mayúsculas.AcontinuaciónpreseIltamosun
programacompletoqueleeunarrayunidimensional decaracteres,conviertetodos suselementosa
mayúsculasy.escribe
elarraymodificado.Programassiniilares semuestranenlosEjemplos4.4,6.9,
6.12y6.16.

ARRAYS 301
/*leerunalíneadetextoenminúsculasyescribirlaenmayúsculas*/
#include<stdio.h>
#include<ctype.h>
#defineTAMANO80
main()
{
charletras(TAMANO];
intcont;
/*leerlalínea*/
for(cont=O;cont<TAMANO;++cont)
letras[cont]=getchar();
/*escribirlalíneaenmayúsculas*/
for(cont=O;cont<TAMANO;++cont)
putchar(toupper(letras[cont]));
}
Observequelaconstantesimbólica TAMANOtieneasignadounvalor de8O.Enladefinicióndelarray
yenlasdosinstruccionesforapareceestaconstantesimbólicaen vezdesuvalor.(Recuerdeque elvalor
de
laconstantesimbólicaserásustituido porlaconstantedurante elprocesode
compilación.)Portanto,
paraalterar
elprogramaacomodándoloadiferentestamañosdelarray,sólo debecambiarselainstrucción
#define.
Porejemplo,paraalterar elprogramaanterior demodoqueprocese unarrayde6Oelementos,simple­
mente
sereemplazalainstrucción #defineoriginalpor
#defineTAMANO60
Esteúnicocambio seencargadetodaslasalteracionesnecesarias delprograma;nohayposibilidadde
pasarporaltoalgunasmodificacionesnecesarias.
Losarraysautomáticos,adiferencia delasvariablesautomáticas,nopuedenserinicializa­
dos.
Sinembargo,lasdefinicionesdearraysexternosyestáticospuedenincluir,sisedesea,la
asignacióndevaloresiniciales.Losvaloresinicialesdebenaparecer
enelordenenqueserán
asignadosaloselementosindividualesdelarray,encerradosentre
llavesyseparadosporcomas.
Laformagenerales
tipo-de-almacenamientotipo-datoarray[expresión]=
{valor1,valor2,. o,valorn}¡
dondevalor1serefierealvalordelprimerelemento.delarray, valor2alvalordelsegun­
doelemento,yasísucesivamente.
Lapresenciade·laexpresión,queindicaelnÚ1llerode
elementosdelarray,esopcionalcuandoestánpresenteslosvaloresiniciales.

302 PROGRAMACiÓN ENC
EJEMPLO9.3. Acontinuaciónsemuestranvariasdefiniciones dearraysqueincluyenlaasignación de
valoresiniciales.
intdigitos[lO]={l,2,3,4,5,6,7,S,9,lO};
staticfloatx[6]={O,0.25,O,-0.50,O,O};
charcolor[4]={IRI , fO'/ 'J'/ 'O/}i
Observeque xesunarrayestático.Losotrosdosarrays (digitosycolor)sesuponequesonexternos
envirtuddesucolocacióndentrodelprograma.
Elresultado
deestasasignacionesiniciales,entérminosdeloselementosindividualesdelarray,esel
siguiente.(Recordarquelosíndicesdeunarraydenelementosvan
deOa n-1.)
digitos[O]=1 x[O]=O color[O]='R'
digitos[l]=2 x [1]=0.25color[l]='o'
digitos[2]3 x [2]=O color[2]='J'
digitos[3]=4 x [3]=-0.50color[3]='o'
digitos[4]=5 x [4] O
digitos[5]=6 x [5]=O
digitos[6]=7
digitos[7]=S
digitos[S]=9
digitos[9]=10
Todosloselementosdelarrayque
notienenasignadosvaloresinicialesexplícitosseránpues­
tosautomáticamenteacero.Estoincluyealrestodeloselementosdeunarrayenelqueun.cierto
númerodeelementostienenasignadosunvalordistintodecero.
EJEMPLO9.4. Considerarlassiguientesdefinicionesdearrays.
intdigitos[lO]={3,3,3};
staticfloatx[6]={-0.3,O,0.25};
Losresultados,elementoaelemento,son:
digitos[O]=3 x [O]=-0.3
digitos[1]=3 x [1]=O
digitos[2]=3 x[2]=0...25
digitos[3]=O x [3]=O
digitos.[4]=O x [4]=O
digitos[5]=O x [5]=O
digitos[6]=O
digitos[7]=O
digitos[S]=O
digitos[9]=O
Encadacaso,todosloselementosdeIariayseponenautomáticamenteacero,exceptolosquehansido
explícitamenteinicializadosdentrode
ladefinicióndelarray.Observequelosvaloresrepetidos(porejem­
plo
3, 3,3)sedebenponerseparadamente.

ARRAYS 303
Eltamañodelarraynonecesitaserespecificadoexplícitamentecuandoseincluyenlosvalo­
resinicialescomounapartedeladefinicióndelarray.Conunarraynumérico,eltamañodel
arrayseráfijadoautomáticamenteigualqueelnúmerodevaloresincluidosdentrode
ladefini­
ción.
EJEMPLO9.5. Considerarlassiguientesdefiniciones dearrays,quesonvariacionesdelas
definicio
C
nesmostradasen losEjemplos9.3y9.4.
intdigitos[]={l,2,3,4,5,6};
staticfloatxl]={O,0.25,O,-0.5};
Asidigitosseráunarraydeseiselementosy",unarrayestáticodecuatroelementos encomaflotante.
Loselementosindividualestendrán asignados lossiguientesvalores. (Observeloscorchetesvacíosenlas
declaracionesdelosarrays.)
digitos[O]=1 x[O] =O
digitos[l]2 x [1]=0.25
digitos[2]=3 x [2]=O
digitos[3]=4 x [3]=-0.5
digitos[4]=5
digitos[5]=6
Lascadenasdecaracteres(arraysdecaracteres)sonmanejadasdemodoalgodiferente,como
seindicó
enlasección2.6. Enparticular,cuandoseleasignaunacadenadecaracteresconstante
aunarrayestáticooexternocomopartede
ladefinición,laespecificacióndeltamañodelarray
normalmenteseomite.Eltamañoadecuadoseráasignadoautomáticamente.Estoincluirálapro­
visión
paraelcarácternulo\ O,queseañadeautomáticamentealfinaldecadacadenadecarac­
teres(verEjemplo2.26).
EJEMPLO9.6. Considerarlasdosdefinicionessiguientes dearraysdecaracteres.Cadauna deellas
incluyelaasignacióninicial
delaconstantedecadenadecaracteres"ROJO".Sinembargo,elprimer
array
sedefinecomounarraydecuatroelementos,mientras quenoseespecificaeltamañodelsegundo
array.
charcolor[4]="ROJO";
charcolor[].="ROJO
I
!;
Elresultadodeestasasignacionesiniciales noeselmismodebidoalcarácternulo,\ O,queseañade
automáticamentealfinal
delasegundacadena. Deestemodo,loselementosdelprimerarray s.on
color[O]='R'
color[l]='o'
color[2]='J'
color[3]'o'
mientrasqueloselementosdelsegundoarrayson

304 PROGRAMACiÓN ENC
colar[O]='R'
color[l]='O'
color[2]='J'
color[3]='O'
color[4]='\0I
Portanto,laprimera formaesincorrecta,yaqueelcarácternulo\ O noseincluyóenelarray.
Ladefinición
delarraypodríahaberseescrito como
charcolor[5]="ROJO";
Estadefiniciónescorrecta,yaqueahoradefinimos unarraydecincoelementos queincluyeunelemento
paraelcarácter
nulo.Sinembargo,muchosprogramadoresprefieren laprimeraforma,queomiteel
espe~
cificadordetamaño.
Sielprogramarequiereuna declaracióndeunarrayunidimensional(porqueelarrayestá
definidoencualquierotrapartedelprograma),ladeclaraciónseescribede
lamismamaneraque
ladefinicióndelarrayconlassiguientesexcepciones:
1.Los corchetespuedenestarvacíos, yaqueeltamaño hasidoespecificadocomopartede
ladefinición.Lasdeclaracionesdearraysseescribenhabitualmentedeestamanera.
2.Nosepuedenincluirvaloresiniciales
enladeclaración.
Estasreglasseaplicantantoadeclaracionesdeargumentosformalesdentrodelasfunciones
comoadeclaracionesdevariablesexternas.Sinembargo,lasreglas
paradefinirargumentos
formales
multidimensionalessonmáscomplejas(versección9.4).
EJEMPLO9.7. Acontinuaciónsemuestraelesqueletodelaestructuradeunprogramaenequehace
usodearraysexternos.
Primerarchivo
intc[]={l,2,3);
charmensaje[J= njHola
tn;
externvoidfuncl(void);
main()
{
}
Sevundoarchivo
externintc[];
externcharmensaje[];
/*DEFINICIONdearrayexterno*/
/*DEFINICIONdearrayexterno*/
/*prototipodefunción*/
/*DECLARACIONdearrayexterno*/
/*DECLARACIONdearrayexterno*/

externvoidfuncl(void)
{
}
ARRAYS 305
/*definicióndefunción*/
Esteesquemadeprogramaincluyedosarraysexternos,c y mensa je.Elprimerarray (c)esun
array
detreselementosenteros quesedefineneinicializanenelprimerarchivo.Elsegundoarray (men­
saje)esunarraydecaracteresdefinidoeinicializadotambiénenelprimerarchivo.Losarraysestán
luego
declaradosenelsegundoarchivo,yaquesonarraysglobalesquedebenserreconocidosentodoel
programa.
Nilasdefinicionesdearrays
enelprimerarchivonilasdeclaraciones dearraysenelsegundoarchivo
incluyenespecificaciónexplicita
detamaño.Estasespecificacionessepermitenenelprimerarchivo,pero
seomitendebidoalainicialización.Además,lasespecificacionesdetamañodelosarraysnotienensen­
tido
enelsegundoarchivoporqueeltamaño delosarraysyahasidofijado.
9.2.PROCESAMIENTO DEUNARRAY
Enenosepermitenoperacionesqueinvolucrenarrayscompletos.Así,sia y bsonarrays
similares(mismotipodedatos, mismadimensionalidadymismotamaño),opera­
cionesdeasignación,decomparación,etc.,debenrealizarseelementoporelemento.Estose
hacenormalmentedentrode unbucle,dondecadapasadaporelbucleseusaparaprocesarun
elementodelarray.Elnúmerodepasadasporelbucleseráportantoigualalnúmerodeelemen­
tosdelarraya procesar.
Yahemosvistovariosejemplosdondeseprocesanloselementosindividualesdeunarrayde
caracteresdeunauotramanera(verEjemplos4.4,4.19,6.9,6.12,6.16, 6.19, 6.20, 6.32, 6.34,
8.3,8.5
Y9.2).Losarraysnuméricosseprocesandelamismamanera.Enunarraynumérico,
cadaelementodelarrayrepresentaunacantidadnumérica,comoseilustraenelejemplosi­
guiente.
EJEMPLO9.8.Desviacionesrespectoala media.Supongamosquequeremosleerunalistade ncan­
tidadesencomaflotanteyluegocalcularsumedia,comoenelEjemplo6.17.Sinembargo,ademásde
calcularsimplementelasuma,secalcularátambiénla
desviacióndecadacantidadnuméricarespecto dela
media,utilizandolafórmula
d=x.-media
,
dondex;representacadauna delascantidadesdadas, i=1,2,...,n,ymedialamediacalculada.
Pararesolveresteproblemadebemosalmacenarlascantidadesdadasenunarrayunidimensional
de
elementosencomaflotante.Ésta eslaparteesencialdelprograma.Larazón,qúedebequedarclara,esla
quesigue.
Entodoslosejemplosanterioresdondesehacalculadolamedia
deunalistadenúmeros,cadanúmero
erasustituidoporsusucesorenlalista(verEjemplos6.10,6.13,6.17
Y6.31).Portanto,cadanúmero
individualnoestabadisponibleparacálculosposterioresunavezqueelsiguienteeraintroducido.Sin
embargo,ahoraestosnúmerosdebenserretenidosdentrodelacomputadoraparacalcularsucorrespon­
dientedesviaciónrespectodelamediadeterminada.Portanto,losalmacenamosenunarrayunidimensio­
nalllamado
1ista.

306 PROGRAMACiÓN ENC
Definirnos1 istacornounarrayde 100elementosencomaflotante.Sinembargo,nonecesitarnos
usartodosloselementos.Ensulugar,deberemosintroducir
enlavariableenteranunacantidadentera
positiva(quenopase
de10O)paraespecificarelnúmerodeelementosreales.
Acontinuaciónsemuestra
elprogramacompleto enC.
/*calcularlamediadennúmeros,despuéscalcularladesviaciónde
cadanúmerorespectoalamedia*/
#include<stdio.h>
main()
{
intn,
float
float
cont¡
medialdIsuma=O;
lista[lOO],
/*leerelvalorden*/
printf("¿Cuantosnúmerosparacalcularlamedia?"),
scanf(lI%dll,&n)i
printf(""),
/*leerlosnúmerosycalcularsusuma*/
for(cont=O,cont<n,++cont){
printf('ri=%d x="/cont+1);
scanf("%f",&lista[cont]);
suma+=lista[cont],
}
/*calcularlamediayescribirlarespuesta*/
media=suma/ni
printf("Lamediaes%5.2f", media),
/*calcularyescribirlasdesviacionesrespectodelamedia*/
for(cont=O,cont<n,++cont){
d =
lista[cont]-media,
printf("i=%dx =%5.2fd =%5.2f",cont+1,lista[contJ,d),
}
}
Observequelasegundafunción scanf(dentrodelprimerbucle for)incluyeunampersand (&)de­
lantede
lista[cont],yaquerefiereaunelementosimpledelarrayynoalarrayentero(ver.sec­
ción4.4).
Ahorasupongamosqueelprogramaseejecuta.usandolassiguientescincocantidadesnuméricas:
Xl=3,x
2
=-2,x,=12,x.
'"4.4,x,'"3.5.Lasesióninteractiva,incluyendolaentradadedatos]losresul­
tadoscalculados,semuestraacontinuación.Lasrespuestasdelusuarioestánsubrayadas.
¿Cuantosnúmerosparacalcularlamedia?
2
i= 1 x=.1
i=2 x=.::.2.
i=3 x=12.
i= 4 x=4.4
i=5 x=3.5

ARRAYS 307
Lamediaes4.18
i=1 x 3.00 d=-1.18
i 2 x=-2.00d=-6.18
i=3 x=12.00 d= 7.82
i=4 x=4.40 d= 0.22
i=5 x 3.50 d=-0.68
Enalgunasaplicacionespuededesearseasignarvaloresinicialesalos elementosdeunarray.
Estorequierequeelarrayseadefinidoglobalolocalmente(dentrodeunafunción)comoun
arrayestático.Elsiguienteejemploilustrael usodeunarrayglobaldeformación.
EJEMPLO9.9.Desviacionesrespectoa lamedia(revisión).Calculemosdenuevolamedia de
.
unconjuntodadodenúmerosyluegocomputemosladesviacióndecadanúmerorespectoalamedia,
comoenelEjemplo9.8.Sinembargo,ahoraasignaremoslosnúmerosdadosalarraydentrodesudefini­
ción.Parahacerlo,movemosladefinicióndelarray
listafuerademain.Asílistaseráunarray
externo.Ademásquitaremosla especificación
detamañoexplícitadeladefinición,yaqueelnúmero de
valoresinicialesdeterminaráeltamañodelarray.
Losvaloresinicialesincluidosenelsiguienteprogramasonlosmismoscincovaloresquefueron
usadoscomodatosenelEjemplo9.8.Paraserconsistentesasignaremosunvalorinicialan.Estosepuede
realizardefiniendonbiencomounavariableautomáticadentrode
mainobiencomounavariableexter­
na.Sehaelegidoestoúltimoparaqueesténagrupadaslasasignacionesiniciales,queenotrocasopodrían
serintroducidascomodatos
deentrada.
Acontinuaciónsemuestraelprogramacompleto.
/*calcularlamediadennúmeros,despuéscalcularladesviación
decadanúmerorespectoalamedia*/
#inc1udeestdiO.h>
intn=Si
floatlistar]={3,-2,12,4.4,3.5};
main()
{
intconti
floatmedia,d,suma=O;
/*calcularlamediayescribirlarespuesta*/
for(cont=O;conten;++cont)
suma+=lista[cont];
media=suma/ni
printf("Lamediaes%5.2f", media);
/*calcularyescribirlasdesviacionesrespectodelamedia*/
for(cont=O;conten;++cont){
d =
lista[contJ-media;
printf("i=%dx=%5.2fcl=%5.2f",cont+1,lista[contJ,d);
}
}

308 PROGRAMACiÓN ENC
Observequeestaversióndelprogramanorequiereningún datodeentrada.
Laejecucióndelprogramageneralasiguientesalida:
Lamediaes4.18
i=1 x=3.00 d=-1.18
i 2 x=-2.00d=-6.18
i=3 x=12.00 d=7.82
i=4 x=4.40 d=0.22
i=5 x=3.50 d=-0.68
9.3.PASODEARRAYSAFUNCIONES
Unarraycompletosepuedepasaraunafuncióncomoargumento.Sinembargo,lamaneraen la
queelarraysepasadifieremuchodela deunavariableordinaria.
Parapasarunarrayaunafunción,elnombredelarraydebeaparecersolo,sincorchetesni
índices,comounargumentorealenlallamadaalafunción.Elcorrespondi,mteargumentofor­
malseescribedelamismamanera,perodebeserdeclaradocomounarrayenladeclaración
de
losargumentosformales.Cuandosedeclaraunarrayunidimensionalcomounargumentofor­
mal,elarrayseescribeconunpar
decorchetesvacíos.Eltamañodelarraynoseespecificaen
ladeclaracióndeargumentosformales.
Sedebetenercuidadoalescribirprototiposdefuncionesqueincluyanargumentos dearray.
Unaparejavacía
decorchetesdebeseguiralnombredecadaargumentodearray,indicando de
estemodoqueelargumento esunarray.Sinoseincluyenlosnombresdelosargumentosenuna
declaración
defunción,entoncesunaparejavacíadecorchetesdebeseguiraltipo dedatosde
argumento
dearray.
EJEMPLO9.10. Elsiguienteesquemadeprogramailustra elpasodeunarraydesdelaparteprincipal
delprogramaa unafunción.
f10atmedia(inta,floatxl]);
main()
{
intn;
f10atmed;
floatlista[100];
med=media(n,lista);
}
floatmedia(inta,f10atxl])
{
}
/*prototipodefunción*/
/*DECLARACIONdevariable*/
/*DECLARACIONdevariable*/
/*DEFINICIONdearray*/
/ *DEFINICIONdefunción'* /

ARRAYS 309
Dentrode mainvemosunallamadaalafunción media.Estallamadaafuncióncontienedosargu­
mentosreales,lavariableenteran yelarrayunidimensionalencomaflotante1i s
taoObserveque1i s­
taaparececomounavariableordinariaenlallamadaalafunción; esdecir,no seincluyenloscorchetes.
Laprimeralíneadeladefinición
delafunciónincluyedosargumentosformales,a yx.Ladeclaración
deargumentosformalesestablecequea esunavariableenteray xunarrayunidimensionalencoma
flotante.Existepuesunacorrespondenciaentreelargumentorealn yelargumentoformal
a.Análoga­
mente,existeunacorrespondenciaentreelargumentoreal1i s
tayelargumentoformalx.Observeque
eltamañodexno
seespecificadentro deladeclaraciónformaldeargumentos.
Observequeelprototipo
defunciónsepodriahaberescritosinlosnombresdelosargumentos, como
floatmedia(int,float[]);
Cualquieradelasdosformas esválida.
/*prototipodefunción*/
Yahemosdiscutidoelhechode quelosargumentossepasanaunafunciónporvalorcuando
losargumentossonvariablesordinarias (versección7.5).Sinembargo,cuandosepasaunarray
aunafunción,nosepasanalafunciónlosvaloresdeloselementosdelarray.Ensulugar,el
nombredelarrayseinterpretacomoladireccióndelprimerelementodelarray(ladirecciónde
laposicióndememoriaquecontieneelprimerelementodelarray).Estadirecciónse asignaal
correspondienteargumentoformalcuandosellamaalafunción.Elargumentoformalse con­
vierteportantoenunpunteroalprimerelementodelarray(mássobreestoenelpróximocapí­
tulo).
Losargumentospasadosdeestamanerasedicequesonpasadosporreferenciaenvezde
porvalor.
Cuandosehaceunareferenciaaunelementodelarraydentrodelafunción,elvalordel
índicedel elementoseañadeal valordelpunteroparaindicarladireccióndelelementoespeci­
ficado.Portanto,cualquierelementodelarraypuedeseraccedidodesdedentrode lafunción.
Además,
siunelementodelarrayesmodificadodentrode lafunción,estamodificaciónserá
reconocida
enlapartedelprogramadesde laquesehizo lallamada(enrealidad,entodoel
ámbito
delarray).
EJEMPLO9.11. AcontinuaciónsemuestraunprogramasencilloenCquepasaunarraydetresele­
mentosenterosaunafuncióndonde
semodificandichoselementos.Losvaloresdeloselementosdel
array
seescribenentrespartesdelprogramaparailustrarlosefectos delasmodificaciones.
#include<stdio.h>
voidmodificar(intal]);
main( )
{
intcont,a[3];
/*prototipodefunción*/
/*definicióndearray*/
printf("Desdemain,antesdellamaralafunción:")
;
for(cont=O;cont<=2;++cont){
a[cont]=cont+1;
printf("a[%d]=%d",cont,a[cont]);
}

310 PROGRAMACiÓN ENC
modificar(a);
printf("Desdemain,despuésdellamaralafunción:") ;
for(cont~O;cont<~2;++cont)
printf("a[%d]~%d",cont,a[cont]);
}
voidmodificar(inta[])
{
intconti
/*definicióndefunción*/
demodificarlosvalores:");
{
printf("Desdelafunción,después
for(cont~O;cont<~2;++cont)
a[cont]~-9;
printf("a[%d]~%d",cont,a[cont]);
}
return;
}
Aloselementosdelarrayselesasignanlosvaloresa [ O]~1,a [1 ]~2 Ya [2 ]~3enel
primerbucle
demain.Estosvaloresseescribentrasserasignados.Entonceselarraysepasaalafunción
modificar,dondeseleasignaelvalor -9acadaelementodelarray.Estosnuevosvaloresseescriben
desdedentrodelafunción.Finalmente,losvaloresdelarrayseescribendenuevoen
main,unavezque
elcontrolhayasidotransferidodesde
modif icarhastamain.
Cuandoelprogramaseejecuta,segeneralasiguientesalida:
Desdemain,antesdellamaralafunción:
arO]
~1
a[1] 2
a[2]~3
Desdelafunción,despuésdemodificarlosvalores:
arO] ~-9
a[l]~-9
a[2]~-9
Desdemain,despuésdellamaralafunción:
arO] ~-9
a[l]~-9
a[2]~-9
Estosresultadosmuestranqueloselementosdeasemodificandentrode maincomoresultadodelos
cambiosrealizadosdentrode
modificar.
EJEMPLO9.12. Consideremosahoraunavariacióndelprogramaanterior. Elprogramaactualincluye
lautilizacióndevariablesglobalesylatransferenciatantodeunavariablelocalcomode
unarrayala
función.
#include<stdio.h>
inta=1;
voidmodificar(intb,intc[]);
/*variableglobal*/
/*prototipodefunción*/

ARRAYS 311
main()
{
intb=2;
intcont,c[3];
/*variablelocal*/
/*definicióndearray*/
printf("Desdemain,antesdellamaralafunción:") ;
printf("a=%d b =%d",a,b);
for(cont=O;cont<=2;++cont){
c[cont]=10*(cont+1);
printf("c[%d]=%d",cont,c[cont]);
}
/*accesoalafunción*/
despuésdellamaralafunción:");
%dn /a,b)i
<=2;++cont)
%d",cont,c[cont]);
modificar(b,c);
printf("Desdemain,
printf("a=%d b =
for(cont=O;cont
printf("c[%d]=
}
voidmodificar(intb ,intc[])
{
/*definicióndefunción*/
intcont;
printf("Desdelafunción,despuésdemodificarlosvalores:");
a=-999;
b=-999;
printf("a=%d b =%d",a,b);
for(cont=O;cont<=2;++cont){
c
[cont]=-9;
printf("c[%d]=%d",cont,c[cont]);
}
return¡
}
Cuandoseejecutaelprograma,segeneralasiguientesalida:
Desdemain,antesdellamaralafunción:
a=1 b=2
c[O]=10
c[l]=20
c[2]=30
Desdelafunción,despuésdemodificarlosvalores:
a=-999 b=-999
c[O]=-9
c[l]=-9
c[2]=-9
Desdemain¡
a=-999
c[O]=-9
c[l]=-9
c[2]=-9
despuésdellamaralafunción:
b=2

312 PROGRAMACiÓN ENC
Vemosahoraqueelvalor dea yloselementosdecsonmodificadosdentrode maincomoresultadode
loscambiosrealizadosen
modificar.Sin embargo,elcambiorealizadoa bseconfinaalafunción,
comoeradeesperar.(Compararestosresultadosconlosobtenidosenelúltimoejemployen
elEjem­
plo7.12.)
Elhechodequeunarraypuedasermodificadoglobalmentedentrodeunafunciónpropor­
cionaunmecanismoadecuadoparamovermúltiplesdatosa odesdeunafunciónalapartedel
programadesdelaquesehizolallamada.Simplementesepasaelarrayalafunciónysealteran
suselementosdentrodeella.O,sielarrayoriginaldebeserpreservado,secopiaelarray(ele­
mentoporelemento)dentrodelapartedelprogramaquehacelallamada,sepasalacopiaala
funcióny serealizanlasmodificaciones.Elprogramadordebetenerciertocuidadoalmodificar
unarraydentrodeunafunción,yaqueesmuyfácilmodificarlodemodonointencionadofuera
delafunción.
EJEMPLO9.13.Reordenacióndeunalistadenúmeros.Consideremoselfamosoproblemadereor­
denarunalistadenenterosenunasecuencia
devaloresalgebraicoscrecientes.Escribamosunprograma
querealicelareordenacióndemodoquenoseusealmacenamientoinnecesario.Portanto,elprogra­
macontendrásólounarray:unarrayunidimensionaldeenterosllamado
x,enelquesereordenaránlos
elementosdeunoenuno.
Lareordenaciónempezarárecorriendotodoelarrayparaencontrarelmenordelosnúmeros.Este
númeroseráintercambiadoconelprimerelementodelarray,colocandoasíelmenornúmeroalprincipio
delalista.Elrestodelos n-1elementosdelarrayserecorreránparaencontrarelmenor,queseintercam­
biaráconelsegundonúmero.Elresto
delosn - 2númerosserecorreránbuscandoelmenor,queseinter­
cambiaconeltercernúmero,yasísucesivamente,hastaquesehayareordenado
elarraycompleto.La
reordenacióncompletarequeriráuntotalden
-1pasadasporelarray,perocadavezeltrozodelarraya
consideraresmenor.
Paraencontrarelmenordelosnúmerosencadapasada,comparamossecuencialmentecadanúmero
delarray, x [ i ] ,conelnúmerodecomienzo,x [
elem] ,dondeelemesunavariableenteraqueseusa
paraidentificarunelementoparticulardelarray.Six
[i]esmenorquex [elem],entoncesseintercam­
bianlosdosnúmeros;enotrocasosedejanlosdosnúmerosensusposicionesoriginales.Unavezqueeste
procedimientosehaaplicadoatodoelarray,elprimernúmerodelarrayseráelmenar.Despuésserepite
esteproceso
n-2veces,parauntotal den-1pasadas(e1em=0.1
•...•n-2).
Laúnicacuestiónquequedaescómoseintercambianrealmentelosnúmeros.Pararealizarelinter­
cambio,primeroalmacenamostemporalmenteelvalordex
[elem]parareferenciarioenelfuturo.Des­
puésasignamoselvaloractualdex
[i]a x[elem].Finalmenteasignamoselvalor originaldex[elem],
quefuetemporalmentealmacenado,a x
[i].Elintercambioestáahoracompleto.
LaestrategiadescritaanteriormentepuedeserescritaenCcomosigue:
/*reordenartodosloselementosdelarray*/
for(e1em=O;elem<n -1;++elem)
/*encontrarelmenordelrestodeloselementos*/
for(i=elem+1;i<n;++i)
if(x[i]<x[elem]){
/*intercambiarlosdoselementos*/
temp= x[elem]
;
x[elem]=x[i];
x[i]=temp;
}

ARRAYS 313
Estamossuponiendoque elemeisonvariablesenterasqueseusancomocontadoresyque tempesuna
variable enteraqueseusaparaalmacenartemporalmenteelvalorde
x[elem].
Ahorasimplementequedaañadirlasdefinicionesnecesariasdevariablesy del array, ylasinstruccio­
nesdeentrada/salida.Acontinuaciónsemuestraelprogramacompletoen
C.
/*reordenarunarrayunidimensionaldeenteros,demenora
mayor*/
#include<stdio.h>
#defineTAM100
voidreordenar(intn,intx[]);
main()
{
inti,n,x[TAM];
/*leerelvalorden*/
printf("¿Cuantos númerosseránintroducidos?11)i
scanf("%d
ll
,&n)¡
printf(n
ll
)i
/*leerlalistadenúmeros*/
for(i=O;i<
printf("i=
scanf
(lI%dll,
n;++i){
%d x= 11
&x[i]);
i+1);
}
/ *reordenar
reordenar(n,
todosloselementosdelarray*/
x);
/*escribirlalistareordenadadenúmeros*/
printf("Listadenúmerosreordenada:");
for(i=O;i <n;++i)
printf("i=%d x=%d", i +1,xli]);
}
voidreordenar(intn,intxl])
{
inti,'elero,tempi
/*reordenarlalistadenúmeros*/
for(elem=O;elem< n -1;++elem)
/ *encontrarelmenordelrestodeloselementos*/
for(i=elem+1;i <n;++i)
if(x[i]<x[elem]){
/ *intercambiarlosdos·elementos* /
temp=x[elem];
x[elem]=x[i];
xli]=temp;
}
return¡
}

314 PROGRAMACiÓN ENC
Enesteprogramaxsedefineinicialmentecomounarrayde 100elementosenteros.(Observeelusodela
constantesimbólica
TAMparadefinireltamañode x.)Primeroseleeunvalorpara n,seguidoporlos
valoresnuméricosdelosprimerosnelementos
dex(x[O] ,x [ 1 ] ,..., x [n-1]).Traslaentradade
datos,
ny xsepasanalafunción reordenar,dondelosprimeros nelementosdexseordenan demodo
ascendente.Alfinaldelprograma,loselementosreordenadosdexseescribenen
main.
Ladeclaraciónde reordenarqueapareceen mainestáescritacomounprototipodefunción,
comoejemplo
debuenapráctica deprogramación.Observelamaneraenqueseescribenlosargumentos
delafunción.Enparticular,observequeelsegundoargumentoseidentificacomounarrayenteroporlos
corchetesquesiguenalnombredelarray,estoes,
intx [ ] .Loscorchetessonnecesarioscomounaparte
delaespecificacióndeesteargumento.
Supongamosahoraqueelprogramaseutilizaparareordenarlossiguientesseisnúmeros:
59578
-15O5891-29-7.Elprogramageneraráelsiguientediálogointeractivo.(Comosiempre,lasres­
puestasdelusuarioestánsubrayadas.)
¿Cuantosnúmerosseránintroducidos?
Q
i=1 x =.5...22
i=2 x=N
i=3 x-1505
i=4 x=891
i=5 x=-29
i=6 x==.2
Listadenúmerosreordenada:
i=1 x -1505
i=2 x =-29
i=3 x=-7
i=4 x=78
i=5 x 595
i=6 x=891
Debeindicarseque lainstrucciónreturnnopuedeserusadaparadevolver unarray,ya
que
returnsólopuededevolverexpresiones unievaluadasalapartedelprogramaquehizola
llamada.Portanto,sisetienenquepasarloselementosdeunarrayalapartedelprogramaque
hacelallamada,elarraydebeestardefinidobiencomounarrayexternocuyoámbitoincluya
tantolafuncióncomolapartedelprogramadesdelaquesellamaalafunción,obiendebeser
pasadoalafuncióncomounargumentoformal.
EJEMPLO9.14.Un generadorde«pig
latin>>.«Piglatin»esunaformacodificadadeescribiryde
hablarquesuelenusarlosniñoscomojuego.Unapalabraen«piglatin»seformatransponiendoelprimer
sonido(generalmentelaprimeraletra)
deunapalabraoriginalalfinal delamismayañadiéndoleluegola
letra
«a».Deestemodo,lapalabra«perro»seconvierteen«erropa»,«computadora»en«omputadoraca»,
«piglatin»en
<<iglatinpa»(o<<igpaatinla»siseconsideracomodospalabrasseparadas),yasísucesivamente.
EscribamosunprogramaenCqueacepte
unalíneadetextoyescribasucorrespondientetextoen«pig
latim>.Supondremosquecadamensajetextualpuedeestarcontenidoenunalíneade8 Ocolumnas,conun
soloespacioenblancoentrecadadospalabrassucesivas.(Realmente,seexigiráqueelmensajeen«pig
latin»noexcedade80caracteres.Portanto,elmensajeoriginaldebeconstar
dealgomenosde8 Ocarac­
teres,yaqueelcorrespondientemensajeen«pig
latim>tendrámayorlongitudporelañadidodelaletra

ARRAYS 315
«a»alfinaldecadapalabra.)Porsimplicidad,sólotranspondremoslaprimeraletra(noelprimersonido)
decadapalabra.Ademásignoraremoscualquierconsideraciónespecialquepudieradarsealasletrasma­
yúsculasy alossignosdepuntuación.
Utilizaremosdosarraysenesteprograma.Unarraycontendrálalínea
detextooriginalyelotroel
«piglatin»correspondiente.
Laestrategiageneraldeoperacióncontendrálossiguientespasosprincipales:
1.Inicializarambosarrays,asignandoespaciosenblancoatodosloselementos.
2.Leerunalíneaenteradetexto(variaspalabras).
3.Determinarelnúmerodepalabrasdelalínea(contandoelnúmero
deespaciosenblancoquevan
seguidosporuncarácternoblanco).
4.Convertirlaspalabrasa«piglatin»,palabraapalabra,delasiguientemanera:
a)Localizarelfinaldelapalabra.
b)Pasarlaprimeraletraalfinaldelapalabrayluegoañadiruna«a».
e)Localizarelprincipio delasiguientepalabra.
5.Escribirlalíneade«pig
latin»completa.
Secontinuarárepitiendoesteprocedimiento,hastaquelacomputadoralea unalínea detextocuyastres
primerasletrassean«fin»(o«FIN»).
Paraimplementarestaestrategiaharemosuso
dedosindicadores,llamados miym2,respectivamente.
Elprimerindicador
(mi)señalarálaposicióndelcomienzodeunapalabraenparticulardentrodelalínea
detextoorigina!.Elsegundoindicador(m2)señalaráelfinaldelapalabra.Observequeelcarácterenla
columnaanterioralaindicadapor
miseráunespacioenblanco(exceptoenlaprimerapalabra).También
seráunespacioenblancoelcarácterenlacolumnaposterioralaseñaladaporm2.
Esteprogramaseestructuraenvariarfuncionespararealizarcadaunadelastareasprincipales.Sin
embargo,antesdediscutirlasfuncionesindividualesdefiniremoslassiguientesvariablesdeprograma:
texto=arrayunidimensional decaracteresquerepresentalalíneadetextooriginal
piglatin
~arrayunidimensional decaracteresquerepresentalanueva líneadetexto(en«pig
latin»)
palabras=variabledetipoenteroqueindicaelnúmerodepalabrasexistentesencadalíneade
textodada
n
=variable enteraqueseusacomocontadordepalabras (n=i,2,...,palabras)
cont=variable enteraqueseusacomocontadordecaracteresdentro decadalíneadetexto
(cont=0,1,2,...,79)
Haremosusotambiéndelasvariablesenteras miym2discutidasanteriormente.
Volvamosahoraalesquemageneraldelprogramapresentadoanteriormente.Elprimerpaso,
lainicializacióndelosarrays,se puederealizardirectamenteconlasiguientefunción:
/*inicializarelarraydecaracteresconespaciosenblanco*/
voidinicializar(chartexto[],charpiglatin[])
{
intcont¡
}
for(cont=O;cont<80;++cont)
texto[cont]=piglatin[cont]=
return¡
,.
,

316 PROGRAMACiÓN ENC
Elpaso2puederealizarseconunafunciónsencilla.Esteprocedimientocontendráunbucle whileque
continuaráleyendocaracteresdesdeeltecladohastaquesedetecteelfindelinea.Estasecuencia
decarac­
teresformaráloselementosdelarraydecaracteres
texto.Acontinuaciónsemuestralafuncióncompleta.
/*leerunalíneadetexto*/
voidleerentrada(ehartexto
[])
{
intcont=Di
charc¡
while((e=getehar())!=''){
texto[eont]=e;
++cont¡
}
return¡
}
Elpaso3delesquemageneral esigualmentedirecto.Simplementebuscamosenlalíneaorigínaespacios
enblancoseguidos
decaracteresdistíntos deblanco.Elcontadordepalabras (palabras)seincrementacada
vezqueseencuentraunsoloespacioenblanco.Acontínuaciónsemuestralarutina
decontar palabras.
/*examinarlalíneadetextoycontarelnúmerodepalabras*/
inteontarpalabras(ehartexto[J)
{
inteont,palabras
=1;
}
for(eont=O;eont<79;
if(texto[eont]
++palabras;
return(palabras);
++eont)
&&texto[eont+1]!=
,)
Ahoraconsideraremoselpaso4(convertireltextoen«piglatin»),queesrealmenteelnúcleodel
programa.Lalógicapararealizarestoesalgomáscompleja,yaquenecesitatresoperacionesindividuales
peroasuvezrelacionadas.Primerodebemosidentificarelfinal
decadapalabraencontrandoelprimer
espacioenblancodetrás
deml.Despuésasignamosloscaracteresquecomponenlapalabraalarrayde
caracteres
piglatin,conelprimercarácteralfinaldelapalabra.Fiualmentedebemosañadirlale­
tra«a»yrestablecerelindicadorinicialparaqueidentifiqueelprincipio
delasiguientepalabra.
Lalógicadebesertratadacuidadosamente,porquelanuevalíneadetextoserámáslargaquelalínea
original(debidoala«a»añadidaalfinal).Poresto,loscaracteresenlaprimerapalabra«piglatin»ocupa­
ránlasposicionesdesde
mlhastam2+l.Loscaracteresdelasegundapalabraocuparánlasposiciones
desde
ml+1hastam2+2(observequeéstossonlosnuevosvaloresde m1ym2),yasísucesivamente.
Estasreglassepuedengeneralizarcomosigue.
Primero,paralapalabranúmero
n,transferirtodosloscaracteresexceptoelprimerodelalíneaorigi­
nalalanuevalínea.Estopuederealizarseescribiendo
for(eont
=m1;eont<m2;++eont)
piglatin[eont+(n-1)]=texto[eont+1];

ARRAYS 317
Losdosúltimoscaracteres(elprimercarácter delapalabraoriginalmáslaletra«a»)puedenañadirse
delasiguientemanera:
piglatin[m2+(n1)]=texto[ml];
piglatin[m2+n]='a';
Despuésmodificamoselvalorde ml:
ml=m2+2;
paraprepararloparalasiguientepalabra.Estegrupodecálculosserepiteparacadapalabradelalínea
original.
Acontinuaciónsemuestralafunciónquerealizatodoesto.
/ *convertircadapalabraen I1pig-latin11* /
voidconvertir(intpalabras,chartexto[],charpiglatin[])
{
intnIconti
intml=O;
intm2i
/*indicador->comienzodelapalabra*/
/*indicador->finaldelapalabra*/
}
/*convertircadapalabra*/
for(n=1;n<=palabras;++n){
/*localizarelfinaldelapalabraactual*/
cont ;;;;;mi;
while(texto[cont]!= ' )
m2 ;;;;;cont++;
/*transponerlaprimeraletrayañadiruna'a'*/
for(cont=ml;cont<m2;++cont)
piglatin[cont+(n-1)]=texto[cont+1];
piglatin[m2+(n1)]=texto[ml];
piglatin[m2+n]='a';
/*reinicializarelindicadorinicial*/
ml=m2+2;
}
return¡
Elpaso5(escribirel«pig latim»requierepocomásqueunbucle for.Lafuncióncompletapuede
escribirsecomo
/*escribirlalineadetextoen"pig-latin"*/
voidescribirsalida(charpiglatin[])
{

318 PROGRAMACiÓN ENC
intcont=O;
for(cont=O;cont<BO; ++cont)
putchar(piglatin[cont]);
printf(lI
ll
);
return;
}
Consideremosahoralaparteprincipaldelprograma.Estonoesnadamásque ungrupodedefiniciones
ydeclaraciones,unmensajeinicial, unbucledo-whilequepermitelaejecuciónrepetidadelprogra­
ma(hastaquelapalabra«fin»sedetecta,tanto enmayúsculascomoenminúsculas,comoprimerapalabra
enunalineadetexto)
yunmensajedefinalización.Elbucle do-whilesepuedehacerquecontinúe
deformaindefinidausandolacomprobación
(palabras>=O)alfinaldelbucle.Como palabras
tieneasignado unvalorinicialde1 ysuvalornodecrece,lacomprobaciónserásiempreverdadera.
Elprogramacompletosemuestraacontinuación.
/*convertiruntextoa"piglatin
ll
,líneaalínea*/
'include<stdio.h>
'include<stdlib.h>
'include<ctype.h>
voidinicializar(chartexto[],charpiglatin[]);
voidleerentrada(chartexto[J);
intcontarpalabras(chartexto[]);
voidconvertir(intpalabras,chartexto[],charpiglatin[]);
voidescribirsalida(charpiglatin[]) ;
main()
{
chartexto[BO],piglatin[BO];
intpalabras;
printf("Bienvenidoalgeneradordepig-latin");
printf("Escribir\'FIN\'paraterminar");
do{/*procesarunanuevalíneadetexto*/
inicializar(texto,piglatin);
leerentrada(texto);
/*comprobacióncondicióndefinalización*/
if(toupper(texto[O])--'F'&&
toupper(texto[l])--' I '&&
toupper(texto[2])--'N')break;
/*contarelnúmerodepalabrasenlalínea*/
palabras=contarpalabras(texto);
/*convertirtextoen"pig-latin11* /
convertir(palabras,texto,piglatin);
escribirsalida(piglatin);
}

ARRAYS 319
while(palabras>=O);
printf("ueQaengatanuauenbaiada(Quetengaunbuendía)");
}
/*inicializarelarraydecaracteresconespaciosenblanco*/
voidinicializar(chartexto[],charpiglatin[])
{
intcont;
for
}
(cont=O;
texto[cont]
return;
cont<80;++cont)
=piglatin[cont]=
,.
,
/*leerunalíneadetexto*/
voidleerentrada(chartexto[])
{
intcont
charc¡
O·,
}
while((c=getchar())!=''){
texto[cont]=c;
++cont¡
}
return;
/*examinarlalíneadetextoycontarelnúmerodepalabras*/
intcontarpalabras(chartexto[])
{
intcont,palabras=1;
}
for(cont=O;cont
if(texto[cont]
++palabras;
return(pa1abras);
<79;++cont).
&&texto[cont+1]! =
,)
/*convertircadapalabraenl'pig-latin,r*/
voidconvertir(intpalabras,chartexto[],charpiglatin[])

320 PROGRAMACiÓN ENe
{
intn,cont¡
intm1=O,
intm2,
/*indicador->comienzodelapalabra*/
/*indicador->finaldelapalabra*/
/*convertircadapalabra*/
for(n=1,n<=palabras,++n){
/*localizarelfinaldelapalabraactual*/
cont=rol;
whi1e(texto[cont]!=')
m2=cont++;
/*transponerlaprimeraletrayañadiruna'al*/
for(cont=m1,cont<m2,++cont)
piglatin[cont+(n-1)]=texto[cont+1],
pig1atin[m2+(n-1)]=texto[m1],
piglatin[m2+n]='a',
/*reinicializarelindicadorinicial*/
m1=m2+2,
}
return¡
}
/*escribirlalineadetextoen"pig-latin"*/
voidescribirsalida(charpiglatin[])
{
intcont=O,
for(cont=O,cont<80;++cont)
putchar(pig1atin[cont]);
printf(1!
ll
)i
return¡
}
Observequecadafunciónrequierepor lomenosunarraycomoargumento.En contarpalabrasy
escribirsalidalosargumentosdearraysimplementeproporcionanlaentradadelafunción.Sin
embargo,en
convertir,unodelosargumentosdearrayproporcionalaentradayelotrolasalidaa
main.Yeninicializaryleerentradalosarraysrepresentaninformaciónqueesdevueltaa
main.
Lasdeclaracionesdelasfuncionesdentrode mainestánescritascomoprototiposcompletosde fun­
ciones.Observequecadaargumento dearrayseidentificamedianteunpardecorchetestraselnombredel
array.
Ahoraconsideremosquépasacuandoseejecutaelprograma.Acontinuaciónsemuestraunasesión
interactivatípica,dondelasrespuestasdelusuarioestánsubrayadas.

ARRAYS 321
Bienvenidoalgeneradordepig-latin
Escribir'FIN'paraterminar
Qesunpopularlenguajedeprogramacionestructurada
Caseanuaopularpaenguajelaedarogramacionpastructuradaea
elbeisboleselgranpasatiempoamericano,
leaeisbolbasealearangaasatiempopamericano,aa
aunquehaymuchosqueprefierenelfutbol
unqueaaayhauchosmaueqarefierenpaleautbolfa
porfavor,noestornudeenlasaladecomputadoras
ropaavor,faonastornudeeaneaalaalasaedaomputadorasca
ueQaengatanuauenbaiada(Quetengaunbuendía)
Elprogramanoincluyeningúnprocesamientoespecialdelossignosdepuntuación,lasletrasmayús­
culasolossonidosdedobleletra(porejemplo«qu»o<<11»l,Estosrefinamientossedejancomoejercicio
para
ellector,
9.4.ARRAYSMULTIDIMENSIONALES
Losarraysmultidimensionalessedefinenprácticamente delamismamaneraquelosarraysuni­
dimensionales,exceptoqueserequiereunparseparadodecorchetesparacadaíndice,Así,un
arraybidimensionalrequerirádosparesdecorchetes,unarraytridimensionalrequerirátrespa­
res
decorchetes,yasísucesivamente,
Entérminosgenerales,ladefinición
deunarraymultidimensionalsepuedeescribircomo
tipo-de-a1macenamientotipo-datoarray[expresión1]
[expresión2]...[expresiónn];
dondetipo-de-a1macenamientoserefierealtipodealmacenamientodelarray, tipo­
datoessutipodedatos, arrayelnombredelarray, yexpresión1,expresión2,""
expresiónnsonexpresionesenteraspositivasqueindicanelnúmerodeelementosdelarray
asociadosconcadaíndice,Recordarque
tipo-de-a1macenamientoesopCIOnal;losvalo­
resporomisiónson
autoparalosarraysdefinidosdentrodeunafuncióny externparalos
arraysdefinidosfuera
deunafunción.
Hemosobservadoque
unarrayunidimensionaldenelementospuedeservistocomo una
listadevalores,comoseilustróenlaFigura9.1.Análogamente,unarraybidimensionalde
IDxnpuedeservistocomo unatabladevaloresquetienen IDfilasy ncolumnas,como
seilustra
enlaFigura9,2.Extendiendo estaidea,unarraytridimensionalpuedeverse
comoun
conjuntodetablas(porejemplo,unlibroen.elcualcadapáginaesunatabla),yasí
sucesivamente.

322 PROGRAMACiÓN ENC
col1 col2 col3 col(n-l) coln
fila1I [ ]
x[Oj[O) x[O)[1] x[O1[2] x(D)[n-2] x[O)[n-l]
fila,1 []
x[1][O) x[!][1J x[!][2J x[!][n-2] x[!][n-l]
• • • • •
filaroI []
x[m-l][O] x[m-l][1]x[m-l][2J x[m-l][n-2]x[m-l][n-l)
Xesunarraybidimensional demxn
Figura9.2.
EJEMPLO9.15.Variasdefiniciones
dearraysmultidimensionales semuestranacontinuación.
floattabla[50][50];
charpagina[24][80];
staticdoubleregistros[lOOJ[66][255];
staticdoubleregistros[L][M][N];
Laprimeralíneadefine tablacomounarray deelementosencomaflotantecon 50filasy 50columnas
(portanto
50x50=2500elementos),yla segundalíneaestablece paginacomounarraydecaracteres
con
24filasy 80columnas(24x80=1920elementos).Eltercerarraypuedeservistocomounconjunto
de100tablasestáticasendobleprecisión,cadaunacon 66líneasy 255columnas(portanto 100x66x
255=1683000 elementos).
Laúltimadefinición
esanálogaaladefiniciónprecedenteexcepto quelasconstantessimbólícas L,M
YNdefineneltamañodelarray.Asílosvaloresasignadosadichasconstantessimbólicasdeterminan el
tamañoreal delarray.
Sedebetenercuidado
enelordenenquelosvaloresinicialesseasignanaloselementosdel
arraymultidimensional.(Recordarquesólopuedeninicializarselosarraysestáticosyexter­
nos.)
Lareglaesque elúltimoíndice(extremoderecho)es elqueseincrementamásrápidamente,
yel
primeríndice(extremoizquierdo)eselquese incrementamáslentamente.Asíloselementos
de
unarraybidimensionaldebenserasignadosporfilas,estoes,primeroseránasignados losele­
mentosde
laprimerafila,luegoloselementosde lasegunda,yasísucesivamente.

ARRAYS 323
EJEMPLO9.16. Considerarlasiguientedefinicióndearraybidimensional:
intvalores[3][4]={l,2,3,4,5,6,7,8,9,10,11,12};
Observeque valorespuedeservistocomounatabladetresfilasycuatrocolumnas(cuatroelementos
porfila).Comolosvaloresinicialesseasignanporfilas(elúltimoÍndiceseincrementamásrápidamente),
elresultadodeestaasignacióninicialserácomosigue:
valores[O] [O]=1
valores[1][O]=5
valores[2][O]=9
valores[O][1]=2
valores[1][1]=6
valores[2][1]=10
valores[O][2]=3
valores[1] [2]=7
valores[2] [2]=11
valores[O][3]=4
valores[1][3]=8
valores[2][3]=12
RecordarqueelprimerÍndicevaríaentreOy2,YelsegundoentreOy3.
Elordennaturalenelquelosvaloresinicialessonasignadossepuedealterarformando
gruposdevaloresinicialesencerradosentrellaves( {...}).Losvaloresdentrodecadapar
internodellavesseránasignadosaloselementosdelarraycuyoúltimoíndicevaríemásrápida­
mente.Porejemplo,enunarraybidimensional,losvaloresalmacenadosdentrodelparinterno
dellavesseránasignadosaloselementosdeunafila,yaqueelsegundoíndice(columna)se
incrementamásrápidamente.Sihaypocoselementosdentrode cadapardellaves,alrestodelos
elementosdecadafilaseleasignaránceros.Porotraparte,elnúmerodevaloresdentrode cada
pardellavesnopuedeexcederdeltamañodefiladefinido.
EJEMPLO9.17. Acontinuaciónsemuestraunavariación deladefinicióndearraybidimensionalpre­
sentadaenelúltimoejemplo.
intvalores[3] [4]= {
{l,2,3,
4l.
{5,6,7,8l.
{9,10,11,12}
};
.Estadefiniciónproducelasmismasasignacionesinicialesqueelúltimoejemplo.Asíloscuatrovalores
delprimerpardellavesinternassonasignadosaloselementosdelaprimerafiladelarray,losvaloresdel
segundopardellavessonasignadosaloselementosdelasegundafiladelarray,yasísucesivamente.
Observequeelparexternodellavessenecesitaparacontenerlosparesinternos.
Considerarahoraladefinicióndelsiguientearraybidimensional:
intvalores[3][4]= {
{1,2,
3l.
{4,5,6),
(7,8,9)
};
Estadefiniciónasignavaloressoloalostresprimeroselementosencadafila.Portanto,loselementosdel
arraytendránlossiguientesvaloresiniciales:

324 PROGRAMACiÓN ENC
valores[O] [O]=1
valores[1][O]=4
valores[2][O]=7
valores[O][1]=2
valores[1][1]=5
valores[2][1]=8
valores[O][2]=3
valores[1] [2]=6
va1ores[2][2]=9
valores[O][3]=0
valores[1] [3]=0
valores[2][3J=0
Observequeelúltimoelementoencadafilatieneasignadovalorcero.
Silaanteriordefinicióndearrayseescribecorno
intvalores[3][4]=(1,2,3,4,5,6, 7,8,9);
entoncestreselementosdelarraytendránasignadoelvalorcero,pero elordendeasignaciónserádiferen­
te.Enparticular,loselementosdelarraytendránlossiguientesvaloresiniciales:
valores[O] [O]
=1
valores[1][O]=5
valores[2][O]=9
va1ores[0][1]=2
valores[l][1]=6
valores[2][1]=0
valores[O][2]=3
valores[1] [2]=7
valores[2] [2]=0
valores[O][3]=4
valores[l][3]=8
valores[2][3]=0
Ahoralosvaloresinicialesseasignanfilaafila,conelúltimoindicequeseincrementamásrápidamente,
hastaquetodoslosvaloresinicialeshayansidoespecificados.Sinembargo,sinlosparesinternosde
llaves
nosepuedenagruparlosvaloresinicialesparaasignarlosaunafilaespecífica.
Finalmente,considerarladefinicióndelarray
intva1ores[3][4]
={
{1,2,3,4,5},
(6,7,8,9,lO),
{ll,12,13, 14,15}
};
Estoproduciráunerrordecompilación,yaqueelnúmerodevaloresdentro decadaparinterno dellaves
(cincovaloresencadapar)excedeeltamañodefinidodelarray(cuatroelementosencadafila).
Elusodegruposinternosdcvaloresinicialessepuedegeneralizarparaarraysdemayor
dimensión.
EJEMPLO9.18. Considerarlasiguientedefinición dearraytridimensional:
intt[10][20][30]
={
{
/*tabla1*/
{1,2,3,
4}, /*fila1*/
(5,6,7,8), /*fila2*/
(9,10,11,12) /*fila3*/
},
{ /*tabla2*/
{21,22, 23,24},/*fila1*/
(25,26,27,28),/*fila2*/
(29,30,31,32)/*fila3*/
}
}
;

ARRAYS 325
Verestearraycornounacolecciónde 10tablas,con2 Ofilasy 3 Ocolumnas.Elgrupo devaloresiniciales
producirálaasignación
delossiguientesvaloresnonulosenlasprimerasdostablas.
troJ[O][0]=1 t[O] [O][1]=2 t[O] [O][2]=3 trOJ[O][3]=4
t[O][1][O]=5 t[O][1][1]=6 t[0][1][2]=7 trOJ[1][3]=8
t[O][2][O]=9 t[O][2][1]=10 trOJ[2][2]=11 trOJ[2][3]=12
t[1][O] [O]=21t[l][O][1]=22t[l][O][2]=23t[l][O][3]=24
t[1][1][O]=25 t[1] [1] [1]=26 t[1] [1] [2]=27t[l][1][3]=28
t[l][2][0]=29t[l][2][1]=30t[l][2][2]=31t[l][2][3]=32
Elrestodeloselementosdelarraytendránasignadosceros.
Losarraysmultidimensionalesseprocesandelamismamaneraquelosarraysunidimensio­
nales,sobrelabasedeelementoaelemento.Sinembargo,serequierealgúncuidadocuandose
pasanarraysmultidimensionalesaunafunción.Enparticular,lasdeclaracionesdeargumentos
formalesdentrodeladefinicióndefuncióndebenincluirespecificacionesexplícitasde tamaño
entodoslosíndicesexceptoenelprimero.Estasespecificacionesdebenserconsistentesconlas
correspondientesespecificacionesdetamañoenelprogramaquehacelallamada.Elprimer
índicepuedeserescritocomounpardecorchetesvacíos,comoenunarrayunidimensional. Los
prototiposcorrespondientesdefuncióndebenescribirsede lamismamanera.
EJEMPLO9.19.Suma
dedostablasdenúmeros.Supongamosquequerernosleerdostablasdeente­
rosenlacomputadora,calcularlasumadeloselementoscorrespondientes,estoes,
c[i][j]=a[i][j]+b[i][j]
y acontinuaciónescribirlanuevatablaquecontieneestassumas.Supondremosquetodaslastablascon­
tendrán
elmismonúmerodefilasydecolumnas, noexcediendode2 Ofilasy 3 Ocolumnas.
Haremosusodelassiguientesdefiniciones
dearraysyvariables.
a,b,c=arraysbidimensionalesconelmismonúmero defilasyelmismonúmerodecolumnas,
noexcediendode2 Ofilasy 3 Ocolumnas.
nfi1as=variableenteraqueindica elnúmerorealdefilasencadatabla.
ncols=variableenteraqueindicaelnúmerorealdecolumnasencadatabla.
fi1 a=contadorenteroqueindicaelnúmero defila.
col=contadorenteroqueindicaelnúmerodecolumna.
Elprogramasemodularizaráescribiendofuncionesindividualesparaleer
elarray,calcularlasuma de
loselementosdelarrayyescribirelarray.Llamaremosaestasfunciones leerentrada,calcular­
sumayescribirsalida,respectivamente.
Lalógicadentro
decadafunciónesbastantedirecta.Acontinuaciónsemuestraelprogramacompleto
en
epararealizarelcálculo.
!*calcularlasuma
deloselementosendostablasdeenteros*!
#include<stdio.h>
#defineMAXFIL20
#defineMAXCOL30

326 PROGRAMACiÓN ENC
voidleerentrada(intal][MAXCOL],intnfilas,intncols);
voidcalcularsuma(intal][MAXCOL],intbE][MAXCOL],
intcE][MAXCOL],intnfilas,intncols);
voidescribirsalida(intcE][MAXCOL],intnfilas,intncols);
main()
{
intnfilas,ncols;
/*definicionesdearrays*/
inta[MAXFIL][MAXCOL], b [MAXFIL][MAXCOL], c[MAXFIL][MAXCOL];
printf("¿Cuantasfilas?");
scanf("%0.",&nfilas);
printf("¿Cuantascolumnas?");
scanf(n%d11r&ncols)i
printf("Primera tabla:");
leerentrada(a,nfilas,ncols);
printf("Segundatabla:");
leerentrada(b,nfilas,ncols);
}
calcularsuma(a,b,
printf("Sumas
escribirsalida(c,
c,nfilas,ncols);
deloselementos:");
nfilas,ncols);
/*leerunatabladeenteros*/
voidleerentrada(intal][MAXCOL],.intm,intn)
{
intfila,col;
for(fila=O;fila<m;++fila){
printf("lntroducirdatosparalafilanº%2d",fila+1);
for(col=O;col<n;++col)
scanf("%0.",&a[fila][col]);
}
return;
}
/*sumarloselementosdedostablasdeenteros*/
voidcalcularsuma(intal][MAXCOL],
intc[][MAXCOL],
{
intfila,col;
intb[][MAXCOL],
intm,intn)

ARRAYS 327
for(fila=O;fila<m;++fila)
for(col=O;col<n;++col)
c[fila][col]=a[fila][col]+b[fila][col];
return¡
}
/*escribirunatabladeenteros*/
voidescribirsalida(intal][MAXCOL],intm,intn)
{
intfila,col;
for
}
(fila=O;fila<
for(col=O;col
printf("%4d",
printf("");
m:++fila){
<ni++col)
a[fila][col]);
}
return¡
Lasdefinicionesdearraysseexpresanentérminos delasconstantessimbólicas MAXFI L Y
MAXCOL,
cuyosvalores seespecificancomo 2OY 3O,respectivamente,alprincipiodelprograma.
Observelamaneradeescribirlasdeclaraciones
delosargumentosformalesdentro decadadefinición
defunción.Porejemplo,laprimeralíneadelafunción
leerentradaseescribecomo
voidleerentrada(intal][MAXCOL],intm,intn)
Elnombredel array, a,estáseguidopordosparesdecorchetes.Elprimerparestávacioporqueelnúmero
defilasnonecesitaserespecificadoexplícitamente.Sinembargo,
elsegundoparcontienelaconstante
simbólica
MAXCOL,queproveeunaespecificacióndetamañoexplícitaparaelnúmero decolumnas.Los
nombresdearraysqueaparecenenotrasdefinicionesdefunción(porejemplo,enlasfunciones
calcu­
larsumayescribirsalida)estánescritosdelamismamanera.
Observetambiénlosprototiposdefuncionesalcomienzodelprograma.Cadaprototipo
esanálogoala
primeralínea
deladefinicióndefuncióncorrespondiente.Enparticular,cadanombre dearrayestásegui­
dopordosparesdecorchetes,elprimerodeloscualesestávacío.Elsegundo
pardecorchetescontienela
especificacióndetamañorequeridaparaelnúmerodecolumnas.
Supongamosqueelprogramaseutilizaparasumarlasdostablasdenúmerossiguientes:
Primeratabla
Segundatabla
1 2 3 4
567 8
91011 12
10.11
1415
1819
12 13
1617
2021
Laejecucióndelprogramageneraráelsiguientediálogo.(Comosiempre,lasrespuestasdelusuarioestán
subrayadas.)

328 PROGRAMACiÓN ENC
¿Cuantasfilas?1
¿Cuantascolumnas?~
Primeratabla:
Introducirdatosparalafilanº1
.l2.1~
Introducirdatosparalafilanº2
.2.2.21J.
Introducirdatosparalafilanº3
.2..l.Q.II12
Segundatabla:
Introducirdatosparalafilanº1
.l.Q.IIII13
Introducirdatosparalafilanº2
14tili17
Introducirdatosparalafilanº3
IIli2..Q.21
Sumasdeloselementos:
111315 17
19212325
27293133
EnalgunoscompiladoresdeCno esposiblepasararraysmultidimensionales dedistintota­
mañoafunciones.Entalessit:uacionesesposiblerediseñarelprograma
demodoquelosarrays
multidimensionalessedefinanexternamente(globales
).Portanto,losarraysnonecesitanser
pasadosalasfuncionescomoargumentos.Sinembargo,estaestrategianofuncionará siempre,
yaquealgunosprogramas(talescomoelprogramamostradoenelúltimoejemplo)utilizanla
mismafunciónparaprocesardiferentesarrays.
Losproblemasdeestetipopuedenserevitados
medianteeluso
depunteros,comosediscutiráenelpróximocapítulo.
9.5.ARRAYS yCADENASDECARACTERES
Yahemosvistoqueunacadena decaracterespuedeserrepresentadaporunarrayunidimensio­
nal
decaracteres.Cadacarácterdelacadenaseráalmacenadoenunelementodelarray.Algu­
nosproblemasrequierenqueloscaracteres
delacadenaseanprocesadosindividualmente(por
ejemplo,elgeneradorde«piglatin»mostradoenelEjemplo9.14).Noobstante,haymuchos
otrosproblemasenlosqueserequierequelascadenasdecaracteresseprocesencomoentidades
completas.TalesproblelUaspuedensimplificarseconsiderablementeutilizando.funcionesespe­
cialesdebibliotecaorientadasacadenas
decaracteres.

ARRAYS 329
Porejemplo,lamayoríadeloscompíladoresdeeincluyenfuncionesdebibliotecaquepermi­
tencompararcadenasdecaracteres,copiarlasoconcatenarlas(esdecir,combinarlasunadetrás
deotra).Otrasfuncionesde bibliotecapermitenoperacionessobrecaracteresindividualesdentro
delascadenas;porejemplo,permitenencontrarcaracteresindividualesdentrodeunacadena,y
asísucesivamente.Elsiguienteejemploilustraelusodealgunasdeestasfuncionesdebiblioteca.
EJEMPLO9.20.Reordenacióndeunalistadecadenasde caracteres.Supongamosquequeremos
leerunalistadecadenasdecaracteres,reordenarlasalfabéticamenteyescribirlalistareordenada.La
estrategiaparahacerestoesmuyparecidaalamostradaenelEjemplo9.13,dondesereordenóunalistade
númerosenordenascendente.Sinembargo,ahoraexistelacomplicaciónadicionaldecompararcadenas
decaracterescompletas,enlugardevaloresnuméricossimples.Portanto,almacenaremoslascadenasde
caracteresenunarraybidimensionaldecaracteres.Cadacadenasealmacenaráenunafiladistintadelarray.
Parasimplificarelproceso,hacemosuso
delasfuncionesdebiblioteca strcmpystrcpy.Estas
funciones
seutilizanparacomparardoscadenas decaracteresyparacopiarunacadenaenotra,respecti­
vamente.(Algunoscompiladorestambiénincluyenlafunción
strcmpi,queesunavariación delamás
común
strcmp.Elusodestrcmpies algunasvecesmásconveniente,yaquenodistingueentrema­
yúsculasyminúsculas.Sinembargo,noestásoportadaporelestándar ANSI.)
Lafuncións trcmpaceptadoscadenascomoargumentosydevuelveunvalorentero,dependiendo
delordenrelativo
delasdoscadenas,comosigue:
l.Sedevuelveunvalornegativosilaprimeracadenaprecedealfabéticamentealasegunda.
2.Sedevuelvecerosilasdoscadenassonidénticas(casonoconsiderado).
3.Sedevuelveunvalorpositivosilasegundacadenaprecedealfabéticamentealaprimera.
Portanto,si
strcmp(cadena1,cadena2)devuelveunvalorpositivo,indicaráquela cadena2
debeirantesquela cadena1paracolocarlascadenasenordenalfabético.
Lafunciónstrcpyaceptatambiéndoscadenascomoargumentos.Generalmentesuprimerargu­
mentoesunidentificadorquerepresentaunacadena.Elsegundoargumentopuedeserunacadenacons­
tanteounidentificadorquerepresenteunacadena.Lafuncióncopiaelvalorde
cadena2encadenal.
Portanto,estohaceque
únacadenaseaasignadaaotra.
Elprogramacompleto
esmuysimilaralprogramadereordenacióndenúmerospresentado enelEjemplo
9.13. Sinembargo,abara
sepermiteque elprogramaacepteunnúmero noespecificadodecadenas,hastaque
seintroduzca unacadenacuyostresprimeroscaracteressean
FIN(tantoenminúsculascomoenmayúsculas).
Elprogramacontarálascadenassegúnseanintroducidas,ignorandolaúltimacadenaquecontiene
FIN.
Acontinuaciónsemuestraelprogramacompleto.
/*ordenaralfabéticamenteunalistadecadenasdecaracteres,
utilizandounarraybidimensional*/
#include<stdio.h>
Hnclude<stdlib.h>
#include<string.h>
'Voidreordenar(intn,'charxl][121);
main()
{
inti
ln=O;
charx [10][12l ;
/ *prototipode'función*/

330 PROGRAMACiÓN ENC
printf("Introducirdebajocadacadenaenunalínea");
príntf("Escríbír\'FIN\'paratermínar");
/*leerlalistadecadenasdecaracteres*/
do{
printf("cadena%d: n + 1);
scanf("%s",x[n]);
}while(strcmp(x[n++],"FIN"));
/*ajustarelvalorden*/
n--i
/*reordenarlalistadecadenasdecaracteres*/
reordenar(n,x);
/*escriblrlalistareordenadadecadenasdecaracteres*/
printf("Lista reordenadadecadenas:");
for(i=O;i<n;++i)
printf("cadena%d:%s",i +1,x[i]);
}
voidreordenar(intn,charxl][12])
{
chartemp[12];
inti,elem¡
/ *reordenarlalistadeca­
denasdecaracteres*/
for(elem=O;elem<n -1;++elem)
/*encontrarlamenordelascadenasrestantes*/
for(i=elem+1;i<n;++i)
í.f(strcmp(x[elem],x[i])>O){
/*intercambiarlasdoscadenas*/
strcpy(temp,x[elem]);
strcpy(x[elem],x[i]);
strcpy(x[i],temp);
}
return¡
}
Lafuncións trcmpapareceendossitiosdistintosdelprograma:en main,cuandosecompruebala
condicióndefinalización,
yenreordenar,cuandosecompruebalanecesidaddeintercambiardos
cadenas.Elintercambiorealseefectúausandos
trcpy.
Acontinuación.semuestraundiálogotípicodelaejecucióndeesteprograma.Como
siempr~, las
respuestasdelusnarioestánsubrayadas.
Introducirdebajocadacadenaenunalínea
Escribir'FIN'paraterminar

ARRAYS 331
cadena1:PACIFICO
cadena2:ATLANTICO
cadena3:INDICO
cadena4:CARIBE
cadena5:BERING
cadena6:NEGRO
cadena7:ROJO
cadena8:NORTE
cadena9:BALTICO
cadena10:CASPIO
cadena11:FIN
Listareordenadadecadenas
cadena1:ATLANTICO
cadena2:BALTICO
cadena3:BERING
cadena4:CARIBE
cadena5:CASPIO
cadena6:INDICO
cadena7:NEGRO
cadena8:NORTE
cadena9:PACIFICO
cadena10:ROJO
Enelpróximocapítuloveremosdiferentesmaneras derepresentarlistasdecadenasdemodomás
eficienteentérminos
derequerimientosdememoria.
9.1.
9.2.
9.3.
9.4.
9.5.
9.6.
9.7.
9.8.
9.9.
9.10.
9.11.
¿Enquésediferenciaunarraydeunavariableordinaria?
¿Quécondicionesdeben
cumplirtodosloselementos
decualquierarray?
¿Cómoseidentificanloselementosindividuales
deunarray?
¿Quésonlosíndices?¿Cómoseescriben?¿Quérestriccionesseaplicanalosvalores
de
losíndices?
Sugerir.unaformaprácticadeyisualizararrays
deunay.dedosdimensiones.
¿EnquésediferencialadefiniciqfldelInarraydeladeunavariableordinaria?
Mencionarlasreglaspara escribirdefinicionesdearraysunidimensionales.
¿Quéventajatienedefinir
eltamañodeunarrayentérminosdeunaconstantesimbólica
envez
deusarunacantidadenterafija?
¿Puedenespecificarsevaloresiniciales·en
unádefinicióndearray·externo?¿Puedenespe­
cificarseenunadefinicióndearrayautomático?
¿Cómoseescribenlosvaloresinicialesenunadefinicióndeunarrayunidimensional?
¿Debeinicializarsetodoelarray?
¿Quévalorselesasignaautomáticamentealoselementosdelarrayquenoestánexplíci­
tamenteinicializados?

332 PROGRAMACiÓN ENC
9.12.Describirlaformahabitualdeasignarinicialmenteunaconstantedecadena decaracteres
aunarrayunidimensional.¿Puedeusarseunprocedimientosimilarparaasignarvalores
inicialesaunarraynumérico?
9.13.Cuandoaunarray decaracteresunidimensional detamañonoespecificadoseleasigna
unvalorinicial,¿quécarácterextraseañadealfinaldelacadena?
9.14.¿Cuándoserequierendeclaraciones dearrays(encontrastecondefinicionesdearrays)
en
unprogramaenC?¿Enqué sediferencianestasdeclaraciones delasdefinicionesdearrays?
9.15.¿CómoseprocesangeneralmentelosarraysenC?¿Puedenprocesarselosarraysconins­
truccionessimples,sinrepetición?
9.16.Cuandosepasaunarrayaunafunción,¿cómosedebeescribirelargumento dearray?
¿Cómoseescribeelargumentoformalcorrespondiente?
9.17.¿Cómoseinterpretaelnombredelarraycuandosepasaaunafunción?
9.18.Supongamosqueunadeclaración defunciónincluyelasespecificacionesdetipo,y
uno
delosargumentosesunarray.¿Cómodebeescribirselaespecificacióndeltipodel
array?
9.19.Cuandosepasaunargumentoaunafunción,¿cuálesladiferenciaentreelpasoporvalor
y
elpasoporreferencia?¿Aquétipodeargumentosseledebeaplicarcadauno?
9.20.Sisepasaunarrayaunafunciónydentro deellasemodificanvarios desuselementos,
¿sereconocenestoscambiosenlapartedelprogramaquehizolallamada?Explicarlo.
9.21.¿Sepuedepasarunarraydesdeunafunciónhastalapartedelprogramaquehizola-llama­
da,medianteunainstrucción
return?
9.22.¿Cómosedefinenlosarraysmultidimensionales?Compararconlaformadedefinirlos
arraysunidimensionales.
9.23.Enunciarlareglaquedeterminaelordendeasignacióndevaloresinicialesaloselemen­
tos
deunarraymultidimensional?
9.24.Cuandoseasignanvaloresinicialesaloselementos deunarraymultidimensional,¿qué
ventajasexistenalformargrupos
.devaloresiniciales,dondecadagruposeencierraentre
supropioconjuntodellaves?
9.25.Cuandosepasaunarraymultidimensionalaunafunción,¿cómoseescribeladeclaración
formaldelargumento?Compararconlosarraysunidimensionales.
9.26.¿Cómopuedealmacenarseunalistadecadenasdecaracteresenunarraybidimensional?
¿Cómopuedenprocesarselascadenasindividuales?¿Quéfunciones
debibliotecasetie­
nenparasimplificarelprocesado
decadenas?
9.27.Describirelarray
defini~oencada.unadelassiguie¡1tesinstrucciones:
a)charnombre[3O];
b)floatc[6];
ti)intparametros[5] [5];
e)
#defineN50
inta[N];.

ARRAYS 333
e)#defineA66
#defineB132
charmemo[A] [B];
1)doub1ecuentas[50] [20][80];
9.28.Describirelarraydefinidoencadaunadelassiguientesinstrucciones.Indicarquévaloresson
asignadosaloselementosindividualesdel array.
a)floatc[8]={2.,5.,3.,-4.,12., 12.,O.,8.};
b)floate[8]={2.,5.,3.,-4.};
e)intz[12]={O,O,8,O,O, 6};
d)charindicador[9]={'V'/'E'/'R'I'D'f'A'I'D','El,'R','O',};
e)charindicador[lO]={'V'ffE'r'R','D'I'A','D'f'E',tRIf'0',}
charindicador[]
k)intp[2][4]
"FALSO
n
;
1)intc[2] [3] [4]
{
3,5,5,7,7};
7};
3,5,
7),
4,6,8}
3),
7}
"VERDADERO";
{1,3,5,
{1,1,3,
{
{l,
{2,
};
{
{l,
{5,
};
={
indieador[]
p[2][4]=
p[2][4]=
p[2][4]
int
int
int
1)char
g)
h)
i)
j)
{1,2,3),
{4,5},
{6,7,8,9}
},
{
{la,11},
{j,
{12,13,14}
}
}
;
m)charcolores[3] [6]= {
{,R',' OI I
'J'ID'},
{ ,VI,lE/1'RI
I ' DI 1/El}1
{lAI ,'Z',IU'I' L1 }
};

334 PROGRAMACiÓN ENC
9.29.Escribirunadefiniciónapropiadadearrayparacadaunodelossiguientesproblemas.
a)Definirunarrayunidimensionalde 12elementosenterosllamado c.Asignarlosvalo­
res
1,4,7,lO,..., 34aloselementosdelarray.
b)Definirunarrayunidimensionaldecaracteresllamado punto.Asignarlacadena
"NORTE"aloselementosdelarray.Terminarlacadenaconelcarácternulo.
e)Definirunarrayunidimensionaldecuatrocaracteresllamado letras.Asignarloscaracteres
'N','8','E'Y 'O'aloscaracteresdel array.ti)Definirunarrayunidimensional deseiselementosencomaflotantellamado constantes.
Asignarlossiguientesvaloresaloselementosdelarray:
0.005
-0.032 le-6 0.167
-0.3e8 0.015
e)Definirunarraybidimensionaldeenteros, de3x4,llamadon.Asignarlossiguientesvalores
inicialesaloselementosdelarray:
lO
20
30
12
22
32
14
24
34
16
26
36
f)Definirunarraybidimensionaldeenteros, de3x4,llamadon.Asignarlossiguientesvalo­
resinicialesaloselementosdelarray:
lO
O
O
12
20
30
14
22
32
O
O
O
g)Definirunarraybidimensionaldeenteros, de3x4,llamadon.Asignarlossiguientesvalores
inicialesaloselementosdelarray:
lO
20
O
12
22
O
14
O
O
16
O
O
9.30.Paracadaunadelassiguientessituaciones,escribirlasdefinicionesydeclaracionesnecesarias
paratransferirlasvariablesylosarraysindicadosdesde
mainhastalafunciónllamada muestra
(verEjemplos9.10Y9.11).Encadacaso,asignarelvalordevueltoporlafunciónalavariableen
comaflotantex.
a)Transferirlasvariablesencomaflotantea y b Yelarrayunidimensionalde20elementos
enteros
jstar.
b)Transferirlavariableentera n,lavariablecarácterc yelarrayunidimensionalde 50elementos
endobleprecisión
valores.
e)Transferirelarraybidimensional decaracteresde 12x80,llamadotexto.
ti)Transferirelarrayunidimensionalde40caracteres mensajeyelarraybidimensionalde
50
x100elementosencomaflotante cuentas.
9.31.Describirlasalidaproducidaporlossiguientesprogramas:
a)#include<stdio.h>
main()
{

ARRAYS 335
inta,b ~o;
statieinte[lO]~{l,2,3,4,5,6,7,8,9,O};
for(a~O;a < 10;++a)
if«e[a]%2)~~O) b+~era];
printf(lI%d"
rb)¡
}
~#inelude<stdio.h>
main()
{
inta,b ~O;
statieinte[lO]~{l,2,3,4,5,6,7,8,9,O};
for(a~O;a < 10;++a)
if«a%2)--O)b+~era];
printf(Il%d
n
Ib);
}
e)#inelude<stdio.h>
main()
{
inta,b=O;
inte[lO]~{l,2,3,4,5,6,7,8,9,O};
for(a~O;a < 10;++a)
b+~e[a];
printf(l1%d
ll
lb)¡
}
á)#inelude<stdio.h>
inte[lO]~{l,2,3,4,5,6,7,8,9,O};
main()
{
inta,b=O;
for(a~O;a < 10;++a)
if«e[a]%2)~~1) b+~era];
printf("%d",b);
}
e)#inelude<stdio.h>
#defineFILAS3
#defineCOLUMNAS 4
intz[FILAS][COLUMNAS]~{l,2,3,4,5,6,7,8,9,10, 11,12};

336 PROGRAMACiÓN ENC
main()
{
inta,b,e ~999;
for(a~O;a <FILAS;++a)
for(b~O;b <COLUMNAS; ++b)
if(z[a][b]<e)e~z[a][b];
printf("%d",e);
}
1)#inelude<stdio.h>
#defineFILAS3
#defineCOLUMNAS 4
intz[FILAS][COLUMNAS] ~{l,2,3,4,5,6,7,8,9,la,11,12};
main()
{
inta,b,c¡
for(a~O;a <FILAS;++a){
e ~999;
for(b~O;b <COLUMNAS; ++b)
if(z[a]lb]<e)e~z[a][b];
printf("%d"e);
}
}
g)#inelude<stdio.h>
#defineFILAS3
#defineCOLUMNAS 4
voidsubl(intz[][COLUMNAS]);
main()
{
statieintz[FILAS][COLUMNAS] ~{l,2,3,4,5,6, 7,8,9,
la,11,12};
subl(z);
}
voidsubl(intxl][4])
{
intalb,c¡
for(b~O;b <COLUMNAS; ++b){
e:::;O;
for(a~O;a <FILAS;++a)
if(x[a]lb]>e) e ~x[a][b];
printf("%d",e);
}
return¡
}

ARRAYS 337
h)#inelude<stdio.h>
#defineFILAS3
#defineCOLUMNAS 4
voidsubl(intz[][COLUMNAS]);
main()
{
inta,b¡
statieintz[FILAS][COLUMNAS]={l,2,3,4,5,6,7,8,9,
10, 11,12};
subl(z);
for(a=O;a <FILAS;++a){
for(b=O;b <COLUMNAS; ++b)
printf("%d",z[a][b]);
printf("");
}
}
voidsubl(intxl][COLUMNAS])
{
inta,b;
for(a=O;a <FILAS;++a)
for(b=O;b <COLUMNAS; ++b)
if((x[a]lb]%2)==1)x[a]lb]--;
returu;
}
i)#inelude<:stdio.h>
main()
{
inta;
staticcharc[]:'= 11Programarenepuedesermuydivertido!'11i
for(a=O;era]!='\0';++a)
if((a%2)==O)
printf("%e%e",e[a],era]);
}
9.32.ModificarelprogramadadoenelEjemplo.9.8(desviacionesrespecto delamedia)paraincluir.dos
funcionesadicionales.LaprimerafunciónleelosnÚtnerosparacalcularlamedia yalavezrealiza
la.surna;Lasegulldafuncióndebecalcularlas·desviacion.esrespectoa lamedia.Elr.estodelas

338 PROGRAMACiÓN ENC
acciones(leerelvalorde n,calcularelvalordelamedia,escribirlamediacalculadaylasdesvia­
cionesrespecto
deella)debenrealizarseenlaparte maindelprograma.
9.33.ModificarelprogramadadoenelEjemplo9.9(desviacionesrespectoalamedia,revisión)inclu­
yendodosfuncionesadicionales.Calcularyescribirlamediaenlaprimerafunción.Calculary
escribirlasdesviacionesrespectodelamediaenlasegundafunción.
9.34.ModificarelprogramadadoenelEjemplo9.13(reordenación
deunalistadenúmeros) demodo
quelosnúmerossereordenenensecuenciadevalores
decrecientes(delmayoralmenor).Compro­
barelprogramaconlosdatosdadosenelEjemplo9.13.
9.35.Modificar
elprogramadadoenelEjemplo9.13(reordenación deunalistadenúmeros) demodo
quesepuedanrealizarcualquieradelassiguientesreordenaciones:
a)demenoramayor,envalorabsoluto
b)demenoramayor,algebraicamente(consigno)
c)demayoramenor,envalorabsoluto
d)demayoramenor,algebraicamente(consigno)
Incluirunmenúquepermitaalusuarioseleccionarquéreordenaciónseráusadacadavezquese
ejecuteelprograma.Comprobarelprogramausandolosdiezvaloressiguientes:
4.7
-8.0
-2.3 11.4
12.9
5.1
8.8 -0.2
6.0
-14.7
9.36.Modificarelgeneradorde«piglatin»dadoen elEjemplo9.14 demodoquepermitalasmarcas de
puntuación,letrasmayúsculasysonidos deletrasdobles.
9.37.ModificarelprogramadadoenelEjemplo9.19(sumadedostablasdenúmeros)demodoque
calculelasdiferenciasenvezdelassumasdeloselementoscorrespondientesen lasdostablasde
enteros.ComprobarelprogramausandolosdatosdadosenelEjemplo9.19.
9.38.ModificarelprogramadadoenelEjemplo9.19(sumadedostablasdenúmeros)demodoque
seutiliceunarraytridimensionalenvezdetresarraysbidimensionales.Elprimeríndicerefe­
riráaunadelastrestablas.Elsegundoreferiráelnúmerodefilayelterceroelnúmerode
columna.
9.39.EscribirunprogramaenCqueleaunalíneadetexto,laalmaceneen
unarrayylaescribaalrevés.
Lalongitud
delalíneanoseráespecificada(terminaráalpulsarlatecla Intro),perosesupone
quenoexcederáde
80caracteres.
Comprobarelprogramaconcualquierlíneadetextode suelección.Compararconelprograma
dadoenelEjemplo¡.15,quehaceusodlllareclJIsividadenyezdeutilizarunarray.¿Quéenfoque
esmejoryporqué?
9.40.Escribirunprogramainteractivo
enCparaprocesarlasnotasdeungrupodeestudiantesdeun
cursodeprogramaciónen
C.Empezarespecificandoelnúmerodenotasdeexamenparacadaestu­
diante(suponerqueestevalores
elmismoparatodoslosestudiantesdelaclase).Despuésintrodu-

ARRAYS 339
cirelnombre decadaestudianteylasnotasdelosexámenes.Calcularunanotamediaparacada
estudianteyunamediageneraldelaclase(unamediadelasmedias
delosestudiantes).Escribirla
mediadelaclase,seguidapor
elnombre,lasnotasindividuales delosexámenesylamediapara
cadaestudiante.
Almacenarlosnombresdelosestudiantesenunarraybidimensionaldecaracteresylasnotas
enunarraybidimensionalencomaflotante.Hacerelprogramalomásgeneralposible.Rotular
claramentelasalida.
Comprobar
elprogramautilizandoelsiguienteconjuntodenotas deexámenesdeestu­
diantes.
Nombre Puntuaciones
Adrián 458080 955575
Antonio 605070
755580
Carmen 4030 10456055
Félix O 5 5 O10 5
Guillermo 9085100
959090
José 959080
958580
Lidia 3550
55654570
Maruja 756075607080
Pedro
857560 8590100
Raúl 50605035
6570
Rosa 70607570
5575
Sonia 1025352030
10
Víctor 254065 758595
Zoraida 6580701006095
CompararconelprogramaescritoparaelProblema
6.69(k).
9.41.Modificarelprogramaescritoparaelproblemaanteriordemaneraquepermitapesosdesigualesen
lasnotas
delosexámenesindividuales.Enparticular,suponerquecadauno delosprimeroscuatro
exámenescontribuyecon
el15por100 delanotafinal,ycadaunodelosdosúltimosconel20por
100[verProblema6.69(1)].
9.42.Extenderelprogramaescritoparaelproblemaanteriordemodo
qu~sedetermineladesviación de
lamediadecadaestudianterespecto delamediageneral.Escribirlamediadelaclase,seguidapor
cadanombredeestudiante,lasnotas
delosexámenesindividuales,lanotafinalyladesviación
respectodelamediageneral.Asegurarsedequelasalidaseorganiza
deformalógicayserotula
claramente.
9.43.EscribirunprogramaenCquegenereunatabla devalores
paralaecuación
y=2e-o·
1tseno0.5t
dondetvariaentreOy60.Permitirqueelvalordelincremento tseaintroducidocomounparáme­
trodeentrada.

340 PROGRAMACIÓN ENC
9.44.EscribirunprogramacompletoenCquegenereunatabladefactoresdeinteréscompuesto, FIP,
donde
FIP=(i+i/lOO)"
Enestafórmula Frepresentaelvalorfuturodeunasumadadadedinero, Psuvaloractual, ilatasa
deinterésanual,expresadacomounporcentaje,y
nelnúmerodeaños.
Cadafilaen
latablacorrespondeaunvalordiferentede n,connenelrangode1 a30(por
tanto,30filas).Cadacolunmarepresentaunatasadeinterésdiferente.Incluirlassiguientestasas
deinterés:4,4.5,5,5.5,
6,6.5,7,7.5, 8,8.5,9,9.5,10,11,12Y15porciento(portanto,untotal
de
16colunmas).Asegurarsederotularlasfilasylascolumnasdeformaapropiada.
9.45.ConsiderarlassiguientesmonedasextranjerasysusequivalenciasendólaresUSA:
Librabritánica:
Dólarcanadiense:
Florínholandés:
Francofrancés:
Marcoalemán:
Liraitaliana:
Yenjaponés:
Pesomejicano:
Francosuizo:
0.65libraspordólarUSA
1.4dólarespordólarUSA
1.7florinespordólarUSA
5.3francospordólarUSA
1.5marcospordólarUSA
1570liraspordólarUSA
98yenespordólarUSA
3.4pesospordólarUSA
1.3francospordólar USA
Escribirunprogramainteractivo,guiado pormenús,queaceptedosmonedasextranjerasydevuel­
vaelvalordelasegundamonedaporcadaunidaddelaprimeramoneda.(Porejemplo,silasdos
monedassonelyenjaponésyelpesomejicano,elprogramadevolveráelnúmerodepesosmejica­
nosequivalentesaunyenjaponés.)Utilizarlosdatosdadosanteriorespararealizarlasconversio­
nes.Diseñarelprogramademodoque
seejecuterepetidamente,hastaqueseseleccionelacondi­
cióndesalidadelmenú.
9.46.Considerarlasiguientelistadepaisesysuscapitales:
Canadá
Inglaterra
Francia
Alemania
India
Israel
Italia
Japón
México
RepúblicaPopularChina
Rusia
EstadosUnidos
Ottawa
Londres
París
Bonn
NuevaDelhi
Jerusalén
Roma
Tokio
CiudaddeMéxico
Pekin
Moscú
Washington
EscribirunprogramainteractivoenCqueacepteelnombredeunpais comoentradayescribasu
correspondientecapitalyviceversa,Diseñarelprograma.demodoqueseejecuterepetidamente,
hastaqueseintroduzcalapalabra
Fin.

ARRAYS 341
9.47.Escribirunprogramacompletoen eparacadaunodelosproblemaspresentadosacontinuación.
Incluireltipodearraysmásapropiadoparacadaproblema.Asegurarsedemodularizarcadapro­
grama,rotularclaramentelasalidayhacerusodetiposdedatosnormalesydeestructuraseficien­
tesdecontrol.
a)Suponerquetenemosunatabladeenteros A,commfilasy ncolumnas,y unalistadeenteros,
x,connelementos.Sedeseagenerarunanuevalistadeenteros, Y,queseformarealizandolas
siguientesoperaciones:
y[l]=A[l][1]*X[l]+A[l][2]*X[2]+
y[2]=A[2][1]*X[l]+A[2][2]*X[2]+
y[m]=A[m][1]*X[i]+A[m][2]*X[2]+
+A[l][n]*X[n]
+A[2][n]*X[n]
+A[m][n]*X[n]
Escribirlosdatosdeentrada(losvaloresdeloselementos Ayx),seguidosporlosvaloresde
loselementosde
Y.
Usarelprogramaparaprocesarlossiguientesdatos:
12345678
23456789
3 4 5 6 7 8 9 lO
A=
4 5 6 7 8 9 10II
5 6 7 8 9 lO1112
6 7 8 9 101112 13
I
-8
3
-6
X=
5
-4
7
-2
b)SuponerqueAesunatabladenúmeros encomaflotante,quetienekfilasy mcolunmas,y Bes
unatabladenúmerosencomaflotantedemfilasy ncolumnas.Sedeseagenerarunanueva
tabla
C,dondecadaelementosedeterminamediante
C[i][jI=A[i][1]*B[l][jI+A[i][2]*B[2][jI+. . +
A[i][m]*B[m][jI
dondei=1 ,2,..., k Yj=1 ,2,...,n.(Estaoperaciónesla multiplicacióndematrices.)
Utilizarelprogramaparaprocesarlossiguientesdatos:
615O-21/3
'+;2
-1/3O2/3
4;3]
57/23/4-3/2
312 4-2 B=O-1 I O
3-917617 912317 -3 3
4
-1/2O3/4
Escribirloselementosde A,B YC.Asegurarsedequetodoestébienrotulado.

342 PROGRAMACiÓN ENC
e)Leerlosprimeros melementosdeunarrayunidimensionalencomaflotante.Calcularlasuma
deestoselementos,lamedia,lasdesviaciones,ladesviaciónestándar,elmáximoy
elminimo
algebraico.
La
mediasedefinecomo
La
desviaciónrespectoalamedia es
yladesviaciónestándar es
Utilizarelprogramaparaprocesarelsiguienteconjunto
dedatos:
27.5 87.0
13.4 39.9
53.8 47.7
29.2 8.1
74.5 63.2
Repetir
elcálculopara klistasdiferentes denúmeros.Calcularlamediaglobal,ladesviación
estándarglobal,elmáximoabsoluto(mayor)y
elmínimoabsoluto(menoralgebraico).
d)Suponerquetenemosunconjuntodevalorestabuladosde xey,estoes,
Yo
X
o
Y2
x
2
yqueremosobtenerelvalorde yparaalgúnvalor dexquecaeentredos delosvalorestabula­
dos.Esteproblemaseresuelvenormalmentemediante
interpolación,pasandounpolinomio
y(x)atravésde npuntostalesque y(x
o
)
~Yo'y(x¡)=y!'...,y(x"l=y,ydespuésevaluando ypara
elvalordeseadode
x.
Unaformacomún derealizarlainterpolaciónesusarla fórmuladeLagrange delainterpo­
laciónpolinomial.Parahacerestoseescribe
y(x)=
fo(x)Yo+f;(x)y¡+...+J;(x)y,
dondef,(x)esunpolinomiotalque
!,(X)=[(x-xo)(x-x¡)(x-x,¡)(x-x,+¡)...(x-x,)]
(x,-xo)(x,-x¡)(x,-x,_¡)(x,-X'+l)"'(X,-x
n
)
Notarque
f,(x,)=I Yf,(x)~0,dondex
j
esunvalortabuladode xdistintodexi"Portanto,se
aseguraque
y(x,)=y,.

ARRAYS 343
EscribirunprogramaenCquelea nparesdedatos,donde nnoexcededelO,yobtengaa
continuaciónunvalorinterpoladode
yparaunoomásvaloresespecificados dex.Usarel
programaparaobtenervaloresinterpoladosde
yenx
~13.7,x~37.2,x=112Yx=147apartir
delosdatosdadosacontinuación.Determinarcuántosparestabulados dedatosserequierenen
cadacálculoparaobtenerunvalorrazonablementeajustadode
y.
y=0.21073
0.45482
0.49011
0.50563
0.49245
0.47220
0.43433
0.33284
0.19390 x=O
20
30
40
50
60
80
120
180
9.48.LossiguientesproblemasestánrelacionadosconjuegosdeazarUuegosdeapuestas).Cadapro­
blemarequiereelusodenúmerosaleatorios,comosedescribeenelEjemplo7.11.Cadaprogra­
marequieretambiéneluso deunarray.Losprogramasdebenserinteractivosyestarmodulari­
zados.
a)EscribirunprogramaenCquesimuleunjuego de
«blackjack»entredosjugadores.Lacompu­
tadoranoseráunparticipanteeneljuego,simplementedarálascartasacadajugadoryprovee­
ráacadajugadorconunaomáscartasadicionalescuandoéstelosolicite.
Lascartassedanenorden,primerounacartaacadajugador,despuésotracartaacadauno.
Sepuedendemandarcartasadicionales.
Elobjetodeljuegoesobtener
21puntos,otantospuntoscomoseaposiblesinexcederde
21encadamano.Unjugadoresautomáticamentedescalificadosilascartasensumanoexce­
den
de21puntos.Lasfigurascuentan 10puntosyunaspuedecontarunpuntou 11puntos.
Asi,unjugadorpuedeobtener
21puntos(<<¡blackjack!»)sitieneun asyunafiguraoun lO.Si
eljugadortienemenospuntosconsusdosprimerascartas,puedepedirunacartaomás,mien­
trassupuntuaciónnopase
de21.
Utilizarnúmerosaleatoriosparasimularelrepartodelascartas.Asegurarlainclusiónde
unacondiciónparaquelamismacartanoseadadamásdeunavez.
b)Alaruletasejuegaconunaruedaquecontiene 38cuadrosdiferentesensucircunferencia.Dos
deloscuadros,numeradosconelO
y00,sonverdes; 18cuadrossonrojos y18sonnegros.Se
alternanloscuadrosrojos
ynegrosyestánnumeradosdeI a36enordenaleatorio.
Unapequeñabolagiradentrodelarueda,quecomoresultadoterminaquedandodentrode
unaranuradebajo
deunodeloscuadros.Eljuegoesapostaralresultado delosgiros,deunade
lasmanerassiguientes:
i)Seleccionandouncuadrorojoonegro,conunaparidadde 35al.Asi,sieljugadorapuesta
1dólar
ygana,recibiráuntotalde36dólares:eloriginalmásotros 35dólares.
ii)Seleccionandouncolor,rojoonegro,conunaparidadI a
1.Así,sieljugadoreligerojo y
apuestaIdólar,silabolaseparadebajodeuncuadrorojorecibirá2dólares.
iii)Seleccionandolosnúmerosparesoimpares(excluidosO
y00),conparidadI a 1.
iv)Seleccionandolos 18númerosbajosolos 18altos,conparidad1 a 1.
Eljugadorperderáautomáticamentesilabolitaseparadebajodeunodeloscuadrosverdes
(Oo00).

344 PROGRAMACiÓN ENC
EscribirunprogramainteractivoenCquesimuleeljuegodelaruleta.Permitirquelos
jugadoresseleccionencualquiertipodeapuestaquedeseeneligiéndolaenunmenú.Escribir
el
resultadodecadajuegoseguidoporunmensajeapropiadoqueindiquesieljugadorhaganado
ohaperdido.
e)EscribirunprogramainteractivoenCquesimuleunjuegodeBINGO.Escribircadacombina­
cióndeletra-númerosegúnseasacada(generada).Asegurarsequeunacombinaciónnosesaca
másdeunavez.Recordarquecadaunadelasletras
deB-I-N-G-Ocorrespondeauncierto
rango
denúmeros,comoseindicaacontinuación.
B:I - 15
1:16-30
N:31-45
G:46-60
O:61-75
Cadajugadortendráuncartónconcincocolumnas,rotuladasB-I-N-G-O.Cadacolumna
contendrácinconúmeros,dentrodelosrangosindicadosarriba.Dosjugadoresnopuedentener
elmismocartón.Elprimerjugadorquetengaunalíneadenúmerossacados(envertical,hori­
zontaloendiagonal)gana.
Nota:Aveceslaposicióncentral decadacartónsecubreantes decomenzareljuego(unajugada
«gratis»).Avecestambiénsejuegaaquedebensalir
todoslosnúmerosdelcartónparaganar.
9.49.EscribirunprogramainteractivoenCquecodifiqueydecodifiqueunalíneadetexto.Paracodifi­
carunalíneadetexto,procedercomosigue:
I.Convertircadacarácter,incluidosespaciosenblanco,ensuequivalenteASCII.
2.Generarunenteropositivoaleatorio.AñadiresteenteroalASCIIequivalenteacadacarácter.
Elmismoenteroaleatorioseráusadoparalalíneadetextocompleta.
3.Suponerque
NIrepresentaelmenorvalorpermisibleenASCIIy N2representaelmayorvalor
permisibleenASCII.Si elnúmeroobtenidoenelpaso2anterior(elASCIIoriginalmásel
enteroaleatorio)excede
deN2,selerestaelmúltiplomayorposiblede N2ysesumaelrestoa
NI.Portanto,elnúmerocodificadoestarásiempreentre NIyN2,Ysiemprerepresentaráal­
gúncarácterASCII.
4.EscribirloscaracterescorrespondientesalosvaloresASCIIcodificados.
Elprocedimientoseinviertecuandosedecodificaunalínea
detexto.Asegurarsequeseusapara
decodificarelmismoenteroquefueusadoparacodificar.

CAPíTULO
Punteros10
Unpunteroesunavariablequerepresentala posición(envezdelvalor)deotrodato,talcomo
unavariableounelementodeunarray.LospunterossonusadosfrecuentementeenC ytienen
grancantidaddeaplicaciones.Porejemplo,puedenserusadosparatrasvasarinformaciónentre
unafunciónysuspuntosdellamada.Enparticularproporcionanunaformadedevolvervarios
datosdesdeunafunciónatravésdelosargumentosdelafunción.Lospunterostambiénpermi­
tenquereferenciasaotrasfuncionespuedanserespecificadascomoargumentosdeunafunción.
Estotieneelefectodepasarfuncionescomoargumentosdeunafuncióndada.
Lospunterosestánmuyrelacionadosconlosarraysyproporcionanunavíaalternativade
accesoaloselementosindividualesdelarray.Esmás,proporcionanunaformaconvenientepara
representararraysmultidimensionales,permitiendoqueunarraymultidimensionalseareempla­
zadoporunarraydepunterosdemenordimensión.Estacaracterísticapermitequeunacolec­
cióndecadenasdecaracteresseanrepresentadasporunsoloarray,inclusocuandolascadenas
puedantenerdistintalongitud.
10.1.CONCEPTOS BÁSICOS
Dentrodelamemoriadelacomputadora,cadadatoalmacenadoocupaunaomásceldasconti­
guasdememoria(esdecir,palabrasobytesadyacentes).Elnúmerodeceldasdememoriare­
queridasparaalmacenar
undatodependedesutipo.Porejemplo, uncaráctersealmacenará
normalmenteenunbyte
(8bits)dememoria;unenterousualmentenecesitadosbytescontiguos;
unnúmeroencomaflotantepuedenecesitarcuatrobytescontiguos;yunacantidadendoble
precisiónpuederequerirochobytescontiguos.(VéanseCapítulo2 yApéndiceD.)
Supongamosquevesunavariablequerepresentaundeterminadodato.Elcompiladorauto­
máticamenteasignaráceldasdememoriaparaestedato.Podemosaccederaldatosiconocemos
lalocalización
(dirección)delaprimeraceldadememoria *.Ladireccióndememoriadev
puedeserdeterminadamediantelaexpresión&v,donde&es
unoperadorunario,llamadoel
operadordirección, queproporcionaladireccióndeloperando.
*Lasceldasadyacentesdememoriadentrodelacomputadoraestánnumeradasconsecutivamente,desde elprinci­
piohastaelfindeláreadememoria. Elnúmeroasociado concadaceldadememoria esconocidocomola direcciónde
lacelda.Lamayoríadelascomputadorasusanelsistema denumeracióndecimal paradesignarlasdirecciones de
celdasdememoriaconsecutivas,aunquealgunascomputadorasusan elsistemadenumeraciónoctal(verApéndiceA).
345

346 PROGRAMACiÓN ENC
Ahoravamosaasignarladireccióndev aotravariable, pv.Así,
pv=&v
Estanuevavariablees unpunteroav,puestoque«apunta»alaposicióndememoriadondese
almacena
v.Recordar,sinembargo,que pvrepresentala direccióndevynosuvalor.Deesta
forma,
pvesreferidacomouna variableapuntadora. Larelaciónentrev ypvestáilustradaen
laFigura10.1.
Direccióndev
------••1 Valordev
'---------------'
pv v
Figura10.1.Relaciónentre pvyv(dondepv=&vyv =*pv)
Eldatorepresentado
porv(esdecir,eldatoalmacenado enlasceldasdememoriade v)
puedeseraccedidomediantelaexpresión *pv,donde*esunoperadorunario,llamadoel
apee
radarindirección, queoperasólosobreunavariablepuntero.Portanto, *pvyvrepresentanel
mismodato(elcontenidodelasmismasceldasdememoria).Además,siescribimos
pv=&v
yu = *pv,entoncesu yvrepresentanelmismovalor;estoes,elvalordevseasignaindirec­
tamentea
u.(Sesuponequeu yvestándeclaradascomodelmismotipodedatos.)
EJEMPLO10.1. Mostramosacontinuación unprogramasencillo queilustralarelación entredosva­
riablesenteras, suscorrespondientesdirecciones ysuspunterosasociados.
#include<stdio.h>
main( )
{
/*punteroaunentero*/
/*punteroaunentero*/
/*asignadireccióndeuapu*/
/*asignavalordeu a v*/
/*asignadireccióndevapv*/
pu=&u;
v=*pUi
pv=&v¡
intti=3;
intVi
int*PUi
int*PVi
printf("u=%d
printf("v=%d
pu=%X
pv=%X *pu=%d
ll
,U,&u,pu,*pu)¡
*pv=%d" IV,&v,pv,*pv)i
}
Observequepuesunpunteroau, ypvunpunteroa v.Portanto,purepresentaladirección deuypvla
dirección
dev.(Enlapróximasección setrataráladeclaración depunteros.)
Laejecucióndeesteprogramaproducelasiguientesalida:
u=3
v=3
&u=F8E
&v=F8C
pu=F8E
pv=F8C
*pu=3
*pv=3

PUNTEROS 347
Enlaprimeralineavemosqueurepresentaelvalor 3,comoestáespecificadoenlainstrucción dedecla­
ración.
Ladirecciónde uestádirectamentedeterminadaporelcompiladorcomo F8E(hexadecimal).Al
puntero
puseleasignaestevalor;portanto putambiénrepresentaladirección F8E(hexadecimal):Final­
menteelvaloralqueapunta
pu(elvaloralmacenadoenlaceldadememoriacuyadirecciónes F8E)es3,
comoeradeesperar.
Análogamente,lasegundalineamuestraque
vrepresentaelvalor 3.Estoeraloesperado,yaque
hemosasignado
elvalor*puav.Ladirecciónde v,yportantoelvalorde pv,esF8C.Notarque uyv
tienendireccionesdiferentes. Yfinahnente,vemosqueelvaloralqueapunta pves3,comoerade
es­
perar.
Larelaciónentre
puyu,ypvyv,esmostradaenlaFigura10.2.Notarquelasposiciones
delasvariablespunteros(direcciones
EC7parapuyEC5parapv)nosonescritas porelprograma.
DirecciónEC7 DirecciónF 8E
____F_8_E
-'I------··I... 3 _
pu
DirecciónEC5
u
DirecciónF8C
'-- F_8_C -------l.~ 1 3 .......J
pv
Fignra10.2.
v
Losoperadoresunarios &y*sonmiembrosdelmismogrupodeprecedenciaquelosotros
operadoresunarios,-,++,--,!,sizeofy(tipo),loscualesfueronpresentadosenelCa­
pítulo3.Recordarqueestegrupodeoperadorestienemayorprecedenciaquelosgruposque
contienenalosoperadoresaritméticos,yque
laasociatividaddelosoperadoresunariosesde
derechaaizquierda(verApéndiceC).
Eloperadordirección
(&)sólopuedeactuarsobreoperandoscondirecciónúnica,como
va­
riablesordinariasoelementosindividualesde unarray.Porconsiguiente, eloperadordirección
nopuedeactuarsobreexpresionesaritmética,
talescomo2 *(u+v).
Eloperadorindirección (*)sólopuedeactuarsobreoperandosqueseanpunteros(por
ejem­
plo,variablespuntero).Sinembargo,si pvapuntaa v(estoes,pv=&v),entoncesunaexpre­
sióncomo
*pvpuedeintercambiarseconlacorrespondientevariable v.Asíunareferencia
indi­
recta(porejemplo, *pv)puedeaparecerenlugardeunavariable(porejemplo v)dentrodeuna
expresiónmáscomplicada.
EJEMPLO10.2. ConsiderarelsiguienteprogramasencilloenC.
#include<stdio.h>
main()
{

348 PROGRAMACiÓN ENC
intul,u2;
intv=3 ;
int*pV¡
ul 2* (v+5);
pv=&V¡
u2=2*( *pv+5);
/*pvapuntaa v*/
/*expresiónordinaria*/
/*asignadireccióndev apv*/
/*expresiónequivalente*/
}
printf("ul=%d u2=%d",ul,u2);
Esteprogramainvolucra elusodedosexpresionesenteras.Laprimera,2 *(v+5),esunaexpresión
aritméticaordinaria,mientrasquelasegunda,
2 *(*pv+5),implicaeluso deunpuntero.Las
expresionessonequivalentes,yaque
vy*pvrepresentanelmismovalorentero.
Lasiguientesalida esgeneradacuandoseejecutaelprograma:
ul=16u2=16
Unareferenciaindirectapuedeaparecertambiénenlaparteizquierdadeunainstrucciónde
asignación.Estoproporcionaotrométodoparaasignarunvaloraunavariableo aunelemento
deunarray.
EJEMPLO10.3. AcontinuaciónsemuestraunprogramasencilloenC.
#include<stdio.h>
main()
(
intv=3;
int*pv;
}
pv=&V¡
printf("*pv=%d
*pv=Oi
printf("*pv=%d
/*pvapuntaa v*/
v=%d
ll
,*pv,v)¡
/*reasignavindirectamente*/
v=%d
ll
,*pv,v)¡
Elprogramaempiezaasignandounvalorinicialde3 alavariableenterav yasignandoladireccióndev a
lavariablepuntero
pv.Asípvseconvierteenunpunteroa v.Laexpresión*pvrepresentaportantoel
valor
3.Laprimerainstrucción printfseusaparailustrarestoalescribirlosvaloresactuales de*pvyv.
Acontinuacióndelaprimerainstrucción printf,elvalorde *pvespuestoacero.Portanto, v
tendráreasignadoelvalor O.Estoseilustramediantelasegundainstrucción printf,quehacequese
escribanlosnuevosvaloresde
*pvyv.
Cuandoseejecutaelprograma,segeneralasiguientesalida:
*pv=3 v=3
*pv=O v=O
Asíelvalorde vhasidomodificadoalasignarunnuevovalora *pv.

PUNTEROS 349
Lasvariablespunteropuedenapuntaravariablesnuméricasodecarácter,aarrays,afuncio­
neso aotrasvariablespuntero.(Tambiénpuedenapuntaraotrostiposdeestructurasdedatos
queveremosposteriormenteenestelibro.)Portanto,aunavariablepunteroselepuedeasignar
ladireccióndeunavariableordinaria(porejemplo,
pv=&v).Tambiénselepuedeasignarla
direccióndeotravariablepuntero(porejemplo,
pv=px),siemprequeambasvariablespuntero
apuntenalmismotipodedatos.Además,aunavariablepunteroselepuedeasignarunvalor
nulo(cero),comoseexplicaenlasección10.2.Porotraparte,lasvariables ordinariasno pue­
denserasignadasadireccionesarbitrarias(porejemplo,unaexpresióncomo &xnopuedeapa­
recerenlaparteizquierdadeunainstruccióndeasignación).
Lasección10.5presentainformaciónadicionalconcernientealasoperacionesquepueden
serrealizadasconpunteros.
10.2.DECLARACIÓN DEPUNTEROS
Lospunteros,comocualquierotravariable,debenserdeclaradosantesdeserusadosdentrode
unprogramaenC.Sinembargo,lainterpretaciónde
unadeclaracióndepunteroesunpoco
diferentede
ladeclaracióndeotrasvariables.Cuandosedeclaraunavariablepuntero,elnombre
delavariabledebeirprecedidoporunasterisco(*).Ésteidentificaalavariablecomounpun­
tero.Eltipodedatosqueapareceenladeclaraciónserefiereal
objetodelpuntero,estoes,el
datoquesealmacenaenladirecciónrepresentadaporelpuntero,envezdelpunteromismo.
Así,unadeclaracióndepunteropuedeserescritaentérminosgeneralescomo
tipo-dato*ptvar;
dondeptvareselnombredelavariablepunteroy tipo-datoserefierealtipodedatodel
objetodelpuntero.Recordarqueunasteriscodebeprecedera
ptvar.
EJEMPLO10.4. Unprogramaenecontienelassiguientesdeclaraciones:
floatu,v;
float*pv;
Laprimeralíneadeclarau y vcomovariablesencomaflotante.Lasegundalíneadeclara pvcomouna
variablepuntero cuyoobjetoesunacantidadencomaflotante;esdecir,pvapuntaa unacantidadencoma
flotante.Notar
quepvrepresentaunadirección,nounacantidadencomaflotante.(Algunasdeclaraciones
adicionales
depunterossonmostradasenlosEjemplos10.1a10.3.)
Dentrode unadeclaracióndevariablessepuedeinicializarunavariablepunteroasignándole
ladireccióndeotravariable.Recordarque lavariablecuyadirecciónseasignaalpunterodebe
estarpreviamentedeclaradaenelprograma.
EJEMPLO10.5. Unprogramaenecontienelassiguientesdeclaraciones:
floatlitVi
float*pv=&v;

350 PROGRAMACiÓN ENC
Lasvariablesu y v sondeclaradascomovariablesencomaflotantey pvesdeclaradacomounavariable
puntero
queapuntaacantidades encomaflotante,comoenelEjemplo10.4.Además,ladireccióndevse
asignainicialmentea pv.
Estaterminologíapuederesultarconfusa.Recordar queestasdeclaracionessonequivalentesaescríbir
floatu,v;
float*pv;
pv=&V¡
/*declaracióndevariablesencomaflotante*/
/*declaracióndevariablepuntero*/
/*asignarladireccióndev apv*/
Notarquenoseincluyeunasteriscoenlainstruccióndeasignación.
Engeneralnotienesentidoasignarunvalorenteroaunavariablepuntero.Perounaexcep­
cióneslaasignaciónde0,queavecesseutiliza
paraindicaralgunascondicionesespeciales.En
talessituaciones,laprácticarecomendadaesdefinirunaconstantesimbólicaNULLquerepre­
senteelvalor
°yusarNULLenlainicializacióndelpuntero.Estaprácticaenfatizaelhechode
que
laasignacióndelcerorepresentaunasituaciónespecial.
EJEMPLO10.6. Unprogramaenecontienelassiguientesdefiniciones deconstantessimbólicasy
declaraciones:
#defineNULLO
floatUfVi
float*pv=NULL;
Lasvariablesu y v sondeclaradascomovariablesencomaflotantey pvesdeclaradacomounavaríable
puntero
queapuntaacantidades encomaflotante.Además, pvtieneasignadoinicialmenteelvalorOpara
indicaralgunacondiciónespecialdictadaporlalógica
delprograma(quenosemuestraenesteejemplo).
Elusodelaconstantesimbólica NULLsugierequelaasignacióninicial esalgomásquelaasignaciónde
unvalorenteroordinario.
Veremosotrostiposdedeclaracionesdepunterosposteriormenteenestecapítulo.
10.3.PASODEPUNTEROSAUNAFUNCIÓN
Amenudolospunterossonpasadosalasfuncionescomoargumentos.Estopermitequedatosde
lapartedelprogramaenlaquesellamaalafunción seanaccedidos porlafunción,modificados
dentrodeella
yluegodevueltosalprogramadeformamodificada.Referimosesteusodelos
punteroscomopasarargumentos
porreferencia(opordirecciónoporposición),encontraste
conpasarargumentospor
valor,comodiscutimosenelCapítulo 7.
Cuandosepasaunargumento porvalor,eldatoes copiadoalafunción.Asícualquiermodi­
ficaciónhechaaldatodentrodelafunciónnoesdevueltaalarutinallamadora(versección7.5).
Sinembargo,cuando
unargumentosepasa porreferencia(porejemplocuandose pasaunpun­
teroaunafunción)la
direccióndedatoespasadaalafunción.Elcontenidodeestadirección
puedeseraccedidolibremente,tantodentrode
lafuncióncomodentrode larutinadellamada.

PUNTEROS 351
Ademáscualquiercambioqueserealiza aldato(alcontenido deladirección)seráreconocido
enambas,lafunciónylarutinadellamada.Así,elusodepunteroscomoargumentos
defuncio­
nespermitequeeldatoseamodificadoglobalmentedesdedentro
delafunción.
Cuandolospunterosseutilizancomoargumentos
deunafunción,esnecesariotenercuidado
conladeclaracióndelosargumentosformalesdentro
delafunción.Losargumentosformales
queseanpunterosdebenirprecedidosporunasterisco.Losprototipos
defuncionesseescriben
delamismamanera.Siunadeclaración
defunciónnoincluyenombres devariables,eltipode
datosdecadaargumentopunterodebeirseguido
deunasterisco.Eluso deargumentospuntero
seilustraenelsiguienteejemplo.
EJEMPLO10.7. Acontinuaciónsemuestraunprogramasencilloenequeilustraladiferenciaentre
argumentosordinarios,quesonpasadosporvalor,yargumentospuntero,quesonpasadosporreferencia.
#include<stdio.h>
voidfuncl(intu,intv);
voidfunc2(int*pu,int*pv);
main()
(
intu= 1 ;
intv= 3 ;
/*prototipodefunción*/
/*prototipodefunción*/
printf("Antesdelallamadaafuncl:u=%d v=%d 11
ru,v);
funcl(u,v);
printf("Despuésdelallamadaafuncl:u;:::;%d v=%d HIu,v);
printf("Antesdelallamadaafunc2:u=%d v=%d",u,v);
func2(&u,&v);
printf("Despuésdelallamadaafunc2:u=%d v=%d
ll
,u,v);
}
voidfuncl(intu,intv)
{
u ;:::;O;
v ;:::;O;
printf("Dentrodefuncl:
return¡
}
voidfunc2(int*PU,int*pv)
{
u=%d v=%d
ll
/U,v)¡
*pu=Oi
*pv ;:::;Oi
printf("Dentrodefunc2:
return¡
}
*pu=%d*pv=%d
ll
I*pu,*pv);

352 PROGRAMACiÓN ENC
Esteprogramacontienedosfunciones,llamadas funclyfunc2.Laprimerafunción, funcl,recibe
dosvariablesenterascomoargumentos.Estasvariablestienenoriginalmenteasignadoslosvalores1 y3,
respectivamente.Losvaloressonmodificadosa
OyOdentrode funcl.Sinembargo,losnuevosvalores
nosonreconocidosen
main,porquelosargumentosfueronpasadosporvalorycualquiercambiosobre
losargumentoseslocalalafunciónenlacual
sehanproducidoloscambios.
Consideremosahoralasegundafunción,
func2.Estafunciónrecibedos punterosavariablesenteras
comoargumentos.Losargumentossonidentificadoscomopunterosporlosoperadores
deindirección(los
asteriscos)queaparecenenladeclaracióndelosargumentos.Además,ladeclaracióndeargumentosindi­
caquelospunterosrepresentandireccionesdecantidades
enteras.
Dentrodefunc2loscontenidosdelasdireccionesapuntadassonreasignadosconvalores OyO.
Comolasdireccionessonreconocidastantoen func2comoen main,losvaloresreasignadosserán
reconocidosdentrode
maintraslallamadaa func2.Portanto,lasvariablesenteras uyvhabráncam­
biadosusvalores
de1 y 3 aOyO.
Lasseisinstruccionesprintfilustranlosvaloresde uyvysusvaloresasociados *puy*pvdentrode
mainydentrodelasdosfunciones.Portanto,cuandoseejecutaelprogramasegeneralasiguientesalida:
Antesdelallamadaafuncl:
Dentrodefuncl:
Despuésdelallamadaafuncl:
u=l
u=O
u=l
v=3
v=O
v=3
Antesdelallamadaa
Dentrodefunc2:
Despuésdelallamada
func2:u=l
*pu=O
afunc2:u=O
v=3
*pv=O
v=O
Observequelosvaloresde uyvquedansinmodificardentro demaindespuésdelallamadaa funcl,
mientrasquelosvaloresdeesasvariablescambiandentrode maindespuésdelallamadaa func2.Así
lasalidailustralanaturalezalocal
delasmodificacionesdentrode funclylaglobaldentro defunc2.
Esteejemplocontienecaracteristicasadicionalesquedebenserremarcadas.Observe,porejemplo,el
prototipo
defunción
voidfunc2(int*pu,int*pv);
Loselementosentreparéntesisidentificanlosargumentoscomopunterosacantidadesenteras.Lasvaria­
blespuntero
puypvnohansidodeclaradasenningunapartedentrode main.Estoestápermitidoenel
prototipodelafunción,yaque
puypvsonargumentosficticiosenvezdeargumentosreales.Tambiénse
podríahaberescritoladeclaración
delafunciónsinlosnombresdelosargumentoscomo
voidfunc2(int
*,int*);
Consideremosahoraladeclaración delosargumentosformalesenlaprimeralíneadelafunción func2,
estoes,
voidfunc2(int*pu,int*pv)
Losargumentosformales puypvsonconsistentesconlosargumentosficticiosdelprototipo delafun­
ción.Enesteejemplo,losnombres
delasvariablescorrespondientessonlosmismos,peroengeneralesto
noesnecesario.
Finalmente,notarlamaneraenque
uyvsonaccedidosdentrode func2,estoes,
*pu=O;
*pv=O;

PUNTEROS 353
Asiu y vsonaccedidosindirectamente,alreferenciarelcontenido delasdireccionesrepresentadaspor
lospunteros
puypv.Estoesnecesario,yaquelasvariablesu y v nosereconocencomotalesdentro de
func2.
Yahemosmencionadoelhechodequeunnombredearrayes unpunteroalarray;estoes, el
nombredelarrayrepresentaladireccióndelprimerelementodelarray(versección9.3).Por
tanto,unnombredearraysetratacomounpunterocuandosepasaaunafunción.Noobstante,
noesnecesarioprecederelnombredelarrayconelsímbolo&(ampersand)dentrodelallamada
alafunción.
Unnombredearrayqueaparececomoargumentoformalenunadefinicióndefunciónpuede
serdeclaradocomopunteroocomoarraydetamañonoespecificado,comoseindicaenlasec­
ción9.3.Laelecciónescuestióndepreferenciapersonal,peroamenudovendrádeterminada
porlaformaenlacualloselementosíndividualesdelarrayseanaccedidosdentrodelafunción
(mássobreestoenlasiguientesección).
EJEMPLO 10.8. Análisisde unalíneadetexto.Supongamosquequeremosanalizarunalínea de
textoexaminandocadacarácterydeterminandoaquécategoriapertenece.Enparticular,supongamosque
contamoselnúmerodevocales,consonantes,digitos,espaciosenblancoy«otros»caracteres(puntuacio­
nes,operadores,paréntesis,etc.).Estopuederealizarsefácilmenteleyendounalíneadetexto,almacenán­
dolaenunarrayunidimensionalyanalizandocadaunodesuselementos.Uncontadorapropiadoserá
incrementadoparacadacarácter.Elvalor
decadacontador(númerodevocales,númerodeconsonantes,
etcétera)puedeescribirseacontinuacióndespuésdequetodosloscaractereshayansidoanalizados.
EscribamosunprogramacompletoenCqueefectúedichoanálisis.Paraello,primerodefinimoslos
siguientesidentificadores.
linea
vocales
consonantes
digitos
blancos
otros
arrayde80caracteresquecontendrálalíneadetexto
contadorenteroqueindicaelnúmerodevocales
contadorenteroqueindicaelnúmero
deconsonantes
contadorenteroqueindicaelnúmerodedigitos
contadorenteroqueindicaelnúmero
deespaciosenblanco(espaciosenblanco
otabuladores)
contadorenteroqueindicaelnúmerodecaracteresquenopertenecenalasante­
riorescategorias
Observequeloscaracteresdenuevalíneanosonincluidosenlacategoria«blancos»,yaquenopueden
estardentro
deunalíneasimpledetexto.
Estructuraremoselprogramademodoquelalíneadetextoseleadentrodelaparteprincipaldel
programayseapasadaalafuncióndondeseráanalizada.Lafuncióndevolverá
elvalordecadacontador
despuésdequetodosloscaractereshayansidoanalizados.Losresultadosdelanálisis(elvalor
decada
contador)seránescritosdesdelaparteprincipaldelprograma.
Elanálisisrealpuedeserrealizadoconunbucleparaexaminarcadauno
deloscaracteres.Dentrodel
bucleprimeroseconviertecadacarácterqueseaunaletraamayúsculas.Estoevitalanecesidaddedistin­
guirentreletrasmayúsculasyminúsculas.Acontinuaciónpodemosclasificarelcarácterutilizandoins­
trucciones
if -elseanidadas.Unavezidentificadalaclase,seincrementaelcorrespondienteconta­
dor.Elprocesocompletoesrepetidohastaqueseencuentraelcarácterdefindecadena
(\O).
Acontinuaciónsemuestraelprogramacompletoen C.

354 PROGRAMACiÓN ENC
/*contarelnúmerodevocales,consonantes,dígitos,espaciosen
blancoy"otros"caracteresenunalineadetexto*1
#include
#include<stdio.h>
<ctype.h>
1*prototipodefunción*1
voidanaliza_linea(charlinea[],int*pv,int*pc,int*pd,int*pb,int*po);
main( )
{
charlinea[SO];
intvocales=O;
intconsonantes=O;
intdigitos=O;
intblancos=O;
intotros=O;
1*lineadetexto*1
1*
contadordevocales*1
1*contadordeconsonantes*1
1*contadordedigitos*1
1*
contadordeespaciosenblanco*1
1*contadordelrestodecaracteres*1
printf("Introducirunalineadetexto:") ;
scanf("%[A]",linea);
analiza_linea(linea,&vocales,&consonantes,&digitos,&blancos,
&otros);
}
printf("Nº
printf("Nº
printf("Nº
printf("Nº
printf("Nºdevocales:%d",vocales);
deconsonantes:%d",consonantes)
dedigitos:%d",digitos);
decaracteresenblanco:%d",blancos)
deotroscaracteres:%d",otros);
voidanaliza_linea(charlinea[],int*pv,int*pc,int*pd,int*pb,int*po)
1*analizarloscaracteresenunalineadetexto*1
{
chare;
intcont=O;
1*carácterenmayúsculas*1
1*contadordecaracteres*1
while((e=toupper(linea[cont]))!='\0'){
++*pVi
elseif(e>='A'&&e<='Z')
++*PCi
elseif(e>='O'&&e<=
++*pd;
elseif(e
-- I 1
++*pb¡
else
++*po;
.if(e--'A'11e 'E'11e'I'
19')
e==
I 1e 'O'1 1e--'U')
1*vocal*1
1*consonante*1
1*dígito*1
'\t')
1*espacioenblanco*1
1*otro*1
}
++cont¡
}
return;

PUNTEROS 355
Observeelprototipo defunciónpara analiza_lineaqueaparecealprincipiodelprograma.En
particular,notareltipodedato
vai d Ylamaneraenqueseespecificanlostipos dedatosdelosargumen­
tos.Obsérveseladiferenciaentreelargumentodearrayyelresto
delosargumentospunteros.
Obsérvesetambiénlamaneraenlaqueestánescritoslosargumentosrealesenlallamadaa
analiza_linea.Elargumentodearray, linea,novaprecedidopor eloperador&,yaquelosarrays
sonpunterospordefinición.Eloperador
&debeprecederacadaunodelresto delosargumentos,yaquese
pasaalafunciónnosuvalorsinosudirección.
Consideremosahoralafunción
analiza_linea.Todoslosargumentosformales,incluido li­
nea,sonpunteros.Noobstante, lineaestádefinidacomounarray detamañonoespecificado,mientras
queelrestodelosargumentosestánespecíficamentedeclaradoscomopunteros.
Esposible(ybastante
normal)declarar1
ineacomounpunteroenvezdecomounarray.Así,laprimeralíneade
analiza_lineapuedeserescritacomo
voidanaliza_linea(char*linea,int*pv,int*pc,int*pd,int*pb,int*po)
envezdecomoestáenellistadodelprograma.Paraserconsistente,elcorrespondienteprototipode
funcióndebeserescritodemodosimilar.
Elincrementodeloscontadorestambiénrequiereciertaexplicación.Primero,observe queel
conteni­
dodecadadirección(el objetodecadapuntero)esincrementado.Segundo,notarquecadaexpresión de
indirección(porejemplo, *pv)esprecedidaporeloperadorunario ++.Comolosoperadores unarios se
evalúandederechaaizquierda,nosaseguramosqueseincrementeelcontenidodecadadirecciónynola
direcciónmisma.
Acontinuaciónsemuestraundiálogotípicoquepuedeserobtenidocuandoseejecutaelprograma.
(Lalíneadetextointroducidaporelusuarioestásubrayada.)
Introducirunalíneadetexto:
Computadoraspersonalesconmasde1024RBsonahorabastantecomunes.
Lasalidacorrespondiente es:
N°devocales:22
N°deconsonantes:33
N°dedígitos:4
N°decaracteresenblanco:10
N°deotroscaracteres:1
Asívemosqueestalínea
detextocontiene22vocales, 33consonantes,cuatrodígitos, 10caracteresen
blanco(espaciosenblanco)yunodeotroscaracteres(elpunto).
Recordarquelafunciónscanfrequierequelosargumentosqueseanvariablesordinarias
vayanprecedidosporampersands(versección4.4).Noobstante,losnombresdearrayestán
exentosdeesterequerimiento.EstopudopareceralgomisteriosoenelCapítulo4,peroahora
debetenersentido,considerandoloquesabemosdenombresdearrayydirecciones.Así,la
funciónscanfrequierequeseespecifiqueladireccióndeloselementosquevayanaserintro­
ducidosenlamemoriadelacomputadora.Losampersands(&)proporcionanunmediopara
accederalasdireccionesdelasvariablesordinariasunievaluadas.Losampersandsnosonnece­
sariosconnombresdearrays,yaqueestosmismosnombresrepresentandirecciones.

356 PROGRAMACiÓN ENC
EJEMPLO10.9. Acontinuaciónsemuestraelesquema delaestructuradeunprogramaenC(repetido
del Ejemplo
4.5).
#include<stdio.h>
main()
{
charconcepto[2O];
intnUffi_partida;
floatcoste;
scanf("%s%d%f",concepto,&num_partida,&coste);
}
Lainstruccións c anfhacequeunacadenadecaracteres,unacantidadenterayunaencomaflotantesean
introducidasenlacomputadorayalmacenadasenlasdireccionesdememoriaasociadascon
concepto,
num-partidaYcoste.Cornoconceptoeselnombre deunarray,estáclaroquerepresentauna
dirección.Poresto,
conceptononecesita(nopuede)irprecedidoporunampersanddentro delains­
trucción
scanf.Sinembargo,num_partidaycostesonvariablesconvencionales.Portantodeben
serescritascorno
&num_partiday&costedentrodelainstrucción scanf.Senecesitaeloperador
ampersandparaaccederala
direccióndeestasvariablesenlugardesuvalor.
Siseutilizalafuncións canfparaintroducirunsoloelementodelarrayenvez detodaelarray,el
nombredelelementodelarraydebeirprecedidopor
unampersand,cornosemuestraacontinuación(del
Ejemplo
9.8).
scanf("%f",&lista[cont]);
Sepuedepasarunapartedeunarray,envezdetodaelarray,aunafunción.Parahacerlo,la
direccióndelprimerelementoapasarhadeserespecificadacomoargumento.Elrestodelarray,
comenzandoporelelementoespecificado,seráentoncespasadoalafunción.
EJEMPLO10.10. Acontinuaciónsemuestraelesquema delaestructuradeunprogramaen C.
#include<stdio.h>
voidprocesar(floatz[]);
main()
{
floatz[lOO];
! *
.introducirvaloresparaloselementosde.z*!
procesar(&z[50]);
}

PUNTEROS 357
voidprocesar(floatf[])
{
/*procesarloselementosdef*/
return;
}
zsedeclaradentro demaincomounarrayde 100elementosencomaflotante.Después deintro-ducir
loselementos
dezenlacomputadora,sepasaladirección dez[50](&z[50]) alafunciónproce­
sar.Asílosúltimos5 Oelementosdez(loselementos dez[5O]alz [99] )estarándisponiblespara
procesar.
Enlasiguientesecciónveremosqueladireccióndez [5 O]sepuedeescribircomoz +5Oenvezde
&z[5O].Portanto,lallamadaa procesarpuedehacersecon procesar(z+5O)envezde
procesar(&z[5O]) ,comosehahecho. Sepuedeutilizarcualquieradelosdosmétodos,dependiendo
delaspreferenciasdelprogramador.
Dentrode
procesar,elarraycorrespondienteesreferidocomo f.Estearraysedeclaradecoma
flotanteperocontamañonoespecificado.Deestamanera,elquelafunciónrecibasólounaparte
dezes
indíferente;sitodosloselementosdezsonmodificadosdentro
deprocesar,sólolos 50últimosse
veránafectadosdentrode
main.
Seríadeseabledeclarardentrode procesarelargumentoformal fcomounpunteroauna cantidad
encomaflotanteenvez
decomounnombre dearray.Así,elesquemade procesarpuedeserescrito
como
voidprocesar(float*f)
{
/*procesarloselementosdef*/
return;
}
Observelasdiferenciasentreladeclaración delosargumentosformalesenlosdosesquemasdefunción.
Ambasdeclaracionessonválidas. .
Unafuncióntambiénpuededevolverunpunteroalapartellamadoradelprograma.Para
haceresto,ladefinicióndelafunción.y cualquierdeclaracióndelafuncióndebeindicarquela
funcióndevolveráunpuntero.Estoserealizaprecediendoelnombredelafunciónconunaste­
risco.Elasteriscodebeaparecertantoenladefinicióndelafuncióncomoenlasdeclaraciones
delafunción.
EJEMPLO10.11. Acontinuaciónsemuestraelesquemadelaestructuradeunprograma eneque
transfiereunarraydeelementosdedobleprecisiónaunafunciónydevuelveunpunteroaunodelos
elementosdelarray.

358 PROGRAMACiÓN ENC
#include<stdio.h>
double*analiza(doublez[]);
main()
(
doublez[100J;
double*pz;
/*declaracióndearray*/
/*declaracióndearray*/
/*introducirvaloresparaelementosdez*/
pz=analiza(z);
}
double*analiza(doublef[])
(
double*pf; /*declaracióndepuntero*/
/*procesarloselementosdef*/
}
pf=
return(pf);
.,
Dentrodemainvemosquezsedeclaracomounarrayde 100elementosdedobleprecisióny pzes
unpunteroaunacantidadendobleprecisión.Tambiénvemosunadeclaraciónparalafunción
analiza.
Observeque scanfaceptaráunarray deelementosendobleprecisióncomoargumentoydevolveráun
puntero(ladirección)aunacantidadendobleprecisión.Elasteriscoprecediendoelnombre
delafunción
(*analiza)indicaquelafuncióndevuelveunpuntero.
Dentrodeladefinicióndelafunción,laprimeralíneaindicaque
analizaaceptaunparámetro
formal
(f[])ydevuelveunpunteroauna cantidadendobleprecisión.Elparámetroformalseráunarray
unidimensionaldeelementosendobleprecisión.Elesquemasugierequeladireccióndeunodelosele­
mentosdelarrayseasignaa p
fduranteodespuésdelprocesamientodeloselementosdel array.Esta
direcciónesdevueltaa
main,dondeseasignaalavariablepuntero pz.
10.4.PUNTEROSYARRAYSUNIDIMENSIONALES
Recordarqueelnombredeunarray esrealmenteunpunteroalprimerelementodeesearray.
Portanto,si
xesunarrayunidimensional,entoncesladireccióndelprimerelementodelarrayse
puedeexpresartantocomo
&x[O]osimplementecomo x.Además,ladireccióndelsegundo

PUNTEROS 359
elementodelarraysepuedeescribirtantocomo &x[1]ocomo(x+1),yasísucesivamen­
te.
Engeneral,ladireccióndelelemento (i+1)delarraysepuedeexpresarbiencomo
&x[i]ocomo(x+i).Portanto,tenemosdosmétodosdiferentesdeescribirladirección
decualquierelementodelarray:podemosescribirelelementorealdelarrayprecedidoporun
ampersand
(&);opodemosescribirunaexpresiónen lacualelíndiceseañadealnombredel
array.
Enelúltimocaso,sedebeentenderqueestamostratandoconuntipo
muyespecialeinusual
deexpresión.En
laexpresión(x+i),porejemplo,xrepresentaunadirección,mientrasque i
representaunacantidadentera.Además,xeselnombredeunarraycuyoselementospuedenser
caracteres,enteros,cantidadesencomaflotante,etc.(aunquetodosloselementosdelarrayhan
deserdelmismotipodedatos).Portanto,noestamossimplementeañadiendovaloresnuméri­
cos.Másbienestamosespecificandounadirecciónqueestáunciertonúmerodeposicionesde
memoriamásalládelprimerelementodelarray.
Entérminosmássimples,estamosespecifican­
dounalocalizaciónqueestá
ielementosdelarraymásalládelprimero.Portanto,laexpresión
(x+i)esunarepresentaciónsimbólicadeunaespecificacióndedirecciónenvezdeunaex­
presiónaritmética.
Recordarqueelnúmerodeceldasdememoriaasociadascon
unelementodelarraydepende
deltipodedatosdelarray,asícomodelapropiaarquitecturade
lacomputadora.Porejemplo,
conalgunascomputadoras
unacantidadenteraocupadosbytes(dosceldasde
memoria),unacantidadencomaflotanterequierecuatrobytesyunacantidadendobleprecisión
necesitaochobytes.Enotrascomputadoras,unacantidadenterapuedeocuparcuatrobytes,y
lascantidades encomaflotanteyendobleprecisión puedenrequerirochobytescadauna.Yasí
sucesivamente.
Sinembargo,cuandoseescribeladireccióndeunelementodelarraydelaforma
(x+i),elprogramadornotieneque
preocu¡Yarseporelnúmerodeceldasdememoria
asociadasconcadatipodedatosdelarray;el compiladordeCloajustaautomáticamen­
te.Elprogramadordebeindicarsóloladireccióndelprimerelemento(elnombredel
array)yelnúmerodeelementosdelarraymásalládelprimero(valordelíndice).El
valordeisedenominaavecesdesplazamiento(eninglés,offset)cuandoseusadeesta
manera.
Puestoque &x[i]y(x+i)representanladireccióndeli-ésimoelemento dex,parece
razonableque
x [i]y*(x+i)representenelcontenidodeesadirección,esdecir,el valordel
elementoi-ésimode
x.Estoesrealmentecierto.Losdostérminossonintercambiables.Cada
términosepuedeusarencualquieraplicaciónparticular.Laeleccióndependedelaspreferen­
ciasindividualesdelprogramador.
EJEMPLO10.12. Acontinuaciónsepresentaunprograma queilustralarelaciónentre loselementos
deunarrayy susdirecciones.
linclude<stdio.h>
main()
{
staticintx[10]
inti¡
{10,11, 12,13, 14, 15,16,17,18,19};

360 PROGRAMACiÓN ENC
for(i=O;i<=9;++i){
/*escribirunelementodel
printf("i=%d x[i]=%d
array*/
*(x+i)=%d",i,xli],*(x+i));
}
}
/*escribir
printf("
lacorrespondientedireccióndelarray*/
&x[i]
=%X x+i=%X",&x[i],(x+i)) ;
Esteprogramadefineunarrayxunidimensional de10elementosenteros,quetienenasignadosvalores
10, 11,,..,19.Lapartedeaccióndelprogramaconsisteenunbuclequemuestraelvaloryladirección
correspondienteparacadaelementodelarray.Observequeelvalordecadaelementodelarray
seespeci­
ficadedosformasdistintas,como
x[i]Ycomo*(x+i)parademostrarsuequivalencia,Análogamente,
ladireccióndecadaelementodelarrayestáexpresadaendosformasdiferentes,como
&x[i]Ycomo
(x+i),porlamismarazón.Portanto,elvaloryladireccióndecadaelementodelarrayaparecerádos
veces.
Laejecucióndelprogramageneralasiguientesalida:
i=O x[i]=10 *(x+i)=10 &x[i]=72 x+i=72
i=1 x[i]=11 *(x+i)=11 &x[i]=74 x+i=74
i=2 x[i]=12 *(x+i)=12 &x[i]=76 x+i=76
i=3 x[i]=13 *(x+i)=13 &x[i]=78 x+i=78
i=4 x[i]=14 *(x+i)=14 &x[i]=7A x+i=7A
i::::;5 x[i]=15 *(x+i)=15 &x[i]=7C x+i=7c
i=6 x[i]=16 *(x+i)=16 &x[i]=7E x+i=7E
i=7 x[i]=17 *(x+i)=17 &x[i]=80 x+i=80
i=8 x[i]=18 *(x+i)=18 &x[i]=82 x+i=82
i=9 x[i]=19 *(x+i)=19 &x[i]=82 x+i=84
Lasalidailustraclaramenteladistinciónentrex [ i ] ,querepresentaelvalordeli-ésimoelementodel
array, y
&x[i],querepresentasudirección.Además,vemosqueelvalordeli-ésimoelementosepuede
representarpor
x[i]o*(x+i ) ,ysudirecciónpor &x[i]ox+i.Asíobservamosotraanalogíaentre
*(x+i),quetambiénrepresentaelvalordeli-ésimoelemento,y x+i,quetambiénrepresentasu dire.c­
ción.
Enparticularobservequealprimerelementodelarray(correspondientea i
=O)lehasidoasignado
elvalor
10Yunadirección 72(hexadecimal).Elsegundoelementotieneelvalor 11ydirección74,etc.
Así,laposicióndememoria
72contendráelvalorentero 10,la74contendráel11,etc.
Debequedarclaroqueelcompiladorasignaautomáticamenteestasdirecciones.
Cuandoasignamosun valoraunelementodelarraytalcomox [ i],laparteizquierda dela
asignaciónpuedeserescritacomox [
i]ocomo*(x+i ) .Deestamanera,unvalorpuede
serasignadodirectamenteaunelementodelarrayoaláreadememoriacuyadirecciónesladel
elementodelarray.
Porotraparte,avecesesnecesarioasignaruna
direcciónaunidentificador.Entalessitua­
cionesunavariablepunterodebeaparecerenlaparteizquierdadelaasignación.
Noesposible
asignarunadirecciónarbitrariaaunnombre
dearrayo aunelementodelmismo.Portanto,
expresionestalescomo
x,(x+i)Y&x[i]nopuedenaparecerenlaparteizquierdadeuna
instruccióndeasignación.Además,ladirección
deunarraynopuedesermodificadaarbitraria­
mente,porloqueexpresionescomo
++xnoestánpermitidas.

PUNTEROS 361
EJEMPLO10.13.Consideremos
elesquemadelaestructuradelprogramaCmostradoacontinuación.
#include<stdio.h>
main()
{
intlinea[SO];
int*pl;
/*asignarvalores*/
linea[2]linea[l];
1inea[2]=*(1inea+1);
*(linea+2)=linea[l];
*(linea+2)=*(linea+1);
/*asignardirecciones*/
pI=&linea[l];
pI=linea+1;
}
Cadaunadelascuatroprimerasinstruccionesdeasignación leasignaelvalordelsegundoelemento
delarray
(1inea[1])altercerelementodelarray (1inea[2]).Portanto,lascuatroinstruccionesson
equivalentes.Unprogramadorexperimentadoelegiríaprobablementelaprimeraolacuarta,demodoque
lanotaciónfueraconsistente.
Cadaunadelasdosúltimasinstruccionesdeasignaciónasignala
direccióndelsegundoelementodel
arrayalpunterop
1.Podernoselegirhacerestoenunprogramarealsinecesitarnos«marcar»ladirección
de1inea[1]poralgunarazón.
Observeque
ladireccióndeunelementodelarraynopuedeserasignadaaotroelementodelarray.
Nopodemosescribirunainstruccióntalcorno
&linea[2]=&linea[l];
Porotraparte,sisedeseapodernosasignarel valordeunelementodelarrayaotromedianteunpuntero,
porejemplo,
pI=&linea[l];
linea[2]=*pl;
o
pI=linea+1;
*(linea+2)=*pl;
Siunarraynuméricosedefinecomounavariablepuntero,noselepuedenasignarvalores
inicialesaloselementosdelarray.Portanto,seránecesariaunadefinicióndearrayconvencio­
nalsisequiereasignarvaloresinicialesaloselementosdeunarraynumérico.Sinembargo,a

362 PROGRAMACiÓN ENC
unavariablepunterodetipocarácter selepuedeasignarunacadenadecaracterescompleta
comopartedeladeclaracióndelavariable.Deestemodo,unacadenadecaracterespuedeser
convenientementerepresentadatantoporunarrayunidimensionaldecaracterescomoporun
punteroacarácter.
EJEMPLO10.14.Acontinuaciónsemuestraunprogramasencilloen
eenelqueserepresentan dos
cadenasdecaracteresmediantearraysdecaracteresunidimensionales.
#ínclude<stdío.h>
charx[]="Estacadenasedeclaraexternamente";
maín()
{
statícchary[]
printf(Il%Sll,x);
printf("%8
11
fy);
}
"Estacadenasedeclaradentrodemaín";
Laprimeracadenadecaracteresestáasignadaalarrayexternox [ ] .Lasegunda cadenadecaracteres
estáasignadaalarrayestáticoy [ ] ,quesedefinedentrode
maín.Estasegundadefiniciónocurre
dentrodeunafunción;portantoy
[]debedefinirsecomounarray statícparaquepuedaserinicia­
lizado.
Heaquiunaversióndiferentedelmismoprograma.Lascadenas
decaracteresestánahoraasignadasa
variablespunteroenvezdeaarraysunidimensionales.
#ínclude<stdío.h>
char*x=1rEstacadenasedeclaraexternamente
l
';
maín()
{
char*y="Estacadenasedeclaradentrodemain
11
;
printf
(11%8n,x);
príntf("%s",y);
}
Lavariablepunteroexternaxapuntaalcomienzodelaprimeracadenadecaracteres,mientrasquela
variablepuntero
y,declaradadentrode maín,apuntaalcomienzodelasegundacadenadecaracteres.
Observequeyahorapuedeinicializarsesinserdeclaradacomos t a t í
c.
Laejecucióndecualquieradelosprogramasgeneralasiguientesalida:
Estacadenasedeclaraexternamente
Estacadenasedeclaradentrodemaín
Esposiblesintácticamente,porsupuesto,declararunavariablepunterostatic.Sinembar­
go,nohayrazónparahacerloenesteejemplo.

PUNTEROS 363
10.5.ASIGNACIÓNDINÁMICADEMEMORIA
Puestoqueunnombredearrayesrealmenteunpunteroalprimerelementodentrodelarray,
debeserposibledefinirelarraycomounavariablepunteroenvezdecomounarrayconvencio­
nal.Sintácticamentelasdosdefinicionessonequivalentes.Sinembargo,ladefiniciónconven­
cionaldeunarrayproducelareservadeunbloquefijodememoriaalprincipiodelaejecución
delprograma,mientrasqueestonoocurresielarrayserepresentaentérminosdeunavariable
puntero.Porconsiguiente,elusodeunavariablepunteropararepresentarunarrayrequiere
algúntipodeasignacióninicialdememoria,antesdequeloselementosdelarrayseanprocesa­
dos.Estoseconocecomoasignacióndinámicadememoria.Generalmente,lafuncióndebiblio­
tecamallocseutilizaparaestepropósito,comoseilustraenelsiguienteejemplo.
EJEMPLO10.15.Supongamosquex
esunarrayunidimensional de10elementosenteros.Esposible
definirxcomounavariablepunteroenvez
decomounarray.Así,podemosescribir
int*x¡
envezde
intx[10];
o
#defineTAM10
intx[TAM];
Sinembargo,xnotieneasignadoautomáticamenteunbloquedememoriacuandosedefinecomouna
variablepuntero,perosíselereservaráporadelantadounbloquesuficientementegrandeparaalmacenar
10enteroscuandoxsedefinecomounarray.
Podemosusarlafuncióndebiblioteca
mallocparaasignarsuficientememoriapara x,comosigue:
x
=(int*)malloc(10*sizeof(int));
Estafunciónreservaunbloquedememoriacuyotamaño(enbytes)esequivalentea 1 Ocantidadesente­
ras.Talcomoestáescrita,lafuncióndevuelveunpunteroaunentero.Estepunteroindicaelcomienzodel
bloquedememoria.Engenerallaconversíóndetipo(eninglés«cast»)queprecedea
ma110cdebeser
consistenteconeltipodedatosdelavariablepuntero.Así,síysehubieradefinídocomounpunteroauna
cantidadendobleprecisiónysolicitáramoslamemoríasuficienteparaalmacenar
10cantidadesendoble
precisión,escribiríamos
y
=(double*)malloc(10*sizeof(doub1e));
Sinembargo,si ladeclaraciónincluyelaasignacióndevaloresiniciales,entonces xdebeserdefini­
docomounarrayenvezdecomounavariablepuntero. Porejemplo:
intx[10]={1,2,3,4,5,6, 7,8,9,lO};
o
intxl]={l,2,3,4,5,6,7,8,9,lO};

364 PROGRAMACiÓN ENC
Cuandose programaenCesusualutilizarexpresiones conpunterosenvezdereferenciasa
elementosindividualesdelarray.El
programaresultantepuedeaparecerextrañoalprincipio,
perodejadeserloalacostumbramosaaccederavaloresalmacenados
endireccionesespecifi­
cas.Generalmentesólosenecesita
unpocodepráctica.
EJEMPLO10.16.Reordenacióndeunalistadenúmeros.Parailustrareluso depunterosconasig­
nacióndinámica
dememoria,consideremos denuevoelproblemadereordenarunalista deenteros,como
sedescribíaenelEjemplo9.13.Peroahorautilizaremosexpresiones depunterosparaaccederavalores
individualesenvez
dereferimosexplícitamenteaelementosindividualesdelarray.Enlosotrosaspectos
presentamosunprogramaidéntico
aldadoenelEjemplo9.13.
Aquíestá elprogramacompleto
enC.
/*reordenarunarrayunidimensionaldeenteros,demenoramayor,
usandonotacióndepunteros*/
#include<stdio.h>
#include<stdlib.h>
voidreordenar(intn,int*x);
main()
{
int
i,n,*x;
/*leerelvalorden*/
printf(11¿Cuantos númerosseránintroducidos?11)i
scanf(n%dn/&n);
printf(nn) i
/*.reservadememoria* /
x=(int*)malloc(n*sizeof(int));
/*leerlalistadenúmeros*/
for(i=O;i <n;++i){
printf("i=%d x="i +1);
scanf("%d
ll
lx+i)¡
}
/*reordenartodosloselementosdelarray*/
reordenar(n,x);
/*escribirlalistareordenadadenúmeros*/
printf("Listadenúmerosreordenada:");
for(i=O;i <n;++i)
printf("i=%d x=%d", i +1,*(x+i));
}
voidreordenar(intn,int*x)
{
/*reordenarlalistadenúmeros*/

PUNTEROS 365
inti,elem,tempi
for(elem=o;elem<n -1;++elem)
/*encontrarelmenordelrestodeloselementos*/
for(i=elem+1;i<n;++i)
if(*(x+i)<*(x+elem)){
/*intercambiarlosdoselementos*/
temp=*(x+elem);
*(x+elem)=*(x+i);
*(x+i)=temp;
}
return¡
}
Enesteprogramaelarraydeenterosestádefinidocomounpunteroaunentero.Laasignacióninicial
dememoriaparalavariablepunterosehacemediantelafuncióndebiblioteca
malloc.Entodoelpro­
gramaseutilizalanotacióndepunterosparaprocesarloselementosindividualesdelarray.Porejemplo,el
prototipodefunciónespecificaahoraqueelsegundoargrunentoesunpunteroaunacantidadenteraenvez
deunarraydeenteros.Estepunteroidentificaráelcomienzodelarray
deenteros.
Tambiénvemosquelafunción
scanfespecificaahoraladireccióndeli-ésimoelementocomox +
i
envezde&x[i].Análogamente,lafunción printfrepresentaahoraelvalordeli-ésimoelemento
como
*(x+i)envezde x[i].Sinembargo,lallamadaa reordenareslamismaqueenel
programaanterior,
reordenar(n,x);.
Dentrodelafunciónreordenarvemosque elsegundoargumentoformalsedefineahoracomouna
variablepunteroenvezdecomounarraydeenteros.Estoesconsistenteconelprototipodefunción.Las
diferenciasmáspronunciadasseencuentranenlainstrucción
if.Enparticular,observequecadareferen­
ciaaunelementodelarrayseescribeahoracomoelcontenidodeunadirección.Asíx [
i]seescribe
ahoracomo
*(x+ i ) ,yx [elem]como*(x+elem).Estainstruccióni fcompuestapuedeser
vístacomounintercambiocondicionalentreloscontenidosdedosdirecciones,envezdecomouninter­
cambioentredoselementosdiferentesdeunarrayconvencional.
DeberíamoscompararesteprogramaconelmostradoenelEjemplo9.13paraapreciarlasdiferencias.
Ambosprogramasgeneranlosmismosresultadosparalosmismosdatos
deentrada.Sinembargo,ellector
deberíaentenderlasdiferenciassintácticasentrelosdosprogramas.
Unaventajaimportantedelaasignacióndinámicadelamemoriaeslaposibilidaddereser­
varlamemoriaquesenecesitadurantelaejecucióndelprogramayluegoliberarestamemoria
cuandonosenecesita. Másaún,esteprocesosepuederepetirvariasvecesdurantelaejecución
delprograma.Lasfuncionesdebibliotecamallocyfreeseutilizanparaestospropósitos,
comoseilustraenelEjemplo11.32(versección11.6).
10.6.OPERACIONES CONPUNTEROS
EnlasecciónlOAhemosvistoquesepuedesumarunvalorenteroa unnombredearraypara
accederaunelementoindividualdelarray.Elvalorenteroseinterpretacomoelíndicedelarray;

366 PROGRAMACiÓN ENC
representalaposiciónrelativadelelementodeseadoconrespectoalprimerelementodelarray.
Estofunciona,yaquetodosloselementosdelarraysondelmismotipoyportantocadaelemen­
toocupaelmismonúmerodeceldas
dememoria(mismonúmerodebytesopalabras).Elnúme­
rodeceldasqueseparanadoselementosdelarraydependerádeltipodedatosdelarray,perode
estoseencargaelcompiladorautomáticamenteyportantonoconciernealprogramadordirecta­
mente.
Esteconceptosepuedeampliaralasvariablespunteroengeneral.Deestemodo,a
una
variablepunteroselepuedesumarorestarunvalorentero,peroelresultadodelaoperación
debeserinterpretadoconcuidado.Supongamos,porejemplo,que
pxesunavariablepuntero
querepresentaladireccióndeunavariable
x.Podemosescribirexpresionestalescomo ++px,­
-px,(px+3),(px+i)Y(px-i),dondeiesunavariableentera.Cadaexpresión
representaráunadirecciónlocalizadaaciertadistanciadelaposiciónoriginalrepresentadapor
px.Ladistanciaexactaseráelproductodelacantidadenteraporelnúmero debytesopalabras
queocupacadaelementoalcualapunta
px.Porejemplo,supongamosque pxapuntaaunente­
ro,ycadaenterorequieredosbytesdememoria.Entonceslaexpresión
(px+3)darácomo
resultadounadirecciónqueestáseisbytesmásalládelenteroapuntadopor
px,comoseilustra
enlaFigura10.3.Sinembargo,debequedarclaroqueestanuevadirección
notienenecesaria­
mentequerepresentarladireccióndeotroelemento,enparticularcuandoloselementosalmace­
nadosentrelasdosposicionessondetiposdedatosdiferentes.
px
-------
...=
1./byte\1 i
(px+3)
Figura10.3.
EJEMPLO10.17.
Consideremoselprograma enCquesemuestraacontinuación.
#include<stdio.h>
main()
{
int*px; /*punteroaunentero*/
inti ;::;1;
floatf =0.3;
doubled
~0.005;
chare ;::; T*,;
c=%c
ll
,i,f ,d,e)i
&d=%X &c=%X" ,
&i,&f,&d,&c);
px+2=%X");
d=%f
&f=%X
f=%f
&i=%X
px ;::;&i;
printf("Valores:i=%i
printf(I'Direcciones:
printf("Valoresdepunteros:px=%X px+l=%X
printf(l1px+3=%X
Il
¡px,px+l
rpx+2,px+3);
}

PUNTEROS 367
Esteprogramaescribelosvaloresydireccionesasociadosconcuatrotiposdiferentes devariables:i,una
variableentera;
f,unavariableencomaflotante;d,unavariableendobleprecisión;y e,unavariable
carácter.Elprogramahaceusotambién
deunavariablepuntero, px,querepresentaladirecciónde i.
Tambiénsemuestranlosvalores depx,px+1,px+2ypx+3,paraquepuedansercomparados
conlasdirecciones
delasdiferentesvariables.
Laejecucióndelprogramaproducelasiguientesalida:
Valores:i=lf=0.300000 d=O.OOSOOO c=*
Direcciones:&i=117E &f=1180 &d=1186 &c=118E
Valoresdepunteros:px=117Epx+1=1180px+2=1182px+3=1184
Laprimeralíneamuestrasimplemente elvalordelasvariablesylasegundalasdireccionesasignadas
porelcompilador.Observeque
elnúmerodebytesasociadoconcadatipodedatoesdiferente.Así,el
valorenterorepresentadopor
irequieredosbytes(específicamente,direcciones 117EY117F).El
valorencomaflotanterepresentadopor
ftieneasignadosseisbytes(direcciones 118Oa1185),pero
sólosonusadoscuatrobytes(direcciones
118Oa1183).(Loscompiladoresgestionanelespaciode
memoriasegúnsuspropiasreglas.)Paraelvalorendobleprecisióndsonnecesariosochobytes(direc­
ciones
1186a118D).Yfinalmente,elcarácterrepresentadoporeempiezaenladirección 118E.Sólo
serequiereunbyteparaalmacenarestecarácter,aunquelasalida
nOíndicaelnúmerodebytesentreeste
carácteryelpróximodato.
Consideremosahoralaterceralíneadelasalida,quecontienelasdireccionesrepresentadasporlas
expresionesdepuntero.Estáclaroque
pxrepresentaladirecciónde i (117E).Estonoproducesorpre­
sa,yaqueestadirecciónhasidoasignadaa
pxmediantelaexpresión px= &i.Sinembargo,px+1
sedesplazadosbytes, a 118O,px+2sedesplazaotrosdosbytes,a 1182,Yasísucesivamente.La
razónesque
pxapuntaaunentero,yuna cantidadenteranecesitadosbytesconestecompiladordeC
particular.Comoresultado,cuandosesumanconstantesenterasa
px,estasconstantesseinterpretancomo
múltiplodedosbytes.
Sipxsedefinecomounpunteroaotrotipodiferente dedato(uncarácterounacantidadencoma
flotante),entoncescualquierenterosumadoorestadoal
Pllnteroseinterpretarádemaneradistinta.En
particular,cadavalorenterorepresentaráunnúmeroequivalentedebytesindividualessi
pxapuntaaun
carácter,ounnúmerodebytesmúltiplodecuatrosi
pxapuntaaunacantidadencomaflotante. Sereco­
miendaallectorqueverifiqueestopor
simismo.
Unavariablepunteropuedeserrestadadeotrasiemprequeambasvariablesapuntenaele­
mentosdelmismoarray.Elvalorresultanteindicaelnúmerodepalabrasobytesqueseparanlos
correspondienteselementosdelarray.
EJEMPLO10.18.Enelprogramamostradoacontinuación,dosvariablespunteroapuntanalprimeroy
alúltimoelemento
deunarraydeenteros.
#include<stdio.h>
main()
{
int*px,*PYi
staticinta[6]
/*punterosaentero*/
={l,2,3,4,5;6};

368 PROGRAMACiÓN ENC
}
px=&a[O];
py=&a[5];
printf("px=%X
printf("py
py=%X
ll
/px,PY)i
-px=%X",py-px);
Enparticular,lavariablepuntero pxapuntaa a [ O]Ypya a [5 ] .Ladiferencia,py-px,deberíaser
5,yaquea [
5]eselquintoelementodespuésdea [ O] .
Laejecucióndelprogramaproducelasiguientesalida:
px=52 py=5C
py-px=5
.Laprimeralíneaindicaqueladirección dea [O]es52Yladireccióndea [ 5]es5C.Ladiferenciaentre
estosnúmeroshexadecimaleses
10(endecimal).Asía [5]estáalmacenadoenunadirecciónqueestá
10bytesmásalládeladireccióndea [ O].Comocadacantidadenteraocupadosbytes,deberíamos
esperarqueladiferenciaentre
pyypxfuera10/2 =5.Lasegundalíneadelasalidaconfirmaestevalor.
Lasvariablespunteropuedensercomparadassiemprequeseandelmismotipodedatos.
Talescomparacionespuedenserútilescuandoambasvariablesapuntenaelementosdeunmis­
moarray.Lascomparacionespuedenprobarlaigualdadodesigualdad.Además,unavariable
punteropuedesercomparadaconcero(normalmenteexpresadocomoNULLcuandoseusade
estamanera,comoseexplicóenlasección10.2).
EJEMPLO10.19. Supongamosque pxypysonvariablespunteroqueapuntanaelementosdeun
mismoarray.Acontinuaciónsemuestranvariasexpresioneslógicasqueinvolucranaestasdosvariables.
Todaslasexpresionessonsintácticamentecorrectas.
(px<py)
(px>=py)
(px--py)
(px!=py)
(px--NULL)
Estasexpresionessepuedenutilizardelamismamaneraquecualquierotraexpresiónlógica.Por
ejemplo,
if(px<py)
printf(lIpX<py")i
else
printf("px>=py");
Expresionestalescomo (px<py)indicansielelementoasociadocon pxestásituadodelanteo nodel
elementoasociadocon
py(sielíndiceasociadocon *pxesmenaranoqueelasociadocon *py).

PUNTEROS 369
Debequedarclaroquelasoperacionestratadaspreviamentesonlas
únicasquesepueden
realizarconpunteros.Estasoperacionespermitidasseresumenacontinuación.
1.Aunavariablepunteroselepuedeasignarladireccióndeunavariableordinaria
(pv=&v).
2.Aunavariablepunterose lepuedeasignarelvalor deotravariablepuntero(porejemplo,
pv=px),siempreque ambospunterosapuntenalmismotipodedatos.
3.Aunavariablepunteroselepuedeasignarunvalornulo(cero)(porejemplo,
pv=
NULL,dondeNULLesunaconstantesimbólicaquerepresentaelvalor O).
4.Aunavariablepunteroselepuedesumarorestarunacantidadentera(porejemplo,
pv+3,++pv,etc.).
5.Unavariablepunteropuedeserrestadadeotracontalqueambasapuntenaelementos
delmismoarray.
6.Dosvariablespunteropuedensercomparadassiemprequeambasapuntenadatosdel
mismotipo.
Nosepermitenotrasoperacionesaritméticasconpunteros.Así,unavariablepunteronopue­
desermultiplicadaporunaconstante;nosepuedensumardospunteros;yasísucesivamente. Se
lerecuerdaallectorqueaunavariableordinarianoselepuedeasignarunadirecciónarbitraria
(unaexpresióncorno
&xnopuedeaparecerenlaparteizquierda deunaasignación).
10.7.PUNTEROSYARRAYSMULTIDIMENSIONALES
Cornounarrayunidimensionalpuedeserrepresentadoentérminos deunpuntero(elnombredel
array)y
deundesplazamiento(elíndice),esrazonableesperarquelosarraysmultidimensiona­
lespuedenserrepresentadastambiénconunanotaciónequivalente
depunteros.Enefecto,éste
eselcaso.Porejemplo,unarraybidimensional esenrealidaduna coleccióndearraysunidimen­
sionales.Portanto,podernosdefinirunarraybidimensionalcornounpunteroaungrupo
de
arraysunidimensíonalescontiguos.Deestemodo,podernosescribirunadeclaracióndearray
bidimensionalcorno
tipo-dato(*ptvar)[expresión2]
envezde
tipo-datoarray[expresión1][expresión2];
Esteconceptopuedegeneralizarseparaarraysmultidimensionales,estoes,
tipo-dato(*ptvar)[expresión2][expresión3]...[expresiónn];
reemplazaa
tipo-datoarray[expresión1][expresión2]...[expresiónn];

370 PROGRAMACiÓN ENC
Enestasdeclaraciones tipo-datoeseltipodedatosdelarray, ptvarelnombredelavaria­
blepuntero,
arrayelnombredelarraycorrespondientey expresión1,expresión2,
...,expresiónnexpresionesenteraspositivasqueindicanelmáximonúmerodeelemen­
tosdelarrayasociadosconcadaíndice.
Observelosparéntesisquerodeanalnombredelarrayyelasteriscoqueloprecedeenla
versióndepunterodecadadeclaración.Estosparéntesisdebenestarpresentes.Sinellosestare­
mosdefiniendounarraydepunteros
envezde unpunteroaungrupodearrays,yaqueestos
símbolosparticulares(loscorchetesyelasterisco)seevalúannormalmentedederechaaiz­
quierda.Veremosmássobreestetema
enlasiguientesección.'
EJEMPLO10.20. Supongamosquexesunarraybidimensionaldeenteroscon 10filasy 20colum­
nas.Podemosdeclararx como
int(*x)[20];
envezde
intx[10][20];
Enlaprimeradeclaración,x sedefinecomounpunteroa ungrupodearraysunidimensionalesconsecuti­
vosde2Oelementosenteros. Asíxapuntaalprimerodelosarraysde2Oelementos,queesenrealidadla
primerafila(fila
O)delarraybidimensionaloriginal.Análogamente, (x+1)apuntaalsegundoarrayde
2Oelementos,queeslasegundafila(fila 1)delarraybidimensionaloriginal,yasísucesivamente, como
seilustraenlaFiguralOA.
x
.1__-'- _
Primerarrayunidimensional
(x+1).,__--' _
Segundoarrayunidimensional
(x+9).1__--'-- _
Décimoarrayunidimensional
Figura10.4.
Consideremosahora elarraytridimensionaldenúmerosencomaflotantet.Estearraysepuededefi­
nIrCOfiO
float(*t)[20][30];

PUNTEROS 371
envezde
floatt[10][20][30];
Enlaprimeradeclaración, tsedefinecomounpunteroaungrupo dearraysbidimensionalesconsecutivas
encomaflotantede
2 Ox3O.Aquítapuntaalprimerarray de2 Ox3O,(t+1)alsegundo,yasí
sucesivamente.
Se
puedeaccederaunelementoindividualdeunarraymultidimensionalmediantelautiliza­
ciónrepetidadeloperadorindirección.Sinembargo,normalmenteestemétodoesmásdificil
queel
convencionalparaaccederaunelementodelarray.Elsiguienteejemploilustrael usodel
operadorindirección.
EJEMPLO10.21.Supongamosque xesunarraybidimensionalde 10filasy 2Ocolumnas,comose
declaróenelejemploanterior.Elelementoenlafila
2,columna5,puedeseraccedidoescribiendo
x[2][5]
o
*(*(x+2)+5)
Lasegundaformarequierealgunaexplicación.Primero,notarque (x+2)esunpunteroalafila 2.Por
tantoelobjetodeestepuntero,
*(x+2),refieretodalafila.Comolafila 2esunarrayunidimensional,
*(x+2)esrealmenteunpunteroalprimerelementodelafila 2.Sumamos5aestepuntero.Portanto,
(*(x+2)+5)esunpuntero alelemento5(elsextoelemento) delafila2.Elobjetodeestepuntero,
* ( *(x+2)+5),refierealelementoenlacolumna 5delafila 2,quees x[2] [5].LaFigura10.5
ilustraestarelación.
x
--~~I --' --'-__--J[
Primerarrayunidimensional
(x+1)---~~I,- -'-__..1.-__..1.-__[
SegundoarrayunidimensiOnt,1.
(x+2)----.1
*(x+2)
Tercerarrayunidimensional
*(*(x+2)+5)
Figura10.5.
*(x+2)+5

372 PROGRAMACiÓN ENC
Losprogramasquehacenusodearraysmultidimensionalespuedenserescritosdediversas
maneras.
Enparticular,haydiferentesmanerasdedefinirlosarrays,ydiferentesformasdepro­
cesarloselementosindividuales.
Laeleccióndeunmétodouotroesunasuntodepreferencias
personales.
Enaplicacionesconarraysnuméricosesamenudomásfácildefinirlosdelmodo
convencional,evitandoasílasposiblessutilezasasociadasconlaasignacióninicialdememoria.
Detodosmodos,elsiguienteejemploilustraelusodepunterosparaprocesararraysnuméricos
multidimensionales.
EJEMPLO10.22.Sumadedostablasdenúmeros. EnelEjemplo9.19desarrollamosuumétodo
paracalcularlasumadeloselementoscorrespondientesa dostablasdeenteros.Elprogramanecesitaba
tres arraysbidimensionalesseparados,
queerandefinidosdelaformaconvencional.Aquitenemosuna
variación
deeseprograma,enquecadaarraybidimensional esdefinidocomounpunteroa unconjuntode
arraysunidimensionalesdeenteros.
/*calcularlasumadeloselementosendostablasdeenteros*/
/*cadaarraybidimensionalseprocesacomounpunteroaunconjunto
dearraysunidimensionalesdeenteros*/
#include<stdio.h>
#include<stdlib.h>
#defineMAXFIL20
/*prototiposdefunciones*/
voidleerentrada(int*a[MAXFIL],intnfilas,intncols);
voidcalcularsuma(int*a[MAXFIL],int*b[MAXFIL],
int*c[MAXFIL],intnfilas,intncols);
voidescribirsalida(int*c[MAXFIL],intnfilas,intncols);
main()
{
intfila,nfilas,ncols¡
/*definicionesdepunteros
int*a[MAXFIL],*b[MAXFIL],
printf("¿Cuantasfilas?");
scanf
(11%d11,&nfilas)i
printf("¿Cuantascolumnas?
scanf(n%dn,&ncols);
*/
*c[MAXFIL];
11)i
/*reservainicialdememoria*/
for(fila
~O;fila<nfilas;++fila){
a[fila]
~(int* )malloc(ncols*sizeof(int));
b
[fila]
~(int* )malloc(ncols*sizeof(int));
c[fila]
~(int* )malloc(ncols*sizeof(int));
}
printf("Primeratabla:") ;
leerentrada(a,nfilas,ncols);

PUNTEROS 373
printf("Segundatabla:") ;
leerentrada(b,nfilas,ncols);
calcularsuma(a,b
re,nfilas,neols)¡
}
printf("Sumas delos
escribirsalida(c,nfilas,
elementos:");
ncols);
voidleerentrada(int*a[MAXFIL],intm,intn)
/*leerunatabladeenteros*/
{
intfila,col;
for(fila=O;fila<m;++fila){
printf("lntroducirdatosparalafilan
Q
%2d",fila+1);
for(col=O;col<n;++col)
scanf("%d",(*(a+fila)+col));
}
return¡
}
voidcalcularsuma(int*a[MAXFIL],int*b[MAXFIL],int*c[MAXFIL],
intm,intn)
/*sumarloselementosdedostablasdeenteros*/
{
intfila,col;
for(fila=O;
for(col=
*(*(c+
fila<m;++fila)
O;col<n;++col)
fila)+col)=*(*(a+fila)+col)+*(*(b+fila)
+col);
}
return¡
voidescribirsalida(int*a[MAXFIL],intm,intn)
/*escribirunatabladeenteros*/
{
intfila
lcol;
for
}
(fila=O;fila<
for(col=O;col
printf(II%4d
ll
,
printf(11 11)i
m;++fila){
<ni++col)
*(*(a+fila)+col));
}
return¡

374 PROGRAMACiÓN ENe
Enesteprograma a,b y csondefinidascomounarray depunterosaenteros.Cadaarraytieneunmáximo
deMAXFILelementos.Losprototiposdefuncionesylasdeclaraciones deargumentosformalesdentrode
lasfuncionessubordinadastambiénrepresentanlosarraysdeestamanera.
Puestoquecadaelemento
dea,b y cesunpuntero,debemosreservarmemoriainicialparacadafila
deenteros,utilizandolafunción
malloc,comosedescribeenlasección10.5.Estareservadememoria
apareceen
main,despuésdehabersidointroducidoslosvalorespara nfilasyncols.Consideremos
laprimerareserva
dememoria;estoes,
a[fila]
=(int*)malloc(ncols*sizeof(int));
Enestainstrucción a [O]apuntaalaprimerafila.Análogamente, a [1]apuntaalasegundafila, a [2]a
latercera,yasísucesivamente.Portanto,cadaelementodelarrayapuntaaunbloque
dememoriasufi­
cientementegrandepara almacenarunafila
deenteros(ncolsenteros).Reservasdememoriasimilares
sehanescritoparalosotrosdosarrays.
Loselementosindividualesdelarrayseprocesanutilizando
eloperadorindirecciónrepetidamente.En
leerentrada,porejemplo,cadaelementodelarrayesreferenciadocomo
scanf("%d",(*(a+fila)+col));
Deigualmodo,lasuma
qeloselementosdelarraydentro decalcularsumaseescribecomo
*(*(c+fila)+col)=*(*(a+fila)+col)+*(*(b+fila)+col)
ylaprimerainstrucción printfdentrode escribirsalidaestáescritacomo
printf("%4d",*(*(a+fila)+col));
Porsupuesto,podríamoshaberutilizadolanotaciónmásconvencionaldentro delasfunciones.Así,en
leerentradapodríamoshaberescrito
scanf("%d",8a[fila][col]);
envezde
scanf("%d",(*(a+fila)+col));
Análogamente,en calcularsumapodríamoshaberescrito
c[fila][col]=a[fila][col]+b[fila][col];
envezde
*(*(c+fila)+col)=*(*(a+fila)+~ol)+*(*(b+fila)+col);
yenescribirsalidapodríamoshaberescrito
printf("%4d",a[fila][col]);

PUNTEROS 375
envezde
printf("%4d",*(*(a+fila)+col));
Esteprogramageneraráidénticasalida queelmostradoenelEjemplo9.19cuandoseejeclltaconlos
mismosdatosdeentrada.
10.8.ARRAYSDEPUNTEROS
Unarraymultidimensionalpuedeserexpresadocomounarray depunterosenvezdecomoun
punteroaungrupodearrayscontiguos.Enestoscasoselnuevoarrayserádeunadimensión
menorqueelarraymultidimensional.Cadapunteroindicaráelprincipio
deunarraydedimen­
sión
(n-1).
Entérminosgenerales,unarraybidimensionalsepuededefinircomounarrayunidimensio­
naldepunterosescribiendo
tipo-dato*array[expresión1];
envezdeladefiniciónconvencionaldelarray,
tipo-datoarray[expresión1][expresión2];
Análogamente,unarrayn-dimensionalsepuededefinircomounarray depunterosdedimensión
(n
-1)escribiendo
tipo-dato*array[expresión1][expresión2]...[expresiónn-1];
envezde
tipo-datoarray[expresión1][expresión2]...[expresiónn];
Enestasdeclaraciones tipo-datoserefierealtipodedatosdelarrayn-dimensionaloriginal,
arrayeselnombredelarrayyexpresión1,expresión2,...,expresiónnson
expresionesenteraspositivasqueindicanelmáximonúmerodeelementosasociadosconcada
índice.
Observequeelnombredelarrayprecedidoporunasterisco
noestáencerradoentreparénte­
sisenestetipodedeclaración.(Compararcuidadosamenteconlasdeclaracionesdepunteros
presentadasenlaúltimasección.)Asílaregladeprecedenciadederechaaizquierdaasociael
primerpar
decorchetes
c<,>narray,definiéndoloc()m()unarray.Elasterisco queJoprecede
establecequeelarraycontendrápunteros.
Además,notarquela
últimaexpresión(extremoderecho)seomitecuandosedefineunarray
depunteros,mientrasquela primeraexpresión(extremoizquierdo)seomitecuandosedefine
unpunteroaungrupo de.arrayS.(DenuevOcolllpararcuidadosamentecon
las.declaraciones
presentadasenla.últimasección.)
Ellectordebeentender ladistinción·entreeste
•tipodedecla­
raciónylapresentadaenlasecciónanterior.

376 PROGRAMACiÓN ENC
Cuandounarrayn-dimensionalseexpresadeestamanera,unelementoindividualdentrodel
arrayn-dimensionalpuedeseraccedidomedianteunsimpleusodeloperadorindirección.El
siguienteejemploilustracómosehaceesto.
EJEMPLO10.23. Supongamosquexesuuarraybidimensionaldeenterosquetiene 10filasy2O
columnas,comoenelEjemplo 10.20.Podemosdefinirxcomounarrayunidimensionaldepunterosescri­
biendo
int*x[lO];
Portanto,x [ O]apuutaalprimerelemento delaprimerafila,x [ 1]alprimerelementodelaseguudafila,y
asisucesivamente.Observeque
elnúmerodeelementosdentrodecadafilanoestáespecificadoexplícitamente.
x[O] Primerarrayunidimensional
x[1]
x[2]
Segundoarrayunidimensional
Tercerarrayunidimensional
*(x[2]+5)
(x[2]+5)
x[9] Décimarrayunidimensional
Figura10.6.
Unelementoindividualdel array,talcomox [2][5],puedeseraccedidoescribiendo
*(x[2]+5)En'estaexpresiónx[2]eSUnpunteroalprimerelementoen lafila2,demodoque(x[2]+5)apuuta
alelemento
5(realmenteel
sextoelemento)delafila 2.Elobjetodeestepuntero, *(x[2]+5),refiere
portantoa x [
2][5].Estarelación.estáilustradaenlaFigura 10.6.

PUNTEROS 377
Considerarahoraelarraytridimensionalencomaflotante t.Supongamosqueladimensionalidad
de
tes10x20x30.Estearraypuedeserexpresadocomounarraybidimensionaldepunterosescri­
biendo
float*t[10][20];
Portanto,tendremos 200punteros(10filas,20columnas),cadaunoapuntandoaunarrayunidimen­
sional.
Unelementoindividualdelarray,talcomo
t[2] [3][5],puedeseraccedidoescribiendo
*(t[2][3]+5)
Enestaexpresión t [2][3]esunpunteroalprimerelementoenelarrayunidimensionalrepresentado
por
t[2][3].Deaqui(t[2] [3]+5)apuntaalelemento 5(elsextoelemento)dentrodeestearray.
Elobjetodeestepuntero,
*(t[2][3]+5),representaportanto t [2][3][5].Estasituaciónes,por
supuesto,análogaalcasobidimensionaldescritoanteriormente.
EJEMPLO10.24.Sumadedostablasdenúmeros. Aquitenemosotraversióndel programa
presentadoenlosEjemplos9.19y10.22,quecalculalasumadeloselementoscorrespondientesde
dostablasdeenteros.Ahoracadaarraybidimensionalserepresentacomounarrayde
punterosa
arraysunidimensionales.Cadaarrayunidimensionalcorresponderáaunafiladelarraybidimensional
original.
/*calcularlasumadeloselementosendostablasdeenteros*/
/*cadaarraybidimensionalseprocesacomounarraydepunteros
cadapunteroindicaunafiladelarraybidimensionaloriginal*/
#include<stdio.h>
#inc1ude<std1ib.h>
#defineMAXFIL 20
#defineMAXCOL 30
/*prototiposdefunciones*/
voidleerentrada(int*a[MAXFIL],intnfilas,intnco1s);
voidca1cu1arsuma(int*a[MAXFIL],int*b[MAXFIL]
,
int*c[MAXFIL],intnfi1as,intncols);
voidescribirsalida(int*c[MAXFIL],intnfilas,intilco1s);
main()
{
intfila,nfilas,ncolsi
/ *definicionesdearrays* /
int*a[MAXFIL],*b[MAXFIL],*c[MAXFIL];

378 PROGRAMACiÓN ENC
printf(U¿Cuantasfilas?U);
scanf(11%dn,&nfilas);
printf("¿Cuantascolumnas?"),
scanf(n%dH 1&ncols)i
/*reservainicialdememoria*/
for(fila=O,fila<=nfilas,fila++){
a[fila]=(int*)malloc(ncols*sizeof(int));
b[fila]=(int*)malloc(ncols*sizeof(int)),
c[fila]=(int*)malloc(ncols*sizeof(int)),
}
printf("Primeratabla:"),
leerentrada(a,nfilas,ncols),
printf("Segundatabla:"),
leerentrada(b,nfilas,ncols),
calcularsuma(a,b,c,nfilas,ncols),
}
printf("Sumas delos
escribirsalida(c,nfilas,
elementos:"),
ncols),
voidleerentrada(int*a[MAXFIL],intm,intn)
/*leerunatabladeenteros*/
{
intfila,col,
for(fila=O,fila<m,++fila)(
printf("lntroducirdatosparalafilan
2%2d",fila+1),
for(col=O,col<n,++col)
scanf("%d",(a[fila]+col)),
}
return¡
}
voidcalcularsuma(int*a[MAXFIL],int*b[MAXFIL],
int*c[MAXFIL],intm,intn)
/*sumarloselementosdedostablasdeenteros*/
{
intfila,col,

for(fila=O,fila<m;
for(col=O;col<
*(c[fila]+col)
++fila)
n,++col)
=*(a[fila]+col)+ *(b[fila]+col),
}
return;
voidescribirsalida(int*a[MAXFIL],intm,intn)
/*escribirunatabladeenteros*/

PUNTEROS 379
{
intfila,col;
for
}
(fila=O;fila<
for(col=O;col
printf("%4d",
printf("");
m;++fila){
<n;++col)
*(a[fila]+col»;
}
return;
Observeque a,b y cestándefinidosahoracomoarraysunidimensionalesdepunteros.Cadauno
contendrá
MAXFILelementos(MAXFILpunteros).Cadaelementodelarrayapuntaráaunarrayunidi­
mensionaldeenteros.Losprototiposdefuncionesylasdeclaraciones
deargumentosformalesdentrode
lasfuncionessubordinadastambiénrepresentanlosarraysdeestamanera.
Sedebereservarunbloquedememoriainicialparacadaarrayunidimensionalqueesobjeto
deun
puntero(cadafiladentrodecadauna
delastablas).Estolorealizalafunción malloc.Porejemplo,cada
fila
delaprimeratabla tienereservadoespaciodememoriadelasiguientemanera:
a[fila]=(int*)malloc(ncols*sizeof(int»;
Estainstrucciónasociaunbloquedememoriasuficienteparaalmacenar ncolsenterosconcadapuntero
(concadaelementodea).Similarreserva
dememoriasehaceparab y c.Lasinstruccionesmallocse
encuentrandentro
deunfarparareservarunbloque dememoriaparacadaunadelasfilasutilizadas
dentro
delastrestablas.
Loselementosdelarrayseprocesanutilizandounacombinación
denotacióndearraysypunteros.Por
ejemplo,en
leerentradacadaelementodelarrayesreferenciadocomo
scanf("%d",(a[fila]+col»;
Análogamente,en calcularsumayescribirsalidaloselementosdelarraysereferencian
como
*(c[fila]+col)=*(a[fila]+col)+*(b[fila]+col);
y
printf("%4d",*(a[fila]+col»;
respectivamente.Estasinstruccionessepuedenescribircon notacióndearraybidimensionalsise
desea.
Esteprograma,comoelpresentadoenelEjemplo10.22,generará
lamisníasalidaqueelmostradoen
elEjemplo9.19cuandose
ejecutaconlósmismosdatosdeentrada.Puedeverificarloporsímismo.Sin
embargo,siesteprogramafuera.r.ealizadodesdeelprincipio,elenfoqueconvencionalmostradoenel
Ejemplo9.19,usandoarraysbidimensionales,seríaelescogido.
Losarraysdepunterosofre.cenunmétodo.particularmente
cOl1venientepar<talmac.enar
caden<tsdecaracteres.Enestasituación;.cadaelementodel'arrayesUllpunterode tipocarác-

380 PROGRAMACiÓN ENC
terqueindicadóndecomienzacadacadena.Asiunarraydenelementospuedeapuntara n
cadenasdiferentes.Cadacadenaparticularpuedeseraccedidarefiriendosupunterocorres­
pondiente.
EJEMPLO10.25.Supongamosquelassiguientescadenas decaracterestienenqueseralmacenadasen
unarray
detipocarácter:
PACIFICO
ATLANTICO
INDICO
CARIBE
BERING
NEGRO
ROJO
NORTE
BALTICO
CASPIO
Estascadenas sepuedenalmacenaren
1illarraybidimensionaldetipocarácter;porejemplo,
charnombres[10][12];
Observeque nombrescontiene10filaspara las10cadenas.Cadafiladebesersuficientementegrande
paraalmacenarporlomenos
10caracteres,yaque ATLANTICOtienenueveletrasyelcarácternulo (\O)
alfinal.Permitimoscadafila dehasta12caracteres,
¡jaratenerlaposibilidad decadenlismáslargas,
Unaformamejor
dehaceresto esdefinirunarray de10
p1illteros;estoes,
char*nombres[10];
Deestamanera nombres[O]apuntaráa PACIFICO,nombres[1]apuntaráa ATLANTICO,yasí
sucesivamente.Observeque
noesnecesarioincluirelmáximotamaño decadenadentro deladeclaración
delarray.Sínembargo,
setendráquereservarunacantidadespecificada dememoriaparacadacadena de
caracteresposteriormenteen elprograma,porejemplo,
nombres[i]
=(char*)malloc(12*sizeof(char));
Unacadenadecaracterespuedeseraccedidarefiriendoelcorrespondientepuntero(elco­
rrespondienteelementode]array);deestemodo,unelementodelacadenapuedeseraccedido
medianteel.usodeloperadorindirección.Porejemplo,*C*(nombrE>s+2)+3)esel
cuartocarácter(elcarácternúmero3) enlaterceracadena(filanúmero2)delarray nombres,
comosehadefinidoen.elejemploprecedente.
Lareordenacióndelascadenasdecaracterespuederealizarsesimplementereasignandopun"
teros(reasignandoloselementosenunarraydepunteros).Lascadenasdecaracteres nonecesi.
tanmoverse.
EJEMPLO10.26.Reordenación deunalistadecadenasdecaracteres. Consideremosdenuevoel
problema
deintroducir
1illalistadecadenasdecaracteresenlacomputadorayreordenadasalfabéticainen-

PUNTEROS 381
te.VimosesteproblemaenelEjemplo9.20,dondelalistasealmacenabaenunarraybidimensional.
Trataremosesteproblemaahorautilizandounarrayunidimensionaldepunteros,dondecadapunteroindi­
caélprincipiodeunacadena.Elintercambio decadenaspuederealizarseahorareasignandopunteros
cuandoseanecesario.
Acontinuación
sepresentaelprogramacompleto.
/*ordenaralfabéticamenteunalistadecadenasdecaracteres,
utilizandounarraydepunteros*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
voidreordenar(intn,char*x[]);
main()
{
int
char
i,n=O;
*x[lD];
printf("Introducirdebajocadacadenaenunalínea");
printf("Escribir\'FIN\'paraterminar");
/*leerlalistadecadenasdecaracteres*/
do{
/*reservarmemoria*/
x[n]=(char*)malloc(12*sizeof(char));
printf("cadenaid:
scanf("%s",x[n]);
"n+1);
}
while(strcmp(x[n++],"FIN"));
/*reordenarlalistadecadenasdecaracteres*/
reordenar(--n,x);
/*escribirlalistareordenadadecadenasdecaracteres*/
printf("Listareordenadadecadenas:");
for(i=O;i <n;++i)
printf("cadenaid:%s",i +1,xli]);
}
voidreordenar(intn,char*x[])/*reordenarlalistadecadenas*/
{
char*tempi
intiIelem¡
for(elem=O;elem< n -1;++elem)

382 PROGRAMACiÓN ENC
/*encontrarlamenordelascadenasrestantes*/
for(i=elem+1;i<n;++i)
if(strcmp(x[elem],x[i])>O){
/*intercambiarlasdoscadenas*/
temp=x[elem];
x[e1em]=x[i];
x[i]=temp;
}
return¡
}
LalógicaesesencialmentelamismaqueladelEjemplo9.20,peroelarrayquecontienelascadenasde
caracteressedefineahora comounarraydepunteros.Observe queelsegundoargumento formalenla
función
reordenarsedeclaradelamismamanera.Observartambiénlarutina deintercambiodecade­
nas(lainstrucciónif)dentrodereordenar.Ahoraseintercambianlospunterosy nolascadenas
reales.
Poresto,lafunción debibliotecastrcpy,quefueusadaenelEjemplo9.20,nosenecesita.El
programafuncionará,pues, algomásrápidoqueenlaversiónanterior.
Laejecucióndeesteprograma generaráelmismodiálogoqueelmostradoenelEjemplo9.20.
Siloselementosdeunarraysonpunterosacadenasdecaracteres,selespuedenasignarun
conjuntodevaloresinicialescomopartedeladeclaracióndelarray.
Entalescasos,losvalo­
resinicialesseráncadenasdecaracteres,dondecada
unacorrespondea unelementodistinto
delarray.Recordarqueunarraydebeserdeclarado
staticsiesinicializadadentrodeuna
función.
Unaventajadeesteesquemaesquenotenemosquereservarunbloquefijodememoriapor
adelantado,comosehacecuandoseinicializaunarrayconvencional.Así,siladeclaraciónini­
cialincluyemuchascadenasdecaracteresyalgunasdeellassonrelativamentecortas,seprodu­
ceunahorrosustancial
enelusodelamemoria.Además,sialgunadelascadenasesespecial­
mentelarga,nohayquepreocuparsedeexcederlalongitudmáximadecadena(elmáximonúmero
decaracteres
porfila).Losarraysdeestetiposerefierenamenudo cOmOarraysdesiguales (en
inglés,
raggedarrays).
EJEMPLO10.27. Lasiguientedeclaración dearrayaparecedentro deunafunción:
staticchar*nombres[10]= {
"PACIFICO",
lIATLANTICO" ,
11INDICOn/
"CARIBE" I
UBERING
II
I
"NEGRO 11I
11ROJün/
11NORTE 11,
11BALTICO 11.r
"CASPIO"
};

PUNTEROS 383
Enesteejemplonombresesunarrayde 10punteros.Elprimerelementodelarray(elprimerpuntero)
apuntaráa
PACIFICO,elsegundoa ATLANTICO,yasísucesivamente.
Observequeelarraysedeclaracomo
staticparaquepuedaserinicializadodentrodelafunción.Si
ladeclaracióndelarrayfueraexternaatodaslasfuncionesdelprograma,elindicadordetipodealmacena­
miento
staticnoseríanecesario.
Comoladeclaracióndelarrayincluyevaloresiniciales,noesnecesarioincluirunadesignaciónexplí­
citadetamañodentrodeladeclaración.El tamañodelarrayseráautomáticamenteigualalnúmerode
cadenaspresentes.Comoresultado,ladeclaraciónanteriorpuedeserescritacomo
staticchar*nombres[]
={
11PACIFICO 11;
IIATLANTICQlI,
"INDIcan,
nCARIBEII,
11BERING 11I
11NEGRO 11,
lIROJüllI
11NüRTE",
11BALTICQ 11,
nCASPIO
II
};
Deberíaquedarclaroqueelconceptodearraysdesigualessóloserefierealainicia(¡zación
dearraysdecadenasdecaracteresynoalaasignacióndecadenasqueseleanmediantela
funciónscanf.Así,aplicacionesquerequieranqueseleancadenasyseprocesenacontinua­
ción,comoenelEjemplo10.26,necesitanquesereserveunacantidadespecíficadememoria
paracadaelementodelarray.
Lascadenasinicialespuedenseraccedidasdelaformanormalmediantesuscorrespondien­
tespunteros(suscorrespondienteselementosdelarray).Estospunterospuedenreasignarsea
otrasconstantesdecadenaenotrapartedelprogramasiesnecesario.
EJEMPLO10.28.Presentacióndeldíadelaño. Desarrollaremosunprogramaqueaceptarátresente­
ros,indicandoelmes,díayaño,ymostraráelcorrespondientedíadelasemana,elmes,eldíadelmesy
elañodemodomáslegible.Porejemplo,supongamosqueintroducimoseldato5
241997;esto
produciríalasalida
Sábado,Mayo24,1997.Amenudoseusanprogramasdeestetipo para
mostrarinformaciónalmacenadaenlamemoriadelacomputadorademodocodificado.
Nuestraestrategiabásicaconsistiráenintroducirunafechaenlacomputadora,enlaformames,día,
año
(mmddaaaa),yentoncesconvertirestedatoenelnúmerodedíasrelativoaalgúncasobase.Eldía
delasemanade
lafechaespecificadasepuededeterminarfácilmente,siemprequeconozcamoseldíade
lasemanadelafechabase.Arbitrariamente elegimosellunes,Enero
1,1900comofechabase.'Converti­
remoscualquierfechaposterioral1deenerode1900(realmentecualquierfechaentreel1deenerode
1900y
el31dediciembrede2099)ensucorrespondientedíadelasemana.
Elcálculoserealizausandolassiguientesreglasempíricas:
l.Introducirvaloresnuméricosparalasvariables mm,ddyaa,lascualesrepresentanelmes,díay
año,respectivamente
(porejemplo,5 241997).
2.Determinareldíaaproximadodelañoencurso,como
ndias=(long)00.42+(mm-1))+dd;

384 PROGRAMACiÓN ENC
3.Simm==2(febrero),incrementar elvalorde ndiasenlo
4.Simm>2ymm<8(marzo,abril,mayo,junioojulio),decrementar elvalorde ndiasen1.
5.Convertirelañoenelnúmero deañostranscurridosdesdelafechabase;porejemplo, aa
19OO.Comprobaracontinuaciónparaunañobisiestolosiguiente: si(aa%4)==O Ymm>
2,incrementarelvalor dendiasen1.
6.Determinarelnúmerodecicloscompletosdecuatroañosdetrásdelafechabasemediante
aa.I4.Porcadaciclocompleto decuatroañosseañade 1461andias.
7.Determinarelnúmerodeañoscompletosdespuésdelúltimociclodecuatroañosmediante
aa%4.Porcadaañocompletosumar 365andias.Entoncessumar 1,porqueelprimeraño
despuésdelciclo
decuatroesunañobisiesto.
8.Sindias>59(silafechaescualquierdíadespuésdel 28defebrerode1900),decrementarel
valorde
ndiasen1,yaque1900noesunañobisiesto.(Observeque elúltimoañodecada
siglonoesbisiesto,exceptoaquellosañosquesondivisiblespor
4 OO.Porlotanto 19OO,el
últimoañodelsiglodiecinueve,
noesunañobisiesto,pero 2 OOO,elúltimoañodelsigloveinte,
siesunañobisiesto.)
9.Determinareldíanuméricodelasemanacorrespondientealafechaespecificadacorno
dia=(ndias%7).
Observeque dia= =1correspondeo alafechabase,queeslunes,o aotrafechaquetambíénsea
lunes.Deaquí,
dia==2serámartes,dia==3serámiércoles,..., dia==6serásábado,y dia
=.=Oserádomingo.
Acontinuacíónsemuestralafuncíóncompleta,llamada convertir,querealizalospasosdel 2
al9.Observeque convertiraceptalosenteros mm,ddyaacornoparámetrosdeentrada,ydevuelve
lacantidadentera
(ndias%7).Tambiénobserveque ndiasynciclossonvariablesenteras
largas,mientrasqueelresto
delasvariablessonenterosordinarios.
intconvertir(intmm,intdd,intaa)1*convertirunafechaenel
díadelasemana*1
{
longndias;
longnciclos;
intnanios;
intdia¡
1*númerodedíasdesdeelcomienzode1900*1
1*númerodeciclosde4añosdespuésde1900*1
1*númerodeañosdespuésdelúltimo
ciclóde4años*I
1*díadelasemana(O,1,2,3,4,506)*1
1*conversionesnuméricas*1
aa-=1900;
ndias=(long)(30.42*(mm...1))+dd;1*díaaproximadodel
año*1
if(mm 2 )++ndiasi 1*
if((mm >2 )&&(mm<8)).,.--ndias¡ 1*
if((aa%4--O)&&(mm>2))++ndias¡1*
nciclos=aaI4;
ndias+=nciclos*1461;
ajusteparafebrero*j
ajusteparamarzo­
julio*1
ajusteparaelaño
bisiesto*I
j~ciclosde4años
despuésde1900*1
1*añadirdíasporciclos
de4años*1

}
nanias=aa%4;
if(nanios>O)
ndias+=365*nanios+1;
if(ndias>59)--ndias;
dia=ndias%7;
return(dia);
PUNTEROS 385
/*añosdespuésdel
últimociclode
4años* /
/*añadirdíasporaños
despuésdelúltimo
ciclo* /
/*ajustarpara1900
(NOañobisiesto)* /
Losnombresdelosdíasdelasemanasepuedenalmacenarcomocadenasdecaracteresenunarray
de7elementos;estoes,
staticchar*diasemana[]= {
11Domingo
11,
11Jueves11/
11Lunes 111UMartes 11fIIMiércolesnI
"Viernes","Sábado'!};
Cadadíacorrespondealvalorasignadoa dia,dondedia=(ndias%7).Losdíasempiezancon
Domingoporquedomingocorrespondea dia==O,comoseexplicóanteriormente. Silafechabaseno
fueraunlunes,estaordenaciónparticulardelosdíasdelasemanatendríaquecambíarse.
Igualmente,losnombresdelosmesessepuedenalmacenarcomocadenasdecaracteresenunarrayde
12elementos;estoes,
staticchar*mes[]={llEnero!!1"Febrero11,IIMarzo"/
"Abril
ll
r
11Mayo" ,
IlJunio"¡IIJulio
ll
,IIAgasto" IIISeptiembre
ll
,
1I0ctubre
ll
/lINoviembre",nDiciembre
ll
};
Cadamescorrespondealvalorde mm-1.
AcontinuaciónsemuestraelprogramacompletoenCquerealizalaconversióninteractivamente.
/*convertirunafechanumérica(mmddaaaa)en"díadelasemana,
mes,día
lañal!
(pcnejemplo:5241997->"Sábado,Mayo24,1997")*/
#include<stdio.h>
void1eerentrada(int
intconvertir(intmm,
*prn,
int
intdd,
*pd,int*pa);/*
intaa); /*
prototipo
prototipodefunción*/
defunción*/

386 PROGRAMACiÓN ENC
main()
{
intmm,dd,aa;
intdía_semana;/*díadelasemana(
1->
o ->Domingo,
Lunes,
}
6->Sábado*/
staticchar*diasemana[]= { 11DomingoH/"Lunesu,"Martes
ll
,
lIMiércoles"I 11JU8ves" f"viernes"/
lISábadoll};
staticchar*mes[]= {HEnero
ll
, 11Febrero11,"Marzo",FlAbril
u
,
11Mayo 11,
"Junio11IllJulio"/IlAgosto
ll
, 11Septiembre11I
nOctubre",IlNovíembre",IIDiciembre"};
/*mensajedeentrada*/
printf("RutinadeconversióndefechaParaPARAR,introducirO OO");
leerentrada(&mm,&dd,&aa);
/*convertirfechaadíanuméricodelasemana*/
while(mm>O){
diasemana=convertir(mm,dd,aa);
printf("%s,%s%d,%d",diasemana[dia_semana],mes[mm-l],dd,aa);
leerentrada(&mm,&dd,&aa);
}
voidleerentrada(int*pm,int*pd,int*pa)/ *leerlafechanumérica* /
{
}
printf("lntroducir
scanf("%d%d%d",pm,
return¡
mm
pd,
ddaaaa:
pa)
;
n )i
intconvertir(intmm,intdd,intaa)/*convertirunafechaenel
díadelasemana*/
{
longndias;
longnciclos;
intnarrias;
intdía;
/*númerodedíasdesdeelcomienzode1900*/
/*númerodeciclosde4añosdespuésde1900*/
/*númerodeañosdespuésdelúltimociclode4años*/
/*díadelasemana(O,1,2,3,4,5o6)*/
/*conversionesnuméricas*/
aa-=1900;
ndias=(long)(30.42*(mm-1))+dd;/*díaaproximadodelaño*/

((aa%4==O)&&(rrun>2))++ndias;1*
if
if
if
(rrun==2)
((rrun>2)
++ndias;
&&(rrun<8))--ndias;
1*
1*
PUNTEROS 387
ajusteparafebrero*1
ajusteparamarzo-ju­
lio*I
ajusteparaelañobi­
siesto*1
nciclos=aaI4;
ndias+=nciclos*1461;
1*ciclosde4añosdes­
puésde1900*1
1*
añadirdíasporciclos
de4años*1
nanios=aa%4; 1*añosdespuésdelúltimociclode4años
*1
if(nanios>O) 1*añadirdíasporañosdespuésdelúltimo
ciclo*1
ndias+=365*narrias+1;
if(ndias>59)--ndias;1*ajustarpara1900(NOañobisiesto)*1
dia=ndias%7;
return(dia);
}
Esteprogramaincluye unbuclequeaceptarepetidamenteunafecha enformadetresenteros
(rrundd
aaaa)ydevuelveelcorrespondientedia yfechadeunaformamáslegible.Elprogramaseejecutaráhasta
queseintroduzcaelvalor
Opara
rrun.Observequeelmensajeinicialdelprogramaindicaquesedeben
introducirtrescerosparadetenerlaejecución;
esdecir,O OO.Enrealidadelprogramasólocomprueba
elvalorde
rrun.
Unasesióninteractivatipicasemuestraacontinuación.Comosiempre,lasrespuestasdelusuario
estánsubrayadas.
Rutinadeconversióndefecha
ParaPARAR,introducirO O O
Introducir
rrunddaaaa:1Q~1929
Martes,Octubre29,1929
Introducirrrunddaaaa:~121945
Miércoles,Agosto15,1945
Introducirrrunddaaaa:7-2.Q1969
Dorningo,Julio20,1969
Introducirrrunddaaaa:2-241997
Sábado,Mayo24,1997

388 PROGRAMACiÓN ENC
Introducirmmddaaaa:liII2010
Lunes,Agosto30,2010
Introducirmmddaaaa:~U2069
Viernes,Abril12,2069
Introducirmmddaaaa:QQQ
10.9.PASODEFUNCIONESAOTRASFUNCIONES
Unpunteroaunafunciónpuedeserpasadocomoargumentoaotrafunción.Estopermiteque
unafunciónseatransferidaaotra,comosilaprimerafunciónfueraunavariable.Referiremosla
primerafuncióncomola
funciónhuésped ylasegundafuncióncomola funciónanfitriona. Deeste
modo,lahuéspedespasadaalaanfitriona,dondepuedeseraccedida.Llamadassucesivasala
funciónanfitrionapuedenpasardiferentespunteros(diferentesfuncioneshuésped)alaanfitriona.
Cuandounafunciónanfitrionaaceptaelnombredeunafunciónhuéspedcomoargumento,la
declaracióndeargumentoformaldebeidentificarelargumentocomounpunteroalafunción
huésped.Ensuformamássencilla,ladeclaración
deargumentoformalsepuedeescribircomo
tipo-dato(*nombre-función)()
dondetipo-datoeseltipodedatodelacantidaddevuelta porlahuéspedynombre­
funcióneselnombredelahuésped.Ladeclaración deargumentoformaltambiénsepuede
escribircomo
tipo-dato(*nombre-función)(tipo1,tipo2,...)
ocomo
tipo-dato(*nombre-función)(tipo1arg1,tipo2arg2,...)
dondetipo1,tipo2,refierelostipos dedatosdelosargumentosasociadosconla
huésped,
yarg1,arg2,sonlosnombresdelosargumentosasociados conlahuésped.
Lafunciónhuéspedpuedeseraccedidadentro delaanfitrionamedianteeloperadorindirec­
ción.Parahaceresto,eloperadorindireccióndebeprecederelnombredelafunciónhuésped(el
argumentoformal).Tantoeloperadorindireccióncomoelnombre
delafunciónhuéspeddeben
estarencerradosentreparéntesis;estoes,
(*nombre-función)(argumento1,argumento2,...,argumenton);
dondeargumento1,argumento2,...,argumentonsonlosargumentosnecesarios
enlallamadaalafunción.
Consideremosahoraladeclaracióndefunciónpara
lafunciónanfitriona.Éstasepuedees­
cribircomo

PUNTEROS 389
tipo-dato-funcnombre-func(tipo-dato-arg(*)(tipo1,tipo2,...) ,
If--- punteroafunciónhuésped ----71
tiposdedatosdelosotrosargumentosdelafunción);
dondetipo-dato-funceseltipodedatosdelacantidaddevueltaporlafunciónanfitriona;
nombre-funceselnombredelafunciónanfitriona; tipo-dato-argeseltipodedatosde
lacantidaddevueltaporlafunciónhuésped,
ytipo1,tipo2,...sonlostiposdedatosde
losargumentosdelafunciónhuésped.Observequeeloperadorindirecciónapareceentreparén­
tesis,paraindicarunpunteroalafunciónhuésped.Además,lesiguenlostiposdedatosdelos
argumentosdelafunciónhuéspedencerradosentreunpardeparéntesisseparado,paraindicar
quesonargumentosdefunción.
Cuandoseutilizaelprototipadocompletodefunción,ladeclaracióndelafunciónanfitriona
seexpandedelasiguientemanera:
tipo-dato-funcnombre-func
(tipo-dato-arg(*pt-var)(tipo1arg1,tipo2arg2,...) ,
1<-(--- punteroafunciónhuésped ------>1
tiposdedatosynombresdelosotrosargumentosdelafunción);
Lanotacióneslamismaqueantes,exceptoque pt-vareslavariablepunteroqueapuntaala
funciónhuésped,y
tipo1arg1,tipo2arg2,...sonlostiposdedatos ylos
nombrescorrespondientesdelosargumentosdelafunciónhuésped.
EJEMPLO10.29. Acontinuaciónsemuestraelesquemade unprogramaenC.Esteprogramaconsta
decuatrofunciones:
main,procesar,funclyfunc2.Observeque procesaresunafunción
anfitrionapara
funclyfunc2.Cadaunadelastresfuncionessubordinadasdevuelveunvalorentero.
intprocesar(int(*)(int,
intfuncl(int,int);
intfunc2(int,int);
main()
{
intiIji
int));/*prototipodefunción(anfitriona)*/
/*prototipodefunción(huésped)*/
/ *prototipodefunción(huésped)* /
i
=procesar(funcl)
;/*sepasafunclaprocesar;devuelveunva­
lorparai*/
j=procesar(func2);/ *sepasafunc2aprocesar;devuelveunva­
lorparaj*/
}
procesar(int(*pf)(int,int))/*definicióndefunciónanfitriona*/
/*(elargumentoformalesunpuntero
aunafunción)* /

390 PROGRAMACiÓN ENC
{
c=(*pf)(a,b);
return(c);
}
funcl(inta,intb}
{
inte;
c=
return(c};
}
func2(intx,inty}
{
intZi
z=
return(z);
}
/*accesoalafunciónpasadaaestafunción;
devuelveunvalorparac*/
/*definicióndefunciónhuésped*/
/*utilizaaybparaevaluarc*/
/*definicióndefunciónhuésped*/
/*utilizax e yparaevaluarz*/
Observequeesteprogramacontienetresdeclaracionesdefunciones.Lasdeclaracionespara func1y
func2sondirectas.Sinembargo,ladeclaraciónpara procesarrequierealgunaexplicación.Estade­
claraciónestableceque
procesaresunafunciónanfitrionaquedevuelveunvalorentero ytieneun
argumento.Elargumentoesunpunteroaunafunciónhuéspedquedevuelveunvalorentero
ytienedos
argumentosenteros.Ladesignación
delargumentoparalafunciónhuéspedseescribecomo
int(*)(int,int)
Observeelmodoenqueapareceladesignacióndeargumentosdentrodeladeclaracióndelafunción
anfitriona;estoes,
intprocesar(int(*)(int,int»;
Consideremosahoraladeclaracióndeargumentosformalesqueaparecedentrode procesar;estoes,
int(*pf)(int,int);
Estadeclaraciónestablecequep fesunpunteroaunafunciónhuésped.Estafunciónhuéspeddevolverá
unvalorenteroyrequieredosargumentosenteros.
Aquítenemos otraversióndelmísmo.esquema,utilizandoelprototipadocompletodefunción.Los
cambiossemuestranennegrita.

PUNTEROS 391
intprocesar(int(*pf)(inta,intb));/*declaracióndefunción
(anfitriona)*/
intfuncl(inta,intb); /*declaracióndefunción
(huésped)* /
intfunc2(inta,intb); /*declaracióndefunción
(huésped)* /
main()
{
inti,j;
}
i=procesar(funcl);
j=procesar(func2);
/*sepasafunclaprocesar;devuelveun
valorparai*/
/*sepasafunc2aprocesar;devuelveun
valorparaj*/
procesar(int(*pf)(inta,intb))/*definicióndefunciónanfi-
triona*/
/*(elargumentoformalesun
punteroaunafunción)*/
{
inta,b,c¡
c=(*pf)(a,b);
return(c);
}
funcl(inta,intb)
{
inte;
c=
return(c);
}
func2(intx,inty)
{
intZ¡
z=
return(z);
}
/*accesoalafunciónpasadaaestafun­
ción;devuelveunvalorparae*/
/ *definición.defunciónhuésped* /
/*utilizaaybparaevaluarc*/
/ *definicióndefunciónhuésped* /
/':utilizax eyparaevaluarz*
Losprototiposdefuncionesincluyenlosnombres dejosargumentosasícomolostiposde.datos delos
argumentos.Además,elprototipopara
procesarincluyeahora.elnombredelavariable (pf)queapun-

392 PROGRAMACiÓN ENC
taalafunciónhuésped.Observe queladeclaracióndelargumentoformal pfdentrodeprocesares
consistenteconelprototipodelafunción.
Algunosprogramasdeaplicaciónsepuedenformularmásfácilmenteentérminosdepasode
unafunciónaotra.Porejemplo,unafunciónpuederepresentarunaecuaciónmatemáti-cayla
otrapuedecontenerlaestrategiacomputacionalderesolución.Entalescasoslafunciónque
representalaecuaciónpuedeserpasadaalafunciónqueprocesalaecuación.Estoesparticular­
menteútilsielprogramacontienediferentesecuacionesmatemáticas,delascualeselusuario
seleccionaunacadavezqueseejecutaelprograma.
EJEMPLO10.30. Valorfuturodedepósitosmeusuales(cálculo deinteréscompuesto).Suponga­
mosqueunapersonadecideahorrar unacantidadfija
dedinerocadamesdurante naños.Sieldineroestá
auninterésdel
iporcientoanual,nospreguntamoscuántodinerotendremosdentro denaños(tras12x n
depósitosmensuales).Larespuestadepende,porsupuesto,decuántodinerosedepositacadames,dela
tasadeinterés
ydelafrecuenciaconqueelinteréssesumaaldepósito(frecuencia decomposición).Por
ejemplo,sielinteréssecomponeanualmente,semestralmente,trimestralmenteomensualmente,lacanti­
dadfuturadedineroacumuladodespués
denañosvienedadapor
F=12A[(1
+i/mt"-1]=12A[(1+i/~t"-1]
m ilm 1
dondeFeslacantidadfutura, Alacantidaddedinerodepositadacadames,ilatasadeinterésanual
(expresadacomodecimal)
ymelnúmerocorrespondientedeperiodosporaño(porejemplo, m=Ipara
composiciónanual,
m=2parasemestral, m=4paratrimestral ym=12paramensual).
Silosperiodos
decomposiciónsonmáscortosquelosperíodosdepago,comoenelcaso delacom­
posicióndiaria,lacantidadfuturasedeterminamediante
F=A
[(I+i/mt'-I]
(1+i/m)m/12_1
Observeque mtieneasignado elvalorde360cuando elinteréssecomponediariamente.
Finalmente,enelcasodecomposicióncontinua,lacantidadfuturasedeterminacomo
[
ei'_I]
F=Aei/12_1
Supongamosquedeseamosdeterminar Fcomounafuncióndelatasadeinterésanual i,paravalores
dadosde
A,myn.Desarrollemosunprogramaquelealosdatosnecesariosdentrode mainyentonces
efectúeloscálculosenunafunciónllamada
tabla.Cadaunadelastresfórmulasparadeterminar la
razónF/Aestarácolocadaenunadetresfuncionesindependientes,llamadas mdl,md2ymd3,respectiva­
mente.Portanto,elprogramaconstarádecincofuncionesdiferentes.
Cuandosellamaalafunción
tabladesdemain,unodelosargumentospasadosa tablaseráel
nombre
delafunciónquecontienelafórmulaapropiada,indicadapor unparámetrodeentrada (free).
Losvaloresde A,mynqueseleen enmaintambiénsonpasadosa tablacomoargumentos. Seinicia
unbucledentrode
tabla,enelcuallosvalores deFsedeterminanparatasas deinterésdesde 0.01(1
porcientoanual)··hasta
O.2O(2Oporcientoanual).Losvalorescalculadosseescribensegún·sevan
generando.Acontinuaciónsemuestraelprogramacompleto.

PUNTEROS 393
/*cálculosfinancierospersonales*/
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<math.h>
/*prototiposdefunciones*/
voidtabla(double(*pf)(doublei,intm,doublen),doublea,intm,
doublen),
doublemd1(doublei,intm,doublen),
doublemd2(doublei,intm,doublen),
doublemd3(doublei,intm,doublen),
main()
{
/*calcularelvalorfuturodeunaseriededepósitosmen­
suales* /
intm· /*númerodeperíodosdecomposiciónporaño*/,
doublen, /*númerodeaños*/
doublea¡ /*cantidaddecadapagomensual*/
charfree;/*indicadordefrecuenciadecomposición*/
/*entradadedatos*/
printf("VALOR FUTURODEUNASERIEDEDEPOSITaSMENSUALES ");
printf("Cantidaddecadapagomensual:"),
scanf("%lf",&a),
printf(lINúmerodeaños:11);
scanf("%lf
ll
,&n)¡
/*introducirfrecuenciadecomposición*/
do{
printf(11Frecuenciadecomposición(AlSrT,M,D,e):");
scanf("%ls",&frec),
frec=toupper(frec);. / *convertiramayúsculas* /
if(frec=='A'){
ro;;;;1;
printf("Composiciónanual");
}
elseif(frec=='S'){
ro=2;
printf("Composiciónsemestral"),
}
elseif(frec=='T'){
ro=4;
printf("Composicióntrimestral");
}
elseif(frec=='M'){
m
=12;
printf("Composiciónmensual")
,
}

394 PROGRAMACiÓN ENC
elseif(frec=='D'){
m=360;
printf("Composicióndiaria") ;
}
elseif(frec=='C'){
ro=Oi
printf("Composicióncontinua") ;
}
else
printf("ERROR -Porfavorrepita");
}while(frec!='A'&&frec!='S'&&frec!='T'&&
free1='M'&&free!='D'&&free!='e/);
/*realizarloscálculos*/
if(frec=='C')
tabla(md3, a,m,n);/*composicióncontinua*/
elseif(frec'D')
tabla(md2,a,m,n);/*composicióndiaria* /
else
tabla(mdl,a,mIn);/*composiciónanual,semestral,tri­
mestralomensual*/
}
voidtabla(double(*pf)(doublei,intm,doublen),doublea,intm,
doublen)
/ *generadordelatabla(estafunciónaceptaunpunteroaotra
funcióncomoargumento)
NOTA:double(*pf)(doublei,intm,doublen)esunPUNTEROA
FUNCION
*/
{
intcont¡
doublei;
doublef;
/*contadordelbucle*/
/*tasadeinterésanual*/
/*valorfuturo*/
}
printf("Tasadeinterés
for(cont=1;cont<=20;
i :::;0.01*cont¡
f=a *(*pf)(i,m,n);
printf(" %2d
}
return¡
Cantidadfutura");
++cont){
/ *ELACCESOALAFUNCION
COMOUNPUNTERO*/
%.2f",cont,f);
SEPASA
doublemd1(doub1ei,intm,doublen)
/ *depósitosmensuales,composiciónperiódica* /
{

PUNTEROS 395
doublefactor,razon;
factor=1+i/m;
razon=12*(pow(factor,m*n)-1)/i;
return(razon);
}
doublemd2(doublei,intm,doub1en)
/*depósitosmensuales,composicióndiaria*/
{
doublefactor,razon;
factor=1+i/m;
razon=(pow(factor,m*n)-1)/(pow(factor,m/12)-1);
return(razon);
}
doublemd3(doublei,intnulo,doub1en)
/ *depósitosmensuales,composicióncontinua* /
{
doublerazon;
razon=(exp(i*n)-1)/(exp(i/12)-1);
return(razon);
}
Observemoslosprototiposdefunciones,enparticularelprototipo detabla.Elprimerargumentopa­
sadoatablaesunpunteroaunafunciónhuéspedquerecibedosargumentosendobleprecisiónyun
argumentoentero,ydevuelveunacantidadendobleprecisión.Estepunteroestádestinadoarepresentara
md1,md2omd3.Losprototiposparaestastresfuncionessiguenalprototipode
tabla.Cadafunciónreci­
bedosargumentosendobleprecisiónyunenteroydevuelveunacantidadendobleprecisióncomoserequeria.
Dentrode
mainsegeneraundiálogointeractivoparalaentrada dedatos.Elprogramaaceptavalores
numéricosparaa y
n.Tambiénaceptaunacadenade uncarácterparalavariabledecarácter free,que
indicalafrecuenciadecomposición.Losúnicoscaracterespermitidosquesepuedenasignara
freeson
A,S,T,M,D oe(paracomposiciónAnual,Semestral,Trimestral,Mensual,DiariaoContinua,respectiva­
mente).Estecarácterpuedeserintroducidocomomayúsculaocomominúscula,ya
queesconvertidoa
mayúsculadentrodelprograma.Observequeelprogramahaceunacomprobaciónparaquesólosele
puedanasignarloscaracteres
A,S,T,M,DoC.
Unavezquesedeterminalafrecuenciadecomposición,seleasignaa melvaloradecuado.Elprogra­
maaccedea
tablapasandocomoargumentomd1,md2omd3,determinadoporelcarácterasignadoa
free.(Verinstrucciónif-e1semúltiplealfinal demain.)
Examinemosahoralafunciónanfitriona tabla.Losúltimostresargumentosformales (a,m yn)
estándeclaradoscomovariablesordinariasdedobleprecisiónoenteras.Sinembargo,elprimerargumen­
toformal
(pf)estádeclaradocomounpunteroaunafunciónhuéspedqueaceptadosargumentosendoble
precisiónyunenteroydevuelveunacantidadendobleprecisión.Estadeclaracióndeargumentosforma­
lesesconsistenteconelprototipo
defunciónpara tabla.
Losvaloresparai(lastasas deinterés)segeneraninternamentedentrode tabla.Estosvaloresse
determinancomo
0.01*cont.Comocontvadesde1hasta 20,vemosquelatasa
deinterésvaría
de
0.01aO.20,comosequería.

396 PROGRAMACiÓN ENC
Observelamaneraenquelosvaloresdefsoncalculados,estoes,
f
=a *(*pf)
(i,m,n);
Laexpresión(*pf)refierelafunciónhuéspedcuyonombresepasaa tabla(mdl,md2omd3).Éste
estáacompañadoporlalistarequeridadeargumentos,quecontienelosvaloresactualespara
i,m yn.El
valordevueltoporlafunciónhuéspedesmultiplicadopor
a,yelproductoseasignaa f.
Lastresfuncionesrestantes, mdl,md2omd3,sondirectas.Observequeelsegundoargumentoen
md3esllamado
nulo,yaquesuvalornoseusadentrodelafunción.Tambiénpodríamoshaberhecho
estoconmd2,yaqueelvalorparamessiempre3 6
Odíasenelcasodecomposicióndiaria.
Laejecucióndelprogramaproduceelsiguientediálogointeractivo:
VALORFUTURODEUNASERIEDEDEPOSITaSMENSUALES
Cantidaddepagomensual:100
Númerodeaños:
~
Frecuenciadecomposición(A,S,T,M,D,C):D.
ERROR-Porfavorrepita
Frecuenciadecomposición(A,S,T,M,D,C):ID
Composiciónmensual
Tasadeinterés
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Cantidadfutura
3653.00
3707.01
3762.06
3818.16
3875.33
3933.61
3993,01
4053.56
4115.27
4178.18
4242.31
4307.69
4374.33
4442.2.8
4511.55
4582.17
4654.18
4727.60
4802
..45
4878.78

PUNTEROS 397
10.10.MÁSSOBREDECLARACIONES DEPUNTEROS
Antesdedejarestecapítulomencionemosquelasdeclaraciones depunterospuedenvolverse
complicadasy
esnecesariounciertocuidadoen suinterpretación.Esto esespecialmentecierto
condeclaracionesqueinvolucrenfuncionesoarrays.
Unadificultadeselusodualdelosparéntesis.Losparéntesisseusanparaindicarfunciones
yparaanidaciones(paraestablecerprecedencias)dentro
dedeclaracionesmáscomplejas.Asíla
declaración
int*p(inta);
indicaunafunciónqueaceptaunargumentoenteroydevuelveunpunteroaentero.Porotra
parte,ladeclaración
int(*p)(inta);
indicaun punteroaunafunción queaceptaunargumentoenteroydevuelveunentero.Enesta
últimadeclaración,elprimerpar
deparéntesisseutilizaparaanidaryelsegundoparseutiliza
paraindicarunafunción.
Lainterpretación
dedeclaracionesmáscomplejaspuedehacersemolesta.Porejemplo,con­
sideremosladeclaración
int * (*p)(int(*a)[]) ;
Enestadeclaración, (*p)( ) indicaunpunteroaunafunción.Poresto, int * (*p)
( )indicaunpunteroaunafunciónquedevuelveunpunteroaunentero.Dentrodel
últimopardeparéntesis(laespecificacióndelosargumentosdelafunción),
(*a)[]indicaun
punteroaunarray.Comoresultado,
int (*a)[]representaunpunteroaunarray deenteros.
Uniendolaspiezas,
(*p)(int (*a)[])representaunpunteroaunarraycuyoargumentoes
unpunteroaunarraydeenteros.
y.finalmente,ladeclaracióncompleta
int*(*p)(int(*a)[]);
representaunpunteroaunafunciónqueaceptaunpunteroaunarraydeenteroscomoargumen­
toydevuelveunpunteroaentero.
Recordarqueunparéntesisizquierdosiguiendoinmediatamenteaunnombredeidentifi­
cadorindicaqueelidentificadorrepresentaunafunción.Análogamente,uncorcheteizquier­
dosiguiendoinmediatamenteaun.nombredeidentificadorindicaqueelidentificadorrepre­
sentaunarray.
Losparéntesisqueidentificanlasfuncionesyloscorchetesqueidentifican
arraystienenmayorprecedenciaqueeloperadorunarioindirección(verApéndiceC).Por
tanto,seránnecesariosparéntesisadicionales
cUilndosedeclareunpunteroaunafunciónoun
puntero.aunarray.
Elsiguienteejemploproporcionailustraciones deesto.
EJEMPLQ10.3.1. Acontinuaciónsemuestrandiversasdeclaraciones queinvolucrana punteros.Las
declaracionesestán ordenadasde.simples.acomplejas.

cantidadentera*/
punterosaente-
aceptaunargumento
carácterydevuelve
398 PROGRAMACiÓN ENC
int*Pi
int*p[10];
int(*p)[10];
int*p(vaid);
int p(char*a);
int*p(char*a);
int(*p)(char*a);
int(*p(char*a))[10];
intpichar(*a)[Ji;
intp(char*a[]);
int*p(chara [ ] )
int*p(char(*a)[Ji;
int*p(char*a[]);
int(*p)(char(*a)[]);
int*(*p)(char(*a)[J);
int*(*p)(char*a[]);
int·(*p[10])(void);
/*pesunpunteroauna
/*pesunarrayde10
ros*/
/*pesunpunteroaunarrayde10ente­
ros*/
/*pesunafunciónquedevuelveunpuntero
aentero*/
/*pesunafunciónque
queesunpunteroa
unentero*/
/*pesunafunciónqueaceptaunargumento
queesunpunteroacarácterydevuelve
un-punteroaunentero*/
/*pesunpunteroaunafunciónqueacepta
unargumentoqueesunpunteroacarác­
terydevuelveunentero*/
/*pesunafunciónqueaceptaunargumen­
toqueesunpunteroacarácteryde­
vue1veunpunteroaunarraydediez
enteros*/
/*pesunafunciónqueaceptaunargumento
queesunpunteroaunarraydecaracte­
resydevuelveunentero*/
/*pesunafunciónqueaceptaunargumento
queesunarraydepunterosacaracteres
ydevuelveunentero*/
/*pesunafunciónqueaceptaunargumento
queesunarraydecaracteresydevuelve
unpuntéroaentero*/
/*pesunafunciónqueaceptaunargumento
queesunpunteroaunarraydecaracte­
resydevuelveunpunteroaentero*/
/*pesunafunciónqueaceptaunargu­
mentoqueesunarraydepunterosa
caracteresydevuelveunpunteroaente­
ro*/
/*pesunpunteroaunafunciónqueacepta
unargumentoque"sunpunteroaunarray
decaracteresydevuelveun.entero*/
* p
esunpunteroaunafunciónque
aCf,pta
unargum"ntoqueesunpunteroaunarray
decaractéresydevuelveunpunteroa
entero'*/
/*pesunpUnteroaunafunciónqueacepta
unargumentoqueesunarraydepunteros
acaracteresydevuelveunpunteroaen­
tero*/
/ * pesunarraydé10punterosafUIlción;
cadafuncióndevue1véunentero* /

PUNTEROS 399
int(*p[10])(chara);/*pesunarrayde10punterosafunción;
cadafunciónaceptaunargumentoqueesun
carácterydevuelveunentero*/
int*(*p[10])(chara);/*pesunarrayde10punterosafunción;
cadafunciónaceptaunargumentoquees
uncarácterydevuelveunpunteroaen­
tero*/
int*(*p[10])(char*a);/*pesunarrayde10punterosafunción;
cadafunciónaceptaunargumentoquees
unpunteroacarácterydevuelveunpun­
teroaentero* /
10.1.
10.2.
10.3.
10.4;
10.5.
10.6.
10.7.
10.8.
10.9..
10.10.
10.11.
10,12.
10.13.
10.14.
10.15.
10.16.
Enlaversión deCdisponibleen sucomputadoraparticular,¿cuántasceldasdememo­
riasonnecesariasparaalmacenaruncarácter?¿Unentero?¿Unenterolargo?¿Una
cantidadencomaflotante?¿Unacantidadendobleprecisión?
¿Quéseentiendeporladirección
deunaceldadememoria?¿Cómoestánnormalmente
numeradaslasdirecciones?
¿Cómosedetertninaladireccióndeunavariable?
¿Quétipodeinformaciónrepresentaunavariablepuntero?
¿Cuáleslarelaciónentreladireccióndeunavariablev
ylavariablepunterocorres­
pondiente
pv?
¿Cuáleslafinalidaddeloperadorindirección?¿Aquétipodeoperandossedebe
aplicar?
¿Cuáleslarelaciónentreeldatorepresentadoporlavariablev
ylavariablepuntero
correspondiente
pv?
¿Quéprecedenciaseleasignaalosoperadoresunarioscomparadosconlosoperadores
multiplicación,división
yresto?¿Enquéordenseevalúanlosoperadoresunarios?
¿Puedeactuareloperadordirecciónsobre
unaexpresiónaritméticacomo2 *(u+
v)?Explicarlasrazonesdelarespuesta.
¿Puedeunaexpresióninvolucrarqueunoperadorindirecciónaparezcaalaizquierda
deunainstruccióndeasignación?Explicarlo.
¿Quétiposdeobjetospuedenasociarseconvariablespuntero?
¿Cómosedeclaraunavariablepuntero?¿Cuáleslafinalidaddeltipodedatosincluido
enladeclaración?
¿Dequémanerapuedeincluirselaasignación
deunvalorinicialenladeclaración de
unavariablepuntero?
¿Seasignanalgunavezvaloresenterosaunavariablepuntero?Explicarlo
¿Porquéesavecesdeseablepasarunpunterocomoargumento
deunafunción?
Supongamosqueunafunciónrecibeunpunterocomoargumento.Explicarcómose
escribeelprototipo
delafunción.Enparticular,explicar cómaserepresentaeltipode
datosdelargumentopuntero.

400
10.17.
10.18.
10.19.
10.20.
10.21.
10.22.
10.23.
10.24.
10.25.
10.26.
10.27.
10.28.
10.29.
10.30.
10.31.
10.32.
10.33.
10.34.
10.35.
10.36.
10.37
..
PROGRAMACiÓN ENC
Supongamosqueunafunciónrecibeunpunterocomoargumento.Explicarcómose
declaraelargumentopunteroenladefinición
delafunción.
¿Cuáleslarelaciónentreelnombredeunarrayyunpuntero?¿Cómoesinterpretadoel
nombre
deunarraycuandoaparececomoargumento deunafunción?
Supongamosqueunargumentoformaldentro
deladefinicióndeunafunción esun
array.¿Cómopuededeclararseelarraydentro
delafunción?
¿Cómopuedepasarseunaparte
deunarrayaunafunción?
¿Cómopuedeunafuncióndevolverunpunteroalarutinaquelallama?
Describirdosformasdiferentesdeespecificarladireccióndelelementodeunarray.
¿Porquéelvalordelíndice
deunarrayserefiereavecescomoundesplazamiento
cuandoelíndiceesparte
deunaexpresiónqueindicaladireccióndeunelementodel
array?
Describirdosmodosdiferentesdeaccederaunelementodeunarray.Compararlares­
puestaconladelacuestión10.22.
¿Puedeasignárseleunadirecciónaunnombre
dearrayo aunelementodelarray?¿Puede
asignárseleunadirecciónaunavariablepunterocuyoobjetoesunarray?
Supongamosquesedefineunarraynuméricoentérminosdeunavariablepuntero.¿Pue­
deninicializarseloselementosdelarray?
Supongamosquesedefineunarraydecaracteresentérminosdeunavariablepuntero.
¿Puedeninicializarseloselementosdelarray?Compararlarespuestaconla
delacues­
tiónprevia.
¿Quéseentiendeporasignacióndinámicadememoria?¿Quéfuncióndebiblioteca
seutilizaparaasignarmemoriadinámicamente?¿Cómoseespecificaeltamañodel
bloquedememoria?¿Quéclasedeinformaciónesdevuelta
porlafuncióndebi­
blioteca?
Supongamosqueunacantidadenteraessumadaorestadadeunavariablepuntero.
¿Cómoseráinterpretadalasumaoladiferencia?
¿Bajoquécondicionespuedeunavariablepunteroserrestadadeotra?¿Cómoseinter­
pretaráestadiferencia?
¿Bajoquécondicionessepuedencomparardosvariablespuntero?¿Bajoquécondicio­
nessonútilestalescomparaciones?
¿Cómosedefineunarraymultidimensionalentérminosdeunpunteroaunacolección
dearrayscontiguosdemásbajadimensionalidad?
¿Cómosepuedeutilizareloperadorindirecciónparaaccederaunelemento
delarray
multidimensional?
¿Cómosedefineunarraymultidimensionalentérminosdeun
¡rrraydepunteros?¿Qué
representacadapuntero?¿Enquédifiereestadefinicióndeunpunteroaunacolección
dearrayscontiguosdemásbajadimensionalidad?
¿Cómosepuedeutilizarunarrayunidimensionaldepunterospararepresentarunaco
e
leccióndecadenasdecaracteres?
Sisealmacenanvarias cadenasdecaracteresenunarrayunidimensional
depunteros,¿cómosepuedeaccederaunacadenaindividual?
Sisealmacenanvariascadenasdecaracteresenunarrayunidimensionaldepunteros,
¿quésucedesilascadenassonreordenadas?¿Sonmovidasrealmente.lascadenasde
caracteresadiferentesposicionesdentrodelarray?

PUNTEROS 401
10.38.
¿Bajoquécondicionessepuedeninicializarloselemento deunarraymultidimensional
sielarraysedefineentérminos
deunarraydepunteros?
10.39.Cuandosetransfiereunafunciónaotra,¿cuál eselsignificadodelafunciónhuésped?
¿Cuálel
delafunciónanfitriona?
10.40.Supongamosqueunargumentoformaldentro deunadefinicióndefunciónanfitrionaes
unpunteroaotrafunción.¿Cómosedeclaraelargumentoformal?Dentrodeladecla­
ración,¿aquétipo
dedatosrefiere?
10.41.Supongamosqueunargumentoformalpdentro deunadefinicióndefunciónanfitriona
esunpunteroalafunciónhuésped
q.¿Cómosedeclaraelargumentoformaldentrode
p?Enestadeclaración,¿aquétipodedatosrefiere?¿Cómoseaccedealafunciónq
desdelafunción
p?
10.42.Supongamosquepesunafunciónanfitrionayunodelosargumentosdep esunpuntero
alafunción
q.¿Cómosedeberíaescribirladeclaraciónparapsiseutilizaelprototipo
defuncióncompleto?
10.43.¿Paraquétipo deaplicacionesesparticularmenteútilelpasodeunafunciónaotra.
10.44.Explicarelsentidodecadaunadelassiguientesdeclaraciones:
a)int*px;
b)floata,b;
float*pa,*pb;
e)floata=-0.167;
float*pa=&a;
d)charcl,c2,c3;
char*pcl,*pc2,*pc3=&cl;
e)doublefunc(double*a,double*b,int*c);
fldouble*func(double*a,double*b,int*c);
g)double(*a)[12];
h)double*a[12];
i)char*a[12];
j)char*d[4]={Unorte
ll
, 11sur"r lIeste
ll
,lIoestell};
k)long(*p)[10][20];
1)long*p[10][20};
m)charmuestra(int(*pf)(chara,charb));
n)int(*pf)(void);
o)
int(*pf)(chara,charb);
p)int(*pf)(char*a,char*b);
10.45.Escribirunadeclaraciónapropiadaparacada unadelassiguientessitnaciones:
a)Declarardospunteroscuyosobjetosseanlasvariablesenterasiyj.
b)Declararunpunteroaunacantidadencomaflotanteyotroaunaendobleprecisión.

402 PROGRAMACiÓN ENC
e)Declararunafunciónqueaceptedosargumentosenterosydevuelvaunpunteroaenterolargo.
d)Declararunafunciónqueaceptedosargumentosydevuelvaunenterolargo.Cadaargumento
seráunpunteroaentero.
e)Declararunarrayunidimensionaldeelementosencomaflotanteusandolanotacióndepun­
teros.
j)Declararunarraybidimensionaldeelementosencomaflotante,con 15filasy 3Ocolumnas,
usandonotación
depunteros.
g)Declararunarraydecadenasdecaracterescuyosvaloresinicialessean"rojo","verde"y
"azul".
h)Declararunafunciónqueacepteotrafuncióncornoargumentoydevuelvaunpunteroacarác­
ter.Lafunciónpasadacornoargumentoaceptarácornoargumentounenteroydevolveráotro
entero.
i)Declararunpunteroaunafunciónqueaceptetresenteroscornoargumentosydevuelvauna
cantidadencomaflotante.
j)Declararunpunteroaunafunciónqueaceptetrespunterosaenteroscornoargumentosy
devuelvaunpunteroaunacantidadencomaflotante.
10.46.UnprogramaenCcontienelassiguientesinstrucciones:
charUfV ;:;;lA'i
char*pu,*pv ;:;;&v¡
*pv=v+1;
u=*pv+1;
pu=&u;
Supongamosquecadacarácterocupaunbytedememoria. Sielvalorasignadoa usealmacena
enladirección
F8c(hexadecimal)yelvalorasignadoa vsealmacenaenF8D,entonces:
a)¿Quévaloresrepresentadopor &v?
b)¿Quévaloresasignadoa pv?
e)¿Quévaloresrepresentadopor *pv?
d)¿Quévaloresasignadoa u?
e)¿Quévaloresrepresentadopor &u?
j)¿Quévaloresasignadoa pu?
g)¿Quévaloresrepresentadopor *pu?
10.47.UnprogramaenCcontienelassiguientesinstrucciones:
inti,j
int*pi,
=25;
*pj=&j;
*pj=j+5;
i ;:;;*pj+5;
pi=pj;
*pi;:;;i+
ji

PUNTEROS 403
Supongamosquecadacantidadenteraocupa2bytesdememoria. Sielvalorasignadoa iempie­
zaenladirecciónF9C(hexadecimal)y
elvalorasignadoa jempiezaenF9E,entonces:
a)¿Quévaloresrepresentadopor &i?
b)¿Quévaloresrepresentadopor &j?
e)¿Quévaloresasignadoa pj?
d)¿Quévaloresasignadoa *pj?
e)¿Quévaloresasignadoa i?
j)¿Quévaloresrepresentadopor pi?
g)¿Quévalorfinalesasignadoa *pi?
h)¿Quévaloresrepresentadopor (pi+2)?
i)¿Quévaloresrepresentadoporlaexpresión (*pi+2)?
j)¿Quévaloresrepresentadoporlaexpresión *(pi+2)?
10.48.Unprogramaen Ccontienelassiguientesinstrucciones:
floata=0.001,b=0.003;
floatc,*pa,*pb;
pa=&a¡
*pa=2*a;
pb=&b;
c=3 *(*pb-*pa);
Supongamosquecadacantidadencoma flotanteocupa4bytesdememoria.Si elvalorasignado
a aempiezaenladirección
1130(hexadecimal),elvalorasignadoa bempiezaen 1134yel
valorasignadoa cempiezaen 1138,entonces:
a)¿Quévaloresasignadoa &a?
b)¿Quévaloresasignadoa &b?
e)¿Quévaloresasignadoa &c?
d)¿Quévaloresasignadoa pa?
e)¿Quévaloresrepresentadopor *pa?
j)¿Quévaloresrepresentadopor & (*pa)?
g)¿Quévaloresasignadoa pb?
h)¿Quévaloresrepresentadopor *pb?
i)¿Quévaloresasignadoa c?
10.49.Acontinuaciónsemuestraelesquemadelaestructura deun
pro¡;ramaenC.
intfuncl(chara,charb);
intfunc2(char*pa,char*pb);
main()
{
chara=IX';
charb=
IYI ;
inti,j ;

404 PROGRAMACiÓN ENC
i =funel(a,
printf(11a=%d
b);
b=%d", a,b);
j=fune2(&a,&b);
printf("a=%db=%d",a,b);
}
intfunel(eharel,ehare2)
(
el='pI;
c2= fQI ;
}
return((el<e2)?ele2);
intfune2(ehar*el,ehar*e2)
{
*cl;;;;;'pI;
*c2=' QIi
}
return((*el==*e2)?*el*e2);
a)Dentrode main,¿quévaloresasignadoa i?
b)¿Quévaloresasignadoa j?
e)¿Quévaloressonescritosporlaprimerainstrucción printf?
d)¿Quévaloressonescritosporlasegundainstrucción printf?
Suponercaracteres ASen.
10.50.Elesquemadehiestructurade unprogramaenesemuestraacontinuación.
voidfune(int*p);
main()
{
statieinta[S]={lO,20,30,40,SO};
fune(a);
}
vaidfune(int*p)
{
intiIsuma=O;
far(i=O;i <S;++i)
suma+=*(p+i);
printf(lIsuma=%dll,suma);
return¡
}

PUNTEROS 405
a)¿Quétipodeargumentosepasaa fune?
b)¿Quétipodeinfonnacióndevuelve fune?
e)¿Quétipodeargumentofonnalsedevuelvedentrode fune?
el)¿Cuáleslafinalidaddelbucle forqueaparecedentrode fune?
e)¿Quévaloresescritoporlainstrucción printfdentrode fune?
10.51.Acontinuaciónsemuestraelesquemadelaestructuradeunprograma enC.
voidfune(int*p);
main()
{
statieinta[5]
fune(a+3);
}
voidfune(int*p)
{
{la,20,30,40,50};
inti,suma=o¡
for(i;O;i<2;++i)
suma+;*(p+i);
printf("suma;%d",suma);
return;
}
a)¿Quétipodeargumentosepasaa fune?
b)¿Quétipodeinfonnacióndevuelve fune?
e)¿Quéinfonnaciónsepasarealmentea fune?
el)¿Cuáleslafinalidaddelbucle forqueaparecedentrode fune?
e)¿Quévaloresescritoporlainstrucción printfdentrode fune?
Compararlasrespuestasconlasdelproblemaanterior.¿Enquésediferencianestosdosesque­
masdeprograma?
10.52.Acontinuaciónsemuestraelesquemadelaestructuradeunprogramaen C.
int*func(int*p);
main()
{
statieinta[5]
int*ptmax¡
{la,20,30,40,50};
ptmax fune(a)
;
printf("max;%d",*ptmax);
}

406 PROGRAMACiÓN ENC
int*fune(int*p)
{
inti,imax,max=O;
for(i~O;i<5;++i)
if(*(p+i)>max){
max ~*(p+i);
imax=i¡
}
return(p+imax);
}
a)Dentrode main,¿quées ptmax?
b)¿Quétipodeinformacióndevuelve fune?
e)¿Quéseasignaa ptmaxcuandoseaccedealafunción?
ti)¿Cuáleslafinalidaddelbucle forqueaparecedentro defune?
e)¿Quévalor esescritoporlainstrucción printfdentrodemain?
Compararlasrespuestasconlas delosdosproblemasanteriores.¿Enquésediferencianestos
esquemas?
10.53.UnprogramaenCcontienelasiguientedeclaración:
statieintx[8]
~{lO,20,30,40,50,60,70,80};
a)¿Cuáleselsignificado dex?
b)¿Cuáleselsignificado de(x+2)?
e)¿Cuáleselvalorde *x?
ti)¿Cuáles elvalorde (*x+2)?
e)¿Cuáleselvalorde* (x+2)?
10.54.UnprogramaenCcontienelasiguientedeclaración:
statiefloattabla[2][3]~{
{1.l,1.2,1.3},
{2.l,2.2,2.3}
};
a)¿Cuáleselsignificadode tabla?
b)¿Cuáleselsignificado de(tabla+l)?
e)¿Cuáleselsignificado de*(tabla+l)?
ti)¿Cuáleselsignificadode(* (tabla+1)+l)?
e)¿Cuáleselsignificado de(*(tabla)+l)?
1)¿Cuáleselvalorde*(* (tabla+1)+l)?
g)¿Cuáleselvalorde* (*(tabla)+l)?
h)¿Cuáleselvalorde*(* (tabla+l))?
i)¿Cuáleselvalorde *(*(tabla)+1)+l?
10.55.UnprogramaenCcontienelasiguientedeclaración:
statieehar*eolor[6]~{"rojo"·,
"negro",
11verde11/ lIazulll,
lIamarilloll};
lTblanco
ll
,

PUNTEROS 407
a)¿Cuáleselsignificadode color?
b)¿Cuáleselsignificadode (color+2)?
e)¿Cuáleselvalor de*color?
d)¿Cuáleselvalorde *(color+2)?
e)¿Enquésediferencian color[5]Y*(color+5)?
10.56.Acontinuaciónsemuestraelesquemadelaestructuradeunprogramaen C.
floatuno(floatx,floaty);
floatdos(floatx,floaty);
floattres(float(*pt)(floatx,floaty));
main()
{
floata,b;
atres(uno);
b=tres(dos);
}
floatuno(floatx,floaty)
(
floatz;
z=
return(z);
}
floatdos(floatx,floaty)
{
floatr;
r -
return(r);
}
floattres(float(*pt)(floatx,floaty))
{
floatalbrC¡
c=(*pt)(a,b);
return(c);
}

408 PROGRAMACiÓN ENC
a)Interpretarcadaunodelosprototiposdefunciones.
b)Interpretarlasdefinicionesdelasfunciones unoydos.
e)Interpretarladefinicióndelafunción tres.¿Enqué sediferenciatresdeunoydos?
d)¿Quéocurredentro demaincadavezqueseaccedea tres?
10.57.Acontinuaciónsemuestra elesquemadelaestructura deunprogramaen C.
floatuno(float*px,float*py);
floatdos(float*px,float*py);
float*tres(float(*pt)(float*px,float*py));
main()
{
float*pa,*pb¡
pa=tres(uno);
pb=tres(dos);
}
floatuno(float*px,float*py)
{
floatz;
z= .
return(z);
}
floatdos(float*pp,float*pq)
{
floatr;
r= .
return(r);
}
float*tres(float(*pt)(float*px,float*py))
{
floata,b,e;
e=(*pt)(&a,&b);
return(&c);
}

PUNTEROS 409
a)Interpretarcadaunodelosprototiposdefunciones.
b)Interpretarlasdefinicionesdelasfunciones unoydos.
e)Interpretarladefinicióndelafunción tres.¿Enquésediferencia tresdeunoydos?
d)¿Quéocurredentrode maincadavezqueseaccedea tres?
e)¿Enquésediferenciaesteesquemadeprogramadelmostradoenelúltimoejemplo?
rO.58.Explicarelpropósitodecadauna<lela"siguientesdeclaraciones:
a)float
b)float
e)float
d)float
e)float
f)float
g)float
h)float
i)float
j)float
k)float
(*x)(int*a);
(*x(int*a))[20];
x(int(*a)[]);
x(int*a[]);
*x(inta[]);
*x(int(*a)[]);
*x(int*a[]);
(*x)(int(*a)[]);
*(*x)(int*a[]);
(*x[20])(inta);
*(*x[20])(int*a);
10.59.Escribirunadeclaraciónapropiadaparacada unadelassiguientessituacionesconpunteros:
a)Declararunafunciónqueacepteunargumentoqueesunpunteroaunenteroydevuelvaun
punteroaunarraydeseiscaracteres.
b)Declararunafunciónqueacepteunargumentoquees unpunteroaunarraydeenterosy
devuelvauncarácter.
e)Declararunafunciónqueacepte
unargumentoqueesunarraydepunterosaenterosyde­
vuelvauncarácter.
d)Declararunafunciónqueacepteunargumentoquees unarraydeenterosydevuelvaun
punteroacarácter.
e)Declararunafunciónqueacepte
unargumentoqueesunpunteroaunarraydeenterosy
devuelvaunpunteroacarácter.
f)Declararunafunciónqueacepteunargumentoqueesunarraydepunterosaenterosyde­
vuelva
unpunteroacarácter.
g)Declararunpunteroaunafunciónque acepteunargumentoqueesunpunteroaunarrayde
enterosydevuelvauncarácter.
h)Declararunpunteroaunafunciónqueacepteunargumentoqueesunpunteroaunarrayde
enterosydevuelva
unpunteroacarácter.
i)Declararunpunteroaunafunciónqueacepteunargumentoqneesunarraydepunterosa
enterosydevuelva
unpunteroacarácter.
j)Declararunarrayde12punterosafunciones.Cadafunciónaceptarácomoargumentosdos
cantidades
endobleprecisión
ydevolveráunnúmero endobleprecisión.
k)Declararunarrayde12punterosafunciones. Cadafunciónaceptarácomoargu­
mentosdoscantidades
endobleprecisiónydevolverá unpunteroa unnúmeroendoblepre­
cisión.
l)Declararun·arrayde·12.punterosafunciones. Cadafunciónaceptarácomoargumentosdos
punterosacantidades
endobleprecisiónydevolverá unpunteroaunnúmero endoblepreci­
sión.

410 PROGRAMACiÓN ENC
10.60.ModificarelprogramamostradoenelEjemplo 10.1comosigue:
a)Usardatosencomaflotanteenvezdeenteros.Asignarelvalorinicial 0.3au.
b)Usardatosendobleprecisiónenvezdeenteros.Asignarelvalorinicial 0.3xlO"a u.
e)Usarcaracteresenvezdeenteros.Asignarunvalorinicial de'e'au.
EjecutarcadamodificaciónycompararlosresultadosconlosdelEjemplo 10.1.Asegurarsede
modificarlasinstrucciones
print fdemodoadecuado.
10.61.ModificarelprogramamostradoenelEjemplo 10.3comosigue:
a)Usardatosencomaflotanteenvezdeenteros.Asignarelvalorinicial 0.3av.
b)Usardatosendobleprecisiónenvezdeenteros.Asignarelvalorinicial 0.3xlO"a v.
e)Usarcaracteresenvez deenteros.Asignarunvalorinicial de'e'av.
EjecutarcadamodificaciónycompararlosresultadosconlosdelEjemplo 10.3.Asegurarsede
modificarlasinstrucciones
printfdemodoadecuado.
10.62.ModificarelprogramamostradoenelEjemplo 10.7demodoque sepaseunarrayunidimensional
decaracteresa fune1.Borrarfune2ytodassusreferencias.Inicialmenteasignarlacadena
"rojo"alarraydentro
demain.Reasignarlacadena"verde"alarraydentrode fune1.Ejecutar
elprogramaycompararlosresultadosconlosmostradosenelEjemplo
10.7.Acordarsedemodi­
ficarlasinstrucciones
printfdeformaadecuada.
10.63.ModificarelprogramamostradoenelEjemplo 10.8(análisisdeunalineadetexto) demodoquese
cuententambiénelnúmero
depalabrasyelnúmerototal decaracteresenlalineadetexto. (Nota:
unanuevapalabrapuedeserreconocidaporlapresencia deunespacioenblancoseguido deotro
carácternoblanco.)ComprobarelprogramausandolalineadetextodadaenelEjemplo
10.8.
10.64.ModificarelprogramamostradoenelEjemplo 10.8(análisisdeunalineadetexto)demodoque
sepuedanprocesarvariaslineas
detexto.
PriJ11erointroduciryalmacenartodaslaslineas.Luego
determinarelnúmerodevocales,consonantes,dígitos,espaciosenblancoy«otros»caracteres
paracadalínea.Finalmente,determinarlamediadelnúmerodevocalesporlínea,cousonantes
porlínea,etc.Escribiryejecutarelprogramadedosformasdiferentes:
a)Almacenarlaslíneas detextoenunarraybidimensional decaracteres.
b)Almacenarlaslíneas detextocomocadenasdecaracteres delongitudmáximanoespecifica-
da.Mautenerunpunteroacadacadenadentrodeunarrayunidimensionaldepunteros.
Encadacaso,identificar
laúltimalíneadetextode unmodopredeterminado(porejemplo,in­
troduciendolacadena"FIN").Comprobarelprogramausando variaslíneasdetextodesu
elección.
10.65.ModificarelprogramamostradoenelEjemplo 10.12demodoqueloselementosdexsean
ene
teroslargos envezdeenterosordinarios.Ejecutarelprogramaycompararlosresultadosconlos
delEjemplo
10.12.Recuérdesemodificarla instrucciónprintfparaacomodarlaalosenteros
largos.

PUNTEROS 411
10.66.ModificarelprogramamostradoenelEjemplo10.16demodoquesepuedanefectuarcualquiera
delasreordenacionessiguientes:
a)Menoramayor,envalorabsoluto
b)Menoramayor,algebraico
e)Mayoramenor,envalorabsoluto
d)Mayoramenor,algebraico
Utilizar notacióndepunterospararepresentarenterosindividuales,comoenelEjemplo10.16.
(RecordarqueenelEjemplo9.13sepresentóunaversiónconarraysdeesteproblema.)Incluirun
menúquepermitiráalusuario seleccionarquéreordenaciónseráusadacadavezque
seejecuteel
programa.Comprobarelprogramautilizandolos
10valoressiguientes:
4.7 -8.0
-2.3 11.4
12.9 5.1
8.8 -0.2
6.0 -14.7
10.67.Modificarelprogramamostradoenelejemplo10.22(sumadedostablasdenúmeros)demodo
quecadaelementoenlatablaeseaelmayor
deloscorrespondienteselementosen lastablasa y
b(envezdelasumadeloselementoscorrespondientesdea y
b).Representarcadatabla(cada
array)comounpunteroaungrupodearraysunidimensionales,comoenelEjem­
plo10.22.Utilizarnotación
depunterosparaaccederaloselementosindividualesdelatabla.
ComprobarelprogramausandolastablasdelEjemplo9.19.(Sedeberíaexperimentarconeste
programausandodiferentesformas
derepresentarlosarraysyloselementosindividuales delos
arrays.)
10.68.Repetirelproblemaanteriorrepresentandocadatabla(cadaarray)comounarrayunidimensional
depunteros,comosediscuteenelEjemplo10.24.
10.69.ModificarelprogramamostradoenelEjemplo10.26(reordenación
deunalistadecadenasde
caracteres)demodoquelalistadecadenaspuedaserreordenadaenordenalfabéticooenorden
alfabéticoinverso.Utilizarnotacióndepunterospararepresentarelcomienzodecadacadena.
Incluirunmenúquepermitaalusuario seleccionarquéreordenaciónserealizacadavezquese
ejecutaelprograma.Comprobarelprogramaconlosdatosdel Ejemplo9.20.
10.70.Modificar
.elprogramamostrado enelEjemplo10.28(presentacióndeldíadelaño)demodoque
puedadeterminarelnúmero
dedíasentredosfechas,suponiendoqueambasfechassonposterio­
resalafechabasedel 1deenerode1900.
(Sugerencia:Determinarelnúmero dedíasentrela
primerafecha
ylafechabase;hacera
continuació')10mismoparalasegundafechayfinalmente
calcularladiferenciaentrelosvalorescalculados.)
10.71.ModificarelprogramamostradoenelEjemplo10.30(cálculodeinteréscompuesto)demodoque
genereunatabladevaloresfuturos(valoresdeF)paravariastasasdeinterés,utilizandodiferen­
tesfrecuenciasdecomposición.SuponerqueA y nsonvalores,aintroducir.Mostrar lasalidade
lasiguientemanera:

412 PROGRAMACiÓN ENC
A=
n=
Tasadeinterés=
Frecuenciade
composición
Anual
Semestral
Trimestral
Mensual
Diaria
Continua
5% 6% 7%8% 9%10% 11% 12% 13% 14% 15%
Observequelasprimerascuatrofilassegeneranconunamismafuncióncondiferentesargumen­
tosycadauna
delasdosúltimasfilassegeneraconunafuncióndiferente.
10.72.ModificarelprogramamostradoenelEjemplo 10.30(cálculodeinteréscompuesto)demodoque
genereunatabladevaloresfuturos(valoresF)paravariosperiodosdetiempoydiferentesfre­
cuenciasdecomposición.SuponerqueA e
isonvaloresaintroducir.Mostrarlasalidadela
siguientemanera.
A
=
i=
Períododetiempo(n)=
Frecuenciade
composición
Anual
Semestral
Trimestral
Mensual
Diaria
Continua
1 23 4 5 6 78 910
Observequelascuatroprimerasfilassegeneranconunamismafuncióncondiferentesargumen­
tosycadaunadelasdosúltimasfilassongeneradasporfuncionesdiferentes.
10.73.Repetirelproblemaanterior,perotransponiendolatablademodo
queea~afila representeun
"alordiferenteparan ycadacolumnarepresenteunafrecuenciadecomposicióndistinta.Consi­
~er.arvalores enterosdenenelrango de1.a.50.ObserveqU9Iatablaten<lr*5.0filasy6colum­
nas.
(Sugerencia:Generarlatablaporcolunmas,
almacenan~ocada colunma.e
ll
.
unarraybidi­
mensional.Mostrarelarraycompletocuandosehayangeneradotodoslosvalores.)
Compararelesfuerzodeprogramacióndeesteproblemaconelrequeridoparaelproblemaanterior.
10.74.LosEjemplos9.8y9.9presentan;programasparacalcularlamediadeunalistadenúmerosy
luegocalcularlasdesviaciones.respecto
delamedia;Ambosprogramashacenusodearraysuni­
dimensionalesencomaflotante.Modificarambosprogramasutilizandonotacióndepunteros.

PUNTEROS 413
(ObservequeelprogramadelEjemplo9.9incluye laasignacióndevaloresinicialesaloselemen­
tosdelarray.)Comprobarambosprogramasusandolosdatosdadosenlosejemplos.
10.75.ModificarelprogramadadoenelEjemplo9.14(generadorde«piglatin»)demodoqueutilice
arraysdecaracteres.Modificarelprogramademodoqueutilicenotacióndepunteros.Compro­
barelprogramausandovariaslíneasdetextodesuelección.
10.76.EscribirunprogramacompletoenC,utilizandolanotacióndepunteros envezdearrays,paralos
siguientesprogramastomadosdelfinaldelCapítulo
9.
a)Problema9.39(leerunalíneadetexto,almacenarlaenlamemoriadelacomputadorayescri­
birlahaciaatrás).
b)Problema9.40(procesarunconjuntodecalíficacionesdeexámenesdealumnos).Comprobar
elprogramausandolosdatosdadosenelProblema9.40.
e)Problema9.42(procesarunconjuntodecalificacionesponderadasdeexámenesycalcular
la
desviacióndelamediadecadaalunmorespectoalamediageneraldelaclase).Comprobarel
programaconlosdatosdelProblema9.40.
á)Problema9.44(generarunatabladefactoresdeinterés compuesto).
e)Problema9.45(cambiardeunamonedaextranjeraaotra).
j)Problema9.46(determinarlacapitaldeunpaísespecificadooelpaíscuyacapitalesespeci­
ficada).Comprobarelprogramautilizandolalistadepaísesycapitalesdada
enelProble­
ma9.46.
g)Problema
9.47(a)(multiplicacióndematriz/vector).Comprobarelprogramaconlosdatos
dadosenelproblema
9.47(a).
h)
Problema9.47(b)(multiplicacióndematrices).Comprobarelprogramaconlosdatosdados
enelproblema
9.47(b).
i)Problema9.47(á)(interpolacióndeLagrange).Comprobarelprogramaconlosdatosdados
enelproblema
9.47(á).
j)Problema9.48(a)«<blackjack»).
k)Problema9.48(b)(ruleta).
l)Problema9.48(e)(BINGO).
m)Problema9.49 (codificarydecodificarunalíneadetexto).
10.77.EscribirunprogramacompletoenC,utilizandonotacióndepunteros,quegenerelassiguientes
trescolumnas:
aeb
t
senelae
bt
cosel
Estructurarelprogramadelasiguientemanera:escribirdosfuncionesespeciales,f l Y f 2,don­
de
flevalúalacantidad
aeb<senetyf2evalúaaeb<coset.Leerlosvaloresde a,by eenmain,
yluegollamaralafunción gen_tabla,quegenerarálatablareal.Pasar flyf2agen_tabla
comoargumentos.
Comprobarelprogramautilizandolosvalores
a=2,b=-0.1,e=0.5,dondelosvaloresde tson
1,2,3,...,60.

CAPíTULO11
Estructurasyuniones
EnelCapítulo9hemosestudiadoelarray,que esunaestructuradedatoscuyoselementosson
todosdelmismotipo.AhorafJjamosnuestraatenciónsobrelaestructura,queesunaestructura
dedatoscuyoselementosindividualespuedenserdedistintotipo.Así,unaestructurapuede
contenerelementosenteros,encomaflotanteycaracteres.Punteros,arraysyotrasestructuras
puedensertambiénincluidascomoelementosdentrodeunaestructura.Aloselementosindivi­
dualesdeunaestructuraselesdenominamiembros.
Estecapítuloseocupadelusodeestructurasenunprogramaen
C.Veremoscómosedefinen
lasestructurasycómoseaccedeyseprocesansusmiembrosdentrodeunprograma.Tambiénse
examinalarelaciónentreestructuras
ypunteros,arraysyfunciones.
Estrechamenterelacionadaconlaestructuraestálaunión,quetambiéncontienemúltiplesmiem­
bros.Sinembargo,adiferenciadelaestructura,losmiembrosdeunaunióncompartenelmismo
áreadealmacenamiento,inclusocuandolosmiembrosson
dediferentetipo.Así,launiónpermite
quevariosdatosdiferentessealmacenenenlamismaparte
dememoriadelacomputadoraendistin­
tostiempos.VeremoscómosedefinenyutilizanlasunionesdentrodeunprogramaenC.
11.1.DEFINICIÓNDEUNAESTRUCTURA
Ladeclaracióndeestructurasesalgomáscomplicadaqueladeclaracióndearrays,yaqueuna
estructuradebeserdefinida
entérminosdesusmiembrosindividuales.Engeneral,lacomposi­
ción
deunaestructurapuedeserdefinidacomo
structmarca{
miembro1;
miembro2;
miembrom;
}
;
Enestadeclaración, structesunapalabrareservadarequerida; marcaesunnombreque
identificaestructurasdeestetipo(estructurasquetenganestacomposición);
ymiembro1,
miembro2,
..,miembromsondeclaracionesdemiembrosindividu~les. (Nota:No
existedistinciónformalentredefinicióndeestructura
ydeclaracióndeestructura;ambostérmi­
nossonintercambiables.)
415

416 PROGRAMACiÓN ENC
Losmiembrosindividualespuedenservariablesordinarias,punteros,arraysuotrasestructu­
ras.Losnombresdelosmiembrosdentro
deunaestructuraparticulardebensertodosdiferentes,
peroelnombre
deunmiembropuedeserelmismoqueel deunavariabledefinidafueradela
estructura.Sinembargo,nosepuedeasignaruntipo
dealmacenamientoaunmiembroindivi­
dual,nitampocopuedeinicializarsedentro
deladeclaracióndeltipo delaestructura.
Unavezquelacomposición
delaestructurahasidodefinida,lasvariablesindividuales .de
estetipodeestructurapuedendeclararsecomosigne:
tipo-almacenamientostruet
marcavariable1,variable2, • • • 1variablen;
dondetipo-almacenamientoesunespecificadoropcionaldetipodealmacenamiento,
strueteslapalabrareservadarequerida, marcaeselnombrequeapareceenladeclaraciónde
estructuray
variable
1,variable2,...,variablensonvariablesdeestructura
deltipo
marca.
EJEMPLO11.1. Acontinuaciónsemuestra unadeclaración típicadeestructura.
structcuenta{
intnUffi_cuenta¡
chartipo_cuenta;
charnombre[8O];
floatsaldo;
};
Estaestructurasellama cuenta(lamarcaes cuenta).Contienecuatromiembros:unentero
(num_cuenta),uncarácter(tipo_cuenta),unarrayde 8 Ocaracteres(nombre[8O])yunacanti­
dadencomaflotante
(saldo).LaFigura11.1ilustraesquemáticamentelacomposicióndeestaestructura.
I
cuentaI
(estructura)
I
I
(miembro)
I
num_cuenta
I
tipo_cuenta
I
(miembro)
I
r
lI
nombre[80] (miembro)
r
saldo
I
(miembro)
I
.
Figura11.1.
j
Ahorilpodemosdeclarar1118variablesdeestructuraantiguoclienteynuevoclientecomosigue:
structcuentaantiguocliente,nuevocliente;

ESTRUCTURAS YUNIONES 417
Asi,antiguoclienteynuevoclientesonvaríablesdetípocuenta.Enotraspalabras, an­
tiguoclienteynuevoclientesonvariablesdeestructuracuyacomposición seidentifica
mediantelamarca
cuentao
Esposiblecombinarladeclaraciónde lacomposicióndelaestructura conladelasvariables
deestructura,
comosemuestraacontinuación.
tipo-almacenamientostructmarca{
miembro1;
miembro2;
}
miembro
variable1,
m;
variable2, .
,variablen;
Lamarcaesopcionalenestasituación.
EJEMPLO11.2. Lasiguientedeclaración esequivalentealasdosdeclaracionespresentadasen el
ejemploanterior.
structcuenta{
intnUffi_cuenta¡
chartipo_cuenta;
charnombre[801;
floatsaldo;
}antiguocliente,nuevocliente;
Asiantiguoclienteynuevoclientesonestructurasdeltípo cuenta.
Comoladeclaracióndevariablessecombinaahoraconladeclaracióndeltipo delaestructura,la
marca(esdecir,
cuenta)nonecesitaserincluida.Portanto,ladeclaraciónpuedeserescritacomo
struct{
intnUffi_cuenta;
chartipo_cuenta;
charnombre[ 8O];
floatsaldo;
}antiguocliente,nuevocliente;
Unavariabledeestructurapuedeserdefinidacomomiembrodeotraestructura.Entales
situaciones,
ladeclaracióndelaestructurainternadebeaparecerantes queladeclaraciónde la
estructuraexterna.
EJEMPLO11.3. UnprogramaenCcontienelassiguientesdeclaracionesdeestructuras:
structfechá
intmes;
int
di'a.¡
intarriai
};

418 PROGRAMACiÓN ENC
structcuenta{
intDuro_cuenta;
chartipo_cuenta;
charnombre[8O];
f
loatsaldo;
structfechaultimopago;
}antiguocliente,nuevocliente¡
Lasegundaestructura (cuenta)contieneahoraotraestructura (fecha)comouno desusmiembros.
Observeque
ladeclaracióndefechaprecedealadeclaración decuenta.LaFigura11.2muestra de
modoesquemáticolacomposición decuenta.
Alosmiembrosdeunavariabledeestructuraselepuedenasignarvaloresiniciales dela
mismaformaquealosarrays. Losvaloresinicialesdebenaparecerenelordenenqueserán
asignadosasuscorrespondientes miembrosdelaestructura,encerradosentrellavesyseparados
porcomas.Laformagenerales
tipo-almacenamientostructmarcavariable=
{valor1,valor2, .,valorm};
dondevalor1refierealvalordelprimermiembro,valor2alvalordelsegundo,yasí
sucesivamente.
Unavariabledeestructura,aligualque unarray,solamente puedeserinicializa­
dosi
sutipodealmacenamientoes externostatic.
EJEMPLO11.4. Esteejemploilustralaasignación devaloresinicialesalosmiembros deunava­
riableestructura.
structfecha{
intmes;
intdia;
intarrio;
};
structcuenta{
intDuro_cuenta;
chartipo_cuenta;
charnombre[8O];
floatsaldo;
structfechaultimopago;
};
staticstructcuentacliente={12345,
'R',"JoséR.García",586.30,
5,24,90};
Así,clienteesunavariabledeestructuraestáticadeltipo cuenta,cuyosmiembrostienenasignados
valoresiniciales.Elprimermiembro
(num_cuenta)tieneasignadoelvalorentero 12345,elsegundo
miembro
(tipo_cuenta)tieneasignadoel carácter'R',eltercermiembro (nombre[80])tieneasig­
nadalacadena
"JoséR.García"yelcuartomiembro (saldo)tieneasignadoelvalorencoma
flotante586 . 3
O.Elúltimomiembroesunaestructuraquecontienetresmiembrosenteros (mes,diay
anio).Portanto,elúltimomiembro declientetieneasignadoslosvaloresenteros 5,24Y90.

ESTRUCTURAS YUNIONES 419
(miembro)
(miembro)
(miembro)
)
I
cuenta
I
(estructura)
I
num_cuenta
I
(miembro)
I
I
tipo_cuenta
I
(miembro)
I
I
I
(miembro)
I
nombre[80]
I
saldo
I
(miembro)
I
I
ultirnopago
I
(miembroestructura
I
I
mes
I
I
dia
II
I
anio
II
Figura11.2.
Tambiénesposibledefinirunarraydeestructuras;estoes,unarray enelquecadaelemento
sea
unaestructura.Elprocedimientoseilustraenelsiguienteejemplo.
EJEMPLO 11.5.Unprogramaenecontienelassiguientes declaraciones deestructuras.
structfecha{
intmes;
intdía;
intanioi
}
;
structcuenta{
intnum_cuenta¡
chartipo_cuenta;
charnombre[8O];
floatsaldo;
structfechaultimopago;
}cliente[lOOl;

420 PROGRAMACiÓN ENC
Enestadeclaración clienteesunarrayde 100estructuras.Cadaelementode clienteesuna
estructuradeltipo
cuenta(cadaelemento declienterepresentaunregistro declienteindividual).
Observequecadaestructuradeltipo
cuentaincluyeunarray (nombre[8O])yotraestructura
(fecha)comomiembros.AsItenemosunarrayyunaestructuraincluidasdentrodeotraestructura,
queesasuvezunelemento
deunarray.
Porsupuesto,tambiénsepuededefinir
c1ient eenuna declaraciónseparada,comosemuestraa
continuación.
structfecha{
intmes;
intdia;
intarria;
}
;
structcuenta{
intnuro_cuenta;
chartipo~cuenta;
charnombre[8O];
floatsaldo;
structfechaultimopago;
};
structcuentacliente[100];
Unarraydeestructuraspuedetenerasignadosvaloresinicialescomocualquierotroarray.
Recordarquecadaelementodelarrayesunaestructuraalaquedebeasignarsesucorrespondien­
teconjuntodevaloresiniciales,comoseilustraacontinuación.
EJEMPLO11.6. UnprogramaenCcontienelassiguientesdeclaraciones:
structfecha{
charnombre[8O];
intmesi
intdia¡
intarriai
};
staticstructfechanacimiento[]= {"Ana",12,30,73,
IIJosé
ll
,S,13,66,
"Lidia
ll
,7
115,72,
11Raúl11I11
129,70
1
lIRosa",,2,4/77,
"Sara1l,12,29,63,
11Zoraida11,4
112I69}¡
Enesteejemplo nacimientoesunarraydeestructurascuyotamañoestásInespecificar.Losvalores
InIcIalesdefinIráneltamañodelarrayylacantIdaddememorIanecesarIaparaalmacenarelarray.
ObservequecadafilaenladeclaracíóndelavaríablecontIenecuatroconstantes.Estasconstantes
representanlosvaloresInIcIales,estoes,elnombre,
mes,dlayaño,paraunelemento delarray.Como
haysIetefilas(sIeteconjuntosdeconstantes),elarraycontendrásIeteelementosnumerados
.deOa6.

ESTRUCTURAS YUNIONES 421
Algunosprogramadoresprefierenincluircadaconjuntodeconstantesdentrodeunpardellaves
parasepararmásclaramenteloselementosindividualesdelarray.Estoestápermitido.Asi,ladeclara­
cióndelarraysepuedeescribir
staticstructfechanacimiento[]={
{"Arra
n
I12,30,73
},
{IlJosé
ll
,5,13,66},
{
lI
LidiaHf7,15,72},
{"Raúl",11,29,70},
{IIRosa",2,4,77},
{"Sarall,12,29,63},
{ 11Zoraida11r4,12,69)
};
Recordarquecadaestructura,conrespectoalasdefinicionesde miembros,esunaentidad
autónoma.Así,elmismonombredemiembropuedeusarseendiferentesestructuraspararepre­
sentardiferentesdatos.Enotraspalabras,elámbitodeunnombredemiembroestáconfinadoa
laestructuraparticulardentrode lacualhasidodefinido.
EJEMPLO 11.7. Dosestructurasdistintas,llamadas primeraysegunda,sondeclaradasa
continuación.
structprimera{
floata;
intb¡
charei
};
structsegunda{
chara¡
floatb,c;
};
Observequelosnombresdelosmiembrosindividuales a,b y caparecenenambasdeclaracionesde
estructura,perolostiposdedatosasociadossondiferentes.Así,arepresentaunacantidadencoma
flotanteen
primerayuncarácteren segunda.Análogamente,brepresentaunenteroen primera
yunacantidadencomaflotanteen segunda,mientrasquecrepresentauncarácteren primeray
unacantidadencomaflotanteen
segunda.Estaduplicacióndenombresdemiembrosestápermiti­
da,yaque elámbitodecadaconjuntodedefinicionesdemiembrosestáconfinadoasurespectiva
estructura.Dentrodecadaestructuralosnombresdemiembrossondistintos,comoserequiere.
11.2.PROCESAMIENTO DEUNAESTRUCTURA
Losmiembrosdeunaestructuraseprocesangeneralmentedemodoindividual,comoentidades
separadas.Portanto,tenemosquesercapacesdeaccederalosmiembrosindividualesdela
estructura.Unmiembrodeunaestructurapuedeseraccedidoescribiendo
variable.miembro

422 PROGRAMACiÓN ENC
dondevariablerefiereelnombredeunavariabledetipoestructuray miembroelnombrede
unmiembrodentrodelaestructura.Observeelpunto(.)queseparaelnombredelavariabledel
nombredelmiembro.Estepuntoesunoperador;esunmiembrodelgrupodemayorprioridad,
y
suasociatividadesdeizquierdaaderecha(ver ApéndiceC).
EJEMPLO 11.8. Considerarlassiguientesdeclaraciones deestructuras:
structfecha{
intmes;
intdia;
intarria;
};
structcuenta{
intnUffi_cuentai
chartipo_cuenta;
charnombre[8O];
floatsaldo;
structfechaultimopago;
}cliente;
Enesteejemploclienteesunaestructuradeltipocuenta.Siqueremosacceder alnúmerodecuenta
delcliente,debemosescribir
cliente.num_cuenta
Análogamente,elnombrey elsaldodelclientepuedenseraccedidosescribiendo
cliente.nombre
y
cliente.saldo
Comoeloperadorpuntopertenecealgrupodemayorprecedencia,tendráprecedenciasobre
losoperadoresunarios,asícomosobrelosoperadoresaritméticos,relacionales,lógicosyde
asignación.Porejemplo,unaexpresióndelaforma
++var
iable .miembroesequivalentea
++ (variable .miembro);esdecir,eloperador ++seaplicarásobreelmiembrodelaestruc­
turaynosobrelaestructuracompleta.Análogamente,laexpresión
&variable.miembroes
equivalentea
& (var
iable .miembro);asílaexpresiónaccedea ladireccióndelmiembrode
laestructuraynoaladireccióndecomienzodelavariableestructura.
EJEMPLO 11.9. Consideremoslasdeclaraciones deestructuradadas enelEjemplo11.8.
structfecha{
intmes;
intdia¡
intarriai
};

ESTRUCTURAS YUNIONES 423
structcuenta{
intnum_cuenta;
chartipo_cuenta;
charnombre[8O];
floatsaldo;
structfechaultimopago;
}cliente;
Variasexpresiones queinvolucranalavariable deestructuraclienteyasusmiembrossondadasa
continuación.
Expresión
++cliente.saldo
cliente.saldo++
--cliente.num._cuenta
&cliente
&cliente.numcuenta
Interpretación
Incrementaelvalordecliente.saldo
Incrementaelvalordecliente.saldodespuésdeaccederasuvalor
Decrementaelvalordecliente.num_cuenta
Accedealadirección decomienzodecliente
Accedealadirección decliente.num_cuenta
Sepuedenescribirexpresionesmáscomplejasusandorepetidamenteeloperadorpunto.Por
ejemplo,siunmiembrodeunaestructuraesa
suvezotraestructura,entonceselmiembrodela
estructuramásinternapuedeseraccedidoescribiendo
variable.miembro.submiembro
dondemiembrorefiereelnombredelmiembrodentrodelaestructuraexternay submiembro
elnombredelmiembrodentrode laestructurainterna.Análogamente,siunmiembrode
unaestructuraesunarray,entoncesunelementoindividualdelarraypuedeseraccedidoescri­
biendo
variable.miembro[expresión]
dondeexpresiónesunvalornonegativoqueindicaelelementodelarray.
EJEMPLO11.10. Consideremosdenuevoladeclaración deestructurapresentada enelEjemplo11,8.
structfecha{
intmes;
intdia;
intarriai
};
structcuenta{
intnUffi_cuenta;
chartipo_cuenta;
charnombre[8O];
floatsaldo;
structfechaultimopago;
}cliente;

424 PROGRAMACiÓN ENC
Elúltimomiembrode clienteescliente.ultimopago,queesunaestructura detipofecha.
Portanto,paraaccederalmesdelúltimopagodebemosescribir
cliente.ultimopago.mes
Además,estevalorpuedeincrementarseescribiendo
++cliente.ultimopago.mes
Análogamente,eltercermiembrode clienteeselarraydecaracteres cliente.nombre.El
tercercarácterdentro
deestearraypuedeseraccedidoescribiendo
cliente.nombre[2]
Ladireccióndeestecarácterpuedeobtenersecomo
&cliente.nombre[2]
Elusodeloperadorpuntopuedeextenderseaarraysdeestructurasescribiendo
array[expresión].miembro
dondearrayrefiereelnombredelarrayyarray[expresión].miembroesunelemento
individualdelarray(unavariabledeestructura).Portanto,array[expresión]referiráun
miembroespecíficodentrodeunaestructuraparticular.
EJEMPLO 11.11.Consideremoslasiguientedeclaracióndeestructuraquesepresentóoriginal­
menteenelEjemplo11.5.
structfecha{
intmes;
intdia;
intanio;
}
;
structcuenta{
intnUffi_cuenta;
chartipo_cuenta;
charnombre[8O];
floatsaldo;
structfechaultimopago;
} c 1 iente[10O];
Enesteejemplo c 1 ient eesunarrayquepuedecontenerhasta 100elementos.Cadaelemento
esunaestructuradeltipo
cuenta.Así,siqueremosaccederalnúmerodecuentadelcliente 14
(cliente[13],yaqueelíndiceempiezaen O),debemosescribir cliente[13].num_cuenta.
Análogamente,sepuedeaccederalsaldodeesteclienteescribiendo cliente[13].saldo.

ESTRUCTURAS YUNIONES 425
Sepuedeacceder alnombredelcliente 14escribiendocliente[13].nombre.Además,pode­
mosaccederacaracteresindividualesdentrodelnombreespecificandouníndice.Porejemplo,
eloctavo
carácterdentrodelnombrepuedeseraccedidoescribiendoc 1
iente[13].nombre[7].Deforma
similarpodemosaccederalmes,díayañodelúltimopagodelcliente
14especificandolosmiembros
individuales
decliente[13].ultimopago,quesoncliente[13].ultimopago.mes,
cliente[13].ultimopago.diaycliente[13].ultimopago.anio.Además,laexpresión
++cliente[13].ultimopago.diaproduceunincrementoenelvalordeldía.
Losmiembrosdeunaestructurapuedenprocesarsedelamismamaneraquelasvariables
ordinariasdeestemismotipo.Losmiembrosdeestructuraunievaluadospuedenapareceren
expresiones,puedenpasarseyserdevueltosporfuncionescomosisetrataradevariablesordina­
riasunievaluadas.Los miembroscomplejosdeestructurasse procesandelamismamaneraque
losdatosordinariosdelmismotipo.Porejemplo,unmiembrodeestructuraqueesunarray
puedeprocesarsedelmismomodoqueunarrayordinario,y conlasmismasrestricciones.Análo­
gamente,unmiembrodeestructuraqueseaasuvezotraestructurapuedeserprocesadosobrela
basedemiembropormiembro(aquílos miembroshacenreferenciaa losdelaestructuraanida­
da),
lomismoqueparacualquierotraestructura.
EJEMPLO 11.12. Acontinuaciónsemuestranvariosgrupos deinstruccionesqueaccedenamiem­
brosindividualesdeestructura.Todoslosmiembros
delaestructurasedefinenconformealadeclara­
cióndadaenelEjemplo
ll.S.
cliente.saldo O;
cliente.saldo-=pagos;
cliente.ultimopago.mes=12;
printf("Nombre:%s",cliente.nombre);
if(cliente.tipo_cuenta'P')
printf("Cuentapreferentenº:%d",cliente.num_cuenta);
e1se
printf(
II
Cuentaregularn
Q
:%d
ll
Icliente.num_cuent-a)i
Laprimerainstrucciónasignaelvalorceroa cliente.saldo,mientrasquelasegundaproduceel
decrementodelvalorde
cliente.saldoporelvalorde pagos.Latercerainstrucciónhaceque
elvalor
12seaasignadoa cliente.ultimopago.mes.Observeque cliente.u1timopago.mes
esunmiembrodelaestructuraanidada cliente.ultimopago.
Lacuartainstrucciónpasaelarray cliente.nombrealafunciónprintf,mostrandoelnom­
bredelcliente.Finalmente,elúltimoejemploilustraelusodemiembrosdelaestructuradentrode
unainstruccióni f e 1 s
e.Tambiénvemosunasituaciónenqueelllliembrodelaestructura
cliente.m.lm_cuentasepasaa
,unafuncióncomoargumento.
Enalgunasdelasversionesmásantiguasdee,lasestructurasdebíanserprocesadasmiembro
pormiembro.Conestarestricción,laúnicaoperaciónper¡nisibleconlaestructuracompletaes
tomarsudirección(mássobreestomásadelante).Sinembargo,lamayoríadelasnuevasversio­
nespermitenasignarunaestructuracompletaaotrasiemprequelasestructurastenganlamisma
composición.Estacaracterísticaseincluye·enelnuevoestándarANSI.

ultimopago;
nuevocliente¡
426 PROGRAMACiÓN ENC
EJEMPLO11.13. Supongamosque anteriorclienteynuevoclientesonestructurascon
lamismacomposición;estoes,
structfecha{
intmes;
intdía;
intarrioi
};
structcuenta{
intnuro_cuenta;
chartipo_cuenta;
charnombre[ 8O];
floatsaldo;
structfecha
}anteriorcliente,
comosedeclaróenelEjemplo ll.8.Supongamosqueatodoslosmiembrosde anteriorcliente
selehanasignadovaloresindividuales.EnlamayoríadelasnuevasversionesdeCesposiblecopiar
estosvaloresa
nuevoclientesimplementeescribiendo
nuevoclienteanteriorcliente¡
Porotraparte,algunadelasantiguasversionesdeCpuedenrequerirquelosvaloresseancopiados
individualmente,miembroamiembro;porejemplo,
nuevocliente.nuro_cuenta =
nuevocliente.tipo_cuenta
=
anteriorcliente.nuffi_cuenta¡
anteriorcliente.tipo_cuenta;
nuevocliente.ultimopago.anio=anteriorcliente.ultimopago.anio;
Tambiénesposiblepasarestructurascompletasaydesdefunciones,perolafonnadehacerlo
varíadeunaversióndeeaotra.Lasversionesantiguasdeesólopennitenpasarpunteros,
mientrasqueelestándarANSIpennitepasarlasestructurascompletas.Discutiremosestoposte­
rionnenteenlasección11.5.Sinembargo,antesdetratarlarelaciónentreestructurasypunteros
ylosmétodosdepasarestructurasafunciones,consideremosun.ejemplomássencilloqueinvo­
lucreelprocesamientodemiembrosdelaestructura.
EJEMPLO11.14.Actualizaciónderegistrosdeclientes. Parailustrarmáscompletamentecómo se
procesanlosmiembrosindividualesdeunaestructura,consideremosunsistemadefacturación declien­
tesmuysimple.Enestesistemalosregistrosdeclientessealmacenanenunarraydeestructuras.Cada
registroseráalmacenadocomounaestructuraindividual(comounelementodelarray),conteniendo
elnombredelcliente,direcciónconcalle,ciudadyestado,númerodecuenta, estadodelacuenta(al
día,atrasadaodelincuente),saldoprevio,nuevosaldoyfechadepago.
Laestrategiaseráintroducircadaregistroenlacomputadora,yactualizarlotanprontocomosea
introducido,parareflejarlospagosactuales.Entoncessemostrarántodoslosregistrosactualizados,

e)saldoanterior
1)pagoactual
g)fechadepago
ESTRUCTURAS YUNIONES 427
conelestadoactualdecadacuenta.Elestadodelacuentasebasaráenelúltimopagorealizadoyel
saldopreviodelcliente.
Acontinuaciónsemuestranlasdeclaracionesdeestructuras.
structfecha{
intmesi
intdia;
intaniai
};
structcuenta{
charnombre[SO];
charcalle[SO];
charciudad[SO];
intnUffi_cuentai
inttipo_cuenta;
floatanteriorsaldo;
floatnuevosaldo;
floatpago;
structfechaultimopago;
}cliente[100];
Observeque clienteesunarrayde 100estructuras.Así,cadaelementodelarray(cadaestructura)
representaráunregistrodecliente.Cadaestructuraincluyetresmiembrosquesonarraysdecaracteres
(nombre,calleyciudad)yunmiembroqueesotraestructura (ultimopago).
Elestadodecadacuentaserádeterminadodelasiguientemanera:
l.Sielpagoactualesmayorqueceroperomenorqueeldiezporcientodelsaldopreviamenteal
descubierto,lacuentaseráatrasada.
2.Sihayunsaldoaldescubíertoyelpagoactualescero,lacuentaserádelincuente.
3.Enotrocaso,lacuentaestaráaldía.
Laestrategiaglobalserá.comosigue:
1.Especificarelnúmero decuentasdeclientes(númerodeestructuras)aprocesar.
2.Paracadacliente,leerlossiguienteselementos:
a)nombre
b)calle
e)ciudad
d)númerodecuenta
3.Cadavezqueseleeunregistroenlacomputadora,actualizarlodelasiguientemanera:
a)Compararelpagoactualconelsaldoanteriorydeterminarelestadoapropiadodelacuenta.
b)Calcularelnuevosaldorestandoelpagoactualdelsaldoanterior(unsaldonegativoindi­
caríauncrédito).
4.Unavezquetodoslosregistroshansidointroducidosyprocesados,escribirlasiguienteinfor­
maciónparacadaregistro:
a)nombre
b)númerodecuenta
e)
calle
d)ciudad

428 PROGRAMACiÓN ENC
e)saldoanterior
f)pagoactual
g)nuevosaldo
h)estadodelacuenta
Escribamosahora
elprogramadeformamodular,conunafunciónparaintroduciryactualizarcadaregis­
troyotrafunciónparamostrarlosdatosactualizados.Idealmentedeberíamospasarcadaregistrode
cliente(cadaelementodelarray)acadaunadeestasfunciones.Sinembargo,comocadaregistrode
clienteesunaestructuraytodavíanohemosdiscutidocómosepasaunaestructuraa odesdeunafunción,
definiremoselarray
deestructurascomounarrayexterno.Estonospermitiráaccederaloselementos
delarray,y alosmiembrosindividualesdela estructura,directamentedesdetodaslasfunciones.
Losmódulosindividualesdelprogramasondirectos,perosenecesitaalgúncuidadoparaleerlos
miembrosindividualesdelaestructuradentrodelacomputadora.Aquíestáelprogramacompleto.
/*actualizarunaserie
raciónsimplificado)
/ *mantenerlascuentas
tructuras* /
#include<stdio.h>
decuentasdeclientes(sistemade
*/
declientescomounarrayexterno
factu-
dees-
voidleerentrada(inti);
voidescribirsalida(inti);
struct
int
int
int
};
fecha
mes;
dia;
arrio;
{
floatanteriorsaldo;
floatnuevosaldo;
floatpago;
structfechaultimopago;
}cliente[lOO];
struct
char
char
char
int
int
main()
{
cuenta{
nombre[SO];
calle[SO];
ciudad[SO];
Duro_cuenta;
tipo_cuenta;
/*(enteropositivo)*/
/*A(Aldía),R(atrasada)o D(de-
lincuente)*/
/*(cantidadnonegativa)*/
/*(cantidadnonegativa)'*/
/*(cantidadnonegativa)*/
/ *mantenerhasta100clientes* /
inti,n'
,
printf("SISTEMA DEFACTURACION DE CLIENTES") ;
printf(Ir¿Cuantosclienteshay?")i
scanf("%d",&n);
for(i=O;i <n;++i)(
leerentrada(i);

ESTRUCTURAS YUNIONES 429
/ *determinarelestadodelacuenta* /
if(cliente[i].pago>O)
cliente[i].tipo_cuenta=
(cliente[i].pago<0.1*cliente[i].anteriorsa1do)?
'R'
else
cliente[i].tipo_cuenta=
(c1iente[i].anteriorsa1do>O)?'D''A';
/*ajustarelsaldodelacuenta*/
cliente[i].nuevosaldo=cliente[i].anteriorsaldo
-cliente[i].pago;
}
for(i=O;i <n;++i)
escribirsa1ida(i);
}
void1eerentrada(inti)
/*leerdatosdeentradayactualizarelregistroparacadacliente*/
{
printf("C1ientenº%d", i +1);
printf("Nombre:");
scanf("%[A]",cliente[i].nombre);
printf("Calle:"),
scanf("%[A]",cliente(i].calle),
printf("Ciudad:"),
scanf("%[A]",cliente[i].ciudad),
printf(" Númerodecuenta:11)i
scanf("%d",&cliente[i].num_cuenta),
printf(" Saldoanterior:"),
scanf("%f",&c1iente[i].anteriorsa1do);
printf(n Pagoactual:n)i
scanf("%f",&cliente[i].pago),
printf(" Fechadepago(rnm/dd/aaaa):");
scanf("%d/%d/%d",&c1iente[i].u1timopago.mes,
&c1iente[i].u1timopago.dia,
&cliente[i].ultimopago.anio),
return¡
}
voidescribirsalida(inti)
/ *escribirlainformaciónactualparacadacliente*/
{
printf("Nombre:%s",cliente(i].nombre),
printf(" Númerodecuenta:%d",cliente(i].num_cuenta),

430 PROGRAMACiÓN ENC
printf("Calle:%s",cliente[i].calle);
printf("Ciudad:%s", cliente[i].ciudad)
printf("Saldoanterior:%7.2f",cliente[i].anteriorsaldo);
printf("Pagoactual:%7.2f",cliente[iJ.pago);
printf("Nuevosaldo:%7.2f", cliente[i].nuevosaldo);
printf("Estadodelacuenta:");
switch(cliente[i].tipo_cuenta){
case'A':
printf("ALDIA");
break;
case'R':
printf("ATRASADA")
break;
case'D'
printf("DELINCUENTE")
break;
}
return;
}
Supongamosahoraqueelprogramaseutilizaparaprocesarcuatroregistrosdeclientesficticios.A
continuaciónsemuestralaentradainteractiva,conlasrespuestasdeusuariosubrayadas.
SISTEMA DEFACTURACION DECLIENTES
"¿Cuantosclienteshay?
.4.
Clientenº1
Nombre:SteveJohnson
Calle:123MountainviewDrive
Ciudad:Denver,CO
Númerodecuenta:42O8
Saldoanterior:247.88
Pagoactual:25.00
Fechadepago(mm/dd/aaaa)611411998
Clientenº2
Nombre:SusanRichards
Calle:4383AlligatorBlvd
Ciudad:FortLauderdale,FL
Númerodecuenta:2219
Saldoanterior:135,OO
Pagoactual:135.00
Fechadepago(mm/dd/aaaa)8110/2000
Clientenº
Nombre:
Calle:
Ciudad:
3
MartinPeterson
1787PacificParkway
SanDiego,CA

ESTRUCTURAS YUNIONES 431
Númerodecuenta:8452
Saldoanterior:387.42
Pagoactual:35.00
Fechadepago(mm/dd/aaaa)9/22/1999
Clientenº4
Nombre:PhyllisSmith
Calle:1000GreayVlhiteWay
Ciudad:NewYork,NY
Númerodecuenta:711
Saldoanterior:260.00
Pagoactual:.Q
Fechadepago(mm/dd/aaaa)11/27/2001
Elprogramagenerarálossiguientesdatosdesalida:
Nombre:
Calle:
Ciudad:
SteveJohnson
123Mountain
Denver,ca
Númerodecuenta:
Drive
4208
Saldoanterior:247.88Pagoactual:25.00 Nuevosaldo:222.88
Estadodelacuenta:ALDIA
Nombre:
Calle:
Ciudad:
SusanRichards Númerodecuenta:2219
4383AlligatorBlvd
FortLauderda1e,FL
Saldoanterior:135.00Pagoactual:135.00Nuevosaldo:0.00
Estadodelacuenta:ALDIA
Nombre:
Calle:
Ciudad:
MartinPetersanNúmerodecuenta:
1787PacificParkway
SanDiego,CA
8452
Saldoanterior:387.42Pagoactual:35.00Nuevosaldo:352.42
Estadodelacuenta:ATRASADA
Nombre:
Calle:
Ciudad:
PhyllisSmith Númerodecuenta:
1000GreatWhiteWay
NewYork,NY
711
Saldoanterior:260.00Pagoactual:0.00 Nuevosaldo:260.00
Estadodelacuenta:DELINCUENTE
Debequedarclaroqueesteejemploesirrealdesdeelpuntodevistapráctico,
pordosrazones.Pri­
mero,elarraydeestructuras
(cliente)sedefinecornoexternoparatodaslasfuncionesdelprograma.

432 PROGRAMACiÓN ENC
Seríapreferibledeclarar clientedentrode mainyentoncespasarloa odesde leerentradao
escribirsalidasegúnsenecesite.Aprenderemoscómosehaceestoenlasección11.5.
Unproblemamásserioeselhechodequeelsistema
defacturacióndeclientesrealalmacenarálos
registrosdeclientesenunarchivo
dedatosdeundispositivodememoriaauxiliar,talcomoundisco
duroounacintamagnética.Paraactualizarelregistrodeberíamosaccederalregistrodelarchivode
datos,cambiarlosdatosnecesariosyentoncesescribirelregistromodificadoenelarchivo
dedatos.
Lautilizacióndearchivos
dedatossetrataenelCapítulo 12.Comoelpresenteejemplonohaceuso
dearchivosdedatos,debemosreintroducirtodoslosregistrosdeclientescadavezqueseejecute
el
programa.Estápocologrado,peroproveeunejemplosimpleparailustrarlamaneraenque sepueden
procesarlasestructurasmiembroamiembro.
A
vecesesútileldeterminarelnúmerodebytesrequeridosporunarrayounaestructura.
Estainformaciónpuedeobtenersemedianteelusodeloperadorsiz e of,discutidooriginalmen­
teenlasección3.2.Porejemplo,eltamañodelaestructurapuedeserdeterminadoescribiendo
sizeofvaríableosizeof(structmarca).
EJEMPLO 11.15. AcontinuaciónsemuestraunprogramaelementalenC.
#include<stdio.h>
main()
{
/ *determinareltamañodeunaestructura* /
struct
int
int
int
};
fecha
mes;
dia¡
arrio;
{
structcuenta{
intnum_cuenta¡
chartipo_cuenta;
charnombre[80J;
floatsaldo;
structfechaultimopago;
}cliente;
printf("%d",sizeofcliente);
printf("%d",sizeof(structcuenta));
}
Esteprogramahaceusodeloperador siz e o fparadeterminarelnúmerodebytesasociadosconla
variabledeestructura
cliente(oequivalentementelaestructura cuenta).Lasdosinstrucciones
printfilustrandiferentesmodosdeusareloperador sizeof.Ambasinstruccionesprintf
pro­
ducenlamismasalida.
Laejecucióndelprogramagenerarálasiguientesalida:
93
93

ESTRUCTURAS YUNIONES 433
Asi,lavariabledeestructuracliente(olaestructuracuenta)ocupará93bytes. Estevalorseobtiene
comosIgue:
Miembrodelaestructura
num_cuenta
tipo_cuenta
nombre
saldo
ultimopago
Total
Númerodebytes
2
1
80
4
6
93
Algunoscompiladorespuedenasignar dosbytesa tipo_cuentaparamantener unnúmeropar de
bytes.Deahiqueeltotaldebytespuedaser94 envezde93.
11.3.TIPOSDE DATOSDEFINIDOSPORELUSUARIO
(typedef)
Lacaracterísticatypedefpermitealosusuariosdefinirnuevostiposdedatosqueseanequiva­
lentesalostiposdedatosexistentes.Unavezqueeltipodedatosdefinido
porelusuariohasido
establecido,entonceslasnuevasvariables,arrays,estructuras,etc.,puedenserdeclaradas
en
términosdeestenuevotipodedatos.
Entérminosgenerales,unnuevotipodedatossedefinecomo
typedeftiponuevo-tipo;
dondetiporefiereuntipodedatosexistente(bien untipodedatosestándarobienuntipodedatos
previamentedefinidoporelusuario)y
nuevo-tipoelnuevotipodedatosdefinidoporelusua­
rio.Sinembargo,debequedarclaroqueelnuevotiposeránuevosoloenelnombre.Enrealidad,
estenuevotipodedatosnoseráfundamentalmentediferentedelostiposdedatosestándar.
EJEMPLO 11.16. Aquitenemosunadeclaraciónsimple queinvolucraelusodetypedef.
typedefintedad;
Enestadeclaraciónedadesuntipodedatosdefinidopor elusuarioequivalente altipoint.Deaqui,
ladeclaración
devariable
edadvaran,hembra¡
esequivalenteaescribir
intvaran
lhembra;
Enotraspalabras,varanyhembraseconsideranvariables detipoedad,perosonrealmentevaria­
bles
detipoentero.

434 PROGRAMACiÓN ENC
Análogamente,lasdeclaraciones
typedef
altura
floataltura[lOO];
hombres,mujeres;
definealturacomounarrayde100elementosencomaflotante.
Portanto,
hombresymujeressonarraysde100elementosencomaflotante.Otraforma de
expresaresto es
typedef
altura
floataltura;
hombres[100]•mujeres[lOO];
sibienladeclaraciónanterioresalgomássencilla.
Lacaracterísticatypedefesparticularmenteútil cuandosedefinenestructuras, yaquese
eliminalanecesidaddeescribirrepetidamentes tructmarcacuandose referenciaunaestruc­
tura.
Comoresultado,laestructurapuedeserreferenciadamásconcisamente.Además,elnombre
dadoaltipodeestructuradefinido porelusuariosugierea menudoelpropósitodelaestructura
dentro
deunprograma.
Entérminosgenerales,eltipo deestructuradefinida porelusuariose puedeescribircomo
typedefstruct{
miembro1;
miembro2;
miembrom;
}
nuevo-tipo;
dondenuevo-tipoeseltipodeestructuradefinida porelusuario.Lasvariables deestructura
puedendefinirseentérminosdel nuevotipodedatos.
EJEMPLO 11.17. Lassiguientesdeclaracionessoncomparablesalasdeclaraciones deestructura
presentadasenelEjemplo
11.1y11.2.Sinembargo,ahoraintroducimosuntipo dedatosdefinidopor
elusuarioparadescribirlaestructura.
typedefstruct{
intnum_cuentai
chartipo_cuenta;
charnombre[8O];
floatsaldo;
}registro;
registroanteriorcliente,nuevocliente;
Laprimeradeclaracióndefine registrocomountipo dedatosdefinidoporelusuario.La
segundadecla-racióndefine
anteriorclienteynuevoclientecomovariablesdeestructura
detiporegistro.
Lacaracterísticatypedefpuedeserutilizadarepetidamenteparadefiniruntipodedatosen
términosdeotrostipos dedatosdefinidos porelusuario.

ESTRUCTURAS YUNIONES 435
EJEMPLO 11.18. Acontinuaciónsemuestranalgunasvariacionesdelasdeclaracionesdeestruc­
turaspresentadasenelEjemplo11.5.
typedefstruct{
intmes;
intdia;
intarrioi
}fecha;
typedefstruct{
intnuro_cuenta;
chartipo_cuenta;
charnombre[ 8O];
floatsaldo;
fechaultimopago;
}registro;
registrocliente[100];
{
Enesteejemplo fechayregistrosontiposdeestructurasdefinidasporelusuarioy clientees
unarrayde 100elementoscuyoselementossonestructurasdeltipo registro.(Recordarque fecha
eraunamarcaenvezdeltipodedatorealenelEjemplo 1l.5.)Losmiembrosindividualesdentrodel
i-ésimoelementode
clientepuedenserescritoscomo cliente[i].num_cuenta,
cliente[i].nombre,cliente[i].ultimopago.mes,etc.,comoantes.
Porsupuesto,hayvariacionessobreestetema.Así,unadeclaracíónalternativapuedeescribirsecomo
typedefstruct{
intmes;
intdía;
intarrio;
}fecha;
typedefstruct{
intnuro_cuenta;
chartipo_cuenta;
charnombre[8O];
floatsaldo;
fechaultimopago;
}registro[100];
registrocliente;
osímplemente
typedefstruct{
intmes;
intdía;
intarrio;
}fecha;

436 PROGRAMACiÓN ENC
struct{
intnuro_cuenta;
chartipo_cuenta;
charnombre[8O];
floatsaldo;
fechaultimopago;
}cliente[100];
Estostresconjuntos dedeclaracionessonequivalentes.
11.4.ESTRUCTURAS YPUNTEROS
Podemosaccederaladireccióndecomienzodeunaestructuradelamismamaneraquecualquier
otradirección,medianteelusodeloperadordirección
(&).Así,sivariablerepresentauntipo
devariabledeestructura,entonces
&variablerepresentaladireccióndecomienzodeesava­
riable.Además,podemosdeclararunavariablepunteroaunaestructuraescribiendo
tipo*ptvar;
dondetipoeseltipodedatosqueidentificalacomposicióndelaestructura yptvarrepresenta
elnombrede
lavariablepuntero.Podemosasignarladireccióndecomienzodelavariablede
estructuraaestepunteroescribiendo
ptvar=&variable;
EJEMPLO 11.19. Consideremoslasiguientedeclaración deestructura,queesunavariacióndela
declaraciónpresentada
enelEjemplo11.1:
typedefstruct{
intnUffi_cuenta;
chartipo_cuenta;
charnombre[8O]
;
floatsaldo;
}cuenta;
cuentacliente,*pc;
Enesteejemploclienteesunavariabledeestructuradetipocuentaypcunpunterocuyoobjeto
esunavariabledeestructuradeltipocuenta.Así,ladireccióndecomienzodeclientepuedeser
asignadaa
pcescribiendo
pc=&cliente;
Lasdeclaracionesdelavariable ydelpunteropuedencombinarsecon ladeclaraciónde la
estructuraescribiendo
struct{
miembro1;

ESTRUCTURAS YUNIONES 437
miembro2;
miembrom;
}
variable,*ptvar;
dondevariablerepresentadenuevounavariabledeltipoestructuray ptvarelnombrede
unavariablepuntero.
EJEMPLO11.20. Lasiguientedeclaraciónesequivalentealasdosdeclaracionespresentadasenel
ejemploanterior.
struet{
intnum_cuenta;
chartipo_cuenta;
eharnombre[ 8O];
floatsaldo;
}cliente,*pci
Ladireccióndecomienzode elient epuedeasignarsea peescribiendo
pe=&eliente;
comoenelejemploprevio.
Podemosaccederaunmiembroindividualdeunaestructuraentérminos desucorrespon­
dientevariablepunteroescribiendo
ptvar->miembro
dondeptvarrefiereunavariablepunteroaestructurayeloperador ->escomparablealopera­
dorpunto
(.)discutidoenlasección11.2.Así,laexpresión
ptvar->miembro
esequivalenteaescribir
variable.nombre
dondevariableesunavariabledeestructura,comosediscutióenlasección11.2.Eloperador
- >pertenecealgrupodemayorprecedencia,comoeloperadorpunto (.).Suasociatividadesde
izquierdaaderecha(verApéndiceC).
Eloperador-
>puedecombinarseconeloperadorpuntoparaaccederaunsubmiembro
dentrodeunaestructura(paraaccederaunmiembrodeunaestructuraqueesasuvezmiembro
deotraestructura).Portanto,unsubmiembropuedeseraccedidoescribiendo
ptvar->miembro.submiembro
Análogamente,eloperador- >puedeusarseparaaccederaunelementodeunarrayquees
miembrodeunaestructura.Estoserealizaescribiendo
ptvar~>miembro[expresión]
dondeexpresiónesunenterononegativoqueindicaelelementode1array.

438 PROGRAMACiÓN ENC
EJEMPLO11.21.Acontinuaciónsemuestraunavariación delasdeclaracionesmostradasenel
Ejemplo11.8.
typedefstruct{
intmes;
intdia;
intarria;
}fecha;
{
Duro_cuenta;
tipo_cuenta;
nombre[ 8O];
saldo;
ultimopago;
*pc=&cliente;
struct
int
char
char
float
fecha
}cliente,
Observequelavariablepuntero pcesinicializadaasignándoleladireccióndecomienzo delavaria­
bledeestructura
cliente.Enotraspalabras, pcapuntaráa cliente.
Siqueremosaccederalnúmerodecuentadelcliente,podremosescribircualquieradelassiguien­
tesexpreSIOnes:
cliente.num_cuenta pc->num_cuenta (*pc).num_cuenta
Enlaúltimaexpresiónsenecesitanlosparéntesisporqueeloperadorpuntotienemayorprecedencia
queeloperadorindirección
(*).Sinlosparéntesiselcompiladorgeneraráunerror,porque pc(un
puntero)noesdirectamentecompatibleconeloperadorpunto.
Análogamente,podemosacceder
alsaldodelclienteescribiendocualquiera delassiguientesexpresiones:
cliente.saldopc->saldo (*pc).saldo
yelmesdelúltimopagopuedeseraccedidoescribiendocualquieradelassiguientesexpresiones:
cliente.ultimopago.mespc->ultimopago.mes (*pc).ultimopago.mes
Finalmente,elnombredelclientepuedeseraccedidoescribiendocualquiera de
hssiguientesexpre-siones:
cliente.nombrepc->nombre (*pc).nombre
Portanto,eltercercarácterdelnombredelclientepuedeseraccedidoescribiendocualquieradelas
siguientesexpresiones(versecciónIDA):
cliente.nombre[2]
*(cliente.nombre+2)
pc->nombre[2]
pc->(nombre+2)
(*pc).nombre[2]
* ((*pc).nombre+2 )
Unaestructurapuedeincluirtambiénunoomáspunteroscomomiembros.Así,si ptmiem­
broesalavezunpuntero yunmiembrodevariable,entonces*variable .ptmiembro
accederáalvaloralcualapunta ptmiembro.Análogamente,si ptvaresunavariablepuntero
queapuntaaunaestructura
yptmiembroesunmiembro deesaestructura,entonces *ptvar
- >ptmiembroaccederáalvaloralqueapunta ptmiembro.

ESTRUCTURAS YUNIONES 439
EJEMPLO 11.22.ConsideremoselprogramasencilloenCmostradoacontinuación.
#include<stdio.h>
main()
{
intn=3333;
chart='Al;
floatb=99.99;
typedefstruct{
intmes;
intdía;
intarrio;
}fecha;
struct{
int*num_cuenta¡
char*tipo_cuenta¡
char*nombre¡
float*saldo;
fechaultimopago;
}cliente,*pc=&cliente;
cliente.nuffi_cuenta=&n¡
cliente.tipo_cuenta=&t;
cliente.nombre="Lázaroll;
cliente.saldo&b;
printf("%d%c%s%.2f",*cliente.num_cuenta,*cliente.tipo_
cuenta,cliente.nombre,*cliente.saldo);
printf("%d%c%s%.2f",*pc->num_cuenta,*pc->tipo_cuenta,
pc->nombre,*pc->saldo);
}
Dentrodelasegundaestructura,losmiembros num_cuenta,tipo_cuentaysaldoestánes­
critoscomopunteros.Así,elvaloralqueapunta
num_cuentapuedeseraccedidoescribiendo
*cliente.num_cuentao*pc->num_cuenta.Lomismoescierto paratipo_cuentay
s a 1do.Además,recordarqueunacadenadecaracterespuedeserdirectamenteasignadaaunpuntero
acarácter.Portanto,si
nombreapuntaalprincipiode lacadena,entoncessepuedeaccederalacade­
naescribiendocliente.nombreopc->nombre.
Laejecucióndeesteprogramageneralasdossiguienteslíneasdesalida:
3333ALázaro99.99
3333ALázaro99.99
Comoeradeesperar,lasdoslíneas·desalidasonidénticas.

440 PROGRAMACiÓN ENC
Comoeloperador- >esmiembrodelgrupodemayorprioridad,tendrálamismaprioridad
queeloperadorpunto
(.),conasociatividaddeizquierdaaderecha.Además,esteoperador,
comoeloperador punto,tendráprioridadsobrelosoperadoresunarios,aritméticos,relacionales,
lógicosodeasignaciónquepuedenaparecer
enunaexpresión.Yahemosdiscutidoesto,cómose
aplicaeloperadorpunto,enlasección
11.2.Sinembargo,sedebenhacerciertasconsideraciones
conalgunosoperadoresunarios,talescomo++,cuandoseaplicanavariablespunteroaestructura.
Yasabemosqueexpresionescomo
++ptvar->miembroy++ptvar->miembro.sub­
miembrosonequivalentesa++ (ptvar->miembro)y++(ptvar->miembro.submiem­
bro),respectivamente.Así,talesexpresionesproduciránunincrementodelvalordelmiembroo
delsubmiembro,comosediscutió
enlasección11.2.Porotraparte,laexpresión ++ptvar
produciráelincrementodelvalorde ptvarenelnúmerodebytesasociadoconlaestructuraa la
cualapunta ptvar.(Elnúmerodebytesasociadoconunaestructuraparticularpuededetermi­
narsemedianteelusodeloperador
sizeof,comoseilustró enelEjemplo11.15.)Portanto,la
direcciónrepresentada
porptvarcambiarácomoresultadodeestaexpresión.Análogamente,la
expresión
(++ptvar).miembroharáqueelvalorde ptvarseaincrementadoenesenúmero
antesdeaccedera
miembro.Hayalgúnpeligroenrealizaroperacionescomoéstaporque ptvar
esposibleque yanoapunteaunavariabledeestructura,yaque suvalorhasidomodificado.
EJEMPLO11.23. Acontinuaciónsemuestraunavariación delsencilloprograma enemostradoen
elEjemplo11.15.
#include<stdio.h>
main()
{
typedefstruct{
intmes;
intdia;
intarrio;
}fecha;
struct{
intDuro_cuenta;
chartipo_cuenta;
charnombre[SO];
floatsaldo;
fechaultimopago;
}cliente,*pt
;&cliente;
}
printf("Númerode
printf("Númerode
printf("Dirección
printf("Dirección
bytes(dec):
bytes(hex):
decomienzo
incrementada
%d",sizeof*pt);
%x", sizeof*pt);
(hex):%x",pt);
(hex):%x",++pt);
Observequeptesunavariablepuntero cuyoobjetoeslavariabledeestructuracliente.
Laprimerainstrucciónprintfmuestraelnúmerodebytesasociadosaclienterepresentadocomo
unacantidaddecimal. Lasegundainstrucciónpr int fmuestraeste mismovalorcomounacantidaden

ESTRUCTURAS YUNIONES 441
hexadecimal.Latercerainstrucción printfmuestraelvalordept(direccióndecomienzodecliente)
enhexadecimal,mientras quelacuartainstrucciónp r i n t fmuestra loqueocurrecuandoseincrementap t.
Laejecucióndelprogramaproducelasiguientesalida:
Númerodebytes(dec):93
Númerodebytes(hex):5d
Direccióndecomienzo(hex):f72
Direcciónincrementada(hex):fcf
Asivemosque clientenecesita93bytesendecimal,quees 5denhexadecimal.Elvalorinicial
asignadoa
pt(ladireccióndecomienzode cliente)esf72enhexadecimal.Cuandoseincremen­
tap
t,suvaloraumentaen5dbytes enhexadecimal,hastaf c f .
Esinteresantemodificaresteprogramareemplazandoelarraydecaracteres
nombre[8O]porel
punteroacarácter
*nombreyejecutarelprograma.¿Quépiensaustedquepasará?
11.5.PASODEESTRUCTURAS AUNAFUNCIÓN
Hayvariasmaneras depasarinformacióndeunaestructuraa odesdeunafunción.Sepueden
transferirlosmiembrosindividuales,olasestructurascompletas.Elmecanismopararealizarlas
transferenciasvaría,dependiendodeltipodetransferencia(miembrosindividualesoestructuras
completas)ylaversiónparticularde
C.
Losmiembrosindividualesdeunaestructurasepuedenpasaraunafuncióncomoargumentos
enlallamadaalafunción,yunmiembrodeunaestructurapuedeserdevueltomediantela
instrucción
return.Parahaceresto,cadamiembrodelaestructurasetratacomounavariable
ordinariaunievaluada.
EJEMPLO11.24. Acontinuaciónsemuestraelesquemadelaestructuradeunprogramaen C.Este
esquemahaceusodelasdeclaracionesdeestructuraspresentadasanteriormente.
floatajustar(char
main()
{
nombre[],intnum_cuenta,
! *prototipode
floatsaldo);
función*!
typedefstruct{
intmesi
intdia¡
intarriai
}fecha;
struct{
intnum_cuenta¡
chartipo_cuenta;
charnombre[80];
floatsaldo;
fechaultimopago;
}cliente;
! *declaracióndeestructura*!
! *declaracióndeestructura*!

442 PROGRAMACiÓN ENC
cliente.saldo=ajustar(cliente.nombre,cliente.num_cuenta,
cliente.saldo);
}
floatajustar(charnombre[],intnum_cuenta,floatsaldo)
{
}
floatnuevosaldo;
nuevosaldo=
return(nuevosaldo);
/*declaracióndevariablelocal*/
/*ajustarelvalordesaldo*/
Esteesquema deprogramailustralamanera decómopuedenpasarse losmiembrosdeunaestructuraa
unafunción.
Enparticular,cliente.nombre,cliente.num_cuentaycliente_saldoson
pasadosalafunción ajustar.Dentrodeajustar,elvalorasignadoa nuevosaldopresumible­
mentehace
usodelainformaciónpasadaalafunción.Entoncesestevalor esdevueltoa main,donde
esasignadoalmiembrodelaestructuracliente.saldo.
Observeladeclaración delafuncióndentro demain.Estadeclaraciónsepodríahaberescritosin
losnombres
delosargumentos,comosigue:
floatajustar(char[],int,
float');
Algunosprogramadoresprefierenestaforma,ya queevitalaespecificación denombresdeargumentos
ficticiosparadatos
queenrealidadsonmiembros deestructura.Sinembargo,seguiremosutilizando
prototiposcompletos
defunciónparatenerventajaenlacomprobación deerrores.
Unaestructuracompletasepuedetransferiraunafunciónpasando
unpunteroalaestructura
como
unargumento.Enprincipio,estoessimilaralprocedimientousado paratransferirunarray
a
unafunción.Sinembargo,debemosusarunanotacióndepunterosexplícitapararepresentar
quesepasaunaestructuracomo
unargumento.
Debequedarclaroqueunaestructurapasadadeestamaneraserápasada
porreferenciaenvez
de
porvalor.Portanto,sicualquieradelosmiembrosdelaestructuraesmodificadodentrodela
función,lasmodificacionesseránreconocidasfueradelafunción.
Denuevovemosunaanalogía
directaconlatransferenciadearraysafunciones.
.
EJEMPLO11.25. Consideremoselprogramasencillo enCmostradoacontinuación.
#include<stdio.h>
typedefstruct{
char*nombre¡
intnUffi_cuenta¡

ESTRUCTURAS YUNIONES 443
chartipo_cuenta;
floatsaldo;
}registro;
voidajustar(registro*pt); /*prototipodefunción*/
main()
{
/ *transferirunpunteroaestructuraaunafunción* /
staticregistrocliente=("Lázaro",3333,'A',33.33);
printf("%s%d%c%.2f",cliente.nombre,cliente.num_cuenta,
cliente.tipo_cuenta,cliente.saldo);
ajustar(&cliente);
printf("%s%d%c%.2f",
}
voidajustar(registro*pt)
{
pt->nombre =IIJosé
ll
;
pt->num_cuenta=9999;
pt->tipo_cuenta 'R';
pt->saldo=99.99;
return¡
}
cliente.nombre,cliente.num_cuenta,
cliente.tipo_cuenta,cliente.saldo);
/ *
definicióndefunción* /
Esteprogramailustralatransferenciadeunaestructuraaunafunciónpasandoladireccióndelaestruc­
tura(unpuntero)alafunción.Enparticular,
clienteesunaestructuradeltipo registro,cuyos
miembrostienenasignadosunconjuntodevalores.Estosvaloresinicialessemuestrancuandoelpro­
gramaempiezaaejecutarse.Acontinuaciónsepasaladireccióndelaestructuraalafunción
ajus­
tar,dondeseleasignanvaloresdiferentesalosmiembrosdelaestructura.
Dentrode
ajustar,observeladeclaracióndeargumentoformalquedefinea ptcomounpun­
teroaunaestructuradeltipo
registro.Observetambiénlainstrucciónvacía return;nosede­
vuelvenadaexplícitamentedesde
ajustarhastamain.
Dentrode mainvemosquelosvaloresactualesdelosmiembrosde clientesonmostradosde
nuevodespuésdeaccedera
ajustar.Asíelprogramailustrasiloscambiosrealizadosen ajustar
repercutenonoenlapartedelprogramaquehizolallamada.
Laejecucióndelprogramaproducelasiguientesalida:
Lázaro3333A33.33
José9999R99.99
Observequelosvaloresasignadosalosmiembrosde clientedentrode ajustarsonreconocidos
dentrode
main,comoseesperaba.
Unpunteroaunaestructurapuedeserdevueltodesdeunafunciónalapartedelprogramaque
hizolallamada.Estacaracterísticapuedeserútilcuandosepasenvariasestructurasaunafunción
ysólounadeellasesdevuelta.

444 PROGRAMACiÓN ENC
EJEMPLO11.26.Localizaciónderegistrosdeclientes. Aquitenemosunprogramaqueilustra
cómosepasaunarraydeestructurasaunafunciónycómosedevuelveunpunteroaunaestructura
particular.
Supóngasequeespecificamosunnúmerodecuentaparaunclienteparticular,y acontinuación
localizamosymostramoselregistrocompletoparaesecliente.Cadaregistrodeclienteestarámante­
nidoenunaestructuracomoenelúltimoejemplo.Sinembargo,ahoraelconjuntocompletoderegis­
trosestaráalmacenadoenunarrayllamadoc 1 i
ente.Observequecadaelementodelarrayseráuna
estructuraindependiente.
Laestrategiabásicaseráintroducirunnúmerodecuentaytransferirloconelarray
deregistrosala
funciónllamada
buscar.Dentrode buscar,elnúmerodecuentaserácomparadocon elnúmerode
cuentaalmacenadodentrodecadaregistro,hastaqueseproduzcaunacoincidenciaohastaquese
hayabuscadoentodalalistaderegistros.Siseproduceunacoincidencia,sedevuelvea
mainun
punteroaeseelementodelarray(laestructuraquecontiene elregistrodelclientedeseado)yson
mostradosloscontenidosdelregistro.
Sinoseproduceunacoincidenciadespuésdelabúsquedaentodoelarray,entonceslafunción
devuelveelvalor
NULL(cero)a main.Elprogramamuestraentoncesunmensajedeerrorpidiendoal
usuarioquereintroduzcaelnúmerodecuenta.Estabúsquedacontinuaráhastaqueseintroduzcael
valorcerocomonúmerodecuenta.
Acontinuaciónsemuestraelprogramacompleto.Dentrodeesteprograma,c 1 i
ent eesunarray
deestructurasdeltipo
registroyptunpunteroaestructurasdeestemismotipo.Lafunción bus­
caraceptadosargumentosydevuelveunpunteroaunaestructuradeltipo registro.Losargu­
mentossonunarraydeestructurasdeltipo
registroyuna cantidadenterarespectivamente.Dentro
de
buscar,lacantidaddevueltaesobienladireccióndeunelementodelarrayobien NULL(cero).
/ *
encontrarunregistrodeclientequecorrespondaaunnúmerode
cuentaespecificado* /
#includecstdio.h>
#defineN 3
#defineNULLO
typedefstruct{
char*nombre;
intnum_cuenta;
chartipo_cuenta;
floatsaldo;
}registro;
registro*buscar(registrotabla[],intncuenta);/ *prototipode
función* /
main()
{
staticregistrocliente[N]= {
{TILázaro",3333,lA"33.33}I
{IlJosé
ll
,6666,'R'f66.66},
("Rafael",9999,'D',99.99)
}; /*arraydeestructuras*/

ESTRUCTURAS YUNIONES 445
intncuenta;
registro*pt;
/*declaracióndevariable*/
/ *declaracióndepuntero* /
printf("Localizadordecuentadecliente");
printf("ParaFIN,introducirOparaelnúmerodecuenta");
printf("CuentanQ:" ) ; /*introducirprimernúmerodecuenta*/
scanf(ll%d",&ncuenta);
while
pt
(ncuenta!=O) {
=buscar(cliente,ncuenta)i
if(pt!=NULL)( / * seencontróunacoincidencia* /
printf("Nombre:%s",pt->nombre);
printf("Cuentan
Q
:
%d",pt->num_cuenta);
printf("Tipodecuenta:%c",pt->tipo_cuenta);
printf("Saldo:%.2f",pt->saldo);
}
else
printf("ERROR Porfavorpruebedenuevo") ;
printf(lICuentanº:11); / *introducirsiguiente
númerodecuenta*/
scanf(n%d
11,&ncuenta);
}
}
registro*buscar(registrotabla[N],intncuenta)/*definición
defunción*/
/ *aceptaunarraydeestructurasyunnúmerodecuenta,devuelve
unpunteroaunaestructuraparticular(unelementodelarray)
sielnúmerodecuentacoincideconunelementodelarray* /
{
intcont¡
ncuenta)/*encontrada
una
coinci-:­
dencia* /
return(&tabla[cont]);/*devuelveunpunteroalele­
mentodelarray* /
=O;cont<N;++cont)
(tabla[cont].num_cuenta
(cont
if
for
return(NULL)
}
Eltamañodelarrayseexpresaentérminosdelaconstantesimbólica N.Paraesteejemplohemos
escogidoelvalor
deN
=3.Estoes,estamosalmacenandosólotresregistrosdemuestraenelarray.
Enunejemplomásreal,Ndeberíatenerunvalormuchomásgrande.
Finalmentedebemencionarsequehaymuchasmanerasmejoresdebuscarenunconjuntoderegis­
trosqueirexaminandocada
registrodemodosecuencial.Sehaelegidoesteprocedimientosimple,
aunqueineficiente,paraconcentrarnosenelmecanismodetransferenciadeestructurasentre
mainy
lafunciónsubordinada
buscar.

446 PROGRAMACiÓN ENC
Acontinuaciónsemuestraundiálogotipicoquepuedeproducirseporlaejecucióndelprograma.
Lasrespuestasdelusuarioestánsubrayadas,comosiempre.
Localizadordecuentadecliente
ParaFIN,introducirOparaelnúmerodecuenta
Cuenta
n":3333
Nombre:Lázaro
Cuentan":3333
Tipodecuenta:A
Saldo:33.33
Cuentan":9999
Nombre:Rafael
Cuentan":9999
Tipodecuenta:D
Saldo:99.99
Cuentan
Q
:
666
ERROR- Porfavorpruebedenuevo
Cuenta
n":6666
Nombre:José
Cuentan
Q
:
6666
Tipodecuenta:R
Saldo:66.66
Cuenta
n
Q
:
Q
Lamayoríadelasnuevasversiones deCpermitenqueunaestructuracompletaseatransferida
directamenteaunafuncióncomounargumentoydevueltadirectamentemediantelainstrucción
return.(Observeelcontrasteconlosarrays,quenopuedenserdevueltosmediantelainstruc­
ción
return.)Estascaracterísticasestánincluidas enelnuevoestándarANSI.
Cuandosepasaunaestructuradirectamenteaunafunción,latransferenciaesporvalory
no
porreferencia. Estoesconsistenteconlasotrastransferenciasdirectas(sinpunteros)en C.Por
tanto,sicualquieradelosmiembros
delaestructuraesmodificadodentrodelafunción,las
modificacionesnoseránreconocidasfueradelafunción.Sinembargo,silaestructuramodificada
esdevueltaalapartellamadoradelprograma,entoncesloscambiosseránreconocidosdentro
deesteámbitomayor.
EJEMPLO11.27.EnelEjemplo11.25vimosunprogramaquetransferíaunpilnteroaestructuraa
unafunción.Dosinstrucciones
printfdistintasilustrabanquelatransferenciadeestetipoerapor
referencia,estoes,lasmodificacioneshechasalaestructuradentro
delafunciónsonreconocidasden­
trode
main.Unprogramasimilarsemuestraacontinuación.Sinembargo,elprogramaactualtransfie­
reunaestructuracompletaalafunciónenvezdeunpunteroaestructura.

ESTRUCTURAS YUNIONES 447
#include<stdio.h>
typedefstruct{
char*nombre;
intnUID_cuenta;
chartipo_cuenta;
floatsaldo;
}registro;
voidajustar(registrocliente); / *prototipodefunción* /
main()
{
/ *transferirunaestructuraaunafunción* /
staticregistrocliente;;:{IILázaro",3333,'A',33.33}¡
printf("%s%d%c%.2f",cliente.nombre,cliente.num_cuenta,
cliente.tipo_cuenta,cliente.saldo);
ajustar(cliente);
printf("%s%d%c%.2f",
}
voidajustar(registroclien)
{
clien.nombre ;;:"JoséH;
clien.num_cuenta=9999;
clien.tipo_cuenta;;:'R
/
;
clien.saldo=99.99;
return;
}
cliente.nombre,cliente.num_cuenta,
cliente.tipo_cuenta,cliente.saldo);
/ *definicióndefunción*/
Observequelafunción ajustarahoraaceptaunaestructuradeltipo registroenvezdeunpun­
teroaesetipodeestructura,comoenelEjemplo11.25.Enningunodelosprogramassedevuelvenada
desde
ajustaramain.
Cuandoseejecutaelprograma,seobtiene lasiguientesalida:
Lázaro3333A33.33
Lázaro3333A33.33
Portanto,lasnuevasasignacioneshechasdentrode ajustarnosonreconocidasdentrode main.
Estoesloesperado, yaquelatransferenciade laestructuraclienteaajustaresporvaloryno
porreferencia.(CompararconlasalidamostradaenelEjemplo11.25.)
Supongamosahoraquemodificamoselprogramademodoque
laestructuramodificadaseade­
vueltadesde.
ajustaramain.Aquítenemoselprogramamodificado.
#include<stdio.h>
typedefstruct{
chal:'*nombre¡
intnum_cuenta;

448 PROGRAMACiÓN ENC
chartipo_cuenta;
floatsaldo;
}registro;
registroajustar(registrocliente);/ *prototipodefunción* /
main()
{
/*transferirunaestructuraaunafunciónydevolver
laestructura*/
staticregistrocliente:::{"Lázaro
ll
/3333/'A',33.33};
)
printf("%s
cliente=
printf(11%8
%d%c%.2f",cliente.nombre,cliente.num_cuenta,
cliente.tipo_cuenta,cliente.saldo);
ajustar(cliente);
%d%c%.2f",cliente.nombre,cliente.num_cuenta,
cliente.tipo_cuenta,cliente.saldo);
registroajustar(registroclien)/*definicióndefunción* /
(
clien.nombre :::"José
ll
i
clien.num_cuenta=9999;
clien.tipo_cuenta=IR';
clien.saldo=99.99;
return(clien);
}
Observeque ajustardevuelveahoraunaestructuradeltipo registroamain.Lainstrucción
returnsemodificaadecuadamente.
Laejecucióndeesteprogramaproducelasiguientesalida:
Lázaro3333A33.33
José9999R99.99
Así,lasmodificacioneshechasdentrode ajustarsonreconocidasdentrode main.Estoeraloespe­
rado,yaquelaestructuramodificadasedevuelvealapartellamadoradelprograma.(Compararconla
salidamostradaenelEjemplo11.25asícomolamostradaanteriormenteenesteejemplo.)
Lamayoríadelasversionesde
Gpermitenqueestructurasdedatoscomplejasseantransferi­
daslibrementeentrefunciones.
Sehanvistoejemplosqueinvolucranlatransferenciademiem­
brosindividualesdeunaestructura,estructurascompletas,punterosaestructuras
yarraysde
estructuras.Sinembargo,debidoaunproblemapráctico,hayalgunaslimitacionessobre
lacom­
plejidaddelosdatosquepuedenserfácilmentetransferidosa odesdeunafunción.Enparticular,
algunoscompiladorespuedentenerdificultadesalejecutarprogramasqueinvolucrantransferen­
ciasdeestructurasdedatoscomplejas,debidoaciertasrestriccionesdememoria.Elprograma­
dornoexperimentadodebesaberqueexistenestaslimitaciones,perolos.detallesdeestetema
estánfueradelámbito
deestetexto.

ESTRUCTURAS YUNIONES 449
EJEMPLO11.28.Actualizaciónderegistrosdeclientes. ElEjemplo11.14presentóunsistema
sencillo
defacturacióndeclientesilustrandolautilización deestructurasparamanteneryactualizar
registros
declientes.Endichoejemplolosregistrosdeclientessealmacenaban enunarrayglobal
(externo)
deestructuras.Consideremosahoradosvariacionesdeesteprograma.Encadanuevoprogra­
maelarraydeestructurasesmantenidolocalmente,dentrode main.Loselementosindividualesdel
array(registrosindividualesdeclientes)sontransferidosa odesdefuncionessegúnserequiera.
En
elprimerprogramalasestructurascompletassontransferidas entrelasfunciones.Enparticular,la
función
leerentradapermiteintroducirenlacomputadoralainformaciónquedefineacadaregistro
decliente.Cuandounregistroenterohasidointroducido,sucorrespondienteestructuraesdevueltaa
main,dondeesalmacenadaenelarray de100elementosllamado clienteyajustadosutipo decuen­
ta.Después
dequetodoslosregistroshayansidointroducidosyajustados, setransfierendemodoindi­
vidualalafunción
escribirsalida,dondesemuestraciertainformación decadacliente.
Acontinuaciónsemuestraelprogramacompleto.
/*actualizarunaserie
raciónsimplificado)
#include<stdio.h>
decuentasdeclientes
*/
(sistemadefactu-
/*mantenerlascuentasdeclientes
transferirestructurascompletas
typedefstruct{
intmes¡
intdia¡
intanio;
}fecha;
comounarraydeestructuras,
a ydesdelasfunciones* /
typedefstruct{
charnombre[ SO]
charcalle[SO];
charciudad[ SO];
intnum_cuenta; /*(enteropositivo)*/
inttipo_cuenta; /*A(Aldía),R(atrasada)o D(delin-
cuente)*/
floatanteriorsaldo;/*(cantidadnonegativa)*/
floatnuevosaldo;/*(cantidadnonegativa)*/
floatpago; /*(cantidadnonegativa)*/
fechaultimopago;
}registro;
registroleerentrada(inti);
voidescribirsalida(registro
main()
/ *prototipodefunción* /
cliente);)·prototipodefunción*/
/ *leercuentasdeclientes,procesarcadacuentaypresentarla
salida* /

450 PROGRAMACiÓN ENC
(
inti,n;
registrocliente[lOO],
/ *declaraciónde
/ *declaraciónde
tructuras)*/
variables* /
array(arraydees-
printf("SISTEMA DEFACTURACION DE CLIENTES");
printf("¿Cuantosclienteshay?"),
scanf(lI%dll/&n);
for(i=O;i<ni
cliente[i]=
++i)(
leerentrada(i),
/ *determinarelestadodelacuenta* /
if(cliente[i].pago>O)
cliente[i].tipo_cuenta=
(cliente[i].pago<0.1*cliente[i].anteriorsaldo)?'R'
, A' i
else
cliente[i].tipo_cuenta=
(cliente[i].anteriorsaldo>O)?'D''A',
/*ajustarelsaldodelacuenta*/
}
cliente[i].nuevosaldo=cliente[i].anteriorsaldo
cliente[i].pago;
}
for(i=O;i <n,++i)
escribirsalida(cliente[i]);
registroleerentrada(inti)
/ *leerdatosdeentradaparauncliente* /
{
registrocliente,
printf("Clientenº%d", i+1),
printf(11 Nombre:It);
scanf("%[A]",cliente.nombre);
printf("Calle:");
scanf("%[A]",cliente.calle),
printf("Ciudad:");
scanf("%[A]",cliente.ciudad),
printf(" Númerodecuenta:");
scanf("%d", &cliente.num_cuenta);
printf(" Saldoanterior:");
scanf("%f",&cliente.anteriorsaldo);

ESTRUCTURAS YUNIONES 451
printf( " Pagoactual:");
scanf("%f",&cliente.pago);
print f ( "Fechadepago(mm/dd/aaaa)" ) ;
scanf("%d/%d/%d",&cliente.ultimopago.mes,
&cliente.ultimopago.dia,
&cliente.ultimopago.anio);
return(cliente)
}
voidescribirsalida(registrocliente)
/ *escribirlainformaciónactualparauncliente* /
(
printf(!lNombre: %SH,cliente.nombre);
printf(" Númerodecuenta:%d",cliente.num_cuenta);
printf("Calle:%s",cliente.calle);
printf("Ciudad:%s", cliente.ciudad);
printf("Saldoanterior:%7.2f",cliente.anteriorsaldo);
printf(" Pagoactual:%7.2f",cliente.pago);
printf("Nuevosaldo:%7.2f", cliente.nuevosaldo);
printf("Estadodelacuenta:");
switch(cliente.tipo_cuenta){
casefA':
printf("ALDIA");
break;
case'R'
printf("ATRASADA");
break;
case'D':
printf("DELINCUENTE")
break;
}
return;
}
Elsiguienteprogramaessimilaralanterior.Sin embargo,ahoralatransferenciainvolucrapunteros
aestructurasenvezdeestructuras.Asílasestructurassetransfierenahoraporreferencia,mientrasque
enelprogramaanteriorloeranporvalor.
Porbrevedad,sólosemuestraelesquemadelprogramaenvezdellistadocompleto.Losbloques
quefaltansonidénticosalaspartescorrespondientesdelprogramaanterior.
/*actualizarunaserie
raciónsimplificado)
#include<stdio.h>
decuentasdeclientes
*/
(sistemadefactu-
/ *mantenerlascuentasdeclientescomounarraydeestructuras,
transferirpunterosaestructurasaydesdelasfunciones* /

452 PROGRAMACiÓN ENC
/ *(definicionesdeestructuras)* /
registro*leerentrada(inti);
voidescribirsalida(registro
main()
/ *prototipode
*cliente);/*prototipode
función* /
función* /
/ *
leercuentasdeclientes,procesarcadacuentaypresentarla
salida* /
{
inti,n;
registrocliente[lOO);
/ *declaracióndevariables* /
/*declaracióndearray(arraydees­
tructuras)* /
for(i
~O;i
cliente[i]
<n;++i){
*leerentrada(i);
}
/ *determinarelestadodelacuenta* /
/*ajustarelsaldodelacuenta*/
}
for(i~O;i <n;++i)
escribirsalida(&cliente[i));
registro*leerentrada(inti)
/*leerdatosdeentradaparauncliente*/
{
registrocliente;
/ *introducirdatos* /
return(&cliente);
}
voidescribirsalida(registro*pt)
/ *escribirlainformaciónactualparaun.cliente* /
{
registrocliente;
cliente~*pt;
/ *mostrarlosdatosdesalida* /
return;
}

ESTRUCTURAS YUNIONES 453
Ambosprogramas secomportandelamismamanera queelprogramadadoenelEjemplo11.14
cuando
seejecutan.Sinembargo,debidoalacomplejidad delasestructurasdedatos(elarraydeestruc­
turas,
dondecadaestructuracontienea suvezarraysyestructuras),losprogramascompiladospueden
noserejecutablesconciertoscompiladores.Enparticular,unacondición dedesbordamientodepila
(untipo
decondicióndememoriainadecuada)puedeserexperimentadaconciertoscompiladores.
Esteproblema
noexistiríasielprogramafuera másreal,estoes,silosregistrosdeclientesestuvie­
ranalmacenadosdentro
deunarchivoenundispositivodememoriaauxiliar, envezdeenunarrayque
sealmacenaenlamemoriadelacomputadora.Discutiremosesteproblema enelCapítulo12,donde
consideraremos
elusodearchivosdedatosparaunasituacióncomoésta.
11.6.ESTRUCTURAS AUTORREFERENCIADORAS
Avecesesdeseableincluirdentrodeunaestructuraunmiembroqueseaunpunteroaestetipode
estructura.Entérminosgeneralesestopuedeserexpresadocomo
structmarca{
miembro
1;
miembro2;
structmarca*nombre;
};
dondenombrerefiereelnombrede lavariablepuntero.Así, laestructuradeltipo marca
contendráunmiembroqueapuntaaotraestructuradeltipo marca.Talesestructurassoncono­
cidascomoestructuras
autorreferenciadoras.
EJEMPLO11.29. UnprogramaenCcontienelasiguientedeclaración deestructura:
struct
};
listaelementos {
charelem[40];
structlistaelementos*sig;
Éstaesunaestructuradeltipolista_elementos.Laestructuracontiene dosmiembros:unarrayde
4Ocaracteres,llamadoelem,yunpunteroaotraestructura delmismotipo(unpunteroaotraestructura
deltipolista_elementos)llamadosigoPortanto,setratadeunaestructuraautorreferenciadora.
Lasestructurasautorreferenciadoras
S011muyútilesenaplicacionesqueinvolucrenestructu­
rasdedatosenlazadas,talescomolistasyárboles.Veremosunejemplocompletoqueilustrael
procesamientodeunalistaenlazada
enelEjemplo11.32.Sinembargo,presentamosprimero un
breveresumendeestructuras dedatosenlazadas.
Laideabásicade.unaestructuradedatosenlazadaesquecadacomponente
.dentrodela
estructuraincluye unpunteroindicandodóndeestáelsiguientecomponente.Por.tanto,elorden
relativo
de
los.componentespuede serfácilillentecambiado;simplementemodificandolospunteros.
Además,loscomponentesindividualespuedenserfácilmenteañadidosoborrados,simplemente
modificandolospunteros.Comoresultado,unaestructuradedatosenlazadanoseconfinaa
un
nÚllier()máximodecomponentes.Deestaforma,
laestru>:turadedatospuedeexpandirocontraer
sutamañosegúnsenecesite.

454 PROGRAMACiÓN ENC
EJEMPLO11.30. LaFigura11.3(a)muestraunalistaenlazadacontrescomponentes.Cadacompo­
nenteconstadedoselementos:unacadenadecaracteresyunpunteroquereferenciaelsiguientecom­
ponentedentro
delalista.Asi,elprimercomponentecontienelacadena rojo,elsegundocontiene
verdeyelterceroazul.Elprincipiodelalistaesindicado porunpunteroseparado,etiquetado
como
comienzo.Tambiénelfinaldelalistaestámarcado porunpunteroespecial llamado NULL.
Comienzo
~I rojo~~~I verdeI~i-----...I azul8
a)
Añadamosahoraotrocomponente,cuyovalores blanco,entrerojo yverde.Parahaceresto
simplementecambiamoslospunteros,comoseilustraenleFigura
11.3(b).Análogamente,sielegimos
borrar
elelementocuyovalores verde,sencillamentecambiamoselpunteroasociadocon elsegun­
docomponente,comosemuestraenlaFigura11.3(c).
b)
Comienzo
verde
[!J
e)
Figura11,3.
Hayvariostiposdistintosdeestructurasdedatosenlazadas,incluyendolistaslineales,enlas
queloscomponentesestántodosenlazadosdeunmodosecuencial;listasenlazadas conmúltiples
punteros,
quepermitenrecorrerlalistahaciadelanteohaciaatrás;listasenlazadascirculares,
quenotienenniprincipionifin,yárboles,
enloscualesloscomponentesseordenanjerárquica­
mente.YahemosvistounailustracióndeunalistalinealenlazadaenelEjemplo11.30.Otros
tiposdelistasenlazadasseilustranenelsiguienteejemplo.'
EJEMPLO11.31. En'laFigurallAvernosunalistalinealenlazadasimihiralamOstradaenlaFi­
gura11.3(a).Sinembargo,ahorahay dospunterosasociadosconcadacomponente::unpunteroalsi-

ESTRUCTURAS YUNIONES 455
guienteyunpunteroalanterior.Estedobleconjuntodepunterospermiterecorrerlalistaencualquier
dirección,
deprincipioafin,o delfin alprincipio.
Comienzo
rojo
Figura11.4.
Fin
ConsideremosahoralalistamostradaenlaFigura11.5.Estalistaessimilaralamostradaenla Fi­
gura11.3(a),exceptoqueelúltimoelemento (azul)apuntaalprimerelemento (rojo).Portantoesta
listanotieneprincipionifin.Taleslistassondenominadas
listascirculares.
~Iverde[!jf---.......Im'~
blanco
Figura11.5.
Finalmente,enlaFigura 11.6(a)seveunejemplode un árbol.Losárbolessecomponen denodos
yramas,dispuestos
dealgúnmodojerárquico,queindicalacorrespondienteestructurajerárquicadentro
delosdatos.(Un
árbol
bir¡arioesunárbolenelcualcadanodonotienemás dedosramas.)
EnlaFigura11.6(a)elnodoraíz tieneelvalor pantallaylasramasasociadasconducenalos
nodoscuyosvaloresson
primerplanoyfondo,respectivamente.Análogamente,lasramasaso­
ciadascon
primerplanoconducenalosnodoscuyosvaloresson blanco,verdeyámbar,ylas
ramasasociadascon
fondoconducenalosnodoscuyosvaloresson negro,.azulyblanco.
LaFigura11.6(b)ilustralamaneradecómoseusanlospunterosparaconstruirelárbol.
pantalla
Figura11.6. a)

456 PROGRAMACiÓN ENC
IblancoB
Pantalla
IámbarB InegroB
verdeNULL
Figura11.6.b)
Lasestructurasautorreferenciadorassonidealmenteconvenientesparaaplicacionesque invo­
lucrenestructurasdedatosenlazadas.Cadaestructurarepresentaráuncomponentesimple(un
nodo)dentrode laestructuradedatosenlazada.Elpunteroautorreferenciadorindicarálalocali­
zacióndelsiguientecomponente.
EJEMPLO11.32.Procesamieutodeunalistaenlazada.Presentamosahoraunprogramainterac­
tivoquepermitecrearunalistalinealenlazada,añadirnuevoselementosalalistaoborrarelementos
delalistaenlazada.Cadacomponenteconsistiráenunacadenadecaracteres
yunpunteroalsiguiente
componente.Elprogramafuncionarádirigidopormenúsparafacilitarsuusoalosnoprogramadores.
Incluiremoslaposibilidaddemostrarlalistadespuésdelaselección
'decualquierelementodelmenú
(despuésdecualquiercambiohechoalalista).
Esteprogramaesalgomáscomplejoquelosprogramasdeejemplosprecedentes.
Seutilizala
recursividad(versección7.6) ylagestióndinámicadememoria (versección10.5 yEjemplos10.15,
10.22,10.24Y10.26).
Acontinuaciónsemuestraelprogramacompleto.Despuésdellistadodelprogramasediscutecon
detallecadafunciónindividual.
/ *programaguiadopormenúsparaprocesarunalistaenlazadade
cadenasdecaracteres* /
#include
#include
#include
<stdio.h>
<stdlib.h>
<string.h>
#defineNULLO
structlistaelementos{
charelem[40];
structlistaelementos*sig;
};
/*datodeestenodo*/
/*punteroalsiguientenodo*/

ESTRUCTURAS YUNIONES 457
typedefstructlista_elementosnodo;/ *declaracióndetipodees­
tructura* /
intmenu(void);
voidcrear(nodo*pt);
nodo*insertar(nodo*pt);
nodo*eliminar(nodo*pt);
voidmastrar(nodo*pt);
/*prototipodefunción*/
/*prototipodefunción*/
/*prototipodefunción*/
/*prototipodefunción*/
/*prototipodefunción*/
main()
{
nodo
int
do(
*prin¡
eleccion¡
eleccion=menu();
switch(eleccion){
/*punteroalprincipiodelalista*/
/ *declaracióndevariablelocal* /
case1: /*
prin=
crearlalistaenlazada* /
(nodo*)malloc(sizeof(nodo)) ; / *reservade
espaciopara
elprimer
nodo* /
crear(prin);
printf("");
mostrar(prin);
continue;
case2:/*añadiruncomponente* /
prin=insertar(prin);
printf("");
mostrar(prin);
continue;
case3: / *borraruncomponente* /
prin=eliminar(prin);
printf("n);
mostrar(prin);
continue;
default:/*finalizar
printf("Findelas
*/
operaciones"");
}
}while(eleccion! =4);
}

458 PROGRAMACiÓN ENC
intmenu(void)
{
inteleccion;
do{
1*generarelmendprincipal*1
printf("Mendprincipal:");
printf( " 1 CREAR lalistaenlazada")
printf("2 AÑADIR uncomponente");
printf("3 BORRAR uncomponente");
printf("4 FIN");
printf("Porfavor,introduzcasuelección(1,2,3 o4)->");
scanf("%d",&eleccion);
if(eleccion<1IIeleccion>4)
printf("ERROR -Porfavor,inténtelodenuevo");
}while(eleccion<1IIeleccion>4);
printf("
ll
)i
return(eleccion);
}
voidcrear(nodo*registro)1*crearunalistaenlazada*1
1*
elargumentoapuntaalnodoactual*I
{
printf("Dato(escribir\'FIN\'paraterminar)" ) ;
scanf("%[A]",registro->elem);
elsiguientenodo*I
malloc(sizeof(nodo));
if(strcmp(registro->elem,"FIN")
registro->sig=NULL;
else{
1*reservarespaciopara
registro->sig=(nodo*)
O)
1*crearelsiguientenodo*I
crear(registro->sig);
}
return;
}
voidmostrar(nodo*registro)1*mostrarlalistaenlazada*1
1*
elargumentoapuntaalnodo
actual'*/
{
if(registro->sig!=NULL){
printf("%s",registro->elem);1*mostrarestedato*I
mostrar(registro->sig); 1*tomarelsiguienteelemento*1
}
return;
}

ESTRUCTURAS YUNIONES 459
nodo*insertar(nodo*primero)/ *añadeuncomponentealalistaen­
lazada;devuelveunpunteroalprin­
cipiodelalistamodificada* /
/ *
elargumentoapuntaalprimernodo* /
{
nodo*localizar(nodo*char[ ] ) ;/*declaracióndefunción*/
nodo*nuevoregistroi /*punteroalnuevonodo*/
nodo*marca¡ /*punteroalnodoANTERIOR
albuscado*/
charnuevodato[40]; /*datonuevo*/
charobjetivo[40]; /*datosiguientealanueva
entrada*/
printf("Nuevodato:");
scanf("%[A]
",nuevodato);
printf("Colocardelantede(escribir\'FIN\'sieselúltimo):");
scanf("%[A]",objetivo);
if(strcmp(primero->elem,objetivo) O){
/*elnuevonodoeselprimerodelalista*/
/*reservarespaciopara
nuevoregistro=(nodo*)
elnuevonodo* /
malloc(sizeof(nodo));
/*asignarelnuevodatoa
strcpy(nuevoregistro->elem,
nuevoregistro->elem);
nuevodato);
*/
/ *asignarelpunteroactualanuevoregistro->sig* /
nuevoregistro->sig=primero;
/*elnuevopunteroseconvierteenelprincipiodelalista*/
primero=nuevoregistroi
}
else{
/*insertarelnuevonodotrasalgúnnodoexistente* /
/ *
l09alizarelnodoPRECEDENTEdelnodoobjetivo* /
marca=localizar(primero,objetivo);
if
(¡narca==NULL)
printf("Noseencuentracoincidencia-Pruebedenuevo");
else{
/ *
reservarespacioparaelnuevonodo
*/
nuevoregistro=(nodo*).malloc(sizeof(nodo));
/*asignarelnuevodatoanuevoreg.istro,->elem*/
strcpy(nuevoregistro->elem,Illlevodato);

460 PROGRAMACiÓN ENC
/ *asignarelsiguientepunteroanuevoregistro->sig* /
nuevoregistro->sig=marca->sig;
}
/*asignar
rnarca->sig
}
}
return(primero);
elnuevopuntero
=nuevoregistro;
amarca->sig* /
nodo*localizar(nodo*registro,charobjetivo[])/*localizarun
nodo* /
/*devuelveunpunteroalnodoANTERIORalnodoobjetivo
Elprimerargumentoapuntaalnodoactual
Elsegundoargumentoeslacadenaobjetiva* /
{
if(strcmp(registro->sig->elem,objetivo) O)/*coinci­
denciaen­
contrada*/
}
return(registro)
;
else
if(registro->sig->sig--NULL)
return(NULL);
else
localizar(registro->sig,objetivo);
/*findelista*/
/*probarel
siguientenodo*/
nodo*eliminar(nodo*primero)/*eliminar(borrar)uncomponen­
tedelalistaenla.zada;de~
vuelveunpunteroalprinci­
piodelalistamodificada* /
/ *
elargumentoapuntaalprimernodo* /
{
nodo
nodo
nodo
char
*localizar(nodo
*marca;
*temp;
()bjetivo[40]
;
*char[ ] );/*declaracióndefunción*/
/*punteroalnodoANTERIOR
albuscado* /
/ *
'punterotemporal* //*datoaborrar* /
printf("Datoa·borra.r:");
scanf("%[AJ",objetivo);
if(strcmp(primero"-'>elem;objetivo)
/*borrarelprimernodo*/
O){

ESTRUCTURAS YUNIONES 461
/*marcarelnodosiguientealnodoobjetivo*/
temp=primero->sig;
/*liberarelespaciodelnodoobjetivo*/
free(primero);
/*ajustarelpunteroalprimernodo*/
primero=temp,
}
else(
/ *borrarotrodatodistintodelprimero* /
/*localizarelnodoPRECEDENTEdelnodoobjetivo*/
marca=localizar(primero,objetivo),
if(marca==NULL)
printf("Noseencuentracoincidencia-Pruebedenuevo"),
else(
/ *marcarelnodosiguientealnodoobjetivo*/
temp=marca->sig->sig,
/*liberarelespaciodelnodoobjetivo* /
free(marca->sig),
/*ajustarelenlaceparael$iguientenodo*/
marca->sig=temp,
}
}
return(primero),
}
Elprogramacomienzaconlasinstrucciones
*includeusualesyunadefinicióndelaconstante
simbólica
NULLpararepresentarelvalor O.Siguiendoaestasinstruccionesestáladeclaracióndela
estructuraautorreferenciadora
li$ta_elementos.Estadeclaracióneslamismaquelamostradaen
elEjemplo11.29.Asi,
li$ta_elementosidentificaunaestructuracondosmiembros:unarrayde
40caracteres(elem)yunpuntero(sig)aotraestructnradelmismotipo.Elarraydecaracteresrepre­
sentaráunacadenayelpunteroindicarálalocalizacióndelasiguientecomponentedelalistaenlazada.
Luegosedefineeltipodedatos
nodo,elcualidentificaaestructurasdeltipo lista_eleme'nto$.
Estadefiniciónesseguidaporlosprototiposdelasfunciones.Dentrodelosprototiposdelas
funcio~
nes,observeque ptesunpunteroaunaestructuradeltipo nodo.Estepunteroindicaráelcomienzo
de
lalistaenlazada.Elrestodelos
prototiposdefuncionesidentifi(;anvariasfuncionesadicionales
quesonllamadasdesde
main.Observequeestasdeclaracionesylosprototiposdelasfuncionesson
externas.Portanto,.seránreconocidas
entodoelprograma.
Lafunciónmainconstadeunbucledo-whilequepermitelaejecuciónrepetidadelproceso
completo.Estebuclellamaalafunción
menu,quegeneraelmenúprincipal.ydevuelveunvalorpara
eleccion,indicandolaseleccióndelusuario.Unainstrucción switchllamaentoncesa lafun­
ciónapropiadaenrelaciónconlaseleccióndelusuario.Observequeelprogramadejarádeejecutarse
si
elecciontieneasignadóelvalor4.

462 PROGRAMACiÓN ENC
Sie 1 e c c iontieneasignadoelvalor1,indicandoquesecrearáunanuevalistaenlazada,sedebe
reservarunbloquedememoriaparaelprimerelementoantes
dellamaralafunción crear.Estose
realizausandolafuncióndebiblioteca
ma11oc,comosediscuteenlasección 10.5.Así,lainstruc­
cióndereservadememoria
prin=(nodo*)ma11oc(sizeof(nodo));
reservaunbloquedememoriacuyotamaño(enbytes)essuficienteparaunnodo.Lainstrucciónde­
vuelveunpunteroaunaestructuradeltipo
nodo.Estepunteroindicaelprincipio delalistaenlazada.
Asísepasaa
crearcomoargumento.
Observequelaconversióndetipo
(nodo*)esrequeridacomounapartedelainstrucciónde
reserva
dememoriadinámica.Sinlamisma,lafunción ma110cdevolveríaunpunteroa charenvez
deunpunteroaunaestructuradeltipo
nodo.
Consideremosahoralafunción menu,queseutilizaparagenerarelmenúprincipal.Estafunción
aceptaunvalorpara
e1ecciondespuésdequeelmenúseagenerado.Losúnicosvalorespermitidos
para
e1eccionson1,2,3O4.Unacomprobacióndeerrores,medianteunainstrucción do-whi­
le,hacequesemuestreunmensajedeerroryquesegenereunnuevomenúsiseintroduceotrovalor
distintode
1,2,3 o 4enrespuestaalmenú.
Lalistaenlazadasecreamediantelafunción
crear.Éstaesunafunciónrecursivaqueaceptaun
punteroalnodoactual(elnodoquehasidocreado)comoargumento.
Lavariablepunterosellama
registro.
Lafuncióncrearcomienzapidiendoeldatoactual;estoes,lacadenadecaracteresquevaa
residirenelnodoactual.Si elusuariointroducelacadena
FIN(enmayúsculasoenminúsculas),en­
toncesseleasigna
NULLalpunteroqueindicalalocalizacióndelsiguientenodoyterminalarecur­
sividad.Sinembargo,sielusuariointroduceotracadenadecaracteresdistintadeF
IN,sereservala
memoriapara
elsiguientenodomediantelafunciónma 11o c ylafunciónsellamaasímismademodo
recursivo.Asílarecursividadcontinuaráhastaqueelusuariointroduzca
FINparaunodeloselementos.
Unavezquelalistaenlazadahasidocreada,semuestramediantelafunción
mostrar.Estafun­
ciónsellamadesde
main,despuésdellamara crear.Observeque mostraraceptaunpunteroal
nodoactualcomoargumento.Lafunciónseejecutarecursivamentehastaquerecibeunpunterocuyo
valores
NULL.Portanto,larecursividadhacequesemuestrelalistaenlazadacompleta.
Consideremosahoralafunción
insertar,queseusaparaañadirunanuevacomponente(un
nuevonodo)alalistaenlazada.Estafunciónpreguntaalusuariodónde
seproducelainserción.Observe
quelafunciónaceptaunpunteroalprincipiodelalistacomoargumentoydevuelveunpunteroal
principio
delalistadespuésdehaberrealizadolainserción.Estosdospunterosseránlosmismossalvo
que
lainserciónsearealizadaalprincipiodelalista.
Lafunción
insertarnose·ejecutarecursivamente.Primeropideelnuevodato (nuevodato),
y.seguidamentepideeldatoexistentequeseguiráalnuevodato(eldatoexistentesellama objeti­
vo).Silainserciónserealizaal principiodelalista, sereservamemoriaparaelnuevónodo, nuevo­
datoesasignadoalprimermiembroy
elpunterooriginalqueindicabaelcomienzodelalistaenla­
zada.(primero)esasignadoalsegundomiembro.El puntemdevuelto.porma11oc,queindicael
principiodelnuevonodo,esasignadoa
primero.Portanto,elprincipiodelnuevonodo seconvier­
te.enelprincipiodetoda
lalista.
Silainserciónserealiza detrásdeunnodoexistente, entonceslafunciónlocalizarse.llama
paradetermillarlaJocalizaciónde·lainserción.Estafuncióndevuelve.un.punteroalnodoque precede
al·nodoobjetivo.Elvaloridevueltoes.asignado al.punteromarca.Pórtanto,marcaapuntaalnodo
queprecederáalnuevonodo. Siloca.1izarnoencuentraunacoincidenciaentre elvalorintroduci­
do
paraobj.etivoyundatoexistente,entoncessedevolverá NULL.
Silocalizarencuentraunacoincidencia,lainserciónsehacedelá.siguientemanera: sereser-

ESTRUCTURAS YUNIONES 463
vamemoriaparaelnuevonodo, nuevodatoseasignaalprimermiembrode nuevoregistro(a
nuevoregistro->elem)yelpunteroalnodoobjetivo (marca->sig)seasignaalsegundo
miembrode
nuevoregistro(nuevoregistro->sig).Entonceselpunterodevueltopor
malloc,queindicaelprincipiodelnuevonodo,esasignadoa marca->sig.Portanto,elpuntero
enelnodoprecedenteapuntaráalnuevonodoyelpunteroenelnuevonodoapuntaráalnodoobjetivo.
Consideremosahoralafunción
localizar.Esunasimplefunciónrecursivaqueaceptaunpun­
teroalnodoactualylacadenaobjetivocomoargumentosydevuelveunpunteroalnodoque
precede
alnodoactual.Portanto,sieldatoenelsiguientenodoalactualcoincideconlacadenaobjetivo,la
funcióndevolveráelpunteroalnodoactual.Enotrocaso,
sepuedetomarunadedosopcionesposi­
bles.Si elpunteroenelsiguientenodoalnodoactual
esNULL,queindicaelfinaldelalistaenlazada,
nosehaproducidounacoincidencia.Portanto,lafuncióndevolveráelvalor
NULL.Perosi elpuntero
enelsiguientenodoalactualesdiferentede
NULL,lafunciónsellamarárecursivamente,comproban­
dosiseproduceunacoincidenciaconelsiguientenodo.
Finalmenteconsideraremoslafunción
eliminar,queseusaparaborrarunacomponenteexis­
tente(unnodoexistente)delalistaenlazada.Estafunciónessimilara
insertar,peroalgomás
simple.Aceptaunpunteroalprincipiodelalistaenlazadacomoargumentoydevuelveunpunteroal
principiodelalistaenlazadadespuésdeborrarelelemento.
Lafunción
eliminarempiezapidiendoeldatoaborrar (objetivo).Siésteeselprimerdato,
entonceslospunterossonajustadoscomosigue:elpunteroqueindicalalocalizacióndelsegundo
nodoestemporalmenteasignadoalavariablepuntero
temp;lamemoriautilizadaporelprimernodo
esliberada,usandolafunción
debibliotecafree;ylalocalizacióndelsegundonodo(queesahora
elprimernododebido alborrado)seasignaa primero.Portanto,elprincipio delsegundo(anterior)
nodoseconvierteenelprincipiodelalistacompleta.
Si eldatoaborrar
noeselprimerodelalista,entonces sellamaa localizarparadeterminarla
localizacióndelelementoaborrar.Estafuncióndevolveráunpunteroalnodo
precedentealnodo
objetivo.Elvalordevueltoseasignaalavariablepuntero
marca.Sielvalores NULL,no
seproduce
unacoincidencia.Segeneraunmensajedeerrorpidiendoalusuarioquelointentenuevamente.
Si
localizardevuelveunvalordistintode NULL,elnodoobjetivoseborradelasiguiente
manera:elpunteroalnodosiguientealnodoobjetivoseasignatemporalmentealavariablepuntero
temp;lamemoriautilizadaporelnodoobjetivoselibera,usandolafuncióndebiblioteca free;yel
valorde
tempseasignaa marca->sig.Portanto,elpunteroenelnodoprecedenteapuntaráal
nodosiguientealnodoobjetivo.
Utilicemosesteprogramaparacrearunalistaenlazadaquecontengalassiguientes_ciudades:Bas­
tan,Chicago,Denver,NewYork,PittsburghySanFrancisco.Entoncesañadiremosyborraremosva­
riasciudades,ilustrandoasítodaslascaracterísticasdelprpgrama.Mantendremoslalistadeciudades
ordenadaalfabéticamentealolargodelejercicio.(Porsnpuesto,podríamoshacerquelacomputadora
realizaralaordenaciónpornosotros,peroseríacomplicarmásunprogramaqueyaescomplejP.)
Acontinuaciónsemuestralasesióninteractiva.Comosiemprelasrespuestasdelusuariohansido
subrayadas.
Menúprincipal:
1 -CREAR lalistaenlazada
2 -AÑADIR uncomponente
3 BORRAR uncomponente
4 -FIN
Porfavor,introduzcasuelección(1,2,3,4)->1
Dato
Dato(escribir
(escribir'FIN'
'FIN'
para
paraterminar):
terminar):
BaSTaN
CHICAGO

464 PROGRAMACiÓN ENC
Dato(escribir'FIN'paraterminar):DENVER
Dato(escribir'FIN'paraterminar):NEWYORK
Dato(escribir'FIN
1
paraterminar):PITTSBURGH
Dato(escribirIFIN'paraterminar):SAN FRANCISCO
Dato(escribir'FIN'paraterminar):FIN
BaSTaN
CHICAGO
DENVER
NEWYORK
PITTSBURGH
SANFRANCISCO
Menú
1
2
3
4
Por
principal:
-CREAR lalistaenlazada
-AÑADIRuncomponente
-BORRAR uncomponente
-FIN
favor,introduzcasuelección(1,2,3,4)->2.
Nuevodato:ATLANTA
Colocardelantede(escribir'FIN'sieselúltimo):BaSTaN
ATLANTA
BaSTaN
CHICAGO
DENVER
NEWYORK
PITTSBURGH
SANFRANCISCO
Menúprincipal:
1 -CREARlalistaeniazada
2 AÑADIR·uncomponente
3 BORRAR uncomponente
4 FIN
Porfavor,introduzcasuelección(1,2,3,4)->2.
Nuevodato:SEATTLE
Colocardelantede(escribir'FIN'sieselúltimo):FIN
ATLANTA
BaSTaN
CHICAGO
DENVER
NEWYORK
PITTSBURGH
SANFRANCISCO
SEATTLE

Menú
1
2
3
4
principal:
-CREAR lalistaenlazada
-AÑADIRuncomponente
BORRARuncomponente
FIN
ESTRUCTURAS YUNIONES 465
Porfavor,introduzcasuelección(1,2,3,4)->.:2.
Datoaborrar:NEWYORK
ATLANTA
BaSTaN
CHICAGO
DENVER
PITTSBURGH
SANFRANCISCO
SEATTLE
Menú
1
2
3
4
Por
principal:
-CREAR lalistaenlazada
AÑADIRuncomponente
BORRARuncomponente
FIN
favorrintroduzcasuelección(1,2,3,4)->2.
Nuevodato:WASHINGTON
Colocardelantede(escribir'FIN'sieselúltimo)WILLIAMSBURG
Noseencuentracoincidencia
ATLANTA
BaSTaN
CHICAGO
DENVER
PITTSBURGH
SANFRANCISCO
SEATTLE
Pruebedenuevo
Menúprincipal:
1 CREAR lalistaenlazada
2 AÑADIRuncomponente
3 BORRAR uncomponente
4 FIN
Porfavor,introduzcasuelección·(1,2,3,4)->2.
Nuevodato:WASHINGTON
Colocardelantede(escribir'FIN'sieselúltimo)FIN
ATLANTA
BaSTaN
CHICAGO
DENVER

466 PROGRAMACiÓN ENC
PITTSBURGH
SANFRANCISCO
SEATTLE
WASHINGTON
Menúprincipal:
1 CREAR lalistaenlazada
2 -AÑADIRuncomponente
3 BORRAR uncomponente
4 -FIN
Porfavor,introduzcasuelección(1,2,3,4)->2
Datoaborrar:ATLANTA
BaSTaN
CHICAGO
DENVER
PITTSBURGH
SANFRANCISCO
SEATTLE
WASHINGTON
Menú
1
2
3
4
principal:
-CREAR lalistaenlazada
-AÑADIRuncomponente
BORRARuncomponente
-FIN
Porfavor,introduzcasuelección(1,2,3,4)->
2.
Nuevodato:DALLAS
Colocardelantede(escribir'FIN'sieselúltimo)
BaSTaN
CHICAGO
DALLAS
DENVER
PITTSBURGH
SANFRANCISCO
SEATTLE
WASHINGTON
DENVER
Menú
1
2
3
4
Por
principal:
-CREAR lalistaenlazada
AÑADIRuncomponente
BORRARuncomponente
-FIN
favorIintroduzcasuelección(1,2,3,4)->
2
Datoaborrar:MIAMI
Noseencuentracoincidencia-Pruebedenuevo

ESTRUCTURAS YUNIONES 467
BaSTaN
CHICAGO
DALLAS
DENVER
PITTSBURGH
SANFRANCISCO
SEATTLE
WASHINGTON
Menú
1
2
3
4
Por
principal:
-CREAR lalistaenlazada
-AÑADIRuncomponente
-BORRAR uncomponente
-FIN
favor,introduzcasuelección(1,2,3 ,4)->
.1
Datoaborrar:WASHINGTON
BaSTaN
CHICAGO
DALLAS
DENVER
PITTSBURGH
SANFRANCISCO
SEATTLE
Menúprincipal:
1 -CREAR lalistaenlazada
2 -AÑADIRuncomponente
3 -BORRAR uncomponente
4 -FIN
Porfavor,introduzcasuelección(1,2,3,4)->2.
ERROR -Porfavor,inténtelodenuevo
Menúprincipal:
1-CREARlalistaenlazada
2-AÑADIRuncomponente
3-BORRARuncomponente
4-FIN
Porfavor,introduzcasuelección(1,2,3,4)->.4.
Findelasoperaciones
11.7.UNIONES
Lasuniones,comolasestructuras,contienenmiembroscuyostiposde dat:0spuedellserdiferen­
tes.Sinembargo,losmiembrosquecomponenunaunióncompartenelmismo.:,íreadealmacena­
mientodentrodelamemoria
delacomputadora,mientrasquecadamiembrodentrode
laestruc-

468 PROGRAMACiÓN ENC
turatieneasignadasupropiaáreadealmacenamiento.Así,lasunionesseusanparaahorrar
memoria.Sonútilesparaaplicacionesqueinvolucrenmúltiplesmiembrosdondenosenecesita
asignarvaloresatodoslosmiembrosalavez.
Dentro
delaunión,lareservadememoriarequeridaparaalmacenarmiembroscuyostipos de
datossondiferentes(condiferentesrequisitosdememoria)esmanejadaautomáticamenteporel
compilador.Sinembargo,elusuariodebeconservarunapistadeltipo
deinformaciónqueestá
almacenadaencadamomento.Unatentativa
deaccesoaltipo deinformaciónequivocadaprodu­
ciráresultadossinsentido.
Entérminosgenerales,lacomposicióndeunauniónpuededefinirsecomo
unionmarca {
miembro1;
miembro2;
miembrom;
}
;
dondeunionesunapalabrareservadarequeridaylosotrostérminostienenelmismosignifica­
doqueenunadefinición deestructura(versección11.1).Lasvariablesdeuniónindividuales
puedenserdeclaradascomo
tipo-almacenamientounianmarca
variable1,variable2, .
,variablen;
dondetipo-almacenamientoesunespecificadoropcionaldetipodealmacenamiento,
unioneslapalabrareservadarequerida, marcaelnombrequeaparece enladefinicióndela
unión,y
variable1,variable2,...
,variablensonvariablesdeunióndeltipo
marca.
Lasdosdeclaracionespuedensercombinadas,comosehizoconlasestructuras.Así,sepuede
escribir
tipo-almacenamientounionmarca{
miembro1;
miembro2;
miembrom;
}
variable1,variable2, .
,variablen;
Lamarcaesopcionalenestetipo dedeclaración.
EJEMPLO11.33. Unprogramaenecontienelasiguientedeclaración deunión:
unionid{
charco}or[12];
inttalla;
}camisa:,blusa:¡

ESTRUCTURAS YUNIONES 469
Aquítenemosdosvariables deunión,camisayblusa,deltipoid.Cadavariablepuederepresen­
tarbienunacadenade
12caracteres(color)obienunentero (talla)enunmomentodado.
Lacadenade
12caracteresrequerirámásáreadealmacenamientodentrodelamemoriadelacompu­
tadoraqueelentero.Portanto,sereservaunbloque
dememoriasuficienteparaalmacenarlacadenade
12caracteresparacadavariable deunión.Elcompiladordistinguiráautomáticamenteentre elarray
de
12caracteresy elenterosegún serequiera.
Unauniónpuedeserunmiembrodeunaestructurayunaestructurapuedeserunmiembro
deunaunión.Además,lasestructurasylasunionespuedensermezcladaslibrementeconlos
arrays.
EJEMPLO11.34. UnprogramaenCcontienelassiguientesdeclaraciones:
unionid{
charcolor[12];
inttalla;
};
coste;
iddescripcion;
blusa;
ropa{
fabricante[20];
union
camisa,}
struct
char
float
Ahoracamisayblusasonvariablesdeestructuradeltipo ropa.Cadavariablecontendrálossi­
guientesmiembros:unacadenadecaracteres
(fabricante),unacantidadencomaflotante (cos­
te)yunaunión (descripcion).Launiónpuederepresentarobienunacadenadecaracteres (co­
lor)Obienunacantidadentera (talla).
Otraformaparadeclararlasvariablesdeestructura camisayblusaescombinarlasdosdecla­
racionesanteriorescomosigue:
ropa{
fabricante[20];
coste;
struct
char
float
union{
charcolor[12];
inttalla;
}descripcion;
}camisa,blusa;
Estadeclaraciónesmásconcisa,peroquizámenosdirectaquelasdeclaracionesoriginales.
Unmiembroindividualdeunauniónpuedeseraccedidodelamismamaneraqueunmiembro
deunaestructura,usandolosoperadores.y->.Así,sivariableesunavariabledeunión,
entoncesvariable.miembrorefierealmiembrodelaunión.Análogamente,siptvaresuna
variablepunteroqueapuntaaunaunión,entoncesptvar->miembrorefierealmiembrodeesa
unión.
EJEMPLO11.35. ConsideremoselsencilloprogramaenCmostradoacontinuación.

470 PROGRAMACiÓN ENC
#include<stdio.h>
main()
{
unienid{
charcolori
inttalla;
};
struct{
char
float
union
}camisa,
fabricante[20];
coste;
iddescripcion;
blusa;
printf("%d",sizeof(unionid));
/ *asignarunvaloracolor*/
camisa.descripcion.color='B'i
printf("%c%d", camisa.descripcion.color,camisa.descripcion.talla);
/ *asignarunvaloratalla*/
camisa.descripcion.talla=12;
printf("%c%d", camisa.descripcion.color,camisa.descripcion.talla);
}
EsteprogramacontieneunasdeclaracionessimilaresalasmostradasenelEjemplo11.34.Sinembargo,
observequeelprimermiembrodela.uniónesahorauncarácterenvezdelarrayde
12caracteresdel
ejemploanterior.Estecambiosehahechoparasimplificarlaasignacióndevaloresapropiadosalos
miembrosdelaunión.
Siguiendoalasdeclaracionesy alainstrucción
printfinicial,vemosqueseleasigna elcarácter
'B'almiembrodelaunión camisa.descripcion.color.Observequeelotromiembrodela
unión,
camisa.descripcion.talla,tendráunvalorsinsentido.Losvaloresdeambosmiem­
brosdelauniónsonentoncesmostrados.
Luegoasignamoselvalor
12acamisa.descripcion.talla,reescribiendoasielvalor de
camisa.descripcion.color.Denuevosemuestranacontinuaciónlosvaloresdeambosmiem­
brosdelaunión.
Laejecucióndelprogramaproducelasiguientesalida:
2
B-24713
@12
Laprimeralíneaindicaquelauniónsealmacenaen2bytesdememoriaparaguardarunacantidadente­
ra.Enlasegundalínea,
elprimerdato(B)tienesentido,pero noelsegundo(- 24713).Enlaterceralínea,
elprimerdato
(@)notienesentido,pero elsegundosí lotiene(12).Así,cadalíneadesalidatieneun
valorconsentidodeacuerdoconlainstrucción
deasignaciónqueprecedeacadainstrucción printf.
Unavariabledeuniónpuedeserinicializadasiemprequesutipodealmacenamientosea
externostatic.Recordar,sinembargo,quesólounodelosmiembrosdeunauniónpuede

ESTRUCTURAS YUNIONES 471
tenerunvalorasignado encadamomento. Lamayoríadeloscompiladoresaceptaránunvalor
inicialparaunosolodelosmiembrosdelauniónyasignaránestevaloralprimermiembro
dentrodelaunión.
EJEMPLO11.36. AcontinuaciónsemuestraunsencilloprogramaenCqueincluyelaasignación
devaloresinicialesaunavariabledeestructura.
#include<stdio.h>
main()
{
uníanid
char
int
};
{
color[12];
talla;
structropa{
charfabricante[20];
floatcoste;
uníaniddescripcion¡
};
staticstructropacamisa={"Americana",25.00,"blanca"};
}
printf("%d",sizeof(unionid));
printf("%s%5.2f camisa.fabricante,
printf("%8%d
ll
,camisa.descripcion.color,
camisa.descripcion.talla=12;
printf("%s%5.2f"camisa.fabricante,
printf("%s%d",camisa.descripcion.color,
camisa.coste);
camisa.descripcion.talla);
camisa.coste)i
camisa.descripcion.talla);
Observeque camisaesunavariabledeestructuradeltipo ropa.Unodesusmiembroses
descripcion,queesunaunióndeltipo id.Estauniónconstadedosmiembros:unarrayde
12caracteresyunentero.
Ladeclaracióndelavariabledeestructuraincluyelaasignación
delossiguientesvaloresiniciales:
"Americana"seasignaalmiembro dearraycamisa.fabricante,25.00almiembroencoma
flotante
camisa.costey"blanca"almiembrodelaunión camisa.descripcion.color.
Observequeelsegundomiembrodelaunióndentrodelaestructura, camisa.descripcion.talla,
quedasinespecificar.
Elprogramamuestraprimero
eltamañodelbloqnedememoriareservadoparalauniónseguidopor el
valordecadauno delosmiembrosdecamisa.Luegoseasigna 12acamisa.descripcion.talla
ysemuestra denuevoelvalor decadamiembro decamisao
Cuandoseejecutaelprograma,segeneralasiguientesalida:
12
Americana25.00
Americana25.00
blanca26743
12

472 PROGRAMACiÓN ENC
Laprimeralineaindica quesereservan12bytesdememoriaparalaumon,parapoderalmacenar
elarrayde
12caracteres.Lasegundalineamuestralosvaloresasignadosinicialmentea
camisa.fabricante,camisa.costeycamisa.descripcion.color.Elvalormostrado
para
camisa.descripcion.tallanotienesentido.Enlaterceralineavemosque
camisa.fabricanteycamisa.costeestánsinmodificar.Sinembargo,lareasignacióndelos
miembrosdelauniónproduce
queelvalorde camisa.descripcion.colornotengasentidopero
camisa.descrip-ción.tallamuestresunuevovalor 12.
Entodoslosotrosaspectos, lasunionesseprocesandelamismamanerayconlasmismas
restriccionesquelasestructuras.Así, unmiembroindividualdeunauniónpuedeserprocesado
comosifueraunavariableordinariadelmismotipodedatos,ylos punterosaunionespuedenser
pasadosa odesdefunciones(porreferencia).Además,lamayoríadeloscompiladoresdee
permitenasignarunaunióncompletaaotraunión,siemprequeambasunionestenganlamisma
composición.Estoscompiladorespermitentambiénqueunionescompletasseanpasadasa odes­
de
funciones(porvalor),comoseindicaenelnuevoestándarANSI.
EJEMPLO11.37. Elevacióndeunnúmeroaunapotencia.Esteejemploesunpococomplicado,
peroilustracómosepuedeusarunauniónparapasarinformaciónaunafunción.Elproblema
eselevar
unnúmeroaunapotencia.Queremosevaluarlafórmula
y=
x",dondexeysonvaloresencomaflotante
y
npuedeserunnúmerooenterooencomaflotante.
Si
nesentero,entonces ypuedeserevaluadomultiplicando xporsimismaundeterminadonúmero
deveces.Porejemplo,lacantidad x'puedeserexpresadaentérminosdelproducto (x)(x)(x).Sinesun
valorencomaflotante,entoncessepuedeescribirlog
y=nlogx,oy=
eC"10,").Enelúltimocaso xdebe
serunacantidadpositiva,yaquenosepuedeefectuarellogaritmodeceroodeunacantidadnegativa.
Introduzcamoslassiguientesdeclaraciones:
typedefunion
floatfexp;
intnexp;
}nvalor;
{
/*exponente
/*exponente
encomaflotante
entero* /
*/
typedefstruct{
floatx;
charindicadori
nvaloreXPi
}valores;
valoresa;
/ *valorparaelevaralapotencia* /
/ *
'f'sielexponenteesencomaflotante
, e/sielexponenteesentero*/
/ *uniónquecontieneelexponente*/
Así,nvaloresuntipo deunióndefinidapor elusuario,consistente enelmiembroencomaflotante fexp
yelmiembroentero nexp.Estosdosmiembrosrepresentanlosdosposiblestipos deexponentesenla
expresión
y=
x".Análogamente,valoresesuntipodeestructuradefinidaporelusuario, queconstade
unmiembroencomaflotante x,unmiembrocarácter indicadoryunaunióndeltipo nvalorllamada
exp.Observeque indicadorindicaeltipodeexponenteactualmenterepresentadoporlaunión.Si
indicador
representa'
e',entonceslauniónrepresentaráunexponenteentero (nexptendráasignadoun
valorenesemomento);y
siindicadorrepresenta'f',entonceslauniónrepresentaráunexponenteen
comaflotante
(fexptendráasignadounvalorenesemomento).Finalmentevemosque aesunavariable
deestructuradeltipo valores.

ESTRUCTURAS YUNIONES 473
Conestasdeclaraciones,esfácilescribirunafunciónqueevalúelafórmula y=x",comosigue.
floatpotencia(valoresa)/ *realizalapotenciación* /
{
inti;
floaty=a.x;
/*exponenteenterononegativo*/
*/
*/
entero
cero
++i)
exponente
exponente
/*
/*{
O)
,e/)
(i=1;i <abs(a.exp.nexp);
y*=a.Xi
(a.exp.nexp<O)
y=l./y;
if
(a.indicador
i f (a .exp.nexp
y=1.0;
else{
for
if
}
}
else
y=exp(a .exp. fexp*
/ *
exponenteencomaflotante* /
log(a.x));
return(y);
}
Estafunciónaceptaunavariabledeestructura (a)deltipovalorescomoargumento.Elmétodousado
pararealizarloscálculosdependedelvalorasignadoa
a.indicador.Sia.indicadortieneasigna­
doelcarácter'e',entonceslapotenciaciónserealizamultiplicando a.xporsímismounnúmeroapro­
piado
deveces.Enotrocaso,lapotenciación serealizausandolafórmula y
~é"lo,x).Observequelafunción
contienecorreccionesparaacomodarunexponentecero
(y
~1.0)Yexponentesenterosnegativos.
Seañadealafunción
mainlapeticióndelosvaloresde xynysedeterminasi nesunenteroo no
(comparandonconsu valortruncado),seasignaunvalorapropiadoa a.indicadorya.exp,se
llamaa
potenciaydespuésseescribeelresultado.Seincluyetambiénlaprevisióndegenerarun
mensajedeerrorsi
nesunexponenteencomaflotanteysielvalor dexesmenoroigualacero.
Aquítenemoselprogramacompleto.
/*programaparaelevarunnúmeroaunapotencia*/
#include
#include
<stdio.h>
<math.h>
typedefunion{
floatfexp;
intneXPi
}nvalor;
/*exponenteencomaflotante* /
/*exponenteentero* /
typedefstruct{
floatx;
charindicador;
nvalorexp¡
}valores;
/ *valorparaelevaralapotencia* /
/*'f'sielexponenteesencomaflotante
, eIsielexponenteesentero* /
/ *uniónquecontieneelexponente*/

474 PROGRAMACiÓN ENC
floatpotencia(valoresa);/*prototipodefunción* /
main()
{
valoresa;
intii
floatn,Yi
/*estructuraquecontienex,indica­
doryfexp/nexp* /
/ *introduccióndedatosdeentrada*/
printf(ny=xllntroducirunvalorparax:11)i
scanf("%f",&a.x);
printf("Introducirunvalorparan:");
scanf(lI%f
ll
,&n)¡
/ *determinarel
i=(int)n;
a.indicador=(i
if(a.indicador
a.exp.nexp=
else
a .exp. fexp=
tipode
n)?
leI )
ii
n',
exponente*/
/ *elevarx alapotenciaadecuadaymostrarelresultado* /
if(a.indicador=='f'&&a.x<=0.0){
printf("ERROR -Nosepuedeelevarunnúmeronopositivoa");
printf("unapotenciaencomaflotante");
}
else{
y
=potencia(a);
printf("y=%.4f",y);
}
}
floatpotencia(valoresa)
{
intii
floaty=a.x;
/ *realizalapotenciación* /
if(a.indicador--'e'){ /*exponenteentero*/
if(a.exp.nexp O)
y=1.0; /*exponentecero*/
else{
for(i=1;i<abs(a.exp.nexp);++i)
y*=a.Xi
i f (a .exp.nexp<O)
Y
=l./y; /*exponenteenterononegativo*/
}
}

ESTRUCTURAS YUNIONES 475
else
y=exp(a.exp.fexp*
/ *
exponente
log(a.x));
encomaflotante*/
}
return(y);
Observequelasdeclaraciones delaunióny delaestructurasonexternasalasfuncionesdelprograma,
perolavariabledeestructuraasedefinelocalmentedentrodecadafunción.
Esteprogramanoseejecuta
demodorepetitivo.Variosdiálogostípicosrepresentandodistintas
ejecucionesdelprogramasemuestranacontinuación.Comosiempre,lasrespuestasdelusuarioestán
subrayadas.
Introducirunvalorparax:
2-
Introducirunvalorparay:1
y=8.0000
Introducirunvalorparax:.::.2.
Introducirunvalorparay:1
y=-8.0000
Introducirunvalorparax:2.2
Introducirunvalorparay:3.3
y=13.4895
Introducirunvalorparax:~2.2
Introducirunvalorparay:.l.....J.
ERROR-Nosepuedeelevarunnúmeronopositivoaunapotenciaen
comaflotante
Debeseñalarseque la:mayoríadeloscompiladoresdeCincluyenlafuncióndebiblioteca pow,que
seusaparaelevar
unnúmeroaunapotencia. Sehautilizadopowenvariosejemplosdeprograma­
ciónanteriores(verEjemplos5.2,5.4,6.21,8.13y10.30).Elprogramaactualnotienesentidopara
sustituira
pow;sehapresentadosóloparailustrarelusodeunauniónenunasituaciónrepresentativa
deprogramación.
11.1.¿Quéesunaestructura?¿Enquésediferenciaunaestructura de.unarray?
11.2.¿Quéesunmiembro?¿Cuáleslarelaciónentreunmiembroyunaestructura?
11.3.Describirlasintaxisparadefinirunaestructura.¿Puedenserinicializadoslosmiembros
individualesdentro
deunadeclaración
detipoestructura?

476
11.4.
11.5.
11.6.
11.7.
11.8.
11.9.
11.10.
11.11.
11.12.
11.13.
11.14.
11.15.
11.16.
11.17.
11.18.
11.19.
11.20.
11.21.
11.22.
11.23.
11.24.
11.25.
11.26.
PROGRAMACiÓN ENC
¿Cómopuedendeclararsevariables deestructura?¿Enquésediferencianlasdeclaracio­
nes
devariablesdeestructuradelasdeclaracionesdetipos deestructuras?
¿Quéesunamarca?¿Debeincluirseunamarcaenladeclaración
deunavariablede
estructura?Explicarlo.
¿Sepuededefinirunavariabledeestructuracomomiembro
deotraestructura?¿Puede
incluirseunarraycomomiembro
deunaestructura?¿Puedeunarraytenerestructuras
comoelementos?
¿Cómoseieasignanvaloresinicialesalosmiembrosdeunaestructura?¿Quérestriccio­
nesseaplicanalostiposdealmacenamiento
deunaestructuracuandoseasignanvalores
iniciales?
¿Cómoseinicializaunarray
deestructuras?
¿Cuáleselámbitodeunnombre
demiembro?¿Quéimplicaestoconrespectoalnombre
delosmiembrosdentro deestructurasdiferentes?
¿Cómoseaccedeaunmiembro
deunaestructura?¿Cómosepuedeprocesarunmiem­
bro
deunaestructura?
¿Cuáleslaprecedenciadeloperadorpunto
(.)?¿Cómoessuasociatividad?
¿Puedeusarseeloperadorpuntoconunarray
deestructuras?Explicarlo.
¿Cuáleslaúnicaoperaciónquesepuedeaplicaralaestructuracompletaenalgunas
versionesantiguas
deC?¿Cómosehamodificadoestareglaenlasnuevasversionesdel
lenguajecompatiblesconelestándarANSIactual?
¿Cómosepuededeterminareltamaño
deunaestructura?¿Enquéunidadseindicael
tamaño?
¿Cuáleslafunción
delacaracterísticatypedef?¿Cómoseusaestacaracterísticacon­
juntamenteconlasestructuras?
¿Cómosedeclaraunavariablepunteroaestructura?¿Aquéapuntaestetipo
devariable?
¿Cómosepuedeaccederaunmiembroindividual
deunaestructuraentérminosdesu
correspondientevariablepuntero?
¿Cuáleslaprecedenciadeloperador
->?¿Cómoessuasociatividad?Compararlas
respuestasconlas
delasección11.11.
Supongamosqueunavariablepunteroapuntaaunaestructuraquecontieneotraestruc­
turacomomiembro.¿Cómopuedeseraccedidounmiembrodelaestructurainterna?
Supongamosqueunavariablepunteroapuntaaunaestructuraquecontieneunarray
comomiembro.¿Cómopuedeseraccedidounelementodelarrayinterno?
Supongamosqueunmiembrodeunaestructura
esunavariablepuntero.¿Cómopuede
seraccedidoelobjetodelpunteroentérminosdelnombredelavariable
deestructuray
delnombredelmiembro?
¿Quéocurrecuandoseincrementaunpunteroaunaestructura?¿Quépeligroestáaso­
ciadoconestetipodeoperación?
¿Cómosepuedepasarunaestructuracompletaaunafunción?Describirloampliamente,
tantoparalasantiguascomoparalasnuevasversionesde
C.
¿Cómopuedeserdevueltaunaestructuracompletaporunafunción?Describirloamplia­
mente,tantoparalasantiguas comoparalasnuevasversionesde
C.
¿Quéesunaestructuraautorreferenciadora?¿Paraquétipo deaplicacionessonútileslas
estructurasautorreferenciadoras?
¿Cuáleslaideabásica
deunaestructuradedatosenlazada?¿Quéventajastieneelusode
estructurasdedatosenlazadas?

11.27.
11.28.
11.29.
11.30.
11.31.
11.32.
11.33.
ESTRUCTURAS YUNIONES 477
Indicarvariostiposdeestructurasde datosenlazadasdeusocomún.
¿Quéesunaunión?¿Enquése diferenciadeunaestructura?
¿Paraquétipodeaplicacionessonútileslas uniones?
¿Enquésentidosepuedenmezclarlasuniones,estructurasyarrays?
¿Cómoseaccedeaunmiembrodeunaunión?¿Cómopuedeprocesarseunmiembrode
unaunión?CompararlasrespuestasconlasdelaCuestión11.10.
¿Cómoseleasignaunvaloriniciala unmiembrodeunavariabledeunión?¿Enqué
sediferencialainicializacióndeunavariabledeunióndeladeunavariabledeestruc­
tura?
Resumirlasreglasqueseaplicanalprocesamientodeuniones.Compararconlasreglas
queseaplicanalprocesamientodeestructuras.
11.34.
11.35.
11.36.
11.37
..
11.38.
11.39.
11.40.
11.41.
11.42.
Definirunaestructuraqueconstededosmiembrosencomaflotantellamados realeima­
ginario.Incluirlamarca complejodentrodeladefinición.
Declararlasvariables
xl,x2yx3comoestructurasdeltipo complejo,descritaenelpro­
blemaanterior.
CombinarladefiniciónyladeclaracióndelaestructuradescritasenlosProblemas
11.34y
11.35enunasoladeclaración.
Declararunavariable
xcomounaestructuradeltipo complejo,descritaenelProblema 11.34.
Asignarlosvaloresiniciales 1.3y-2.2alosmiembros x.realyx.imaginario,res­
pectivamente.
Declararunavariablepuntero,
px,queapunteaunaestructuradeltipo complejo,descrita
enelProblema
11.34.Escribirexpresionesparalosmiembros delaestructuraentérminosde
lavariablepuntero.
Declararunarrayunidimensionalde
100elementos,llamado cx,cuyoselementosseanes­
tructurasdeltipo
complejo,descritaenelProblema 11.34.
CombinarladeclaracióndelaestructurayladefinicióndelarraydescritasenlosProblemas
11.34y11.39enunasoladeclaración.
Supongamosque
cxesunarrayunidimensionalde laOestructuras,comosedescribeenel
Problema
11.39.Escribirexpresionesparalosmiembrosdelelementodecimoctavodelarray
(elementonúmero
17).
Definirunaestructuraquecontengalossiguientestresmiembros:
a)unacantidadenterallamada ganados
b)unacantidadenterallamada perdidos
e)unacantidadencomaflotantellamada porcentaje
Incluireltipodedatodefinidoporelusuario registrodentrodeladefinición.
11.43.Definirunaestructuraquecontengalosdosmiembrossiguientes:
a)unarrayde4 Ocaracteresllamado nombre
b)unaestructurallamada posicion,deltiporegistrodefinidoenelProblema 11.42.
Incluireltipodedatodefinidoporelusuario equipodentrodeladefinición.

478 PROGRAMACiÓN ENC
11.44.Declararunavariable deestructuratdeltipoequipo,descritoenelProblema11.43.Escri­
birunaexpresiónparacadamiembroycadasubmiembrode
t.
11.45.Declararunavariabledeestructura tdeltipoequipo,comoen elProblemaanterior.Sin
embargo,inicializarahora
tcomosigue:
nombre:OsosdeChicago
ganados:14
perdidos:2
porcentaje:87.5
11.46.Escribirunainstrucciónquemuestreeltamañodelbloquedememoriaasociadoconlavaria­
ble
tquefuedescritaen elProblema11.44.
11.47.Declararunavariablepuntero pt,queapunteaunaestructuradeltipo equipo,descritaen
elProblema11.43.Escribirunaexpresiónparacadamiembroysubmiembrodelaestructura.
11.48.Declararunarrayunidimensionalde 48elementosllamado 1ig acuyoselementosson
estructurasdeltipo
equipo,descritoenelProblema11.43.Escribirexpresionesparaelnom­
breyelporcentajedelquintoequipoenlaliga(elequiponúmero4).
11.49.Definirunaestructuraautorreferenciadoraconlossiguientestresmiembros:
a)unarrayde4 Ocaracteresllamado nombre
b)unaestructurallamada posiciondeltiporegistro,descritoenelProblema11.42
e)unpunteroaotraestructuradelmismotipo,llamado
sig
Incluirlamarca equipodentrodeladefinicióndelaestructura.Compararsusoluciónconla
delProblema11.43.
11.50.Declararptcomounpunteroalaestructuradescritaenelproblemaanterior.Escribiruna
instrucciónquereserveunbloqueadecuadodememoriaconelpunterop
tapuntandoalprin­
cipiodelbloquedememoria.
11.51.Definirunaestructuradeltipo hmsquecontengatresmiembrosenteros,llamados hora,mi­
nutoysegundo,respectivamente.Despuésdefinirunaunióncondosmiembros,cadauno
deellosunaestructuradeltipo
hms.Llamaralosmiembrosdelaunión localyhogar,
respectivamente.Declararunavariablepunterollamada horaqueapunteaestaunión.
11.52.Definirunaunióndeltipo resquecontenga lossiguientestresmiembros:
a)unacantidadenterallamada eres
b)unacantidadencomaflotantellamada fres
e)unacantidadendobleprecisiónllamada dre s
Despuésdefinirunaestructuraquecontengalossiguientescuatromiembros:
a)unaunióndeltipo resllamadarespuesta
b)uncarácterllamado indicador
e)cantidadesenterasllamadasa y b
Finalmentedeclarardosvariablesdeestructura,llamadasx e
y,cuyacomposiciónsealades­
critaanteriormente.
11.53.DeclararunavariabledeestructuravcuyacomposiciónestádescritaenelProblema11.52.
Asignarlossiguientesvaloresinicialesdentrodeladeclaración:

ESTRUCTURAS YUNIONES 479
respuesta:14
indicador:'e1
a:-2
b:5
11.54.Modificarladefinición delaestructuradescritaenelProblema11.52 demodoquecontengaun
miembroadicional,llamado
sig,queesunpunteroaotraestructuradelmismotipo.(Observe
quelaestructuraahoraseráautorreferenciadora.)Añadirunadeclaraciónde
dosvariables,lla­
madas
xypx,dondexesunavariable deestructuraypxunpunteroaunavariabledeestruc­
tura.Asignarladirección
decomienzode xapxdentrodeladeclaración.
11.55.Describirlasalidageneradaporcadaunodelossiguientesprogramas.Explicarcualquierdi­
ferenciaentreellos.
a)#include<stdio.h>
typedefstruct{
char*a;
char*b¡
char*ci
}colores;
voidfunc(coloresmuestra);
main( )
{
static·coloresmuestra
={lIrojo", lIverde
ll
/"azul
ll

printf("%s%s%s
ll
rmuestra.a,muestra.b,muestra.e);
func(muestra)
printf(11%8%s%8 IT,muestra.a,muestra.b,muestra.e);
}
voidfunc(coloresmuestra)
{
muestra.a=IIcianlli
muestra.b="magenta
ll
;
rnuestra.c=lIamarilloll¡
printf("%s%s%s
ll
,muestra.a,muestra.b,muestra.e)i
return¡
}
b)#include<stdio.h>
typedefstruct{
char*a¡
char*b¡
char*c;
}colores;
voidfunc(colores*pt);

480 PROGRAMACiÓN ENC
main()
{
staticcoloresmuestra { 11rojotif IIverde11f nazul1I};
printf("%s%8%s
ll
/muestra.a,muestra.b,muestra.e);
func(&muestra);
printf("%s%s%s",muestra.a,muestra.b,muestra.c);
}
voidfunc(colores*pt)
{
pt->a ncian11;
pt->b="magenta 11;
pt->c="amarillo"i
printf("%s%s%s",pt->a,pt->b,pt->c)
return¡
}
e)#include<stdio.h>
typedefstruct{
char*a¡
char*b;
char*ci
}colores;
coloresfunc(coloresmuestra)
main( )
{
staticcoloresmuestra={lIrojoll,lIverde
ll
,"azul
n

}
printf("%s
muestra=
printf("%s
%8%s", muestra.a,
func(muestra);
%8%s
l1
,muestra.a,
muestra.b,
muestra.b,
muestra.c)
muestra.c);
coloresfunc(coloresmuestra)
(
muestra.a =IIcian
ll
i
muestra.b=lIrnagentall;
muestra.c=lIarnarilloll¡
printf("%s%8%s
ll
lmuestra.a,muestra.b
lmuestra.e);
return(muestra);
}
11.56.Describirlasalidageneradaporelsiguienteprograma.Distinguirentresaliqasconysinsentido.
#include<stdio.h>
main( )
{

ESTRUCTURAS YUNIONES 481
union{
inti;
floatf;
doubled;
}U;
printf(ti%du/sizeofu);
u.i=100;
printf("%d%f%fniu.i,u.f,u.d);
u.f=O.5;
printf("%d%f%f 11/u.i,u.f,u.d);
u.d=0.016667;
printf("%d%f%f
ll
Iu.i,u.f,u.d);
}
11.57.Describirlasalidageneradaporcadaunodelossiguientesprogramas.Explicarcualquierdi­
ferenciaentreellos.
a)#ine1ude<stdio.h>
typedefunion{
intii
floatf;
}udef;
voidfune(udefu);
main( )
{
udefu;
u.i
=100;
u.f=0.5;
fune(u);
printf("%d%f",u.i,u.f);
}
voidfune(udefu)
{
u.i=200;
printf("%d%f",u.i,u.f);
return¡
}
b)#ine1ude<stdio.h>
typedefunion{
inti;
f10atf;
}udef;
voidfune(udefu);

482 PROGRAMACiÓN ENC
main( )
(
udefu;
u.i=100;
u.f=0.5;
fune(u);
printf("%d%f",u.i,u.f);
}
voidfune(udefu)
{
u.f=-0.3;
printf("%d%f",u.i,u.f);
return;
}
e)#inelude<stdio.h>
typedefunion{
inti;
floatf;
}udef;
udeffune(udefu);
main( )
(
udefu;
u.i=100;
u.f=0.5;
u=fune(u);
printf("%d%f",u.i,u.f);
}
udeffune(udefu)
(
u.f=-0.3;
printf("%d%f",u.i,u.f);
return(u);
}
11.58.Contestaralassiguientescuestionesque serefierenasucompiladorointérpreteparticularde C.
a)¿Puedeserasignadaunavariabledeestructura(ovariabledeunión)aotravariablede
estructura(unión),suponiendoqueambasvariablestienenlamismacomposición?

ESTRUCTURAS YUNIONES 483
b)¿Sepuedepasarunavariable deestructura(odeunión)aunafuncióncomoargumento?
e)¿Puedeserdevueltaunavariable deestructuracompleta(o deunión)desdeunafunción
hastalarutinaquehizolallamada?
d)¿Puedepasarseunpunteroaestructura(ounión)aunafuncióncomounargumento?
e)¿Puededevolverseunpunteroaestructura(ounión)desdeunafunciónhastalarutinaque
hizolallamada?
11.59.ModificarelprogramadadoenelEjemplo11.26(localizaciónderegistrosdeclientes)de
modoquelafunción
buscardevuelvaunaestructuracompletaenvez deunpunteroauna
estructura.(Nointentaresteproblema
sisuversióndeCnosoportaladevolucióndeestructu­
rascompletasdesdeunafunción.)
11.60.ModificarelprogramadefacturaciónmostradoenelEjemplo11.28demodoquecualquiera
delossiguientesinformespuedaserimpreso:
a)Estadodetodoslosclientes(ahoragenerado porelprograma)
b)Estadosólodelosclientesatrasadosydelincuentes
e)Estadosólodelosclientesdelincuentes
Incluirlaposibilidaddequecuandoelprogramaseejecute
semuestreunmenúenelcualel
usuariopuedaelegireltipodeinformeagenerar.Elprogramavuelvealmenúdespuésde
imprimirelinforme,permitiendoasilaposibilidaddegenerarvariosinformesdistintos.
11.61.ModificarelprogramadefacturaciónmostradoenelEjemplo11.28demodoquelaestructura
deltipo
registroincluyaahoraunauniónquecontengalosmiembros direc_oficina
ydirec_casa.Cadamiembro delaunióndebeserasuvezunaestructuraqueconstadedos
arraysde80caracteresllamados
calleyciudad,respectivamente.Añadirotromiembroa
laestructuraprimaria(deltipo
registro),queseauncarácterllamado indicador.Este
miembrodebetenerasignadouncarácter
('o'o'c')paraindicarquétipo dedirecciónestá
actualmentealmacenadaenlaunión.
Modificarelrestodelprograma
demodoquesepreguntealusuarioquétipodedirección
serádadaparacadacliente.Después
semuestraladirecciónapropiadaconsucorrespondiente
etiqueta,conjuntamenteconelrestodelasalida.
11.62.ModificarelprogramadadoenelEjemplo11.37demodoqueelnúmeroelevadoalapotencia
encomaflotantepueda
serejecutadoensimpleoendobleprecisión,segúnespecifiqueel
usuariounapregunta.Eltipode
uniÓnnvalordebecontenerahorauntercermiembro,que
seráunacantidadendobleprecisiónllamada
dexp.
11.63.ReescribircadaunodelossiguientesprogramasenCdemodoquehagausodevariablesde
estructura:
a)ElprogramadedepreciaciónpresentadoenelEjemplo7.20.
b)Elprogramadado enelejemplo10.28paramostrareldía delaño.
e)Elprogramaparadeterminarelvalorfuturodeunaseriededepósitosmensuales,dadoen
elEjemplo10.31.
11.64.Modificarelgeneradorde«piglatin»presentadoenelEjemplo9.14demodoqueacepte
múltipleslíneasdetexto.Representarcadalíneadetextoconunaestructuraseparada.Incluir
lossiguientestresmiembrosencadaestructura:

484 PROGRAMACiÓN ENC
a)Lalíneadetextooriginal
b)Elnúmerodepalabrasdentrodelalínea
e)Lalíneadetextomodificada(el«piglatin»equivalentedeltextooriginal)
IncluirlasmejorasdescritasenelProblema9.36(marcasdepuntuación,letrasmayúsculasy
sonidosdeletrasdobles).
11.65.Escribirunprogramaen equeleavariosnombresydirecciones,reordenelosnombresalfabé­
ticamenteyescribalalistaalfabética.(VerEjemplos9.20y10.26.)Hacerusodevariables
de
estructuradentrodelprograma.
11.66.Escribirunprogramacompletoen equehagausodevariables deestructuraparacadaunode
lossiguientesproblemas
deprogramacióndescritos enloscapítulosanteriores.
a)Lacalificaciónmediadelosestudiantes,descrito enelProblema9.40.
b)Laversiónmáscomprensibledelacalificaciónmediadelosestudiantes,descritaenel
Problema9.42.
e)Elproblemaquerelacionalosnombresdelospaisesconsuscorrespondientescapitales,
descritoenelProblema9.46.
d)Elproblemadecodificar-decodificartextodescritoenelProblema9.49,peroextendidoa
múltipleslíneasdetexto.
11.67.Escribirunprogramaen equeaceptelasiguienteinformaciónparacadaequipo delaligade
béisbolofútbol:
1.Nombredelequipo,incluidalaciudad(porejemplo,PittsburghSteelers)
2.Númerodevictorias
3.Númerodederrotas
Paraunequipodebéisbol,añadirlasiguienteinformación:
4.Númerodebolasbateadasconéxito
5.Númerodecarreras
6.Númerodeerrores
7.Númerodejuegosextra
Análogamente,añadirlasiguienteinformaciónparaunequipo
defútbol:
4.Númerodeempates
5.Númerodetantos
6.Númerodegolesdecampo
7.Númerodecontraataques
8.Totaldeyardasganadas(totaldelatemporada)
9.Totaldeyardascedidasalosoponentes
Introducirestainformaciónparatodoslosequiposdelaliga.Despuésreordenaryescribir
lalistadeequiposdeacuerdoconsuregistrodevictorias-derrotas,usandolastécnicasde
reordenacióndescritasenlosEjemplos9.13y10.16(vertambiénlosEjemplos9.21y10.26).
Almacenarlainformaciónenunarraydeestructuras,dondecadaelementodelarray(cada
estructura)contienelainformaciónparaunequipo.Hacerusodeunauniónpararepresentarla
informaciónvariable(obéisbolofútbol)queseincluyecomopartedelaestructura.Launión

ESTRUCTURAS YUNIONES 485
debeasuvezcontenerdosestructuras,unaparalasestadísticasrelacíonadasconelbéisboly
otraparalasestadísticasdelfútbol.
Comprobar
elprogramausandolasestadísticasdelatemporadaactual.(Idealmente,elpro­
gramadebesercomprobadousandoestadísticasdebéisbolydefútbol.)
11.68.ModificarelprogramadadoenelEjemplo11.32demodoquehagausodecadaunadelas
siguientesestructurasenlazadas:
a)Unalistalinealenlazadacondosconjuntosdepunteros:unoapuntandohaciadelanteyel
otroapuntandohaciadetrás.
b)Unalistaenlazadacircular.Sedebeincluirunpunteroqueidentifiqueelprincipiodela
listacircular.
11.69.ModificarelprogramadadoenelEjemplo11.32 demodoquecadanodocontengalasiguien­
teinformación:
a)Nombre
b)Calle
e)Ciudad/Estado/Código
d)Númerodecuenta
e)Estadodelacuenta(uncarácterindicandoaldía,atrasadaodelincuente)
11.70.EscribirunprogramacompletoenCquepermitaintroducirymantenerunaversióncomputa­
rizadadelárbol familiar.Empezarespecificandoelnúmerodegeneraciones(elnúmerode
nivelesdentrodelárbol).Despuésintroducirlosnombresynacionalidadesdeformajerárqui­
ca,empezandoconsupropionombreynacionalidad.Incluirlaposibilidaddemodificarel
árbolydeañadirnuevosnombres(nuevosnodos)alárbol.Tambiénintroducirlaposibilidad
demostrarelárbolcompletoautomáticamentedespuésdecadapuestaaldía.
Comprobar
elprogramaiocluyendo almenostresgeneracionessiesposible(usted, suspadres
ysusabuelos).Obviamente,elárbol
e,másinteresantecuandoelnúmero degeneracionesaumenta.
11.71.UnacalculadoraRPNutilizaunesquemadondecadanuevovalornuméricoesseguidoporla
operaciónqueserealizaráentreelnuevovalorysupredecesor.(RPNprovienede«notación
polacainvertida»,eninglés
ReversePalishNatatian.) Deestaforma,sumardosnúmeros,ta­
lescomo3 . 3 Y 4 .
8,requerirálassiguientespulsaciones:
3.3<intro>
4.8+
Lasuma,8.1,semostraráenelregistrovisibledelacalculadora.
LacalculadoraRPNhaceusodeuna
pila,quecontienetípicamentecuatroregistros(cua­
trocomponentes),comoseilustraenlaFigura11.
7.Cadanuevonúmeroseintroduceenel
registro
x,haciendoquelosanterioresvaloresintroducidossean«empujadoshaciaarriba»en
lapila.Si elregistrosuperior(elregistro
T)estabapreviamenteocupado,entonceselnúmero
antiguoseperderá(seráreescritoporelvalorempujadodesdeelregistroz).
LasoperacionesaritméticassonsiemprerealizadasentrelosnúmerosdelosregistrosX e
Y.Elresultadodetaloperaciónserásiempremostradoenelregistro x,haciendoquelosregis­
trossuperioresbajenunnivel
(<<sacando»delapila).Esteprocedimiento seilustraenlaFigu­
ra
11.8(a)a(e)paralasumadelosvalores 3.3Y4.8,comosedescribióanteriormente.

486 PROGRAMACiÓN ENC
I-=1---+.
1
'----------'-~
Figura11.7.
(registroT)
(registro
Z)
(registroy)
(registroX)
(registroT)
(registro
Z)
(registroy)
I
~ 8.1INULLI(registroX)
Operaciones
13.3<intro>I
a)
Operaciones
3.3<intro>
4.8
b)
Figura11.8.
Operaciones
3.3<intro>
4.8+
e)

ESTRUCTURAS YUNIONES 487
EscribirunprogramainteractivoenCquesimuleunacalculadoraRPN.Mostrarlosconte­
nidos
delapilatrascadaoperación,cornoenlaFigura11.8(a)a (e).Incluirlaposibilidad de
realizarcadaunadelassiguientesoperaciones.
Operación Pulsaciones
introducirunnuevodato
suma
resta
multiplicación
división
(valor)
(valor)
(valor)
(valor)
(valor)
<intro>
+
*
/
Comprobarelprogramausandodatosnuméricosdesuelección.

CAPíTULO12
Archivosdedatos
.
Muchasaplicacionesrequierenescribiroleerinformación deundispositivodealmacenamiento
auxiliar.Talinformaciónseguardaeneldispositivodealmacenamientoenlaformadeun
archivodedatos.Portanto,losarchivosdedatosnospermitenalmacenarinformación demodo
permanenteyaccederymodificarlamismacuandoseanecesario.
EnCexisteunconjuntoamplio
defuncionesdebibliotecaparacrearyprocesararchivosde
datos.Adiferenciadeotroslenguajesdeprogramación,enCnosedistingueentrearchivos
secuencialesydeaccesodirecto(accesoaleatorio).Peroexistendostiposdiferentesdearchivos
dedatos,llamadosarchivos secuencialesdedatos(oestándar)yarchivosorientadosalsistema(o
debajonivel). Generalmenteesmásfáciltrabajarconarchivosdedatossecuencialesqueconlos
orientadosalsistema,yportantosonlosmásusados.
Losarchivosdedatossecuencialessepuedendividirendoscategorías.Enlaprimeracatego·
ríaestánlosarchivosde
texto,quecontienencaracteresconsecutivos.Estoscaracterespueden
interpretarsecomodatosindividuales,comocomponentesdeunacadenadecaracteresocomo
números.
Lamaneradeinterpretarlosesdeterminadaporlasfuncionesdebibliotecausadaspara
transferirlainformaciónoporlasespecificacionesdeformatodentrodelasfunciones
debiblio·
teca,talescomo
printfoscanf,descritasenelCapítulo 4.
Lasegundacategoríadearchivosdedatossecuenciales,amenudollamadosarchivos sin
formato,
organizalosdatosenbloquesdebytescontiguosdeinformación.Estosbloquesrepre·
sentanestructurasdedatosmáscomplejas,comoarraysyestructuras.Hayunconjuntodiferen·
ciadodefuncionesdebibliotecaparatratarestetipo
dearchivos.Estasfuncionesproveenins·
truccionessimplesquepuedentransferirarraysoestructurascompletasa odesdeunarchivo
de
datos.
Losarchivosorientadosalsistemaestánmásrelacionadosconelsistemaoperativodela
computadoraquelosarchivossecuenciales.Esalgomáscomplicadotrabajarconellos,perosu
usopuedesermáseficienteparaciertotipodeaplicaciones.Paraprocesararchivosorientadosal
sistemaserequiereunconjuntoseparadodeprocedimientosconsusfuncionesdebiblioteca
correspondientes.
Estecapítulotratasóloconarchivossecuenciales.Elenfoquegeneralesprácticamenteestán·
dar,sibienlosdetallespuedenvariardeunaversióndeC aotra.Así,losejemplospresentadosen
estecapítulopuedennoserdirectamenteaplicablesatodaslasversionesdellenguajetalcomose
muestran.Noobstante,debentenersepocasdificultadesparaacondicionarestematerialasu
versiónparticulardeC.
489

490 PROGRAMACiÓN ENC
12.1.APERTURAYCIERREDEUNARCHIVO
Cuandosetrabajaconarchivossecuenciales,elprimerpasoesestablecerun áreadebuffer,
dondelainformaciónsealmacenatemporalmentemientrasseestátransfiriendoentrelamemoria
de
lacomputadorayelarchivodedatos.Esteárea debufferpermiteleer yescribirinformación
delarchivomásrápidamentedeloqueseríaposibledeotramanera.Eláreadebúfferseestablece
escribiendo
FILE*ptvar;
dondeFILE(serequierenletrasmayúsculas)esuntipoespecialdeestructuraqueestableceel
áreadebúffer
yptvareslavariablepunteroqueindicaelprincipiodeesteárea.Eltipode
estructura
FILEestá definidoenunarchivoincludedelsistema,normalmenteen stdio.h.
Elpunteroptvarserefiereamenudocomoun punteroaarchivosecuencial, osimplemente
como
archivosecuencial.
Unarchivodebeser abiertoantesdesercreadooprocesado.Estoasociaelnombredel
archivoconeláreadebúffer(conelarchivosecuencial).Tambiénseespecificacómosevaausar
elarchivo,sóloparalectura,sólo
paraescritura,oparalectura/escritura, enelquesepermiten
ambasoperaciones.
Paraabrirunarchivoseusa
lafuncióndebiblioteca fopen.Estafunciónseescribetípica­
mentecomo
ptvar=fopen(nombre-archivo,tipo-archivo);
dondenombre-archivoytipo-archivosoncadenasdecaracteresquerepresentan,
respectivamente,elnombredelarchivo
ylamaneraenlaqueelarchivoseráutilizado.Elnom­
breelegidopara
nombre-archivadebeserconsistenteconlasreglasparanombrararchivos
delsistemaoperativo.El
tipo-archivodebeser unadelascadenasmostradasen laTa­
bla12.1.
Tabla12.1.Especificaciones detipodearchivo
" r " Abrirunarchivoexistente sóloparalectura.
" w " Abrirunnuevoarchivosóloparaescritura. Siexisteunarchivoconeln om-
bre-archivoespecificado,serádestruido ycreadounonuevoensulugar.
"a " Abrir unarchivoexistenteparaañadir(agregarinformaciónnueva alfinaldel
archivo).Secrearáunarchivonuevo sinoexisteunarchivocon elnom­
bre-archivoespecificado.
"
r+" Abrirunarchivoexistentetantoparalecturacomoparaescritura.
"w+" Abrirunarchivonuevoparalectura yescritura.Siexisteunarchivo connom-
bre-archivoespecificado,serádestruido ycreadounonuevoensulugar.
"a+" Abrirunarchivoexistenteparaleer yañadir.Secrearáunnuevoarchivosi no
existeunarchivocon elnombre-archivoespecificado.

ARCHIVOSDEDATOS 491
Lafunciónfopendevuelveunpunteroalprincipiodeláreade bufferasociadaconelarchi­
vo.
SedevuelveunvalorNULLsinosepuedeabrirelarchivo,porejemplosinosepuede
encontrarunarchivoexistente.
Finalmente,
unarchivodedatosdebe cerrarsealfinaldelprograma.Esto puederealizarse
conlafunciónde bibliotecafclose.Lasintaxisessimplemente
fclose(ptvar);
Esunabuenaprácticadeprogramacióncerrarexplícitamentelosarchivos dedatosmediantela
función
fclose,aunquelamayoríadeloscompiladoresdeecerraránautomáticamentelos
archivosdedatosalfinaldelaejecucióndel
programasinoestápresenteunallamadaa f close.
EJEMPLO 12.1. Unprogramaen econtienelassiguientesinstrucciones:
#include<stdio.h>
FILE*fpt;
fpt=fopen(lImuestra.datll,"Wll)¡
fclose(fpt);
Laprimerainstrucciónincluyeelarchivo decabecerastdio.henelprograma.Lasegundainstruc­
cióndefineunpunterollamado
fptqueapuntaráalaestructuradeltipo FILE,indicandoelprinci­
piodelárea
debufferdelarchivo.Observeque FILEestádefinidoen stdio.h.
Latercerainstrucciónabre unarchivonuevollamado muestra.datcomounarchivo desóloes­
critura.Además,lafunción
fopendevuelveunpunteroalprincipiodelárea debufferyloasignaa la
variablepuntero fpt.Así,fptapuntaaláreadebufferasociadaconelarchivo dedatosmuestra.dato
Todaslassubsiguientesinstrucciones deproceso(que nosemuestranexplícitamenteenesteejemplo)
accederán
alarchivomedianteelpuntero fptenvezdemedianteelnombredelarchivo.
Finalmente,laúltimainstruccióncierraelarchivo
dedatos.Observequeelargumento eslavaria­
blepuntero
fpt,noelnombre muestra.dat.
Elvalordevueltoporlafunción fopenpuedeusarseparagenerarunmensaje deerrorsielarchivo
dedatosnopuedeabrirse,como seilustraen elsiguienteejemplo.
EJEMPLO 12.2. Unprogramaen econtienelassiguientesinstrucciones:
#include<stdio.h>
#defineNULLO
main()
{
FILE*fpt;
fpt=fopen(llmuestra.dat
ll
rIIr+
ll

if(fpt==NULL)
printf("ERROR -Nosepuedeabrirelarchivoindicado");
else{
fclose(fpt);
}
}

492 PROGRAMACiÓN ENC
Esteprogramatratadeabrirparalecturayescrituraunarchivo dedatospreviamenteexistentellamado
muestra.datoSegeneraráunmensaje deerrorsinoseencuentraestearchivo.Enotrocaso,elarchi­
vodedatosseabriráyprocesarácornoseindica.
Lasinstrucciones
fopene i fsecombinanfrecuentementecornosigue:
if((fpt=fopen("muestra.dat","r+"))--NULL)
printf("ERROR -Nosepuedeabrirelarchivoindicado");
Cualquieradelosmétodosesaceptable.
12.2.CREACIÓNDEUNARCHIVO
Unarchivodebecrearseantesde serprocesado.Unarchivosecuencialpuedecrearsededos
formasdistintas.Unaescrearelarchivodirectamente,usandounprocesadordetextoouneditor.
Laotraesescribirunprogramaqueintroduzcainformaciónenlacomputadoraylaescribaenun
archivo.Losarchivossinformatosólopuedencrearseconprogramasespecialmenteescritospara
talfin.
Cuandosecreaunnuevoarchivoconunodeestosprogramas,elenfoquenormalesintroducir
lainformacióndesdeeltecladoyescribirlaenelarchivo.Sielarchivoconstadecaracteres
individuales,sepuedenusarlasfuncionesdebibliotecagetcharyputcparaintroducirlos
datosdesdeeltecladoyescribirlosenelarchivo.Yasehadiscutidoelusodegetcharenla
sección4.2.Lafunciónputcesnueva,perosuusoesanálogoaldeputchar,discutidoenla
sección4.3.
EJEMPLO12.3.Creaciónde nnarchivodedatos(conversióndeltextodeminúscnlasamayús­
culas).Aquítenernosunavariacióndealgunosejemplosanteriores,queleenunalíneaenmínúsculas
ylaescríbenenmayúsculas(verEjemplos4.4,6.9,6.12,6.16
Y9.2).Enesteejemploseleeeltexto
carácteracarácterusandolafunción
getcharydespuésseescribeenunarchivousando putc.La
funcíóndebiblioteca
toupperrealizalaconversíóndemínúsculasamayúsculas,cornoantes.
Elprogramacomíenzadefiníendoelpunteroaarchivosecuencíal
fpt,queíndicaelprincípíodel
áreadebufferdelarchivo.
Seabreunnuevoarchivo, muestra.dat,sóloparaescritura.Acontinua­
ción,elbucle
do-whileleeunaseriedecaracteresdeltecladoyescribelasmayúsculasequiva­
lentesenelarchívo.Lafunción
putcseusaparaescribírcadacarácterenelarchivo.Observeque
putcrequiereque elpunterodelarchívosecuencíal fptseaespecificadocornoargumento.
Elbuclecontínúahastaqueseíntroduceuncarácterdenuevalínea(
,\ n')desdeelteclado.Cuando
sedetectaelcarácterdenuevalínea,sesaledelbucleysecierraelarchívo.
/ *leerunalíneadetextoenminúsculasyalmacenarlaenmayús­
culasenunarchivodedatos* /
#include<stdio.h>
#include<ctype.h>
main()
{

FILE*fpt;
chare;
ARCHIVOSDEDATOS 493
/ *defineunpunteroaltipodeestructuraprede­
finidaFILE* /
/ *abrirunarchivonuevosoloparaescritura*/
fpt=fopen("muestra.dat", lIWll);
/ *leercadacarácteryescribirsumayúsculacorrespondiente
enelarchivo*/
do
putc(toupper(c=getchar()),fpt);
while(c!='');
/ *cerrarelarchivode,datos*/
fclose(fpt);
}
Despuésdeejecutarelprograma,elarchivo muestra.datcontendrálasmayúsculasequivalen­
tesalalineaintroducidadesdeelteclado.Porejemplo,silalineaoriginaldetextohasido
Nosotros,elpueblodelosEstadosUnidos
elarchivocontendríaeltexto
NOSOTROS,
ELPUEBLODELOSESTADOSUNIDOS
Unarchivocreadodeestamanerapuedeservisualizadodedistintasformas. Porejemplo,el
archivopuedeservisualizadodirectamente,usandounaordendelsistemaoperativotalcomo
printotype.Tambiénsepuedevisualizarusandouneditorounprocesadordetexto.
Otraposibilidadesescribirunprogramaqueleaelcontenidodelarchivoylo muestre.Este
programasería,enalgúnsentido,unaimagenespeculardeldescritoanteriormente;lafunciónde
bibliotecagetcleerácaracteresindividualesdel archivodedatosyputcharlosmostraráenla
pantalla.Éstaesunaformamáscomplicadadevisualizarunarchivo,peroofrecegranflexibili­
dad,
yaqueloselementosindividualespuedenprocesarsesegúnseleen.
EJEMPLO12.4. LecturadeunarchivodedatQs.Elsiguienteprogramaleeunaliueadetextode
unarchivodedatos,carácteracarácter,
ymuestraeltextoenlapantalla.Elprogramahaceusodelas
funcionesdebiblioteca
getcyputchar(versección4.3)paraleer ymostrarlosdatos.Complemen­
taalprogramapresentadoenelEjemplo12.3.
LalógicaesanálogaaladelprogramamostradoenelEjemplo
12.3.Sinembargo,observequeeste
programaabre
elarchivomuestra.datsóloparalectura,mientrasqueelprogramaanterior loabríasólo
paraescritura.
Sielarchivomuestra.datnosepuedeabrir,segeneraunmensaje deerror.Finalmente,
observeqne
getcrequierequeelpuntero alarchivosecuencial fptseaespecificadocomoargumento.
/*leerunalíneadetextodeunarchivoymostrarlaenlapantalla*/
#include<stdio.h>

494 PROGRAMACiÓN ENC
#defineNULLO
main()
{
FILE*fpt;
charei
/*defineunpunteroaltipodeestructuraprede­
finidaFILE* /
/ *
abrirelarchivodedatossoloparalectura* /
if((fpt=fopen("muestra.dat","r")) NULL)
printf("ERROR -Nosepuedeabrirelarchivoindicado");
e 1 s e / *leerymostrarcadacarácterdelarchivo* /
do
putchar(c
while(c!=
=getc(fpt)) ;
/ f) ;
/ *cerrarelarchivodedatos* /
fclose(fpt);
}
Losarchivosdedatosquecontienensólocadenas decaracterespuedencrearseyleersemás
fácilmenteconprogramasqueutilizanfuncionesdebibliotecaespecialmenteorientadaspara
cadenas
decaracteres.Algunasfunciones deestetipocomúnmenteusadasson gets,puts,
fgetsyfputs.Lasfuncionesputsygetsleenoescribencadenasdecaracteresa odesdelos
dispositivos
desalidaestándar,mientrasque fgetsyfputsintercambiancadenasconarchi­
vos.Comoelusodeestasfunciones
esdirecto,nocontinuaremosmásalláconestetema.Sin
embargo,deberíaexperimentarconestasfunciones,rehaciendoalgunosdelosprogramasde
lectura/escrituraorientadosacaracterespresentadospreviamente.
Muchosarchivosdedatoscontienenestructurasdedatosmáscomplicadas,talescomoregis­
trosqueincluyencombinaciones
deinformaciónnuméricay decarácter.Talesarchivossepue­
denprocesarusandolasfunciones
debibliotecafscanfyfprintf,quesonanálogasalas
funciones
scanfyprintfdiscutidasenelCapítulo4(versecciones4.4y4.6).Así,lafunción
fscanfpermiteleerundatoconformatodesdeunarchivodedatosasociadoconunarchivo
secuencial,y
fprint fpermiteescribirdatosconformatoenelarchivodedatos.Lasespecifi­
caciones
deformatosonlasmismasqueseusanconlasfunciones printfyscanf.
EJEMPLO12.5.Creaciónde unarchivoquecontieneregistros declientes.Enelúltimocapí-tulo
sepresentarontresprogramasqueeranusadossupuestamenteparacrearyactualizarregistrosdeclien­
tes(verEjemplos11.14y11.28).Cuandosedescribieronlosprogramassedijoquenoeranreales,ya
quesedeberíanusararchivosparaesasaplicaciones.Ahorafijamoslaatenciónenunprogramaque
creaunarchivoparaunaseriederegistrosdeclientescuyacomposiciónescomosigue:
typedefstruct{
intmesi
intdía;
intarrioi
}fecha;

ARCHIVOSDEDATOS 495
typedefstruct{
charnombre[SO]
charcalle[SO];
charciudad[SO];
intnum_cuenta;
inttipo_cuenta;
floatanteriorsaldo;
floatnuevosaldo;
floatpago;
fechaultimopago;
}registro;
Laestrategiageneralserádarlafechaactualyentrarenunbuclequeprocesaráunaseriederegis­
trosdeclientes.Paracadaclienteseleeránelnombredelcliente,lacalle,laciudad,elnúmerode
cuenta
(num_cuenta)yelsaldoanterior (anteriorsaldo).Acontinuaciónseasignaráelvalor
inicial
Oalosmiembrosdelaestructura nuevosaldoypago,seasignaráelcarácter 'A'a
tipo_cuenta(indicandoelestado«Aldía»)ylafechaactualseasignaa ultimopago.Cada
registrodeclienteseescribirá
enunarchivodesóloescriturallamado registro.dato
E!procesocontinuaráhastaqueelnombre deunclientecomienceconloscaracteres FIN(tantoen
mayúsculascomo
enminúsculas).Cuandoseencuentre FIN,seescribiráenelarchivodedatosindi­
candounacondicióndefindearchivo.
Acontinuaciónsemuestraelprogramacompleto.
/*crearunarchivodedatosquecontieneregistrosdeclientes*/
#include
#include<stdio.h>
<string.h>
#defineVERDADERO 1
typedefstruct{
intmesi
intdia;
intarria;
}fecha;
typedefstruct{
charnombre[SO];
charcalle[SO];
charciudad[SO];
intnuro_cuentai
inttipo_cuenta;
floatanteriorsaldo;
floatnuevosaldo;
floatpago;
fechaultimopago;
}registro;
/*(enteropositivo)*/
/*A(Aldía),R(atrasa-
da)o D(delincuente)*/
/*(cantidadnonegativa)*/
/*(cantidadnonegativa)*/
/*(cantidadnonegativa)*/
registroleerpantalla(registro
voidescribirarchivo(registro
cliente);/*'prototipode
cliente);/*prototipode
función* /
función* /

496 PROGRAMACiÓN ENC
FILE*fpt, /*punteroalaestructurapredefinidaFILE*/
main()
{
intindicador
registrocliente,
VERDADERO; / * declaracióndevariable* /
/*declaracióndevariabledeestructura*/
/*abrirunarchivonuevosoloparaescritura* /
fpt;:;fopen(Uregistro.dat
ll
,nwll)¡
,A';=
cliente.nuevosaldo
cliente.pago=O,
cliente.tipo_cuenta
/ *introducirfechayasignarvaloresiniciales* /
printf("SISTEMADEFACTURACION DECLIENTES -INICIALIZACION"),
printf("Introduzcalafecha·actual(mm/dd/aaaa)");
scanf("%d/%d/%d",&cliente.ultimopago.mes,
&cliente.ultimopago.dia,
&cliente.ultimopago.anio),
;:;O;
/ *bucleprincipal* /
while(indicador){
/*introducirelnombredelclienteyescribirloenel
archivo* /
printf("Nombre(introducir\'FIN\'paraterminar):");
scanf(1I%[A]", cliente.nombre);
fprintf(fpt,"%s", cliente.nombre),
/ *comprobacióndelacondicióndeparada* /
if(strcmp(cliente.nombre,"FIN") O)
break,
cliente=leerpantalla(cliente);
escribirarchivo(cliente);
}
fclose(fpt)
}
registroleerpantalla(registrocliente)
/ *leerelrestodedatos* /
{
printf("Calle:"),
scanf("%[A]",cliente.calle),
printf("Ciudad:");
scanf("%[A]",cliente.ciudad),
printf("Númerodecuenta:");\
scanf(n%dti,&cliente.nuro_cuenta)i
printf("Saldoactual:");

ARCHIVOSDEDATOS 497
scanf("%f",&cliente.anteriorsaldo);
return(cliente);
}
voidescribirarchivo(registrocliente)1*escribirelrestode
losdatosenelarchivo*1
{
fprintf(fpt,
fprintf(fpt,
fprintf(fpt,
fprintf(fpt,
fprintf(fpt,
fprintf(fpt,
fprintf(fpt,
fprintf(fpt,
return;
lI%s
ll
,cliente.calle);
"%s",cliente.ciudad);
"%d",cliente.num_cuenta);
lI%c
ll
rcliente.tipo_cuenta);
"%.2f",cliente.anteriorsaldo);
1I%.2f",cliente.nuevosaldo)¡
"%.2f",cliente.pago);
"%dl%dl%d",cliente.ultimopago.mes,
cliente.ultimopago.dia,
cliente.ultimopago.anio);
}
Elprogramacomienzadefiniendolacomposicióndecadaregistrodeclientey delpunterodear­
chivo
fpt.Dentrode mainseabreunnuevoarchivo desóloescritura,llamado registro.datoA
continuación,elprogramapidelafechaactualyseasignanvaloresinicialesalosmiembrosdelaes­
tructura
nuevosaldo,pagoytipo_cuenta.
Elprogramaentraenunbucle whilequepideelnombre deunclientey loescribeenelarchivo
dedatos.Acontinuación,elprogramacompruebasielnombreintroducidoesF
IN(mayúsculaso
minúsculas).
Siesasí,sesaledelbucle,secierraelarchivoyterminalaejecución.Enotrocaso,elresto
delainformacióndelclienteactualseintroducemediantelafunción
leerpantallayseescribeen
elarchivodedatosconlafunción
escribirarchiyo.
Enmainyleerpantallavemosquelosdatosseintroduceninteractivamente,usandolasfuncio­
nes
printfyscanf.Porotrolado,en mainyescribirarchivolosdatosseescribenen elarchivo
mediantelafunción
fprintf.Lasintaxisquegobiernaestafuncióneslamismaquelade printf,
exceptoque setienequeincluirunpunteroaarchivosecuencialcomoargumentoadicional.Observeque
lacadena
decontrolhaceuso delosmismosgrupos decaracteres(lasmismascaracteristicasdeformato)
quelafunción
printfdescritaenelCapítulo 4.
Cuandoseejecutaelprograma,lainformaciónparaelregistrodecadaclienteseintroduciráinte­
ractivamente,comosemuestraacontinuaciónparacuatroclientesficticios.Comosiempre,lasres­
puestasdelusuarioestánsubrayadas.
SISTEMA DEFACTURACION DECLIENTES INICIALIZACION
Introduzcalafechaactual(mm/dd/aaaa):512411998
JohnsonSteveterminar):para
Drive
(introducir'FIN'
123Mountainview
Denver.CO
decuenta:4208
actual:247.88
Nombre
Calle:
Ciudad:
Número
Saldo

498 PROGRAMACiÓN ENC
Nombre(introducir'FIN'paraterminar)
Calle:4383AlligatorBlvd
Ciudad:FortLauderdale.FL
Númerodecuenta:2219
Saldoactual:135.00
SusanRichards
Nombre
Calle:
Ciudad:
Número
Saldo
(introducir'FIN'para
1787PacificParkwav
SanDiego.CA
decuenta:8452
actual:387.42
terminar)MartinPeterson
NewYork,NY
decuenta:711
actual:260.00
Nombre
Calle:
Ciudad:
Número
Saldo
(introducir'FIN'
1000GreatWhite
para
Way
terminar)Phyllissmith
Nombre(introducir'FIN'paraterminar):FIN
Despuésdeejecutar elprogramasehacreadoelarchivo dedatosregistro.dat,quecontiene
lasiguienteinformación:
SteveJohnson
123MountainviewDrive
Denver,ca
4208
A
247.88
0.00
0.00
5/24/1998
SusanRichards
4383A11igatorBlvd
FortLauderdale,FL
2219
A
135.00
0.00
0.00
5.124/1998
MartinPeterson
1787PacificParkway
SanDiego,CA
8452·
A
387.42
0.00
0.00
5/24/1998

ARCHIVOSDEDATOS 499
PhyllisSmith
1000GreatWhiteWay
NewYork,NY
711
A
260.00
0.00
0.00
5/24/1998
FIN
Enlasiguientesección veremosunprogramaqueactualizalainformacióncontenida enestearchivo.
12.3.PROCESAMIENTO DEUNARCHIVO
Lamayoríadelasaplicacionesconarchivosrequierenquesemodifiqueelarchivocuandose
procesa.Porejemplo,enaplicacionesqueinvolucranelprocesamientoderegistros
declientes,se
puededesearañadirnuevosregistrosalarchivo(yaseaalfinaldelarchivooentrelosregistros
existentes),borrarregistrosexistentes,modificarloscontenidosderegistrosoreordenarlos
registros.Estosrequisitossugierenvariasestrategiascomputacionalesdistintas.
Consideremos,porejemplo,elproblema
deactualizarlosregistrosdentro deunarchivode
datos.Hayvariosenfoquesaesteproblema.Quizáelenfoquemásobvioesleercadaregistro
de
unarchivo,actualizarelregistroydespuésescribirelregistroactualizadoalmismoarchivo.Sin
embargo,estaestrategiapresentaalgunosproblemas.Enparticular,esdificilleeryescribirdatos
conformatoalmismoarchivosinmodificarlaordenación
deloselementosdentrodelarchivo.
Además,elconjuntooriginal
deregistrospuedevolverseinaccesiblesialgofuncionamaldurante
laejecucióndelprograma.
Otroenfoqueestrabajarcondosarchivosdiferentes:unarchivoantiguo(la
fuente)yotro
nuevo.
Seleecadaregistrodelarchivoantiguo,seactualizayseescribealnuevoarchivo.Cuan­
dosehanactualizadotodoslosregistros,seborraelarchivoantiguoosealmacenacomocopiade
seguridadyserenombraelarchivonuevo.Asíelnuevoarchivoseconvierteenlafuenteparael
siguientetumodemodificaciones.
Históricamente,
elorigendeestemétodoproviene delosprimerosdíasdelacomputación,
cuandolosarchivosdedatossealmacenabanencintasmagnéticas.
'>inembargo,estemétodose
usatodavía,yaqueproporcionaunaserie
dearchivosfuenteantiguosquepuedenusarsepara
generarlahistoria
.deuncliente.Elarchívofuentemásrecientesepuedeusartambiénparacrear
denuevoelarchivoactualsiéstesedañaosedestruye.
EJEMPLO12.6.Actualización dennarchivoquecontieneregistros declientes.ElEjemplo12.5pre­
sentóunprogramaparacrearunarchivodedatosllamadoregistro.datquecontieneregistrosdeclien­
tes.Ahorasepresentaunprogramaparaactualizarlosregistrosenelarchivodedatos.Elprogramausaráel
procedimientodeactualizacióncondosarchivosdescritoanteriormente.Sesuponequeelarchivodedatos
creadopreviamente,registro.dat,hasidorenombradocomoregistro.aut.Ésteseráelarchivo
fuente.

500 PROGRAMACiÓN ENC
/ *actualizarunarchivodedatosquecontieneregistrosdeclientes*/
LaestrategiageneralserásimilaraladescritaenelEjemplo12.5.Primeroseintroduce lafecha
actual
yseentraenunbuclequeleeunaseriederegistrosdeclientesde registro.antyescribe
loscorrespondientesregistrosactualizadosenunnuevoarchivodedatosllamado
registro.nue.
Cadapasadaporelbucleleeráunregistro,loactualizarásiesnecesarioyloescribiráen
registro.nue.Observequetodoslosregistros,actualizadosono, seescribiránen registro.nue.
Elprocesocontinuaráhastaqueseleaelnombre FINdelarchivofuente(mayúsculasominúsculas).
Cuandoestosuceda,seescribiráF
INenelnuevoarchivo,indicandounacondicióndefindearchivo.
Acontinuaciónsemuestraelprogramacompleto.Elprogramacomienzadefiniendo lacomposi­
cióndecadaregistrodecliente,usandolasmismasdefinicionesqueenelEjemplo12.5.Estasdefini­
cionesvanseguidas
porlasdefinicionesdepunterosaarchivossecuenciales antptynuept.
Dentrodelafunción main,registro.antesabiertocornounarchivodesólolecturayaexis­
tente,y
registro.nuecornounarchivonuevodesóloescritura.Si registro.antnopuede
abrirse,
segeneraunmensajedeerror.Enotrocaso,elprogramaentraenunbucle whi1equeleelos
sucesivosregistrosdeclientesde
registro.ant(enrealidaddelarchivosecuencial antpt),ac­
tualizacadaregistrosiesnecesarioyloescribeen
registro.nue(delarchivosecuencial nuept).
#include
#include
<stdio.h>
<string.h>
#defineNULL O
#defineVERDADERO 1
typedefstruct{
intmes;
intdia;
intarria;
}fecha;
typedefstruct{
charnombre[SO];
charcalle[SO];
charciudad[SO];
intnum_cuentai
inttipo_cuenta;
floatanteriorsaldo;
floatnuevosaldo;
floatpago;
fechaultimopago;
}registro;
/*(enteropositivo)*/
/*A(Aldía),R(atrasada)
o D(delincuente)* /
/*(cantidadnonegativa)*/
/*(cantidadnonegativa)*/
/*(cantidadnonegativa)*/
registroleerarchiva(registrocliente);
registroactualizar(registrocliente);
voidescribirarchivo(registrocliente);
/ *prototipo
/ *prototipo
/ *prototipo
de
de
defunción* /
función*/
función* /
FILE*antpt,*nuept;
intmes,dialarrio;
/ *punterosala
rapredefinida
/ *declaraciónde
globales* /
estructu­
FILE* /
variables

ARCHIVOSDEDATOS 501
main( )
{
intindicador VERDADERO;
registrocliente;
/*
/*
declaracióndevariablelocal*/
declaracióndevariabledeestructura*/
cliente.nombre)
cliente.nombre)
/*abrirarchivosdedatos*/
if«antptfopen("registro.ant","r")) NULL)
printf("ERROR -Nosepuedeabrirarchivoespecificado");
else(
nuept=fopen(llregistro.nue",nwn)¡
/ *introducirfechaactual* /
printf("SISTEMA DEFACTURACION DECLIENTES");
printf("-ACTUALIZACION");
printf("Introduzcalafechaactual(mm/dd/aaaa)");
scanf("%d/%d/%d",&mes,&dia,&anio);
/ *bucleprincipal*/
while(indicador)(
/*leerunnombredelarchivoantiguoyescribirloenel
nuevoarchivo* /
fscanf(antpt,%[A]",
fprintf(nuept,"%s",
/*
if
comprobacióndelacondiciónde
(strcmp(cliente.nombre,"FIN")
break;
parada
--O)
*/
/*leerelrestodelainformacióndelarchivoantiguo*/
cliente~leerarchivo(cliente);
/*solicitarlainformaciónactuaJ.;.zada* /
clienteactualizar(cliente);
/*escribirlainformaciónactualizadaenelnuevo
archivo* /
escribirarchivo(cliente);
}
fclose(antpt);
fclose(nuept);
} / *findelelse* /
}
registroleerarchivo(registrocliente)/*leerelrestodedatos
delantiguoarchivo* /
{

502 PROGRAMACiÓN ENC
fscanf(antpt,
fscanf(antpt,
fscanf(antpt,
fscanf(antpt,
fscanf(antpt,
fscanf(antpt,
fscanf(antpt,
fscanf(antpt,
"
%[A]",cliente.calle);
%[A]",cliente.ciudad);
%d",&cliente.num_cuenta)
%c
l
',&cliente.tipo_cuenta);
%f",&cliente.anteriorsaldo)
%f",&cliente.nuevosaldo);
%fll/&cliente.pago)¡
%d/%d/%d",&cliente.ultimopago.mes,
&cliente.ultimopago.dia,
&cliente.ultimopago.anio)
return(cliente);
}
registroactualizar(registrocliente)/*solicitarlanuevain­
formación,actualizarel
registroymostrarelre­
sumendedatos* /
{
printf("Nombre: %s",cliente.nombre);
printf(" Númerodecuenta:%d",cliente.num_cuenta);
printf("Saldoanterior:%7.2f",cliente.anteriorsaldo);
printf(11 Pagoactual:n)i
scanf("%f",&cliente.pago)
if(cliente.pago>O){
cliente.ultimopago.mes=mes;
cliente.ultimopago.dia=dia;
cliente.ultimopago.anio=anio;
cliente.tipo_cuenta=(cliente.pago<0.1*cliente.anteriorsaldo)
case'D'
default:
/Al;(cliente.anteriorsaldo>O)?'D'
?'R'
cliente.anteriorsaldocliente.pago;
%7.2f",cliente.nuevosaldo);
printf("ERROR")
printf("ATRASADA")
break;
printf("ALDIA")
break;
printf("DELINCUENTE")
l;>reak;
case'R':
}
}
else
cliente.tipo_cuenta
printf(" Estadodelacuenta:");
switch.(cliente.tipo_cuenta){
case'Al:
cliente.nuevosaldo=
printf("Nuevosaldo:

ARCHIVOSDEDATOS 503
return(cliente);
}
voidescribirarchivo(registrocliente)/*escribirlainformación
actualizadaenelnue­
voarchivo* /
{
)
fprintf(nuept,
fprintf(nuept,
fprintf(nuept,
fprintf(nuept,
fprintf(nuept,
fprintf(nuept,
fprintf(nuept,
fprintf(nuept,
return;
"%s",cliente.calle);
"%s",cliente.ciudad)
;
n%d
ll
,cliente.nuro_cuenta)
"%c",cliente.tipo_cuenta);
"%.2f",cliente.anteriorsaldo)
"%.2f",cliente.nuevosaldo);
"%.2f",cliente.pago);
"%d/%d/%d", cliente.ultimopago.mes,
cliente.ultimopago.dia,
cliente.ultimopago.anio);
Dentrodemai nseleecadanombredeclientedelarchivofuenteyseescribeacontinuación
enelarchivonuevo.Lainformaciónrestantedecadaregistroseleeluegodelarchivofuente,
seactua­
lizayseescribeenelnuevoarchivodentrodelasfunciones
leerarchivo,actualizary
escribirarchivo,respectivamente.Esteprocesocontinúahastaqueseencuentraunregistroque
tienecomonombredecliente
FIN.Acontinuaciónsecierranambosarchivosdedatosyterminala
ejecución.
Lafunciónleerarchivoleelainformaciónadicionalparacadaregistrodeclientedelarchivo
fuente.Losdistintosdatosserepresentancomomiembrosdelavariable
deestructuracliente.Esta
variabledeestructurasepasacomoargumentoalafunción.Seusalafuncióndebibliotecaf s c
anf
paraleercadadato,empleandounasintaxisesencialmenteidénticaalausada
enlafunciónscanf,
comosedescribióenelCapitulo4.Sinembargo,en fscanfhayqueincluirelpunteroaarchivo
secuencial
antptcomoargumentoadicionaldentrodecadallamadaafunción.Unavezqueseha
leidotoda
lainformacióndelarchivofuente,elregistrodelclienteesdevueltoama in.
Lafunciónactualizaressimilar,aunqueesnecesarioqueseintroduzcadesdeeltecladounvalor
para
cliente.pago.Acontinuaciónseasignainformaciónadicionala cliente.ultimopago,
cliente.tipo_cuentaycliente.nuevosaldo.Losvaloresasignadosdependendelvalordado
a
cliente.pago.Elregistroactualizadoesdevueltoa main.
Lafunciónrestante, escribirarchivo,aceptacadaregistrodeclientecomounargumentoy
loescribe
enelnuevoarchivodedatos.Dentrode escribirarchivolafuncióndebiblioteca
fprintfseusaparatransferirlainformaciónalnuevoarchivodedatosusandolosmismosprocedi­
mientosmostradosenelEjemplo12.5.
Cuandoseejecutaelprograma,semuestranparacadaclienteelnombre,númerodecuentaysaldo
anterior.Acontinuaciónsepidealusuariounvalorparaelpagoactual.Cuandosehaintroducidoeste
valor,semuestranelnuevosaldoyelestadoactual
delacuentadelcliente.
AcontinuaciónsemuestraunatipicasesióninteractivabasadaenelarchivocreadoenelEjem­
plo12.5.Lasrespuestasdelusuarioestánsubrayadas,comosiempre.

504 PROGRAMACiÓN ENC
SISTEMA DEFACTURACION DECLIENTES ACTUALIZACION
Introduzcalafechaactual(mm/dd/aaaa):12/29/1998
Nombre: SteveJohnson Númerodecuenta:4208
Saldoanterior:247.88Pagoactual:25.00
Nuevosaldo:222.88Estadodelacuenta:ALDIA
Nombre: SusanRichards Númerodecuenta:2219
Saldoanterior:135.00Pagoactual:135.00
Nuevosaldo: 0.00Estadodelacuenta:ALDIA
Nombre: MartinPeterson Númerodecuenta:8452
Saldoanterior:387.42Pagoactual:35.00
Nuevosaldo:352.42Estadodelacuenta:ATRASADA
Nombre: PhyllisSmith Númerodecuenta:711
Saldoanterior:260.00Pagoactual:Q
Nuevosaldo:260.00Estadodelacuenta:DELINCUENTE
Unavezquesehanprocesadotodoslosregistrosdeclientes,
sehabrácreadoelnuevoarchivode
datos
registro.nue,quecontienelasiguienteinformación.
SteveJohnson
123MountainviewDrive
Denver,CO
4208
A
247.88
222.88
25.00
12/29/1998
SusanRichards
4383A11igatorB1vd
FortLauderdale,FL
2219
A
135.00
0.00
135.00
12/29/1998

ARCHIVOSDEDATOS 505
MartinPeterson
1787PacificParkway
SanDiego,CA
8452
R
387.42
352.42
35.00
12/29/1998
PhyllisSmith
1000GreatWhiteWay
NewYork,NY
711
D
260.00
260.00
0.00
5/24/1998
FIN
Observequeelarchivoaotiguo,registro.ant,aúnestádisponibleensuformaoriginal;portanto,
puedeseralmacenadocornoarchivohistórico.Antesdevolveraejecutaresteprograma,elnuevoarchi­
vodedatoshaderenombrarsecornoregistro.ant.(Generalmenteestosehaceaniveldesistema
operativo,antes deentrarenelprogramadeactualización.)
12.4.ARCHIVOSSINFORMATO
Algunasaplicacionesinvolucran elusodearchivosparaalmacenarbloques dedatos,dondecada
bloqueconsisteenunnúmerofijodebytescontiguos.Cadabloquerepresentarágeneralmente
unaestructuradedatoscompleja,comounaestructuraounarray.Porejemplo,unarchivode
datospuedeconstardevariasestructurasquetenganlamismacomposición,opuedecontener
múltiplesarraysdelmismotipoytamaño.Paraestasaplicacionesseríadeseableleeroescribirel
bloqueenterodelarchivodedatosenvezdeleeroescribirseparadamentelascomponentes
individuales(losmiembrosdelaestructuraoelementosdelarray)decadabloque.
Lasfuncionesdebiblioteca
freadyfwritedebenusarseenestassituaciones.Aestas
funcionesselasconocefrecuentementecomofunciones
delecturayescritura sinformato.Igual­
mentesehacereferencia
.aestosarchivosdedatoscomoarchivosdedatossinformato.
Cadaunadeestasfuncionesnecesitacuatroargumentos:unpunteroalbloq\Jededatos,el
tamañodelbloquededatos,elnúmerodebloquesatransferiryelpunteroaunarchivosecuen­
cial.Así,unafunción
fwrit etípicapodríaescribirsecomo
fwrite(&cliente,sizeof(registro),1,fpt);
dondeclienteesunavariabledeestructura de.tiporegistroyfptesunpunteroa.archivo
secuencialasociadoaunarchivodedatosabiertoparasalida.

506 PROGRAMACiÓN ENC
EJEMPLO12.7.Creacióndeunarchivodedatossinformatoquecontieneregistrosdeclientes.
Consideremosunavariacióndelprogramapresentadoen elEjemplo12.5paracrearunarchivo dedatos
quecontieneregistros
declientes.Sinembargo,ahoraseescribecadaregistrodeclienteenelarchivo
datos.bincomounbloquedeinformaciónsimple,sinformato.Estoestáencontrasteconelpro­
gramaanterior,dondeseescribieronloselementosdecadaregistro(losmiembros
delaestructurain­
dividual)comodatosseparados
yconformato.
Acontinuaciónsemuestraelprogramacompleto.
/*crearunarchivodedatossinformatoquecontieneregistrosde
clientes*/
#include
#include<stdio.h>
<string.h>
#defineVERDADERO 1
typedefstruct{
intmesi
intdía;
intarrio;
}fecha;
typedefstruct{
charnombre[8O];
charcalle[80];
charciudad[ 8O];
intnUffi_cuenta;
inttipo_cuenta;
}
float
float
fJoat
fecha
registro;
anteriorsaldo;
nuevosaldo;
pago;
ultimopago;
/*(enteropositivo)*/
/*A(Aldía),R(atrasa-
da)o D(delincuente)*/
/*(cantidadnonegativa)*/
/*(cantidadnonegativa)*/
/*(cantidadnonegativa)*/
registroleerpantalla(registrocliente);/*prototipodefunción*/
FILE*fpt;
main()
{
/*puntero.alaestructurapredefinidaFILE*/
intindicador
=VERDADERO; / *declaracióndevariable* /
registrocliente; /*declaracióndevariabledeestructura* /
/*abrirunarchivonuevosoloparaescritura*/
fpt=fopen(11datos.bin11I " W");
/*introducirdatosyasignarvaloresiniciales* /
prinj:f("SISTEMADEFACTURACION DECLIENTES-INICIALIZACION");
printf("Introduzcalafechaactual(mm/dd/aaaa):").;

scanf("%d/%d/%d",
cliente.nuevosaldo
cliente.pago=O;
cliente.tipo_cuenta
ARCHIVOSDEDATOS 507
&cliente.ultimopago.mes,
&cliente.ultimopago.dia,
&cliente.ultimopago.anio);
=Oi
;;;;:/Al;
/ *bucleprincipal* /
while(indicador){
/ *introducirel
printf("Nombre
scanf("%[A]"/
nombredelcliente
(intraducir\'FIN\'
cliente.nombre);
*/
paraterminar) n ) ;
/ *comprobacióndelacondiciónde
if(strcmp(cliente.nombre,"FIN")
break;
parada
--O)
*/
/*introducirelrestodelosdatosyescribirloenelarchivo*/
cliente=leerpantalla(cliente);
fwrite(&cliente,sizeof(registro),1,fpt);
/ *borrarcadenasdecaracteres* /
strset(cliente.nombre,');
strset(cliente.calle,');
strset(cliente.ciudad,');
}
fclose(fpt)
}
registroleerpantalla(registrocliente)/*leerelrestodedatos*/
{
printf("Calle:O);
scanf("%[A]",cliente.calle);
printf("Ciudad:");
scanf("%[A]",cliente.ciudad);
printf(llNúrnerodecuenta:11)i
scanf-(11%d"r&cliente.nurn_cuenta)i
printf("Saldoactual:");
scanf("%f",&cliente.anteriorsaldo);
return(cliente);
}
Comparando esteprogramaconelmostradoenelEjemplo12.5,seobservaqueambosprogtamasson
muysimilares.Enmain,elprogtamaactualleecadanombredeclienteycomprueba unacondiciónde
finalización(F
IN),peronoescribeelnombredelcliente enelarchivo
de'datos,como'enelprograma
anterior.Porelcontrario,si
noseindicaunacondicióndefinalización,
se<leeinteractivamenteelresto
delregistrodelclienteyseescribe
enelarchivodedatosconlainstrucción fwrite
fwrite(&cliente,sizeof(registro),1,fpt);

50S PROGRAMACiÓN ENC
Observequeelarchivocreadoporesteprogramasellama datos.bin,comoseindicóen elprimer
argumentoenlallamadaalafunciónf
open.
Lafuncióndefinidaporelprogramador escribirarchivomostradaen elEjemplo12.5noes
necesariaenesteprograma,pueslafuncióndebiblioteca
fwritetomasulugar.Porotrolado,ambos
programasusanlafuncióndefinidaporelprogramador
leerpantalla,quehacequelainforma­
cióndadaparaunregistrodeclienteseintroduzcaenlacomputadorainteractivamente.
Despuésdequecadaregistrosehaescritoenelarchivodedatos,seborranlosmiembrosqueson
cadenasdecaracteres
cliente.nombre,cliente.calleycliente.ciudad(sustituidos
conespaciosenblanco
l,deformaquenadadelainformaciónprevia seincluiráencadanuevoregistro.
Lafuncióndebiblioteca
strsetseusaconestepropósito.Asi,ladeclaración
strset(cliente.nombre,');
reemplazaconespaciosenblancoelcontenidode cliente.nombre,comoindica''.Observe
quesehaincluidoelarchivodecabecera
string.hcomosoportealafunción strset.
Laejecucióndeesteprogramaproduceelmismodiálogointeractivoqueelmostradoen elEjem­
plo12.5.Deestaformadurantelaejecucióndelprogramaelusuarionopuededecirsielarchivoestá
siendocreadoconosinformato.Unavezqueelnuevoarchivo
datos.binhayasidocreado,sus
contenidosnoseránlegiblesamenosqueseleaelarchivoconunprogramaespecialmenteescritopara
ello.Esteprogramasemuestraenelsiguienteejemplo.
Unavezquesehacreadounarchivodedatossinformato,surgelapreguntadecómodetectar
unacondicióndefindearchivo. Lafuncióndebibliotecafeofsirveparaestepropósito.(Real­
mentefeofindicaráunacondicióndefindearchivoparacualquierarchivodedatossecuencial,
nosóloparaunosinformato.)Estafuncióndevuelveunvalordistintodecero(VERDADERO) si
se
detectaunacondicióndefindearchivoyunvalorcero(FALSO)sinosedetecta.Portanto,un
programaqueleeunarchivodedatossinformatopuedeutilizarunbuclequelealossucesivos
registroshastaqueelvalordevueltoporfeofseanoVERDADERO.
EJEMPLO12.8. Actualizacióndeunarchivodedatossinformato qnecontieneregistrosdeclien­
tes.SeconsideraahoraotroprogramaparaleeryactualizarelarchivosinformatocreadoenelEjem­
plo12.7.Sevolveráahacerusodeunprocedimientodeactualizacióncondosarchivos,comoenel
Ejemplo12.6.Sinembargo,ahoralosarchivossellamarán
datos.antydatos.nue.Portanto,el
archivocreadoenelejemploanterior,llamado
datos.bin,serenombrarácomo datos.antantes
deejecutarelprogramaactual.
Lalógicageneraldelprograma
essimilaralapreseutada enelEjemplo12.6.Estoes, seleeunregistro
dedatos.ant,seactualizainteractivamenteyseescribeen datos.nue.Esteprocesocontinúahas­
taquesedetectelacondición
defindearchivoenlaoperación freadmásreciente.Observelaforma
enlacualseconstruyelacomprobacióndefindearchivoenelbucle
while,estoes,while
(!feof(antpt)).
Sinembargo,esteprogramaharáusodelasfuncionesdebiblioteca freadyfwriteparaleerre­
gistrosdeclientessinformatode
datos.antyparaescribirlosregistrosactualizados endatos.nue.
Portanto,elprogramaactualnohaceuso delasfuncionesdefinidasporelprogramador leerarchiva
yescribirarchivo,.comoenelEjemplo12.6.
A.continuación
s.emuestraelprogramacompletoen C.
/ *actualizarunarchivodedatossinformatoquecontieneregis­
trosdeclientes* /

ARCHIVOSDEDATOS 509
#include<stdio.h>
#defineNULLO
typedefstruct{
intmesi
intdía;
intarrio;
}fecha;
typedefstruct{
charnombre[8O];
charcalle[80];
charciudad[8O];
intDUffi_cuenta;
inttipo_cuenta;
floatanteriorsaldo;
floatnuevosaldo;
floatpago;
fechaultimopago;
}registro;
/*(enteropositivo)*/
/*A(Aldía),R(atrasa-
da)o D(delincuente)*/
/*(cantidadnonegativa)*/
/*(cantidadnonegativa)*/
/*(cantidadnonegativa)*/
/*declaración
registroactualizar(registro
FILE*antpt,*nuept;
intmes,día,arrio;
main()
{
cliente);/*
/*
prototipodefunción* /
punterosalaestructu­
rapredefinidaFILE* /
devariablesglobales*/
registrocliente; /*declaracióndevariabledeestructura*/
"W
I1
) ;
/*abrirarchivosdedatos*/
if((antpt=fopen("datos.ant","r")) NULL)
printf("ERROR -Nosepuedeabrirelarchivoespecificado");
else{
nuept =fopen(11datos.TIue11i
/ *introducirfechaactual* /
printf("SISTEMADEFACTURACION DECLIENTES-ACTUALIZACION");
printf("Introduzcalafechaactual(mm/dd/aaaa):");
scanf("%d/%d/%d",&mes,&dia,&anio);
/*leerelprimerregistrodelarchivoantiguodedatos*/
fread(&cliente,sizeof(registro),1,antpt);
/ *bucleprincipal(continuarhasta.
fin-de-archivo)
que
*/
sedetecte

510 PROGRAMACiÓN ENC
while(!feof(antpt))(
/ *solicitarlainformaciónactualizada* /
cliente=actualizar(cliente);
/*escribirlainformaciónactualizadaenelnuevoarchivo*/
fwrite(&cliente,sizeof(registro),1,nuept);
/*leerelsiguienteregistrodelarchivoantiguodedatos*/
fread(&cliente,sizeof(registro),1,antpt);
}
fclose(antpt);
fclose(nuept);
}
/*findelelse*/
}
registroactualizar(registrocliente)/*solicitarlanuevain­
formación,actualizarel
registroymostrarelre­
sumendedatos* /
(
printf("Nombre: %s",cliente.nombre);
printf(" Númerodecuenta:%d",cliente.num_cuenta);
printf("Saldoanterior:%7.2f",cliente.anteriorsaldo);
printf(11 Pagoactual:");
scanf("%f",&cliente.pago);
if(cliente.pago>O){
cliente.ultimopago.mes=mes;
cliente.ultimopago.dia=dia;
cliente.ultimopago.anio=anio;
cliente.tipo_cuenta=(cliente.pago<0.1*cliente.anteriorsaldo)
? 'R' /Al;
}
else
cliente.tipo_cuenta
cliente.nuevosaldo
printf("Nuevosaldo:
(cliente.anteriorsaldo>O)?'D'
cliente.anteriorsaldocliente.pago;
%7.2f",cliente.nuevosaldo);
fA'i
printf(" Estadodelacuenta:");
switch(cliente.tipo_cuenta)(
casefA':
printf("ALDIA");
break;
case'R':
printf("ATRASADA") ;
break;
caseID':
printf("DELINCUENTE");
break;

ARCHIVOSDEDATOS 511
defauIt:
printf("ERRüR");
}
return(cIiente);
}
Losresultadosdelaejecucióndeesteprogramasonsimilaresa losdelEjemplo12.6.
Nosecontinuarámásalláempleandoarchivosdedatosenestelibro.Recordar,sinembar­
go,quelamayoríadelasversiones
deCcontienenmuchasfuncionesdebibliotecapararealizar
operacionesorientadasaarchivos.Algunas
deestasfuncionesseusanconlosdispositivosestándar
deentrada/salida(lecturadeltecladoyescrituraenpantalla),otrasseusanparaarchivosde
datossecuencialesyotrasestándisponiblesparaarchivosdedatosorientadosalsistema.En
estecapítulotansólohemosarañadolasuperficie deesteimportantetema.Seanimaallectora
descubrirquéfuncionesrelacionadasconarchivosestándisponiblesensuversiónparticulardel
lenguaje.
12.1.
12.2.
12.3.
12.4.
12.5.
12.6.
12.7.
12.8.
12.9.
12.10.
12.11.
12.12.
12.13.
¿Cuáleslaventajafundamental deusararchivos?
Describirlasdistintasformasenquepuedenclasificarselosarchivosen
C.
¿Cuáleselpropósitodelárea debuffercuandosetrabajaconunarchivosecuencial de
datos?¿Cómosedefineeláreadebuffer?
Cuandosedefineelárea
debufferparausarlaconunarchivosecuencial,¿quérepresen­
taelsímboloFILE?¿Dóndesedefine
FILE?
¿Quéesunpunteroaunarchivosecuencial?¿Cuál eslarelaciónentreunpunteroaun
archivosecuencialyunárea
debuffer?
¿Quéseentiendeporabrirunarchivo?¿Cómoserealiza?
Relacionarlasreglasquegobiernanelusodelafunción
fapen.Describirlainforma­
ciónquedevuelveestafunción.
Relacionarlosdiferentestiposdearchivosquepuedenserespecificadosmediantela
funciónf
apeno
¿Cuáleselpropósito delafunciónfelose?¿Debeaparecerunallamadaaestafunción
dentrodeunprogramaqueusaunarchivo?
Describirunaconstrucciónnormalmenteusadaenprogramaciónquepresenteunmensa­
jedeerrorasociadoalallamadaalafunción fopen.
Describirdosmétodosdistintosparacrearunarchivo dedatossecuencial.¿Puedenusar­
selosdosmétodosenarchivossinformato?
Describirelprocedimientogeneralparacrearunarchivo
dedatossecuencialmediante
unprogramaespecialescritoen
C.¿Quéfunciones debibliotecaorientadasaarchivos
debenusarsedentrodelprograma?
¿Cómopuedevisualizarseunarchivosecuencialunavezquehasidocreado?¿Sepuede
aplicarlarespuestaaarchivossinformato?

512
12.14.
12.15.
12.16.
12.17.
12.18.
12.19.
12.20.
PROGRAMACiÓN ENC
Describirelprocedimientogeneralparaleerarchivosdedatossecuencialesusandoun
programaescritoen
C.¿Quéfuncionesdebibliotecaorientadasaarchivosdebenusarse
dentrodelprograma?CompararlarespuestaconladelProblema12.12.
Describirdosenfoquesdistintosparaactualizarunarchivodedatos.¿Quéenfoquees
mejor
yporqué?
Contrastarelusodelasfunciones
fscanfyfprintfconelusode scanfyprintf
descritasenelCapítulo4.¿Enquésediferencianlasreglasgramaticales?
¿Paraquétipodeaplicacionessonútileslosarchivossinformato?
Contrastarelusodelasfunciones
freadyfwriteconlautilizaciónde fscanf
yfprintf.¿Enquésediferencianlasreglasgramaticales?¿Paraquétipodeaplicacio­
nesesadecuadocadagrupodefunciones?
¿Cuáleselpropósitodelafuncióndebiblioteca
strset?¿Porquédeberíausarsela
funcióndebiblioteca
strsetenunprogramaquecreaunarchivosinformato?
¿Cuáleselpropósitodelafuncióndebiblioteca
feof?¿Cómodebeutilizarselafunción
debiblioteca
feofdentrode unprogramaqueactualiza unarchivodedatossinformato?
12.21.
12.22.
12.23.
12.24.
12.25.
12.26.
Asociarelpunteroaarchivosecuencia puntrconunnuevoarchivosecuencialllamado
e s t
udian.dat.Abrirelarchivosóloparaescritura.
Asociarelpunteroaarchivosecuencial
puntrconunarchivosecuencialpreviamenteexis­
tentellamado
estudian.dat.Abrirelarchivo demodoquesepuedaleer yescribiren él.
Mostrarcómosedebecerrarelarchivo alfinaldelprograma.
Asociarelpunteroaarchivosecuencial
punt rcon unarchivosecuencialnuevollamado
muestra.dat.Abrirelarchivodemodoquesepuedaleer yescribirenél.Mostrarcómose
puedecerrar elarchivoalfinaldelprograma.
Asociarelpunteroaarchivosecuencial
puntrconunarchivosecuencialpreviamenteexis­
tentellamado
muestra.dat.Abrirelarchivo demodoquesepuedaleer yescribiren él.
Mostrarcómopuedecerrarseelarchivo alfinaldelprograma.
Repetir
elProblema12.24,añadiendolaposibilidad degenerarunmensajedeerrorenelcaso
dequeelarchivo dedatosnopuedaserabierto(porejemplo, sielarchivonoestápresente).
Acontinuación
semuestrael
esquem~. delaestructuradeunprogramaen C.
#include<stdio.h>
main( )
{
FILE*fpt;
inta¡
floatb;
chare;
fpt=fopen(lIrnuestr9,o,q.atnI"w
ll
)i
fclose(fpt);
}

ARCHIVOSDEDATOS 513
Introducirlosvalorespara a,byedesdeelteclado,enrespuestaalaspeticionesgeneradas
porelprograma.Despuésescribirlosvaloresenelarchivo.Formatearlosvaloresencoma
flotantedemodoqueseescribanenelarchivoconnomás
dedosdecimales.
12.27.Acontinuaciónsemuestraelesquemadelaestructuradeunprogramaen C.
#include<stdio.h>
main()
{
FILE*fpt¡
inta;
floatb;
charei
fpt=fope,n(l1muestra.dat","r")¡
fclose(fpt)
}
Leerlosvaloresde a,byedelarchivo ymostrarlosenlapantalla.
12.28.Acontinuaciónsemuestraelesquemadelaestructuradeunprogramaen C.
#include<stdio.h>
main()
{
FILE*ptl,
~pt2;
inta;
floatb¡
charei
ptl=
pt2=
fopen(Ilrnuestra.ant11,
fopen(Ilmuestra-.nue 11I
nr11);
"Wll)i
}
fclose(ptl)
fclose(pt2)
a)Leerlosvaloresde a,bye delarchivomuestra.ant.
b)Mostrarcadavalorenlapantallaeintroducirun valoractualizado.
e)Escribirlosnuevosvaloresenelarchivo
muestra.nue.Formatearlosvaloresencoma
flotantedemodoqueseescribanenelarchivo
connomásdedosdecimales.

514 PROGRAMACiÓN ENC
12.29.Acontinuaciónsemuestraelesquemade laestructurade unprogramaen C.
#include<stdio.h>
main( )
{
FILE*ptl,*pt2;
charnombre[20];
ptl=
pt2=
fopen("muestra.ant
l'
,
fopen(lImuestra.nuenf
11r")i
11Wn ) ;
}
fclose(ptl);
fclose(pt2);
a)Leerlacadenadecaracteresrepresentada pornombredelarchivomuestra.ant.
b)Mostrarlaenlapantalla.
c)Introducirunanuevacadena.
d)Escribirlanuevacadenaalarchivo muestra.nue.
12.30.Acontinuaciónsemuestraelesquemade laestructuradeunprogramaenC.
#include<stdio.h>
main()
{
FILE*ptl,*pt2;
struct{
inta;
floatb;
chare;
charnombre[2O];
}valoresi
ptl=
pt2
fopen("datos.ant",
fopen("datos.nue
ll
,
nrn) ;
"W+n)i
}
fclose(ptl);
fclose(pt2);
a)Leerelvalorde valores.nombredelarchivoconformato datos.antymostrarlo
en
lapantalla.
b)Introducirlosvalorespara valores.a,valores.byvalores.edesdeelteclado,
como
respuestaalaspeticionesdelprograma.
c)Escribirlosvaloresde valores.nombre,valores.a,valores.b Yvalores.e
enel'archivoconformatodatos.nue.

ARCHIVOSDEDATOS 515
12.31.RepetirelProblema12.30tratandolosdosarchivos dedatoscomoarchivossinformato.(Leer
unregistrocompletode
dat o s .antyescribirelregistroactualizadoen dat o s .nue.)
12.32.ModificarelprogramadadoenelEjemplo 12.3(lecturadeunalínea detextoenminúsculasy
escribirlaenmayúsculasenunarchivo)demodoquecadacarácterintroducidoportecladosea
comprobadoparaversiestáenmayúsculasominúsculas,yseescribaen
elarchivodemodo
opuesto.(Portanto,lasminúsculasseconviertenamayúsculasylasmayúsculasaminúsculas.)
Usarlasfunciones
debibliotecaisupperoislowerparacomprobarsicadacarácteresmi­
núsculaomayúscula,ylasfunciones
toupperytolowerpararealizarlasconversiones.
12.33.ModificarlosprogramasdadosenlosEjemplos12.3y12.4 demodoquesepuedanprocesar
varias líneasdetexto.Comocondicióndefinalización,verificarsiestápresentelacadena
FIN(enminúsculasomayúsculas)enlostresprimeroscaracteresdentrodecadalínea.
12.34.ModificarelprogramadadoenelEjemplo12.6(actualizacióndeunarchivoderegistrosde
clientes)demodoqueusesólounarchivo;estoes,cadaregistro
declienteactualizadoreem­
plazaalorigina!.Utilizarlafuncióndebiblioteca
ftellparadeterminarlaposiciónactual
enelarchivoylafunción
fseekparacambiarlaposiciónactualenelarchivosegúnsene­
cesite.Asegurarsedeabrirelarchivoenelmodoadecuado.
12.35.AmpliarelprogramadadoenelEjemplo12.6demodoquesepuedanañadirnuevosregistros,
borrarregistrosantiguosymodificarregistrosexistentes.Asegurarse
demantenerlosregistrosen
ordenalfabético.Permitirqueelusuarioescojaquéopciónseejecutaráantes
deprocesarelregistro.
12.36.ModificarelprogramadadoenelEjemplo12.8(actualizarunarchivosinformatoquecon­
tieneregistrosdeclientes)
demodoqueusesólounarchivo;estoes,cadaregistrodecliente
actualiza-doreemplazaalorigina!.Utilizarlafuncióndebiblioteca
ftellparadeterminar
laposiciónactualen
elarchivoylafunción fs e e kparacambiarlaposiciónenelarchivo
segúnsenecesite.Asegurarsedeabrirelarchivoenelmodoadecuado.
12.37.EscribirunprogramaquelearegistrossucesivosdelarchivonuevocreadoenelEjemplo12.8
ymuestrecadaregistroenlapantallaadecuadamenteformateado.
12.38.AmpliarelprogramadescritoenelProblema12.36demodoquesepuedanañadirnuevos
registros,borrarregistrosantiguosymodificarregistrosexistentes.Asegurarsedemantener
losregistrosenordenalfabético.Permitirqueelusuarioescojaquéopciónseejecutaráantes
deprocesarelregistro.
12.39.Escribirunprogramainteractivo enCquecodifiqueydecodifiquevarias líneasdetexto
usandoelprocedimientodecodificación/decodificacióndescritoenelProblema9.49.Alma­
cenareltextocodificadoenunarchivodemodoquepuedaserrecuperadoydecodificadoen
cualquiermomento.
Elprogramadebeincluirlassiguientescaracterísticas:
a)Introducireltextodesdeteclado,codificarloyalmacenareltextocodificadoenunar-
chivodedatos.
b)Recuperareltextocodificadoymostrarloensuformac.odificada.
e)Recuperareltextocodificado,decodificarloymostrarloensu
f.ormadec.odificada.
á)Finalizarlaejecución.
Probarelprogramautilizandovariaslíneasdetextodesuelección.

516 PROGRAMACiÓN ENC
12.40.Ampliarelprogramadadoen elEjemplo12.39demodoque sepuedangenerarenterosalea­
torios,dondecadaenterosucesivoseutilizaparadecodificarcadalíneaconsecutiva.Así,el
primerenteroaleatorioseráusadoparacodificarlaprimeralíneadetexto,elsegundopara
codificarlasegundalínea,
yasísucesivamente.Incluirlaposibilidaddereproducirlasecuen­
ciadeenterosaleatorios,demodoquelosmismosenterosaleatoriospuedanserutilizados
paradecodificareltexto.Comprobarelprogramaintroduciendovariaslíneasdesuelección.
12.41.Modificarelsimuladordeljuego«Craps»dadoenelEjemplo7.11demodoquesimuleun
númeroespecificadodejuegos
ygrabeelresultadoenarchivo.Alfinaldelasimulación,leer
elarchivodedatosparacalcularelporcentajedevictorias
yderrotasdecadajugador.
Comprobarelprogramasimulando500juegosconsecutivos.Basándoseenestosresulta­
dos,calcularlasposibilidadesdeganar.
12.42.Modificarelgeneradorde«piglatin»presentadoenelEjemplo9.14demodoquepuedan
introducirsevarias líneasdetextodesdeelteclado.Grabareltextocompletoenunarchivo
y
elcorrespondiente«piglatin»enotro.
Incluirdentrodelprogramalageneración
deunmenúquepermitaalusuarioseleccionarcual­
quieradelassiguientescaracterísticas:
a)Introducirtextonuevo,convertirloa«piglatin» ygrabarlo.(Grabartantoeltextoorigi-
nalcomoel«piglatin»,segúnsedescribióanteriormente.)
b)Leeruntextopreviamenteintroducidoenunarchivo
ymostrarlo.
e)Leereltexto«piglatin»equivalentedelintroducidopreviamente
ymostrarlo.
d)Finalizarlaejecución.
Comprobarelprogramautilizandovariaslíneadetextoarbitrarias.
12.43.EscribirunprogramacompletoenCquegenereunarchivoquecontienelosdatosdelasnotas
delosexámenesdelosestudiantespresentados enelProblema6.69(k).Cadacomponentedel
archi-voseráunaestructuraquecontengaelnombre
ylasnotasdeexamenparaunestudian­
te.Ejecutarelprogramacreandounarchivoparausarloenelsiguienteproblema.
12.44.EscribirunprogramaenCorientadoaarchivoqueprocesarálasnotasdelosexámenesdelos
estudiantesdadasenelProblema
6.69(k).Leerlosdatosdelarchivocreadoenelproblema
anterior.Crearacontinuaciónuninformequecontengaelnombre,lasnotasdelosexámenes
ylamediadeellasparacadaestudiante.
12.45.AmpliarelprogramaescritoparaelProblema12.44demodoquesedetermineunamedia
generaldelaclase,seguidaporladesviaciónmediadecadaestudianterespectodelamedia
general.Escribirlasalidaenunarchivonuevo.Despuéspresentarlasalidacomouninforme
bienrotulado.
12.46.EscribirunprogramaenCinteractivo yorientadoaarchivoquemantengaunalista denom­
bres,direcciones
ynúmerosdeteléfonoenordenalfabético(porapellidos).Procesarlainfor­
maciónasociadaconcadanombrecomounregistroseparado.Representarcadaregistrocomo
unaestructura.
Incluirunmenúquepermitiráalusuarioseleccionarcualquieradelassiguientescaracte­
rís-ticas:
a)Añadirunnuevoregistro.
b)Borrarunregistro.
e)Modificarunregistroexistente.
d)Recuperarymostrarunregistrocompletoparaunnombredado.
e)Generarunalistacompletadetodoslosnombres,direcciones ynúmerosdeteléfono.
1)Finalizarlaejecución.

ARCHIVOSDEDATOS 517
Asegurarsedereordenarlosregistroscadavezqueseañadaunregistronuevoo siseborraun
registro,demodoquetodoslosregistrossemantengansiempreenordenalfabético.Utilizar
unalistalinealenlazada,comosedescribeenelEjemplo11.32.
12.47.EscribirunprogramaenCquegenereunarchivoquecontienelalistadepaísesysuscorres­
pondientescapitales,dadasenelProblema9.46.Colocarelnombredecadapaísysucapital
correspondienteenunaestructura.Tratarcadaestructuracomounregistroseparado.Ejecutar
elprogramacreandounarchivoparausarloenelsiguienteproblema.
12.48.Escribirunprogramainteractivoen C,guiadopormenús,queaccedaalarchivogeneradoen
elproblemaanteriorypermitaejecutarunadelassiguientesoperaciones:
a)Determinarlacapitaldeunpaísespecificado.
b)Determinarelpaíscuyacapitalseespecifica.
e)Terminarlaejecución.
12.49.AmpliarelprogramaescritoparaelProblema12.48paraincluirlassiguientescaracterísticas
adicionales:
a)Añadirunnuevoregistro(unpaísnuevoysucorrespondientecapital).
b)Borrarunregistro.
e)Generarunlistadodetodoslospaísesysuscapitalescorrespondientes.
12.50.EscribirunprogramaenCquepuedaserusadocomouneditordetextoorientadoalíneas.
Esteprogramadebetenerlassiguientesposibilidades:
a)Introducirvariaslíneasdetextoyalmacenarlasenunarchivo.
b)Listarelarchivo.
e)Recuperarymostrarunalíneaparticular,determinadaporsunúmerodelínea.
ti)Insertarnlíneas.
e)Borrarnlíneas.
1)Grabarelnuevotextoeditadoyfinalizarlaejecución.
Realizarcadaunadeestastareasrespondiendoaunaordencompuestaporunaletraprecedi­
daporelsignodeldólar
($).Laordenbuscar(recuperar)debeirseguidaporunenterosin
signoparaindicarlalíneaquedeberecuperarse.Lasórdenes
deinserciónyborradopueden
irseguidasporunenterosinsignoparaindicarlalíneaquedeberecuperarse.Lasórdenesde
inserciónyborradopuedenirseguidasporunenterosinsignoopcional,sisequiereinsertar
oborrarvariaslíneasconsecutivas.
Cadaordendebeaparecerenunalínea,proporcionandoasíunmétodo
dedistinguirlasórde­
nes
delaslíneasdetexto.(Unalinea deordenempezarásiemprecon elsignodeldólar,seguido
porunaordendeunaletra,unenterosinsignoopcionalyunsímbolodenuevalínea.)
Serecomiendanlassiguientesórdenes:
$E--introducirtexto.
$L--.listarelbloquedetextocompleto.
$Fk--buscar(recuperar)lalíneanúmero k.
$In--insertarnlíneasdespuésdelalíneanúmero k.
$Dn--borrarnlíneasdespuésdelalíneanúmero k.
$S--grabarelbloquedetextoeditadoyterminarlaejecución.

518 PROGRAMACiÓN ENC
12.51.AmpliarelprogramadescritoenelProblema11.67 demodoquelainformacióndelequipose
mantengaenunarchivoenvezdeenunarray.Cadacomponentedelarchivodebeseruna
estructuraquecontengalosdatosde unequipo.Incluirlassiguientesoperaciones:
a)Introducirnuevosregistros(añadirnuevosequipos).
b)Actualizarregistrosexistentes.
e)Borrarregistros(quitarequipos).
d)Generaruninformeresumenparatodoslosequiposdelaliga.

CAPíTULO13
Programaciónabajonivel
Delamateriapresentadaenlosprimerosdocecapítulosdeestelibrodeberíahaberquedadoclaro
queCesunlenguajedeprogramacióncontodaslascaracterísticasdealtonivel.Sinembargo,C
tambiénposeeciertascaracterísticasde«bajonivel»quepermitenalprogramadorrealizarciertas
operacionesquenormalmentesólosonposiblesenlenguajeensambladoroenlenguajemáquina.
Porejemplo,
esposiblealmacenarlosvaloresdeciertasvariablesenlosregistrosde
launidad
central
deprocesamiento.Estonormalmenteacelerarácualquiercálculoasociadoconesosvalores.
AdemásCpermitelamanipulación
debitsindividualesdentro deunapalabra.Así,losbitspue­
denserdesplazadoshacialaizquierdaohacialaderecha,
invertidos(unosycerosinvertidos)o
enmascarados(extraídosselectivamente).Lasaplicacionesquerequierentalesoperacionesson
familiaresalosprogramadoresenlenguajeensamblador.Ctambiénpermiteorganizarlosbits
dentro
deunapalabraengruposindividuales.Estopermiteempaquetarvariosdatosenunasola
palabra.
Estecapítulomuestracómorealizaroperacionesabajonivelen
C.Loslectoresquenotengan
experienciaenesteáreapodríandesearpasarporaltopartedeestamateria,en particularla
sección
13.2.
13.1.VARIABLESREGISTRO
EnelCapítulo8semencionóqueexistencuatroespecificaciones detipodealmacenamientoen
C yseexaminarontresdeellasendetalle(automática,externayestática).Ahoraseprestaaten­
ciónalúltimo
deellos,eltipodealmacenamiento registro.
Losregistrossonáreasespeciales dealmacenamientodentrodelaunidadcentraldeprocesa­
mientodelacomputadora.Lasoperacionesaritméticasylógicasrealesserealizandentro
deestos
registros.Normalmenteestasoperacionesseefectúantransfiriendoinformacióndesdelamemo­
riadelacomputadorahastaestosregistros,realizandolasoperacionesindicadasytransfiriendo
denuevolosresultadosalamemoria
delacomputadora.Esteprocedimientogeneralserepite
muchasvecesduranteelcurso
delaejecucióndeunprograma.
Paraalgunosprogramaseltiempodeejecuciónsepuedereducirconsiderablementesiciertos
valorespuedenalmacenarsedentrodelos
registrosel1vezdeen
lamemoriadelacomputadora.
Además,talesprogramaspuedenseralgomenoresentamaño(puedenrequerirmenosinstruccio­
nes),yaquesenecesitanmenostransferencias.Sinembargo,normalmentenosereduciráel
tamañoespectacularmente
yserámenossignificativoqueelahorroentiempodeejecución.
EnC,losvaloresdelas
variablesregistro sealmacenandentro delosregistrosde
l:iunidad
centraldeprocesamiento.A lUlavariableselepuedeasignarestetipodealmacenamientosimple-
519

520 PROGRAMACiÓN ENC
menteprecediendo ladeclaracióndetipoconlapalabrareservada register.Perosólopuede
haberunaspocasvariablesregistro(normalmente,dosotres)dentrodecualquierfunción.El
númeroexactodependedelacomputadoraparticularydelcompiladorespecíficode
C.Normal­
mentesólolasvariablesenterassonasignadasaltipodealmacenamiento
regi s ter(másso­
breestoposteriormente
enestasección).
Lostiposdealmacenamiento
regi sterya utomaticestánmuyrelacionados. Enparticu­
lar,suvisibilidad(suámbito)eslamisma.Portanto,lasvariables
register,aligualquelas
variables
automatic,sonlocalesa lafunciónenlaquehansidodeclaradas.Además,lasreglas
quegobiernanelusodelasvariables
registersonlasmismasquelasdelasvariables auto­
matic(versección8.2),exceptoqueeloperadordirección (&)nosepuedeaplicaralasvaria­
blesregistro.
Estassemejanzasentrelasvariables
registeryautomaticnosoncasuales,porque
eltipodealmacenamiento
registersólopuedeasignarseavariablesquedeotromodoten­
dríaneltipodealmacenamiento
a utomatic.Además,eldeclararciertasvariablescomo
registernogarantizaqueseantratadasrealmentecomovariablesdetipo register.La
declaraciónserá válidasólosielespaciorequeridoderegistroestádisponible.Siunadeclaración
registernosepuedetenerencuenta,lasvariablessetrataráncomosituvieraneltipode
almacenamiento
automatic.
EJEMPLO13.1. Unprogramaenecontieneladeclaración devariable
registerinta,b,e;
Estadeclaraciónespecifica quelasvariablesa,byeseránvariablesenteras contipodealmacenamiento
register.Portanto,losvalores dea,byesealmacenarándentro delosregistrosdelaunidadcentral
deprocesamientodelacomputadoraenvezdeenlamemoria,siempre queexistaespaciodisponible en
losregistros.
Sinoexisteespaciodisponible enlosregistros,lasvariables setrataráncomoenterascontipode
almacenamientoatitomatic.Estoesequivalentealadeclaración
autointa,b,e;
osimplemente
inta,b,c¡
comoseexplicó
enlasección8.2.
Desafortunadamente,noh<\yotrafOrmadedcterminarsi1<\declarapiónregisterseha
tenidoencuentaqueejecutarel program.aconysinladecl<aciónycompararlosrcsultados. Un
programaquehaceusodevariablcsregistrodebeejecutarsemásrápidoquc.elprogram<\corres­
pondientesinlasvariablesregistro.PuedesertambiéIl.de.tamañoalgomenor.
EJEMPLO13.2.Generación delosnúmerosdeFibonacci.Elprogramapresentadoacontinuación es
unavariacióndelmostrado enelEjemplo.8,7paragenerarunaserie denúmerosdeFibonacci.

PROGRAMACiÓN ABAJONIVEL 521
/*calcularla000000veceslosprimeros23númerosdeFibonacci,
parailustrarelusodevariablesregistro* /
#include
#include
main()
{
<stdio.h>
<time.h>
/*tiemposdecomienzoyterminación*/timetprin,fin;
intcont,
longint
register
n=23;
ciclo,maxciclo
intf,fl,f2;
=10000000;
/ *marcareltiempodecomienzo* /
time(&prin);
/*realizarmúltiplesbucles*/
for(ciclo=1;ciclo<=maxcic10;++ciclo){
fl=1;
f2=1;
/ *generarlosprimerosnnúmerosdeFibonacci* /
for(cont=1;cont<=n;++cont){
f = (
cont <3)?1fl+ f 2 ;
f2fl;
fl=f;
}
}
/ *ajustarelcontadorymarcareltiempodeterminación*/
--cont;
time(&fin)
}
/ *mostrarlasalida*/
printf("i=%dF =%d",
printf("tiempotranscurrido:
cont,f);
%.Olfsegundos",difftime(fin,prin));
Esteprogramaincluyetresvariablesenterasquetieneneltipodealmacenamiento register.Sólo
secalculanlos 23primerosnúmerosdeFibonacci,yaqueéstosserepresentancomovariablesenteras
ordinarias(númerosdeFibonaccimásaltosgenerarianundesbordamiento"overflow"
deenteros).
ElcálculodelosnúmerosdeFibonacciserepite
10OOO OOOveces,paraobtenerunamedidarazona­
blementeacertadadeltiempodeejecucióndelprograma.Laúnicasalidageneradaeselvalordelnúmero
vigésimotercerodeFibonacci,calculadoalfinaldelúltimociclo.Portanto,elprogramaesdecálculo
intensivo(mínimaentrada/salida)paraenfatizarlaventajausandoeltipodealmacenamiento
register.
Observequeelprogramaincluyesumecanismodetiempopropio.Enparticular,elprogramausala fun­
cióndebiblioteca time,queasignalahoraactual(ensegundos)alasvariables prinyfin.Estasvaria-
blessondeltipo
timet,definidoenelarchivode
cabeceratime.h.'ElprogramausatambiénlaAun-
cióndebibliotecadifftime,quedevuelveladiferenciadetiempoentrelasdosvariables finyprin.

522 PROGRAMACiÓN ENC
Ejecutandoelprogramaenunacomputadorapersonaltipopentium, seobtienenlossiguientesresulta­
dos:
i=23 F=28657
tiempotranscurrido:37segundos
Sielprogramasevuelveaejecutarsin ladeclaraciónregister(esdecir,silasvariablesf,f1
Yf2sonvariablesenterasordinarias),lasalidaesesencialmentelamisma.Portanto,elusodeltipo
registernoproporcionaunaventajaapreciable.Sinembargo,cuando seejecutaenunacomputa­
dorapersonalmásantigua,elusodeltiporegistroproduceunareducción
deun36porcientoen eltiempo
empleadoporlacomputadora.Lostamaños
delosprogramasobjetocompilados,con ysinvariablesre­
gister,nosonsignificativamentediferentesconcadacomputadora.
Aunqueeltipodealmacenamiento registerseasocianormalmenteconvariablesdetipo
entero,algunoscompiladores
permitenqueseaasociadoconotrostiposdevariablesque tengan
elmismotamañodepalabra(porejemplo,enteros shortounsigned).Además,se pueden
permitirpunterosatalesvariables.
Laespecificacióndeltipo dealmacenamientoregisterpuedeincluirsecomo unapartede
ladeclaraciónformaldeargumentodentrode unafunción,o comounapartedelaespecificación
detipodeargumentodentrodé unprototipodefunción. (Observeque registereselúnico
especificador
detipodealmacenamientoquepuedeusarsedeestamanera.)
EJEMPLO13.3. Elesquemadelaestructuradeunprogramaen esemuestraacontinuación.
voidfunc(registerunsignedu,registerint*pt);/*prototipode
función* /
main()
{
registerunsignedti¡
registerint*pt;
ti=5i
*pt=12;
/*declaracióndevariable*/
/*declaracióndepuntero*/
/*asignaunacantidadentera*/
/*asignaunacantidadentera*/
func(u,pt);
}
voidfunc(xegisterunsignedu,registerint*pt)/ *definició n
defunción*/
{
r'eturn¡
}
Elprotptipodefunciónindicaque elprimerargumentotransferidoa funcesunenterp,sinsigno
quetieneeltipo
dealmacenamientoregister,yelsegundoargumentoes,unpunteroaenteroconel

PROGRAMACiÓN ABAJONIVEL 523
mismotipo dealmacenamiento.Observequelasdeclaracionesformalesdeargumentosen funesoncon­
sistentesconlasespecificacionesdeargumentosque
semuestranenladefinición delafunción.
Dentro
demainvemosqueuesunenterosinsigno yptunpunteroaunentero.Ambasvariables
tienenasignadoelespecificadordetipodealmacenamiento
register.Portanto,urepresentaráa
unenterosinsignoquesealmacenaenunregistrodelaunidadcentraldeprocesamientodelacompu­
tadora
yptapuntaráalcontenidodeotroregistro. Enamboscasos,eluso delosregistrosdelacom­
putadoraestarárestringidoasudisponibilidad.
Acontinuacióndelasdeclaracionesseasignaunvalorde5 a u
yunvalorde 12alaposiciónala
queapunta
pt.Estosvaloressealmacenaránenlosregistrosdelacomputadora,siemprequeéstos
esténdisponibles.Lasvariables
uyptsepasana fune,dondeseprocesandeformanoespecificada.
13.2.OPERACIONES ANIVEL DEBITS
Algunasaplicacionesrequierenlamanipulación delosbitsindividualesenunapalabra deme­
moria.Normalmenteserequiereellenguajeensambladoroellenguajemáquinaparaestetipo
de
operaciones.Sinembargo, econtienevariosoperadoresespecialesquerealizanfácilyeficiente­
menteestasoperacionesaniveldebits.Estosoperadoresanivel
debitssepueden dividirentres
categoríasgenerales:eloperadordecomplementoauno,losoperadoreslógicosanivel
debitsy
losoperadores
dedesplazamiento.etambiéncontienealgunosoperadoresquecombinanlas
operacionesaniveldebitsconlaasignaciónordinaria.Acontinuaciónsediscutecadacategoría
separadamente.
Eloperadordecomplementoauno
Eloperadordecomplementoauno
(-)esunoperadorunarioqueinviertelosbitsdesuoperan­
do,demodoquelos
UÍ10ssetransformanencerosyloscerosenunos;Esteoperadorprecede
siempreasuoperando.Eloperandotienequeserunentero(incluyendo
integer,long,short,
unsigned,char,etc.).Generalmenteeloperandoseráunoctalounacantidadhexadecimalsin
signo,perono
esobligatorio.
EJEMPLO13.4. Consideremoslaconstantehexadecimal Ox7ff.Elpatróncorrespondientede
bits,expresadoentérminosdeunapalabrade
16bits,es OOOO01111111 1111(verApéndiceA).
Elcomplementoaunodeestepatróndebitses
111110OO OOOO OOO O,quecorrespondeconel
númerohexadecimal
f 8 OO.Portanto,vemosqueelvalor
delaexpresión-Ox7f fesOxf80O.(Observe
quelospatronesdebitsenesteejemplosehanordenadoengruposdecuatroúnicamenteporconveniencia.)
Acontinuaciónsemuestranalgunasexpresionesqueusaneloperadordecomplementoauno ysus
correspondientesvalores.Todoslosresultadosseexpresanentérminos'deunapalabrade
16bits.
Expresi6n
-OxC5
-Ox1111
-Oxffff
-052
-0177777
Oxff3a
Oxeeee
O
0177725
O
(constanteshexadecimales)
(constanteshexadecimales)
(constanteshexadecimales)
(constantesoctales)
(constantesoctales)

524 PROGRAMACiÓN ENC
Enlasdosúltimasexpresiones,eldígitooctaldelextremoizquierdoequivalea unsolobit(deotraforma
elpatrónexcederíade
16bits).
Seanimaallectorademostrarlavalidezdeestasexpresionesescribiendolospatronescorrespon­
dientesdebitscomose
hamostradoconanterioridad.
Eloperadordecomplementoaunoserefiereavecescomo operadordecomplementación.
Esunmiembrodelmismogrupo deprecedenciaquelosotrosoperadoresunarios.Portanto,su
asociatividadesdederechaaizquierda.
EJEMPLO13.5. ConsideremoselprogramaenCquesemuestraacontinuación.
#include<stdio.h>
main( )
{
unsignedi
~Ox5b3c;
}
printf("valoreshexadecimales:
printf("decimalesequivalentes:
i ~%x
i ::;:%u
~i ::;:%x",i,-i);
-i::;:%U
U
1
i
l
-i);
Laejecucióndeesteprogramaenunacomputadoracontamañodepalabrade16bitsproducelasi­
guientesalida:
valoreshexadecimales:
decimalesequivalentes:
i
~5b3c
i=23356
-i~a4c3
-i~42179
Paraentenderestosresultados, consideremosprimerolospatronesdebitscorrespondientesalosvalo­
resdeiy-i.
i~0101101100111100
-i~1010010011000011
Eldecimalequívalentedeeste primerpatrónde.bitssepuededeterminarescribiendo
i~Ox2
15
+1x2"
4
+Ox2
13
+1x2"
2
+1x2
11
+Ox2"
0
+1x2+1x2
8
+
Ox2'+Ox2
6
+1x2
5
+1x2
4
+1x2'+1x2
2
+Ox2"+Ox2°~
16384+4096+2048+512+256+32+16+8+4~23356
Portanto,eldecimalequivalentede Ox5b3ces23356.
Análogamente,elequivalentedecimaldelsegundopatrónsepuededeterminarescribiendo
-i~1x2"
5
+OX2"
4
+1x2
13
OX2"
2
+Ox2
11
'+lx2"
o
+Ox2
9
+Ox2
8
+
1x2'+1x2
6
+Ox2
5
+Ox2
4
+Ox2'+Ox2
2
+1x2"+1x2°~
32768+8192 1024 1Z8+64+ 2 + 1 ~42179
Portanto,vemosqueelequivalentedecimalde Oxa4c3es42179.

PROGRAMACiÓN ABAJONIVEL 525
Operadoreslógicosaniveldebits
Haytresoperadoreslógicosaniveldebits: y aniveldebits (&),oexclusivaaniveldebits(1'),y
o aniveldebits( I).Cadaunodeestosoperadoresrequieredosoperandosenteros.Lasoperacio­
nesserealizandeformaindependienteencadapardebitsquecorrespondenacadaoperando.
Así,secompararánlosbitsmenossignificativos(losbitsdelextremoderecho)delasdospala­
bras,despuéslossiguientesbitsmenossignificativos,yasísucesivamente,hastaquesecompa­
rentodoslosbits.Losresultadosdeestascomparacionesson:
•Unaexpresión
y aniveldebits devolveráun1siambosbitstienenelvalor1(siambos
bitssonverdaderos).
Enotrocasodevolveráunvalorde O.
•Unaexpresión oexclusivaaniveldebits devolveráun1siunodelosdosbitstiene un
valorde1 yelotrotiene unvalordeO(unbitesverdaderoyelotroesfalso).Enotrocaso
devolveráunvalorde
O.
•Unaexpresión o aniveldebits devolveráun1siunoomásdelosbitstieneelvalorde1
(unooambossonverdaderos).
Enotrocasodevolveráunvalorde O.
Estosresultadosestánresumidos enlaTabla13.1.Enestatabla, blyb2representanlosbits
correspondientesdentrodelprimerysegundooperando,respectivamente.
Tabla13.1.Operacioneslógicasaniveldebits
bl b2 bl&b2 bl
Ab2 blI
b2
1 1 1 O 1
1 O O 1 1
O 1 O 1 1
O O O O O
EJEMPLO13.6.Supongamosquea
y'bsonvariablesenterassinsignocuyosvalores sonOx6db7
y.Oxa726,respectivamente.Acontinuación semuestranlosresultados devarias,operacionesanivel
debitsconestasvariables.
-a=Ox9248
-b=Ox58d9
a
&
b=Ox2526
a
A
b=Oxca91
a
I
b=Oxefb7
Lavalidézdeestasexpresionespuedeverificarseexpandiendocadauno delospatronesdebits.De
estamanera,

526 PROGRAMACiÓN ENC
a=01101101 10110111
-a=10010010 01001000
Ox9248
b=1010011100100110
-b=0101100011011001
=Ox58d9
a=0110110110110111
b=10100111 00100110
a&b=0010010100100110
=Ox2526
a=01101101 10110111
b=10100111 00100110
a
A
b=11001010 10010001
=Oxca91
a=0110110110110111
b=1010011100100110
a b =1110111110110111
=Oxefb7
Cadauno delosoperadoreslógicosanivel debitstienesupropiaprecedencia.Eloperador y
aniveldebits (&)tienelamayorprecedencia,seguidoporla oexclusivaaniveldebits(A),
despuésla o aniveldebits( I).Layaniveldebits siguea losoperadoresdeigualdad (==y!=).
Laoaniveldebits esseguidaporla ylógica(&&).Laasociatividadparacadaoperadoranivel
debitsesdeizquierdaaderecha.(VerApéndiceCparaunresumendetodoslosoperadoresde
C,
consusprecedenciasysusasociatividades.)
Enmascaramiento
El
enmascaramientoesunprocesoenelqueunpatróndado debitsseconvierteenotro,patrón
pormediodeunaoperaciónlógicaaniveldebits.Elpatrónoriginaldebitsesunodelos
operandosenlaoperaciónanivel
debits.Elsegundooperando,llamado
máscara,esunpatrón
especialmenteescogidoquerealizalatransformacióndeseada.
Hayvariostiposdistintosdeoperaciones
deenmascaramiento.Porejemplo,unapartedel
patróndadopuedecopiarsea
una
m:¡ílvapalabrarellenandoeLresto,delanuevapalabl"acon
ceros.Asi,unapartedelpatrónoriginalserá«enmascarada»delresultadofinal.Eloperador
y a

PROGRAMACiÓN ABAJONIVEL 527
niveldebits (&)seusaparaestetipodeoperacionesdeenmascaramiento,comoseilustraa
continuación.
EJEMPLO13.7. Supongamosqueaesunavariableenterasin signocuyovaloresOx6db7.Extraere­
mos
los6bitsdeladerechadeestevalorylosasignaremosa lavariableenterasinsignob.Asignaremos
cerosa
los10bitsdebdelaizquierda.
Paraefectuarestaoperación,escribiremoslaexpresiónanivel
debits
b=a&Ox3f;
Elsegundooperando,laconstantehexadecimal Ox3f,servirádemáscara.Así,elvalorresultante de
bseráOx37.
Lavalidezdeesteresultadopuedeestablecerseexaminando elpatróndebitscorrespondiente.
a=01101101 10110111
máscara=0000 000000111111
b=0000 0000 0011 0111
=Ox37
Observequelamáscaraimpide quelos10bitsdelaizquierdasecopiendea ab.
Lamáscaraenesteúltimoejemplocontieneunosenlasposiciones deladerecha(laspo­
sicionesdelosbitsmenossignificativos)ycerosenlasposicionesdela izquierda(lasposicio­
nesdelosbitsmássignificativos).Talesmáscarassonindependientesdelalongituddelapalabra,
yaqueseusancerospararellenarlasposicionesrestantesunavezquelosunosrequeridoshan
sidocolocadosenlasposicionesdemenororden.Si
serequierenlosunosenlasposiciones delade­
recha,
lamáscaratendráqueestarrelacionadaconlalongituddelapalabra.(Recordarquela
posicióndelbitdelextremoderechosiemprerepresenta
2°,mientrasqueelbitdelaposicióndel
extremoizquierdorepresenta
2n~1,dondeneselnúmerodebitsde lapalabra.)Sinembargo,tal
dependenciapuedeevitarseamenudoescribiendolamáscaraentérminosdesucomplementoauno.
EJEMPLO13.8. Supongamosdenuevoqueaesunavariableenterasinsignocuyovalor esOx6db7.
Extraeremosahora los6bitsdelaizquierdadeestevalory losasignaremosalavariableenterasin signo
b.Asignaremoscerosa los10bitsdeladerechadeb.
Paraefectuarestaoperaciónpodemosescribirlaexpresiónanivel
debits
b=a&OxfcOO;
Así,laconstantehexadecimal OxfcOOservirádemáscara.Elvalor
resultatJ.tedebseráOx6cOO.
Lavalidezdeesteresultadopuedeestablecerse denuevoexaminandolospatrones debitscorres­
pondientes.
a=0110110110110111
máscara=1111110000000000
b=011011000000 0000
=Ox6cOO
Lamáscarabloqueaahoralos 10bits
dejaderechaena.

528 PROGRAMACiÓN ENC
Lamáscara,enestasituación,dependedeltamañodepalabrade 16bits,yaquelosunosaparecenen
lasposiciones
delaizquierda.Sinembargo,silamáscara seescribeentérminosdesucomplementoauno,
losunosaparecenen lasposicionesdelosbitsdeladerechayelresto
delasposicionesestánllenasde
ceros.Portanto,lamáscarasevuelveindependientedeltamaño
delapalabra.
Elcomplementoaunodelamáscaraoriginaleslaconstantehexadecimal
Ox3ff.Portanto,pode­
mosexpresaresteenmascaramientocomo
b
~a&-Ox3ff;
ElvalorresultantedebserácomoantesOx 6c O O.
Lavalidezdeesteresultadopuedeverseexaminandoloscorrespondientespatronesdebitsmostrados
acontinuación.
Ox3ff
~000000111111 1111
-Ox3ff
~1111110000000000
~OxfcOO(lamáscaraoriginal)
a
~0110110110110111
-Ox3ff
~1111110000000000
b
~011011000000 0000
~Ox6cOO
Otrotipodeoperacióndeenmascaramiento""'permitecopiarunaparte deunpatróndebits
dado aunanuevapalabra,rellenandoelresto
delapalabra conunos.Parahacerloseutilizael
¡operador
o aniveldebits.(Observeladistinciónentreestaoperacióndeenmascaramiento yla
anterior,quepermitíacopiarunapartedeunpatróndebitsaunanuevapalabra,mientraselresto
delanuevapalabraserellenaconceros.)
EJEMPLO13.9. Supongamoscomoantesque aesunavariableenterasinsignocuyovalores Ox6db7,
comoantes.Transformaremoselpatróncorrespondientedebitsenotroenelcuallos8bitsdeladerecha
seanunosylos8bitsdelaizquierdaconservensu valororiginal.Asignaremosestenuevopatrónala
variableenterasinsigno
b.
Estaoperaciónserealizamediantelaexpresiónanivel
de,bits
b ~aIOxff;
Laconstantehexadecimal Ox f feslamáscara.Elvalorresultantede bseráOx 6d ff.
Examinaremosloscorrespondientespatronesdebits,paraverificarlacorreccióndelresultad,o.
a~01101101 10110111
máscara~0000 00001111 1111
b ~0110110111111111
~Ox6dff
Recordarquelaoperaciónaniveldebitsesahorala o aniveldebits ynolayaniveldebits, comoenlos
ejemplosanteriores.Así,cuandocadaunodelos8bitsdeladerechaenasecomparaconelcorrespondiente

PROGRAMACiÓN ABAJONIVEL 529
lenlamáscara, elresultadoessiemprel.Sinembargo,cuandocadauno delos8bitsdelaizquierdaenase
comparaconelcorrespondienteOenlamáscara,elresultadoseráelmismoqueelbitoriginalen a.
Supongamosahoraquequeremostransformar elpatróndebitsdeaenotroenelcuallos8bitsde la
izquierdaseantodosunosylos8bitsde laderechaconservensuvalororiginal.Esto sepuederealizar
mediantecualquiera
delassiguientesdosexpresiones:
b=aIOxffOO;
o
b=aI
-Oxff;
Encualquiercaso,elvalorresultantede bseráOxffb7.Resultapreferiblelasegundaexpresión,yaque
esindependientedeltamañodepalabra.
Ellectordeberiaverificarlacorreccióndeestosresultadosexpandiendoloscorrespondientespa­
tronesdebitsyrealizandolasoperacionesindicadas.
Sepuedecopiarunapartedeunpatróndadodebitsaunanuevapalabra,mientrasqueelresto
delpatróndebitsoriginalseinviertendentrodelanuevapalabra.Estetipodeenmascaramiento
utilizalaoexclusivaaniveldebits.Losdetallesseilustranenelsiguienteejemplo.
EJEMPLO13.10. Supongamosqueaesunavariable enterasinsignocuyovalores Ox6db7,como
enlosúltimosejemplos.Invirtamoslos8bitsdeladerechaypreservemoslos8bitsdelaizquierda.Este
nuevopatrón
debitsseasignaráalavariable enterasinsigno b.
Paraejecutarloharemosusodelaoperación oexclusivaaniveldebits.
b=a
AOxff;
Laconstantehexadecimal Oxffeslamáscara.Estaexpresiónasignaráelvalor Ox6d48ab.
Aquítenemosloscorrespondientespatrones debits.
a=01101101 10110111
máscara=0000000011111111
b=0110110101001000
=Ox6d48
Recordarqueahoralaoperación·aniveldebitses·la oexclusivaaniveldebits envezdela yola
o aniveldebits. Portanto,cuandocadaunodelos8bitsdeladerechaenasecomparaconelCorres­
pondientel
.delamáscara,elbitresultanteseráelopuestoalbitoriginalde a.Porotraparte,cuando
cadaunodelos8bits
delaizquierdasecomparaconelcorrespondienteOdelamáscara,elbitresul­
tanteseráelmismoqueelbitoriginalen
a.
Sisequiereninvertirlos8bitsdelaizquierdaenamientrassepreservanlos8bitsoríginalesdela
derecha,podemosescribir
b=a
AOxffOO;
olaexpresiónmásdeseable(yaqueesindependientedeltamañodepalabra)
b=aA-Oxff;
Elvalorresultante decadaexpresiónes Ox92b7..

530 PROGRAMACiÓN ENC
Laoperacióno exclusivapuedeusarserepetidamentecomoun conmutadorparacambiarel
valordeunbitparticulardentrodeunapalabra.Enotraspalabras,siunbittieneunvalorde
1,
laoperacióno exclusivacambiarásuvalora O,Yviceversa.Talesoperacionessonparticularmen­
tecomunesenprogramasqueinteractúanestrechamenteconelhardwaredelacomputadora.
EJEMPLO13.11. Supongamosqueaesunavariableenterasin signocuyovalor esOx6db7,comoen
losúltimosejemplos.Laexpresión
a AOx4
invertiráelvalordelbitnúmero2(eltercerbitpor laderecha)dentro dea.Siestaoperaciónserealiza
repetidamente,
elvalordeaalternaráentreOx6db7yOx6db3. Asi,usandoestaoperaciónrepetida­
menteconmutará
eltercerbitporladerechaentreunoycero.
Lospatrones
debitscorrespondientessemuestranacontinuación.
Ox6db7
=0110110110110111
máscara=0000 000000000100
Ox6db3=0110110110110011
máscara=00000000 00000100
Ox6db7=011011011011 0111
Losoperadoresdedesplazamiento
Losdosoperadoresdedesplazamientoaniveldebitsson desplazamientoa laizquierda«<)y
desplazamientoa laderecha(»).Cadaoperadorrequieredosoperandos.Elprirrieroesun
operandodetipoenteroquerepresenta
elpatróndebitsadesplazar.El
sl'lgundoesunenterosin
signoqueindicaelnúmerodedesplazamientos(silosbitsenelprimeroperandosondesplazados
enlposicióndebit, 2posicionesdebit,3posicionesdebit,etc.).Estevalornopuedeexceder
delnúmerodebitsasociadoconeltamañodepalabradelprimeroperando.
Eloperadordedesplazamientoa
laizquierdahacequelosbits enelprimer
opl'lrandosean
desplazadosalaizquierdaelnúmerodeposicionesindicadoporelsegundooperando.Seperde­
ránlosbitsdelaizquierda(losbitsdedesbordamiento)
enelpatrónoriginaldebits.Lasposicio­
nesdeladerechaquequedanvacantesserellenanconceros.
EJEMPLO 13.12. Supongamosquea esunavariableenterasinsignocuyovalor esOx6db7.La
expresión
b=a« 6;
desplazarátodos losbitsseisposicionesalaizquierdayasignará elvalorresultantealavariableentera
sinsignob.
ElvalorresultantedebseráOx6dcO.
Escribamos
loscorrespondientespatrones debitsparaver cómoseobtieneelresultado final.

PROGRAMACiÓN ABAJONIVEL 531
I
bitsI
perdidos
a=0110110110110111
desplazamiento
alaizquierda
I
a«6
=0110110111000000=Ox6dcO
I
rellenoI
conceros
Todoslosbitsasignadosinicialmentea asedesplazanseisposicionesalaizquierdacornoindicanlas
flechas.Los6bitsdelaizquierda(originalmenteO
11O11)sepierden. Lasseisposiciones deladerecha
sellenancon
000000.
Eloperadordedesplazamientoaladerechahacequelosbitsenelprimeroperandosean
desplazadosaladerechaelnúmerodeposicionesindicadasporelsegundooperando.
Seperde­
ránlosbits
deladerecha(losbits de«underflow»)enelpatrónoriginaldebits.Sielpatrónde
bitsquesedesplazarepresentaunentero
sinsigno,lasposicionesdelaizquierdaquequedan
vacantesserellenanconceros.Portanto,elcomportamientodeloperadordesplazamientoala
derechaessimilaral
dedesplazamientoalaizquierdacuandoelprimeroperandoesunentero
sinsigno.
EJEMPLO 13.13. Supongamosque
aesunavariableenterasinsignocuyovalores Ox6db7.La
expresión
b=a»6;
desplazarátodoslosbitsseisposicionesaladerechayasignaráelvalorresultantealavariableentera
sinsigno
b.Elvalorresultantedebserá Ox1b6.
Escribamosloscorrespondientespatronesdebitsparavercómoseobtieneelresultadofina!.
I
pe~d:~osI
a=Olla110110110111
desplazamiento
aladerecha
a»6
=000000011011Olla=Ox1b6
I
rellenoI
conceros

532 PROGRAMACiÓN ENC
Vemosquetodoslosbitsasignadosinicialmentea asedesplazanseisposicionesaladerechacomo
indicanlasflechas.Los6bits
deladerecha(originalmente 110111)sepierden.Lasseisposicionesde
laizquierdasellenancon
OO OOOO.
Sisedesplazaaladerechaelpatróndebitscorrespondienteaunenteroconsigno,elresul­
tadopuededependerdelvalordelbitmásalaizquierda(elbitdelsigno).Lamayoríadelos
compiladoresllenanlasposicionesvacantesconelcontenidodeestebit.(Losvaloresnegativos
tendránestebita1,mientrasquelospositivoslotendránaO.)Sinembargo,otroscompiladores
rellenaránlasposicionesvacantesconcerosindependientementedelbitdesignodelenteroorigi­
na!.Deberíadeterminarcómomanejaestasituaciónsucompiladorparticular.
EJEMPLO13.14. AcontinuaciónsemuestraunprogramasencilloenCqueilustraelusodeloperador
desplazamientoaladerecha.
#ine1ude<stdio.h>
main()
(
unsigneda=Oxf05a;
intb=a¡
printf("%u%d",a,b);
printf(11%x
ll
, a»6);
printf(lI%x"1b»6);
}
Observequearepresentaunacantidadenterasinsigno,mientrasquebrepresentauna cantidadentera
ordinaria(consigno).Ambasvariablestienenasignadooriginalmenteelvalor(hexadecimal)
Oxf05a.
Comolaposicióndelextremoizquierdocontieneun 1,elenteroconsigno (b)interpretaráestevalorcomo
unnúmeronegativo.
Elprogramamuestralosvaloresdecimalesrepresentadosporlospatronesdebitsasignadosa a
y
b.Despuésseveelresultadodedesplazarseisposicioneshacialaderechacadacantidad.Así,
siel
programaseejecutaenuncompiladorquecopiaelcontenidodelbitdesignoenlasposicionesvacan­
tes,seobtienelasiguientesalida:
61530-4006
3e1
ffe1
Laprimeralineamuestraquelacantidadhexadecimal Oxf05aequivaleala cantidaddecimalsin
signo
6153OY alacantidaddecimalconsigno- 4 OO6.Cuandosedesplazaelentero sinsignoseis
posicionesaladerecha,lasposicionesvacantesserellenanconceros.Deestaforma,elhexadecimal
equivalentedelpatróndebitsresultantees
Ox3el.Sinembargo,cuandosedesplazaunentero con
signo
seisposicioneshacialaderecha,lasposicionesvacantesserellenan
conunos(elvalordelbitdel
signo).Portanto,elhexadecimalequivalented"lpatróndebitsresultantees ffe1.
Acontinuaciónsemuestraelpatrónrealdebitsantes ydespuésdelasoperacionesdedesplazamiento
hacialaderecha.

PROGRAMACiÓN ABAJONIVEL 533
a=11110000 01011010
a»6=0000001111000001
b=11110000 01011010
b»6=1111111111000001
Losoperadores deasignaciónanivel debits
Ox3c1
Oxffc1
Ctambiéncontienelossiguientesoperadoresde asignaciónaniveldebits:
&= 1= «=»=
Estosoperadorescombinanlasoperacionesprecedentesaniveldebitsconlaasignación.El
operandodelaizquierdadebeserunidentificadordevariabledetipoentero(porejemplo,una
variableentera),
yeloperandodeladerechadebeserunaexpresiónaniveldebits.Eloperando
delaizquierdaseinterpretacomoelprimeroperandoen
laexpresiónaniveldebits.Elvalorde
laexpresiónaniveldebitsseasignaaloperandode laizquierda.Porejemplo, laexpresióna
&=Ox7fesequivalentea a =a&Ox7f.
Losoperadoresdeasignaciónaniveldebitssonmiembrosdelmismogrupodeprecedencia
queelrestodelosoperadoresdeasignación.Suasociatividadesdederechaaizquierda(ver
Apéndice
C).
EJEMPLO13.15. Acontinuaciónsemuestranvariasexpresiones deasignaciónanivel debits.En
cadaexpresiónsesuponequeaesunavariableenterasinsigno cuyovalorinicialesOx 6db7.
Expresión Expresiónequivalente Valorfinal
a&=Ox7f a a&Ox7f Ox37
a
A=Ox7f a=aA
Ox7f Ox6dc8
a1=Ox7f a=aIOx7f Ox6dff
a«=5 a=a«5 Oxb6eO
a
»=5 a=a»5 Ox36d
Muchasaplicacionesinvolucranelusodemúltiplesoperacionesaniveldebits.Dehecho
aparecenamenudodosomásoperacionesaniveldebits
enlamismaexpresión.
EJEMPLO13.16.Presentación .depatronesdebits.Lamayoría delasversiqnesdeenoincluyen
unafunción
debibliotecaparaconvertirunenterodecimal en
supatróndebitscorrespondiente.A
continuación
semuestraunprogramacompleto enepararealizarestaconversión. Elprogramamostrará
elpatróncorrespondiente
debitsparaunacantidadenterapositivaonegativa.
/*mostrarelpatróndebitscorrespondienteaunenterodecimalcon
signo*/
#include<stdio.h>

534 PROGRAMACiÓN ENC
main()
{
inta,b,
unsigned
m,contf
mascara;
nbitsi
/ *determinareltamaño
inicial* /
nbits=8*sizeof(int),
m=Ox1«(nbits-1);
/ *bucleprincipal* /
do{
depalabraenbitsyponerlamáscara
/*colocarun1enlaposicióndela
izquierda* /
/ *
leerunenteroconsigno* /
printf("lntroducirunvalorentero(Oparaparar):");
scanf(n%d",&a)i
/*salidadelpatróndebits*/
=1;cont<=
(a&mascara)
}
mascara
::::;mi
for(cont
b=
printf(U%x
ll
I
if(cont%4
printf("
mascara»::::
}
}while(a!=O);
b);
O)
n )i
1,
nbits;
?1
cont++){
O,
/*ponerelbitamostrar
a1oO*/
/ *escribirelbit* /
/*espacioenblancocada
cuatrodígitos* /
/*desplazarlamáscara
unaposiciónalade­
recha* /
Elprogramasehaescritodemodoqueesindependientedeltamañodepalabraparaunentero.Por
tantosepuedeutilizarencualquier computadora.Empiezadeterminandoeltamañodepalabraenbits.
Despuésasignaunvalorinicialapropiadoalavariable entera
m.Estevalorseusarácomomáscaraen
unaoperación
y aniveldebits. Observequemcontieneun1enlaposicióndelextremoizquierdo
y.ceros
enelrestodelasposiciones.
Laparteprincipaldelprogramaesunbucle
do-whi1equepermiteconvertirmúltiplescantida­
desenterasen
suspatronesdebitsequivalentes.Cadapasoatravésdelbucleintroduceunenteroenla
computadora,loconvierteensupatrónequivalentedebits
ylomuestra.Laejecucióncontinúahastaque
seintroduceelvalor
Oyseconvierteenunasucesión deceros.
Cuandosehaintroducidoelentero,seleasignaalamáscaraelvalorinicialdefmidoalprincipiodel
programa.
Seusaunbucle forparaexaminarelenterobitabit,empezandoporelmássignificativo(elbit
delextremoizquierdo).Paraexaminarcadaposición
seusaunaoperacióndeemnascaramientobasadaenel
uso
delay aniveldebits. Despuéssemuestraelcontenidodecadaposición.Finalmente,el1delamáscara
sedesplazaunaposiciónaladerecha,como'anticipaciónparaexaminar
elsiguientebit.
Observequetodoslosbitssemuestran
enlamismalinea.Paraaumentarlalegibilidaddelasalidase
introduceunespacioenblancodespuésdecadagrupo
decuatrobits.

PROGRAMACiÓN ABAJONIVEL 535
Acontinuaciónsemuestraeltípicodiálogointeractivoresultante delaejecucióndelprograma.Las
respuestasdelusuarioestánsubrayadas.
Introducirunvalorentero(Oparaparar):1
0000000000000001
Introducirunvalorentero(Oparaparar):-1
111111111111 1111
Introducirunvalorentero(Oparaparar):129
0000000010000001
Introducirunvalorentero(Oparaparar):-129
1111111101111111
Introducirunvalorentero(Oparaparar):1024
00000100 00000000
Introducirunvalorentero(Oparaparar):-1024
1111110000000000
Introducirunvalorentero(Oparaparar):7033
0001101101111001
Introducirunvalorentero(Oparaparar):-7033
1110010010000111
Introducirunvalorentero(Oparaparar):32767
0111111111111111
Introducirunvalorentero(Oparaparar):-32768
1000000000000000
Introducirunvalorentero(Oparaparar):.Q
00.00000000000000
Observequecadanúmeropositivotiene unOenlaposicióndelextremoizquierdo,ycada número
negativotieneun 1enesaposición.(Enrealidad,elpatróndebitsdeunnúmeronegativo eselcomple­
mentoa
dos'delpatrónde,bitsparaunnúmeropositivo.Paraobtener elcomplementoados, sehaceel
complementoa unoyselesuma1 albitdelextremoderecho.)
13.3.CAMPOSDEBITS
Enalgunasaplicacionesserequieretrabajarconelementosqueconstendeunospocosbits (por
ejemplo
unindicadordeunbitqueindique unacondiciónverdadera/falsa,unenterode3bits
cuyorangovayade
Oa7,ouncarácter ASCnde7bits).Variosdatosdeestetiposepueden
empaquetar
enunasolapalabradememoria.Parahaceresto, lapalabrasesubdivide encampos
debits
individuales.Estoscamposdebitssedefinencomomiembrosdeunaestructura.Cada
campodebitspuedeseraccedidoindividualmente,comocualquierotromiembrodeunaestructura.

536 PROGRAMACiÓN ENC
Entérminosgenerales,ladescomposicióndeunapalabraendistintoscamposdebitspuede
escribirsecomo
structmarca{
miembro1;
miembro2;
miembrom;
dondeloselementosindividualestienenelmismosignificadoqueenunadeclaraciónde estructu­
ra.Cadadeclaracióndemiembrodebeincluirahoraunaespecificaciónqueindiqueeltamañodel
campodebitscorrespondiente.Parahacerlo,elnombredelmiembrodebeirseguidopordos
puntos
yunenterosinsignoqueindiqueeltamañodelcampo.
Lainterpretacióndeestoscamposdebitspuedevariardeuncompiladoraotro.Porejemplo,
algunoscompiladorespuedenordenarloscamposdebitsdederechaaizquierda,mientrasque
otroslosordenandeizquierdaaderecha.Supondremosordenacióndederechaaizquierdaenlos
ejemplosmostradosacontinuación.
EJEMPLO 13.17. Unprogramaenecontienelassiguientesdeclaraciones:
structmuestra {
unsigneda 1 ;
unsignedb 3 ;
unsignede 2 ;
unsignedd 1 ;
};
structmuestrav',
Laprimeradeclaracióndefineunaestructura quesesubdivideencuatrocampos debits,llamadosa,
b,e yd.Estoscamposdebitstienentamaños -de1bit,3bits,2bitsy 1bit,respectivamente. Así,los
camposdebitsocupanuntotal de7bitsdentro deunapalabradememoria.Elrestodelosbítsdentrode
lapalabraquedarán sinusar.
LaFigura
13.1ilustraelesquemadelos
campos'debitsdentrodelapalabra,suponiendo unapalabra
de16bitsyordenación dederechaaizquierda.
bitnúmero:15 14131211109 8 7 6 5 432 1 O
bitssinuso IdIe blaI
Figura13.1.Camposdebits dentrodeunapalabrade16bits.
Lasegundadeclaración establece quevesunavariabledeestructura deltipomuestra.Así,v.aes
uncampodentrodevcuyotamañoes1bit.Análogamente,v.besuncampocuyotamañoes3bits;y así
sucesivamente.

PROGRAMACIÓN ABAJONIVEL 537
Unc~mpodebitssólopuededefinirsecomounapartedeunapalabra integer°unsigned.
(Algunoscompiladorestambiénpermitenque uncampodebitssea unapartedeunapalabra
charolong.)Sinembargo,entodoslosdemásaspectos,lasreglasparadefinircamposdebits
sonlasmismasquelasquegobiernanotrostiposdeestructuras.
EJEMPLO13.18. LasdeclaracionesdelEjemplo13.17puedenagruparse
struetmuestra{
unsigneda
unsignedb
unsignede
unsignedd
}v;
l',
3 ;
2 ;
1 ;
Lainterpretacióndelavariablev eslamismaqueladadaenelEjemplo13.17.Además,lamarca puede
omitirsedemodoqueladeclaraciónanteriorpuedereducirse aúnmása
struet{
unsigneda 1;
unsignedb 3 ;
unsignede 2;
unsigneddl',
}v;
Uncampodentrodeunaestructuranopuedesobrepasarunapalabradentrodelamemoriade
lacomputadora.Esteproblemanosurgesilasumadelostamañosdeloscamposnoexcededel
tamañodeunacantidadenterasinsigno.Sinembargo,si
lasumadelostamañosdeloscampos
excedeestetamañodepalabra,cualquieraquelosobrepaseseráforzadoautomáticamenteal
principiode
lasiguientepalabra.
EJEMPLO13.19. Consideremoselprogramasencillo enCmostradoacontinuación.
#inelude<stdio.h>
main()
{
statiestruet{
unsigneda
unsignedb
unsignede
unsignedd :
} v={l,2,3,4};
5;/*principioprimerapalabra* /
5 ;
5 ;
5;/*forzadoalasegundapalabra*/
%dbytes",sizeof(v));
}
printf("v.a=%d
v.d);
print:E("vrequiere
v.b=%dv.e=%dv.d
Loscuatrocampos devrequierenuntotalde2Obits.Silacomputadorasólopermite16bits
parauna
cantidadenterasinsigno,estadeclaración
deestructurarequerirá dospalabrasdememoria.Lostres
primeroscampos
sealmacenaránenlaprimerapalabra. Comoelúltimocampo debitssobrepasael
límite
delapalabra,sefnerzaautomáticamente alprincipiodelasegundapalabra.

538 PROGRAMACiÓN ENC
LaFigura13.2muestraelesquemadeloscampos debitsdentrodelasdospalabrasde 16bits.
bitI
n.o1514131211lO
Palabra2
98765432101151413
Palabra1
12
JIlO9 8 7 6 5 4 3 2 1 01
d e b a
Figura13.2.Cuatrocamposdebitsdentrode dospalabrasde 16bits.
Laejecución
deesteprogramaproducirálasiguientesalida:
v.a= 1v.b=2v.e=3
vrequiere4bytes
v.d=4
Lasegundalíneaverificalanecesidaddedospalabras,yaquecadapalabraesequivalenteadosbytes.
(Conalgunoscompiladores,
vsólonecesitará3bytes,esdecir, 24bits.)
Loscampossinnombresepuedenusarparacontrolarlacolocacióndeloscamposdebits
dentrode
unapalabradememoria.Talescampossirvenderellenodentrodelapalabra.El
tamañodeloscampossinnombredeterminalaextensióndelrelleno.
EJEMPLO13.20.ConsideremoselsencilloprogramaenCmostradoacontinuación.
#ine1ude<stdio.h>
main( )
{
statiestruet{
unsigneda 5;
unsignedb 5;
unsignede 5;
} v={1,2,3};
}
printf("v.a =%d
printf(lIvrequiere
v.b=%d
%d
bytes",
v.e=%d
ll
,
sizeof(v));
v.a
lv.b,v.e);
Esteprogramaessimilar almostradoenelejemploanterior.Sinembargo,ahorasólosedefinentrescam­
pos
(15bits)dentrode v.Portanto,sóloserequiereunapalabradememoriaparaalmacenarestaestructura.
Ejecutandoel
prpgramaseproducelasiguientesalida:
v.a=1v.b=2
vrequiere2bytes
v.e=3

PROGRAMACiÓN ABAJONIVEL 539
Lasegundalíneadesalidaverificaquelostrescampospuedenalmacenarseenunapalabrasimplesin
signo(2bytes).
Modifiquemoselprogramaañadiendouncamposinnombrecuyotamañoesde6bits.
#include<stdio.h>
main()
{
staticstruct{
unsigneda
unsignedb
unsigned
unsignedc
} v={l,
2,3};
5 ;
5 ;
6 ;
5 ;
/*principioprimerapalabra*/
/*rellenarprimerapalabra*/
/*principiosegundapalabra*/
}
printf("v.a=%d
printf("vrequiere
v.b=%d V.c=%d",v.a,
%dbytes",sizeof(v));
v.b,v.e)i
Ahoraserequerirándospalabras dememoria.Losdosprimeroscampossealmacenarándentro delapri­
merapalabra,seguidospor6bitslíbres(parauntotalde
16bits,rellenandoasilaprimerapalabra).Por
tanto,elúltimocamposealínearáconelprincipio
delasegundapalabra,como seilustraenlaFigura13.3.
Palabra2
~i;11514131211109 8 7 6 5 4 3 2 1
,
c
o11514131211109
Palabra1
8 7 6 5
b
4 3
2101
a
Figura13.3.Trescamposde bitsdentrode dospalabrasde 16bits.
Cuandoseejecutaesteprograma,seproducelasiguientesalida:
v.a=1v.b=2
vrequiere4bytes
v.c=3
Delasegundalíneadelasalidavemosqueserequierendospalabras(4bytes)paraalmacenarlostres
camposdebidoalrellenoadicional.
Otraformadecontrolar
laalineacióndeloscamposdebitsesincluiruncampodebitssin
nombrecuyotamañoseacero.Estoforzaráautomáticamentequeelsiguientecamposealinee
conelprincipiodeunanuevapalabra;

540 PROGRAMACIÓN ENC
EJEMPLO13.21. ConsideremoselsencilloprogramaenCmostradoacontinuación.
#include<stdio.h>
main()
{
staticstruct{
unsigneda
unsignedb
unsigned
unsigned
e
} v
~{l,2,3};
5;/*principioprimerapalabra* /
5 ;
O;/*forzaralineamientoconla
segundapalabra* /
5;/*principiosegundapalabra* /
}
printf("v.a~%d
printf("vrequiere
v.b~%d V.c ~%d",v.a,
%dbytes",sizeof(v));
v.b,v.c);
Esteprogramaessimilaralsegundomostradoen elúltimoejemplo.Sinembargo,ahoraladeclaración
deestructuraincluyeuncampodebitssinnombrecuyotamañoescero.Estoforzaráautomáticamente
queelúltimocamposecoloquealprincipiodelanuevapalabra,cornoseilustróenlaFigura13.3.
Cuandoseejecutaelprograma,segeneralasiguientesalida:
v.a~l v.b~2 v.c~3
vrequiere4bytes
Laúltimalíneaverificaqueparaalmacenarlostrescamposserequierendospalabras(4bytes),corno
sedefinióanteriormente.(Conalgunoscompiladores,
vrequerirásólo 3bytes,estoes, 24bits.)
Se
recuerdadenuevoallectorquealgunoscompiladoresordenanloscamposdebitsde
derechaaizquierda(bitsdemenoramayororden)dentrode unapalabra,mientrasqueotros
ordenanloscamposdeizquierdaaderecha(bitsdemayoramenororden).Comprobarenel
manualdereferenciadelprogramadorcómosehaceestoensucomputadoraparticular.
EJEMPLO13.22. Consideremoslaprimeradeclaración deestructurapresentadaenelEjemplo13.20,
quees
staticstruct{
unsigneda :5;
unsignedb 5 ;
unsignede 5;
} v
~{1,2,3};
Conalgunascomputadoras,elprimercampo (v.a)ocuparálos5bitsmásaladerecha(bitsO a4),el
segundocampó(v.b)ocuparálos5bitssiguientes(bitsdel5a19)yelúltimocampo (v.e)ocupará
delbit
10aI14.E1bitdelextremoizquierdo(elbit 15,queeselbitmássignificativo)estarádesocupado,
cornosemuestraenlaFigura
13.4(a).

PROGRAMACiÓN ABAJONIVEL 541
bitnúmero:1514131211109 8 7 6 5 4 3 2 1 O
v.e v.b v.a
Figura13.4(a).Camposdebitsconordenacióndederechaaizquierda.
Sinembargo,conotrascomputadoras,elprimercampo
(v.a)ocuparálos 5bitsdelaizquierda(bits
del
11al15),elsegundocampo (v.b)ocuparálosbitsdel 6al10Yelúltimocampo (v.c)ocuparálos
bitsdel
1al5.Elbitdelextremoderecho(elmenossignificativo)quedarásinocupar,comosemuestraen
laFigura
13.4(b).Portanto,unprogramaescritoparauntipodecomputadorapuedeproducirresultados
incorrectoscuandoseejecutaenotrotipodecomputadora.
bitnúmero:1514131211109 8 7 6 5 4 3 2 1 O
v.a v.b V.c
Figura13.4(b).Camposdebitsconordenacióndeizquierdaaderecha.
Loscamposdebitssonaccedidosdelmismomodoqueotrasestructuras,ypuedenaparecer
enexpresionesaritméticascomocantidadesenterassinsigno.Sinembargo,hayvariasrestriccio­
nes
ensuuso.Enparticular,nosepermitenarraysdecamposdebits;el operadordirección(&)
nosepuedeaplicarauncampodebits;unpunteronopuedeaccederauncampodebits;y una
funciónnopuededevolveruncampodebits.
EJEMPLO13.23.Compresióndedatos(almacenamientodenombres yfechasdenacimiento).Este
ejemplopresentaunprogramaquealmacenaenunarraynombresyfechasdenacimientodevariosestu­
diantes.Laestrategiageneralseráprimerointroducirelnombreylafechadenacimientoparacadaestu­
diante.Elprogramamostraráparacadaestudianteelnombre,eldíadenacimiento(díadelasemanaen
quenacióelestudiante)ylafecha
denacimiento.Losdías denacimientosedeterminaránusandoel
méto­
dodescritoenelEjemplo10.28.
Cadafechadenacimientoconstarádetresnúmerosenteros:elmes,díayañodenacimiento.(El
añose
almacenarácomounentero
detresdígitosquerepresentanelnúmero deañosdesde 19OO,comosedescribe
enelEjemplo10.28.Así,elaño
1999seintroducecomo 1999perosealmacenasimplementecomo 99.
Análogamente,elaño 2010seintroducirácomo2 O1 OYsealmacenarácomo 110.)Paraabarrarmemoria,
estostresenterossealmacenaránencamposdebitsdentro
deunasolapalabrade 16bits,comosigue:
typedefstruct{
}
fecha;
unsignedmes
unsigneddia
unsignedanio
:4i
:5i
7;
Observequeelmessealmacenarácomounenterosinsignode4bits,cuyovalorpuedevariarde Oa
15(tengaencuentaque 2
4
-
1=15).Porsupuesto,sólointeresanvaloresentre 1y12.Análogamente,

542 PROGRAMACiÓN ENC
eldíasealmacenacomonnenterosinsigno de5bits.SuvalorpuedeoscilarentreO y31(observeque
2
5
-
1=31).yelañosealmacenarácomounentero de7bits,quepuedevariarentreO y127(obser­
veque2
7
-
1=127).Así,podremosacomodarfechas denacimientodesdeelaño 19OOalaño2 027.
Aquítenemoselprogramacompleto.
/*almacenarnombresyfechasdenacimientodelosestudiantesenun
array,usandocamposdebitsparalasfechasdenacimiento
Cuandosetermine,mostrarelnombreylafechadenacimientode
cadaestudiante.Mostrarcadafechadenacimientocomosigue:día
delasemana,mes,día,año*/
#include
#include
<stdio.h>
<string.h>
intconvertir(intmm,intdd,intaa)/ *prototipodefunción* /
main( )
{
int
int
mm,dd,aa,
dia_semana;
cont
/*
;:::Oi
díadela
nes,etc.)
semana
*/
(O->Domingo,1->Lu-
typedefstruct{
unsignedmes 4;
unsigneddia 5;
unsignedanio 7;
}fecha;
struct{
charnombre[3O];
fechafechanacimiento;
}estudiante[40];
staticchar*diasemana[] ;:::{
11Dorningo11, 11Lunes11,
IIMiércoles", 11Jueves111
lISábado"}¡
"Martes
ll
¡
"Viernes"!
\ 'FIN\'#") ;
nFebrero"[IrMarzo
ll
,IIAbril",uMayo 11I
lIJulioll["Agosto"¡ 11Septiembre",
IfNoviembre 111nDiciembre11};
staticchar*mes[]={llEnero
n
,
"Junio11,
11Octubre11[
/*mensajedeentrada*/
printf("RutinadeentradadedatosEscribir
printf(licuandosetermine
ll
)i
printf("Nombre:");
scanf("%[A]",estudiante[cont].nombre);
/ *introducirlosdatosdetodoslosestudiantes* /
while(strcmp(estudiante[cont].nombre,"FIN")!=O){
printf("Fechadenacimiento(mmddaaaa):");
scanf("%d%d%d",&mm,&dd,&aa);

PROGRAMACiÓN ABAJO NIVEL 543
/*asignarlosdatosenterosdelaentradaaloscamposde
bits* /
estudiante[cont].fechanacimiento.mes~mm,
estudiante[cont].fechanacimiento.dia~dd,
estudiante[cont].fechanacimiento.anio~aa 1900,
printf("Nombre:");
scanf("%[A]",estudiante[++cont].nombre);
}
/*convertir
todoslos
lasfechasdenacimientoymostrarla
estudiantes* /
salidapara
}
cont
while
}
=Oi
(strcmp(estudiante[cont].nombre,"FIN")!~O){
dia_semana~convertir(estudiante[cont].fechanacimiento.mes,
estudiante[cont].fechanacimiento.dia,
estudiante[cont].fechanacimiento.anio);
printf("%s estudiante[cont].nombre),
printf("%s %s%d,%d",diasemana[dia_semana],
mes[estudiante[cont].fechanacimiento.mes-l],
estudiante[cont].fechanacimiento.dia,
estudiante[cont].fechanacimiento.anio+1900),
++cont¡
intconvertir(intmm,intdd,intaa)/*convertirunafechaen
eldíadelasemana*/
{
longndias,
longnciclos,
intnarrias;
intdia¡
/*númerodedíasdesdeelcomienzode1900*/
/*númerodeciclosde4añosdespuésde1900*/
/ *númerodeañosdespuésdelúltimociclode4años*/
/*díadelasemana(O,1,2,3,4,5 o6)*/
/*conversionesnuméricas*/
ndias~(long)(30.42*(mm ~1))+dd;
i f(mm ~~2)++ndias;
if((mm>2)&&(mm<8))--ndias,
if((aa% 4 ~~O)&&(mm>2))++ndias,
nciclos~aa/4,
ndias+~nciclos*1461;
/ *díaaproximadodel
año*/
/*ajustepara
febrero* /
/*ajusteparamarzo­
julio*/
/*ajusteparaelaño
bisiesto*/
/*ciclosde4años
despuésde1900*/
/*añadirdíasporci­
closde4años*/

544 PROGRAMACiÓN ENC
nanias=aa%4¡
if(nanios>O)
ndias+=365
/ *añosdespués
/ *añadirdías
ciclo*/
*nanias+1¡
delúltimociclode4años*/
porañosdespuésdelúltimo
if(ndias>59)--ndias;/*ajustarpara1900(NOañobisiesto)*/
dia=ndias%7;
return(dia);
}
Dentrodeesteprogramavemosque estudianteesunarrayde40estructuras.Cadaelementodel
array(cadaestructura)consta
deunarraydecaracteresde 3Oelementos(nombre)querepresentael
nombredelestudiante,yotraestructura
(fechanacimiento)quecontienelafecha denacimientodel
estudiante.Estaúltimaestructuracontienetrescamposdebits
fechanacimiento.mes,
fechanacimiento.diayfechanacimiento.aniocomomiembros.
Elprogramatienetambiéndosarraysdecadenasdecaracteres,cuyoselementosrepresentanlosdias
delasemanaylosmesesdelaño,respectivamente.EstosarrayssediscutenenelEjemplo10.28.Además,
elprogramaincluyelafunción
convertir,queseusaparaconvertircualquierfechaentrel-enero-1900
y3l-diciembre-2099eneldíadelasemanaequivalente(dadocomoentero).Estafunciónesidénticaala
descritaenelEjemplo10.28.(Dentro
deconvertir,lainstrucciónaa-=1900,queestabapresente
enelEjemplo10.28,estáahoraausente.)
Lafunción
mainconsisteesencialmenteendosbucles whi1e.Elprimeroseusaparaintroduciry
almacenarlosdatos
decadaestudiante.Encadapasadaporelbucleseintroducirányalmacenarándatos
paraunestudiantedistinto.Esteprocesocontinuaráhastaquesedetectela
palabra"FIN"paraelnombre
deunestudiante(enmayúsculasominúsculas).Observelaformaenqueseasignanvaloresaloscampos
debitsenestebucle.
Elsegundobucleconviertelafechadenacimientoenundíadelasemanaylomuestraporpantalla,
conelnombreylafecha
denacimientodelestudiante.Losdetallesdelaconversión delafechaydela
salidaporpantalla
delainformaciónsedanenelEjemplo10.28y nonecesitanrepetirseaquí.Observe
cómoseaccedenloscamposdebitsdentrodelas llamadasafunciones.
Eldiálogodeentradaylacorrespondientesalidasemuestranacontinuación.Comosiempre,lasres­
puestasdelusuarioestánsubrayadas.
Rutinadeentradadedatos
Escribir'FIN'cuandosetermine
Nombre:RobSmith
Fechadenacimiento(mmddaaaa)7201972
Nombre:JudyThompson
Fechadenacimiento(mmddaaaa):11271983
Nombre:JimWilliams
Fechadenacimiento(mmddaaaa)12291998
Nombre:MortDavis
Fechadenacimiento(mmddaaaa):6102010
Nombre:FIN

PROGRAMACiÓN ABAJONIVEL 545
RobSmith JuevesJulio20,1972
JudyThompson DomingoNoviembre27,1983
JimWilliams
MortDavis
MartesDiciembre29,1998
JuevesJunio10,2010
Unasobservacionesadicionalesantes dedejaresteejemplo.Primero, hadedestacarsequeelahorro
dememoriausando camposdebitsnoesgrande.Elbeneficiodeestatécnicadecompresiónseríamayor si
ladimensióndelarraydeestudiantesseincrementara.
Segundo,lacompresión
dealgunosdatosadicionales sepodríarealizaralmacenandoochocaracteres
ASCn
de7bitsen7bytesdememoría,usando losoperadoresdedesplazamientoanivel debits.Cada
bytecontendríauncaráctercompleto másunbitdeloctavocarácter.Estodaríalugaraunareducción deun
12,5porcientoenlosrequerimientosdememoria.Losdetallesdeestatécnicaestán másalládelámbitode
estadiscusión,sibien loslectoresinteresadospuedenquererexperimentarestatécnicaellossolos.(Ver
Problema
13.55alfinaldelcapítulo.)
13.1.
13.2.
13.3.
13.4.
13.5.
13.6.
13.7.
13.8.
13.9.
13.10.
13.11.
13.12.
13.13.
13.14.¿Quéseentiendeporprogramaciónabajonivel?
¿Quésonlosregistros?
Entérminosgenerales,¿paraquéseusanlosregistros?
¿Cuáleselpropósitodeltipodealmacenamiento
register?¿Qué
beneficiosse
obtienendelusodeestetipodealmacenamiento?
¿Aquétipodevariablespuedeasig­
narseestetipodealmacenamiento?
¿Cuáleselámbitodelasvariablesregistro?
Mencionarlasreglasparaelusodevariablesregistro.
¿Porquépuedenosertenida
encuentaunadeclaración register?Siladeclaración
registernosetieneencuenta,¿cómosetratanestasvariables?
¿Cómopuedesaberunprogramadorsiladec1aración
registersetieneencuenta
dentrodeunprograma?
¿Quéseentiendeporoperacionesaniveldebits?
¿Cuáleselpropósitodeloperadordecomplementoauno?
¿Aquétipodeoperandosse
aplica?¿Aquégrupodeprecedenciapertenece?¿Cuálessuasociatividad?
Describirlostresoperadoreslógicosaniveldebits.¿Cuáleselpropósitodecada
uno?
¿Quétipodeoperandosrequierecadaunodelosoperadoreslógicosaniveldebits?
Resumirlosvaloresdevueltos
porcadaunadelasoperacioneslógicasaniveldebits.
Considerartodoslosposiblesvaloresdelosoperandos
enlarespuesta.
Describirla precedencia ylaasociatividadparacadaunodelosoperadoreslógicosa
niveldebits.
¿Quéesunaoperacióndeenmascaramiento?¿Cuáleselpropósitodecadaoperando?
¿Quéoperandoes
lamáscaraycómoseescoge?

546
13.15.
13.16.
13.17.
13.18.
13.19.
13.20.
13.21.
13.22.
13.23.
13.24.
13.25.
13.26.
13.27.
13.28.
13.29.
13.30.
13.31.
13.32.
13.33.
13.34.
13.35.PROGRAMACiÓN ENC
Describirunaoperación deenmascaramientoenlacualsecopiaunapartedelpatrónde
bitsdadomientrasqueelrestodebitsseponenacero.¿Quéoperaciónlógicaanivel
debitsseusaparaestaoperación?¿Cómoseescogelamáscara?
Describirunaoperación
deenmascaramientoenlacualsecopieunapartedelpatrón de
bitsdadomientrasqueelrestodelosbitsseponena 1.¿Quéoperaciónlógicaanivel
debitsseusaparaestaoperación?¿Cómosedefinelamáscara?Compararlarespuesta
conla
delacuestiónanterior.
Describirunaoperación
deenmascaramientoenlacual secopieunapartedelpatrón de
bitsdadomientrasqueelrestodelosbitsseinvierten.¿Quéoperaciónlógicaanivelde
bitsseusaparaestaoperación?¿Cómosedefinelamáscara?Compararlarespuesta
conladelasdoscuestionesanteriores.
¿Porquéseusaaveceseloperadordecomplementoaunoenunaoperacióndeenmas­
caramiento?¿Bajoquécondicionesesdeseablesuuso?
¿CómosepuedeconmutarunbitentreO
yIdeformarepetida?¿Quéoperaciónlógica
aniveldebitsseutilizaparaestepropósito?
Describirlosdosoperadoresdedesplazamientoanivel
debits.¿Quérequerimientos
debensatisfacerlosoperandos?¿Cuáleselpropósito
decadaoperando?
Describirlaprecedencia
ylaasociatividaddelosoperadoresdedesplazamientoanivel
debits.
'Cuandosedesplazanbitshacialaderechaohacialaizquierda,¿quépasaconlosbits
desplazados
desuposiciónoriginalfuera delapalabra?
Cuandosedesplazanbitsalaizquierda,¿quévalorrellenalasposicionesvacantes
dela
derecha
delosbitsdesplazados?
Cuandosedesplazanbitsaladerecha,¿quévalorrellenalasposicionesvacantes
delos
bits
delaizquierdadesplazados?¿Afectaaestevaloreltipodeoperandoadesplazar?
Explicarloampliamente.Compararlarespuestaconla
delaCuestión13.23.
¿ManejantodosloscompiladoresdeCeldesplazamientoaladerecha
delamismama­
nera?Explicarloampliamente.
Listarlosoperadoresdeasignaciónaniveldebits
ydescribirsupropósito.
Describircadaunodelosoperandosenunaoperación
deasignaciónanivel debits.
Describirlaprecedencia
ylaasociatividadparalosoperadoresdeasignaciónanivel de
bits.
¿Quésonloscampos
debits?¿Aquétipo deestructuradedatospertenecen?¿Cómo
puedeaccederseauncampo
debits?
Mencionarlasreglasparadefinircamposdebits.
¿Quétipodedatosdebeasociarseconcadacampodebits?
¿Quépasasiuncampodebitssobrepasaunapalabra
dememoriadelacomputadora?
Dentro
deladeclaracióndeuncampo debits,¿quéinterpretaciónseledaauncampo
debitssinnombre?¿Quéinterpretacióntieneuncampodebits
detamañocero?
¿Enquéordensecolocanloscamposdebitsdentrodeunapalabra?¿Esteconvenioes
uniformeentretodosloscompiladores?
¿Quérestriccionesseaplican
alusodecamposdebitsdespués dehabersidocorrecta­
mentedeclarados?

PROGRAMACiÓN ABAJONIVEL 547
13.36.Declararlasvariablesu y vcomovariablesenterassinsignoconeltipodealmacenamiento
register.
13.37.Declararlasvariables u,v,x e y comoenterasconvaloresiniciales1,2,3 Y 4respectivamente.
Suponerqueu y vsonvariablesautomáticas.Asignareltipodealmacenamiento
registera x ey.
13.38.Suponerque funeesunafunciónqueaceptacomoargumentounpunteroaunavariableentera
registrosinsignoydevuelveunpunteroaunenterosinsigno.Escribirelesquemadelaestructu­
radelarutinallamadora
mainydefune,ilustrandocómosedefinenestascaracterísticas.
13.39.Supongamosqueaesunavariableenterasinsignocuyovalor(hexadecimal)es
Oxa2e3.Escri­
birelcorrespondientepatróndebitsparaestevalor.Evaluaracontinuacióncadaunadelassi­
guientesexpresionesaniveldebits,mostrandoelpatróndebitsresultanteysuvalorhexadecimal
equivalente.Utilizarelvalororiginaldeaencadaexpresión.Suponerqueasealmacenaenuna
palabrade
16bits.
a)
-a h)a»3 o)a&-(Ox3f06«8)
b)a&Ox3f06 i)a «5 p)a
A
-Ox3f06«8
e)a
A
Ox3f06 j)a&-a q)(a
A
-Ox3f06)«8
ti)aIOx3f06 k)a
A
-a r)a
A
-(Ox3f06«8 )
e)a&-Ox3f06 T)aI-a s)aI
-Ox3f06«8
j)a
A
-Ox3f06 m)a&-Ox3f06«8 t)(aI
-Ox3f06)«8
g)aI
-Ox3f06 n)(a&-Ox3f06)«8 u)aI
-(Ox3f06«8)
13.40.Reescribircadaunadelassiguientesexpresionesaniveldebitsenlaformadeinstruccionesde
asignaciónaniveldebits,dondeelvalordecadaexpresiónseasignaalavariable
a.
a)Problema13.39(b)
b)Problema13.39(c)
e)Problema13.39(g) ti)Problema13.39(h)
e)Problema13.39(i)
j)Problema13.39(k)
g)Problema13.39(0)
13.41.Definirunamáscarayescribirlaoperaciónapropiadadeenmascaramientoparacadaunadelas
situacionesdescritasacontinuación.
a)Copiarlosbitsimpares(bits 1,3,5,oo.,15)ycolocarcerosenlasposicionespares(bits
0,2,4,oo.,14)deunenterosinsignode 16bitsrepresentadoporlavariable v.Suponerque
elbitOeselbitdelextremoderecho.
b)Eliminarelbitmássignificativo(elbitdelextremoizquierdo)de uncarácterde8bitsrepre­
sentado
porlavariablee.(Algunosprocesadoresdetextoutilizanestebitparacontrolarel
formatodeltextodentrodeundocumento.Descartandoestebit,porejemploponiéndoloa
cero,puedetransformarseundocumentode
unprocesadordetextoen unarchivodetextocon
caracteresASCIIordinarios.)
e)Copiarlosbitsimpares(bits
1,3,5,oo.,15)ycolocarunosenlasposicionespares(bits O,2,
4,oo.,14)deunenterosinsignode 16bitsrepresentadoporlavariable v.Suponerqueelbit
Oeselbitdelextremoderecho.
ti)Conmutar(invertir)losvaloresdelosbits1 y 6deunacantidadenterasinsignode 16bits
representada
porlavariablev,preservandoelrestodelosbits.Asignarelnuevopatrónde
bitsa
v.SuponerqueelbitOeselbitdelextremoderecho.

548 PROGRAMACiÓN ENC
13.42.a)Supongamosquevesunacantidadenteraconsignode 16bitscuyovalorhexadecimales
Ox369c.Evaluarcadaunadelassiguientesexpresionesdedesplazamiento.(Utilizarelva­
lororiginaldev
encadaexpresión.)
i)v«4
ii)v»4
b)Supongamosahoraqueelvalorde vsecambiaa Oxc369.Evaluarcadaunadelassiguientes
expresionesdedesplazamientoycompararlosresultadosconlosobtenidos
enlapartea).
Explicarcualquierdiferencia.
i)v
«4
ii)v » 4
13.43.Describirlacomposicióndecadauna delassiguientesestructuras.Suponerunapalabraenterade
16bits.

PROGRAMACiÓN ABAJONIVEL 549
13.44.Escribirunadeclaracióndeestructuraparacadaunadelassiguientessituaciones.Suponeruna
palabraentera
de16bits.
a)Definirtrescampos debitsllamadosa,b ye,contamaños de6,4 Y 6bits,respectivamente.
b)Declararunavariabledetipoestructuravconlacomposicióndefinidaenlaparte a).Asignar
losvaloresiniciales
3,5 Y7,respectivamente,alostrescampos debits.¿Sonsuficientemen­
tegrandesloscamposparaacomodarestostresvalores?
c)¿Cuálessonlosvaloresmásgrandesquesepuedenasignaracadaunodeloscampos
debits
definidosenlaparte
a)?
d)Definirtrescamposdebitsllamados a,b ye,contamaños de8,6 Y 5bits,respectivamente.
¿Cómosealmacenanestoscamposdentrodelamemoriadelacomputadora?
e)Definirtrescamposdebitsllamados a,b ye,contamaños de8,6 Y 5bits,respectivamente.
Separara y bcondosbitsvacantes.
/)Definirtrescamposdebitsllamados a,b ye,contamaños de8,6 Y 5bits,respectivamente.
Forzarbalprincipiodelasegundapalabradealmacenamiento.Separarb y econdosbits
vacantes.
13.45.ModificarelprogramapresentadoenelEjemplo13.2(cálculorepetidodeunaseriedenúmeros
deFibonacci)demodoque
f,f1 Yf2seanpunterosaenterosalmacenadosdentrodere­
gistros.
13.46.ElProblema6.69(j)describeunmétodoparacalcularnúmerosprimosysugiereescribirunpro­
gramaparacalcularlosprimeros
nnúmerosprimos,donde nesunacantidadespecificada(por
ejemplo,
n
~100).Modificaresteproblemademodoquelalista dennúmerosenterossegenere
30000veces.Mostrarlalistasólounavez,despuésdelpasoatravésdelbucle.
Resolverelproblemaconysinespecificacióndetipo
dealmacenamientoregister.Com­
pararlostiempos
deejecuciónylostamañosdelosprogramasobjetocompilados.
13.47.Otraformadegenerarunalista denúmerosprimosesutilizarlafamosa cribadeEratóstenes.
Estemétodoescomosigue:
a)Generarunalistaordenada deenterosentre2 y n.
b)Paraalgunosenterosparticulares
identrodelalista,realizarlassiguientesoperaciones:
i)Marcarelenterocomoprimo(puedeelegirsecolocarloenunarrayoescribirloenun
archivo).
ii)Eliminaracontinuacióntodoslosenterosquesonmúltiplos
dei.
c)Repetirlaparte b)paracadavalorsucesivode
identrodelalista,empezandoconi~2 Y
terminandoconelúltimoenteroqnequede.
EscribirunprogramaenCqueuseestemétodoparadeterminarlosprimosdentrodeunalista
denúmerosde
1an,dondenesuna cantidadintroducidaporelusuario.Repetirloscálculos
30000vecesmostrandolalistadenúmerosprimosalfinaldelúltimopasoporelbucle.
Resolverelproblemaconysinespecificacióndetipodealmacenamiento
register.Com­
pararlostiemposdeejecuciónylostamañosdelosprogramasobjetocompilados.
13.48.EscribirunprogramaenCqueacepteunnúmerohexadecimalcomoentradaymuestreunmenú
quepermitarealizarcualquieradelassiguientesoperaciones:

550 PROGRAMACiÓN ENC
a)Mostrarelhexadecimalequivalentedelcomplementoauno.
b)Realizarunaoperacióndeenmascaramiento ymostrarelhexadecimalequivalentedelre­
sultado.
e)Realizarunaoperación
dedesplazamientodebits ymostrarelhexadecimalequivalentedel
resultado.
d)Salir.
Siseseleccionalaoperación
deenmascaramiento,pedir alusuarioeltipodeoperación (ya
niveldebits,oexclusivaaniveldebits, uo aniveldebits) yluegounvalor(hexadecimal)para
lamáscara.
Siseseleccionalaoperacióndedesplazamiento,pediralusuarioeltipo dedesplaza­
miento(derechaoizquierda)
yelnúmerodebits.
Comprobarelprogramaconvariosvaloresdiferentes
desupropiaelección.
13.49.ModificarelprogramaescritoparaelProblema13.48demodoquesemuestrenlospatrones
binariosdebitsademás
delosvaloreshexadecimales.Usarunafunciónseparadaparamostrarlos
patronesbinarios,tomandocomomodeloelprogramamostradoenelEjemplo13.16.
13.50.ModificarelprogramaescritoparaelProblema13.49 demodoquela cantidad deentradapueda
serunaconstantedecimal,hexadecimaluoctal.Empezarmostrandounmenúparapermitiral
usuarioelegir
eltipodenúmero(elsistemadenumeracióndeseado)antesdeintroducir elvalor
real.Despuésmostrar
elvalorenlosotrosdossistemas denumeraciónyentérminosdesuco­
rrespondientepatróndebits.
Unavezquelacantidadhasidointroducida
ymostrada,generarelmenúprincipalpidiendoel
tipodeoperacióndeseada,comosedescribeenelProblema13.48.
Siseseleccionaunaoperación
deenmascaramiento,introducirlamáscaracomounaconstantehexadecimaluoctal.Mostrarel
resultado
decadaoperaciónendecimal,hexadecimal,octal ybinario.
13.51.EscribirunprogramaenCqueilustrelaequivalenciaentre:
a)Desplazarunnúmerobinario nposicionesalaizquierda ymultiplicarlopor
2".
b)Desplazarunnúmerobinario nbitsaladerecha ydividirlopor2"(oequivalentementemulti­
plicarlopor
2-").
Elegirelnúmerobinarioinicialconcuidadodemodoquenosepierdanbitscomoresultado
delasoperacionesdedesplazamiento.(Paraeldesplazamientoalaizquierda,elegirunnúmero
relativamentepequeñodemodoquetengavarioscerosenlasposicionesdemásalaizquierda.
Paraeldesplazamientoaladerecha,elegirunnúmerorelativamentegrande,concerosenlas
posicionesmásaladerecha.)
13.52.EscribirunprogramacompletoenCquecodifique ydecodifiqueelcontenidodeunarchivode
texto(archivoorientadoacaracteres)medianteelreemplazamiento
decadacarácterconsucom­
plementoauno.Observequeelcomplementoaunodelcomplementoaunodeuncarácteresel
carácteroriginal.Portanto,
elprocesodeobtenerelcomplementoaunopuedeusarsetantopara
codificareltextooriginalcomoparadecodificareltextocodificado.
Incluirlassiguientescaracterísticasenelprograma:
a)Introducirelcontenido deunarchivoordinarío detextodesdeelteclado.
b)Grabarelarchivo detextoactualensuestadopresente(codificadoodecodificado).
e)Recuperareltextoquehasidograbado(codificadoodecodificado).
d)Codificarodecodificarelarchivodetextoactual(cambiarelestadoactualobteniendoel
complementoauno
decadauno deloscaracteres).
e)Mostrarelarchivodetextoactualensuestadopresente(codificadoodecodificado).

PROGRAMACiÓN ABAJONIVEL 551
Generarunmenúquepermita alusuario seleccionarcualquieradeestascaracteristicassegún
desee.
13.53.ModificarelprogramaescritoparaelProblema13.52demodoquelacodificaciónydecodifica­
ciónserealicenusandola
oexclusivaaniveldebits ounaoperacióndeenmascaramientoenvez
delaoperacióndecomplementoauno.Permitiralusuariointroduciruna
clave(unamáscaraque
seráelsegundooperandoenlaoperación
oexclusiva).Comolaoperación oexclusivaproduce
unaoperacióndeconmutación,sepuedeusarparacodificareltextooriginaloparadecodificarel
textocodificado.Sedebeusarlamismaclaveparacodificarydecodificar.
13.54.Modificarelprograma decompresióndedatosmostradoenelEjemplo13.23 demodoquemues­
trelaedaddecadaestudiante(enaños)ademásdelasalidaquegeneranormalmente.Añadirlas
siguientescapacidadescomoopcionesseparadas:
a)Mostrarlaedadde unestudiantecuyonombreyfecha denacimientoseintroduzcancomo
entrada.
b)Mostrarlosnombres delosestudiantescuyaedadsealaespecificadapor elusuario.
e)Mostrarlosnombres
delosestudiantescuyaedadsealaespecificadaporelusuarioomenor.
d)Mostrarlosnombres delosestudiantescuyaedadsealaespecificadaporelusuarioomayor.
Generarunmenúquepermitaalusuarioseleccionarcualquieradeestasopcionessegún
desee.
13.55.Modificarelprograma'presentadoenelEjemplo10.8(análisisdeunalínea detexto)demodo
quelos
80caracteresdelalíneadetextosealmacenenenunarray decaracteresde70bytes.
(Suponercaracteres
ASCnde7bits.)Parahaceresto,usarlosoperadores dedesplazamientoa
niveldebitsdemaneraqueungrupodeochocaracteressealmaceneensieteelementosconsecu­
tivosdelarray(sietebytes).Cadaelementodelarraycontendráuncaráctercompleto,másunbit
deloctavocarácter.
Incluirlaposibilidad
demostrarloscontenidosdelarrayde70bytes(usandoconstanteshexa­
decimales)enlaformacomprimidayenlaformanocomprimidaequivalente.
Usarelprogramaparaanalizarlasiguientelínea
detexto:
Lascomputadoraspersonalesconmásde1024KBsonahorabastante
comunes.
(Observequeestalíneadetexto,incluyendolapuntuaciónylosespaciosenblancoentrelas
palabras,contieneuntotal
de74caracteres.)Examinarlasalidahexadecimal,asicomolosresul­
tadosdelanálisisparaverificarqueelprogramaseejecutacorrectamente.

CAPíTULO14
CaracterísticasadicionalesdeC
Enesteúltimocapítuloconsideramosalgunascaracterísticasnotratadas deC ypresentamosinfor­
maciónsobreotrascaracterísticaspreviamentetratadas.Comenzamosconunadiscusióndelas
enumeraciones,untipodedatosquedefineunconjuntodeidentificadores
detipoenteroque
pue­
denserasignadosalascorrespondientesvariablesdeenumeración.Lasvariables deenumeración
sonútilesenprogramasquerequierenindicadoresparaidentificarcondicioneslógicasinternas.
Acontinuacióntratamoslosargumentosdelalíneadeórdenes,loscualespermitenquelos
parámetrosseantransferidosalprogramacuandoelprogramaobjetocompiladoseejecutadesde
elsistemaoperativo.Porejemplo,losnombres
dearchivospuedensertransferidosfácilmenteal
programa
deestamanera.
Sepresentaunadiscusión
delabibliotecadefuncionesdeC, enlacualson
consideradas,desdeunaampliaperspectiva,lasfuncionessoportadasporlamayoríadelos
com­
piladorescomercialesde C.Estoesseguidoporladiscusióndelasmacros,queproporcionan
unaalternativaalusodefunciones
debiblioteca.Elusodemacrospuedesermásaconsejable
queeluso
defuncionesdebibliotecaendeterminadassituaciones.Elcapítuloconcluyeconuna
discusiónsobreelpreprocesadordeC,que
esunconjuntoespecial deórdenesqueseejecutanal
principiodelprocesodecompilación.
14.1.ENUMERACIONES
Unaenumeraciónesuntipodedatos,similaralaestructurao alaunión.Susmiembrosson
constantesqueestánescritascomoidentificadores,peroquetomanvaloresenterosconsigno.
Estasconstantesrepresentanvaloresquepuedenserasignadosavariablesdeenumeración.
Entérminosgenerales,unaenumeraciónpuedeserdefinidacomo
enummarca{miembro1,miembro2, .,miembrom};
dondeenumeslapalabrareservadarequerida, marcaelnombrequeidentificalaenumeración
conestoscomponentesy
miembro1,miembro2, .,miembromrepresentanlos
identificadoresindividualesquepuedenserasignadosavariables
deestetipo(vermás
adelan~
te).Losnombresdemiembrosdebensertodosdíferentesydebenserdistintosdeotrosidentifi­
cadorescuyoámbitoseaelmismoqueel
delaenumeración.
Unavezquelaenumeraciónhasidodefinida,lascorrespondientesvariables
deenumeración
puedenserdefinidascomo
553

554 PROGRAMACiÓN ENC
tipo-almacenamientoenummarcavariable1,
variable2, .,variablen;
dondetipo-almaeenamientoesunespecificadoropcionaldetipodealmacenamiento, enum
lapalabrareservadarequerida, marcaelnombrequeaparece enladefinicióndelaenumera­
ción
yvariable1,variable2, . ,variablenvariablesdeenumeracióndel
tipo
marca.
Ladefinicióndeenumeraciónpuedesercombinadaconladeclaracióndevariablesdeeste
tipo,comosemuestraacontinuación.
tipo-almacenamientoenummarca{miembro1,
miembro2, .,miembro
variable2,
Lamarcaesopcionalenestasituación.
EJEMPLO14.1. UnprogramaenCcontienelassiguientesdeclaraciones:
m}
.,
variable1,
variablen;
enurocolores{negro,azul,cian,verde,maganta,rojo,blanco,amarillo};
coloresprimerplano,fondo;
Laprimeralíneadefineunaenumeraciónllamada colores(lamarcaescolores).Laenumeración
consta
deochoconstantescuyosnombressonnegro,azul,cian,verde,magenta,rojo,blan­
coyamarillo.
Lasegundalíneadeclara lasvariablesprimerplanoyfondocomovariablesenumeradas deltipo
colores.Así,acadavariable selepuedeasignarcualquiera delasconstantesnegro,azul,cian,...,
amarillo.
Lasdosdeclaracionespueden sercombinadassisedesea,dandocomoresultado:
anurocolores{negro,azul,cian,verde,magenta,rojolblanco,amarillo}
primerplano,fondo;
o,sinlamarca,simplemente
enuro{negrorazul,cian,verde,rnagentarrojo,blanco,amarillo}
primerplano,fondo;
Lasconstantesdeenumeracióntienenautomáticamenteasignadosvaloresenteros,empezan­
doporO
paralaprimeraconstanteeincrementándose en1paralassucesivas.Deestamanera,
miembro1tendráautomáticamenteasignadoelvalor O,miembro2tendráasignado 1,yasí
sucesívamente.
EJEMPLO14.2. Consideremoslaenumeracióndefinida enelEjemplo14.1,estoes,
anurocolores{negro¡azul,cian!verde,maganta,rojo,blanco,amarillo}¡
Lasconstantesdeenumeraciónrepresentaránahoralossiguientesvaloresenteros:

CARACTERíSTICAS ADICIONALESDEC 555
negro O
azul 1
cian 2
verde 3
magenta 4
rojo 5
blanco 6
amarillo 7
Estasasignacionesautomáticaspuedensermodificadasdentrodeladefiniciónde
laenu-.
meración.Estoes,aalgunasconstantesselespuedenasignarvaloresenterosdiferentesdelos
valores
poromisión.Parahaceresto,cadaconstante(cadamiembro)a laqueesasignado
un
valorexplícitoseexpresacomounaexpresióndeasignaciónordinaria; porejemplo,
miembro=int,dondeintrepresentaunacantidadenteraconsigno.Alasconstantesque
notenganasignadosvaloresexplícitosselesasignaránautomáticamentelosvaloresincrementa­
dossucesivamenteen1desdelaúltimaasignaciónexplícita.Estopuedehacerquedosomás
constantesdeenumeracióntenganelmismovalorentero.
EJEMPLO14.3. Aquítenemosunavaríacíón delaenumeracíóndefinída enlosEjemplos14.1y14.2.
enumcolores{negro=-l/azul,cian,verde,magenta,rojo=2,
blanco,amarillo};
Lasconstantesdeenumeracíónrepresentaránahora lossíguíentesvaloresenteros:
negro -1
azul O
cian 1
verde 2
magenta 3
rojo 2
blanco 3
amarillo4
Lasconstantesnegroyrojotíenenahoraasígnadosexplícítamente losvalores-1y2,respectívamen­
tc.Lasotras constantestomanautomátícamentevaloresíncrementadossucesívamente en1desdelaúltí­
maasígnacíónexplícíta. Así,azul,cian,verdeymagentatíenenasígnados losvaloresO,1,2 Y3,
respectívamente.Análogamente,
blancoyamarillotíenenasígnados losvalores3 y4.Observeque
ahoratenemosasígnacíonesduplícadas;porejemplo, verdeyrojorepresentanambos2,míentrasque
magentayblancorepresentan3.
Lasvariablesenumeraciónpuedensertratadasde
lamismamaneraqueotrasvariablesente­
ras.Estoes,puedenasignárselesnuevosvalores,compararse,etc.Sinembargo,debequedar
claroquelasvariablesdeenumeraciónsongeneralmenteusadasinternamenteparaindicarcon­
dicionesquepuedensurgirdentrode
unprograma.Portanto,hayciertasrestriccionesasociadas
con
suuso.Enparticular,unaconstantedeenumeraciónno puedeserleídaporlacomputadora
yasignadaaunavariabledeenumeración.
(Esposibleleer unenteroyasignarloaunavariable
deenumeración,aunquegeneralmentenosehace.)Además,
sóloelvalorenterodeunavariable
deenumeraciónpuedeserescrito
porlacomputadora.

556 PROGRAMACIÓN ENC
EJEMPLO14.4. ConsideremosunavezmáslasdeclaracionespresentadasenelEjemplo14.1,esdecir,
enurocolores{negro,azul,cian,verde,magenta,rojo,blanco,amarillo};
coloresprimerplano.fondo;
Acontinuaciónsemuestranvariasinstrucciones queusanlasvariables deenumeraciónprimerplanoy
fondo.
primerplano=blanco;
fondo=azul;
if(fondo==azul)
primerplano=amarillo;
else
primerplano=blanco;
if(primerplano==fondo)
fondo=(enumcolores)(++fondo%8);
switch(fondo){
casenegro:
primerplano=blanco;
break;
caseazul:
azul:
cian:
verde:
magenta:
rojo:
primerplano=amarillo;
break;
caseblanco:
primerplano=negro;
break;
caseamarillo:
primerplano=azul;
break;
casedefault:
printf("ERRORENLASELECCrONDELCOLORDEFONDO");
}
Amenudosepuedeincrementarlaclaridadlógicadeunprogramausandovariablesdeenu­
meración.Lasvariablesdeenumeraciónsonparticularmenteútilescomoindicadores,paraindi­
carvariasopcionespararealizaruncálculo,oparaidentificarcondicionesquepuedanhaber
surgidocomoresultadodecálculosinternosanteriores.Desdeestaperspectivaseaconsejael

CARACTERíSTICAS ADICIONALES DEC557
usodevariablesdeenumeracióndentrodeunprogramacomplejo.Noobstante,debequedar
claroquesepuedenusarvariablesenterasenvezdevariablesdeenumeración.Portanto,las
variablesdeenumeraciónnoproporcionanfundamentalmentenuevascapacidades.
EJEMPLO14.5. Elevaciónde unnúmeroa unapotencia.EnelEjemplo11.37vimosunprograma
en
eparaevaluarlafónnula y=
x",dondexeysonvaloresencomaflotantey nunexponenteenterooen
comaflotante.Dichoprogramahacíausodelassiguientesestructurasdedatos:
typedefunion{
floatfexp;
intnexp;
}nvalor;
typedefstruct{
floatx;
charindicador;
nvaloreXPi
}valores;
/*exponenteencomaflotante*/
/*exponenteentero*/
/*valorparaelevaralapotencia*/
/*'f'sielexponenteesencomaflotante
'e'sielexponenteesentero*/
/*uniónquecontieneelexponente*/
Observequelaunióncontieneelvalordelexponente,quepuedeserunacantidadenteraoencomaflotan­
te.Laestructuraincluyeelvalorde
x,unindicador(uncarácterqueindicalanaturalezadelexponente)y
launiónquecontieneelexponente.
Ahorapresentamosotra versión,enlacualelcarácterindicadoresreemplazadoporunavariablede
enumeración.Laestructura
dedatosquedamodificadacomosigue:
typedefenum{exp_float,exp_int}tipo_exp;
typedefunion{
floatfexp;
intnexpi
}nvalor;
typedefstruct{
floatx;
tipo_expindicador;
nvaloreXPi
}valores;
/*exponenteencomaflotante*/
/*exponenteentero*/
/*valorparaelevaralapotencia*/
/*indicadordeltipodeexponente*/
/*uniónquecontieneelexponente*/
Observeque indicador,queesunmiembrodelaestructuradeltipo valores,esahoraunavariable
deenumeracióndeltipo
tipo_exp.Estavariablepuedetomarelvalorde exp_floatoexp_int,
indicandounexponenteencomaflotanteoenterorespectivamente.
Loscálculosseránrealizados
demododistintodependiendodeltipodeexponente.Enparticular,la
potenciaciónseefectuarámediantemultiplicacionesenelcaso
deexponenteenteroyutilizandologarit­
mosenelcasodeexponenteencomaflotante.
Aquíestálaversiónmodificadadelprograma.
/*programaparaelevarunnúmeroaunapotencia*/
#include<stdio.h>
#include<math.h>

558 PROGRAMACiÓN ENC
typedefenum{exp_float,exp_int}tipo_exp;
typedefunion{
floatfexp;
intnexpi
}nvalor;
typedefstruct{
floatx;
tipo_expindicador;
nvalorexpi
}valores;
/*exponenteencomaflotante*/
/*exponenteentero*/
/*valorparaelevaralapotencia*/
/*indicadordeltipodeexponente*/
/*uniónquecontieneelexponente*/
floatpotencia(valoresa);/*prototipodefunción* /
main()
{
valoresa¡
inti;
floatn,y;
/*estructuraquecontieneXIindicador,
fexp/nexp* /
/*introduccióndedatosdeentrada*/
printf("y~xAnIntroducirunvalorparax:");
scanf(H%f
ll
r&a.x)¡
printf("Introducirunvalorparan:");
scanf("%f",&n);
/*determinareltipodeexponente*/
i~(int)n;
a.indicador~(i~~n)?exp_intexp_float;
if(a.indicador--exp_int)
a .exp.nexp ~i;
else
a.exp.fexp ;::;ni
/*elevarx alapotenciaadecuadaymostrarelresultado*/
if(a.indicador~~exp_float&&a.x<~0.0)(
printf("ERROR -Nosepuedeelevarunnúmeronopositivoa");
printf("unapotenciaencomaflotante");
}
else(
y~potencia(a);
printf("y"%.4f",y);
}
}
floatpotencia(valoresa)
{
intii
floaty~a.x;
/*realizalapotenciación*/

CARACTERíSTICAS ADICIONALES DEC559
if(a.indicador==exp_int){/*exponenteentero*/
if(a.exp.nexp==O)
Y=1.0; /*exponentecero*/
else{
for(i=1;i<abs(a.exp.nexp);++i)
y*=a.x;
if(a.exp.nexp<O)
y=1./y; /*exponenteenterononegativo*/
}
}
else /*exponenteencomaflotante*/
y=exp(a.exp.fexp*log(a.x));
return(y);
}
Cuandoseejecutaesteprograma, secomportadelamismamaneraquelaversiónanterior.Esto se
puedeverificarejecutandoelprogramaconlosdatosdeentradadelEjemplo11.37.
Estaversióndelprogramanorepresentaunagranmejorasobrelaversiónanterior.Sinembargo,la
ventajadeluso
devariablesdeenumeraciónesmayorenprogramasqueincluyenopcionesmáscomplicadas.
Unavariablede enumeraciónpuedeserinicializadaengeneraldelamismamaneraqueotras
variablesenC.Lainicializaciónpuedeserrealizadaasignandounaconstantedeenumeracióno
unvalorenteroa lavariable.Sinembargo,alavariableseleasignaráunaconstantedeenume­
ración,comoseilustraacontinuación(vertambiénelEjemplo14.13).
EJEMPLO14.6. UnprogramaenCcontienelassiguientesdeclaraciones:
enumcolores{negro,azul,cian,verdefmagenta frojoIblanco/amarillo}i
coloresprimerplano=amarillo,fondo=rojo;
Así,alasvariablesdeenumeración primerplanoyfondoseleasignanlosvaloresiniciales
amarilloyrojo,respectivamente.Estasasignacionesdeinicializaciónsonequivalentesaescribir
primerplano=7;
fondo=5;
Sinembargo,generalmentealasvariablesdeenumeraciónseleasignanconstantes deenumeraciónenvez
denúmerosenterosequivalentes.
14.2.PARÁMETROS DELALÍNEADEÓRDENES
¿SehaestadoustedpreguntandoparaquésirvenlosparéntesisvaéIosenlaprimeralíneadela
funciónmain,estoes,main( )?Estosparéntesispuedencontenerargumentosespecialesque
permitenpasarleparámetrosamaindesdeel sistemaoperativo.Lamayoríadelasversiones

560 PROGRAMACiÓN ENC
deCpermitendosargumentos,quesellamantradicionalmente argcyargv,respectivamente.
Elprimerodeellos,
argc,debeserunavariableentera,mientrasqueelsegundo, argv,esuna
formacióndepunterosacarácter,esdecir,unaformacióndecadenasdecaracteres.Cadacade­
naenestaformaciónrepresentaráunparámetroqueespasadoa
main.Elvalorde argcindica­
ráelnúmerodeparámetrospasados.
EJEMPLO14.7. Elsiguienteesquemaindica cómoestándefinidoslosargumentos argcyargvden­
trodemain.
voidmain(intargc,char*argv[])
{
}
Laprimeralinea sepuedeescribirsinlapalabrareservada void,estoes:
main(intargc,char*argv[])
Unprogramaseejecutanormalmenteespecificandoelnombredelprogramaen unentorno
guiadopormenús,comoseexplicóenlasección5.4.Algunoscompiladorestambiénpermiten
queelprogramaseaejecutadoespecificandoelnombredelprograma(enrealidadelnombredel
archivoquecontieneelprogramaobjetocompilado)enel
niveldelsistemaoperativo. Elnombre
delprogramaesinterpretadocomounaordendelsistemaoperativo.Deaquíquelalíneaenla
queaparecensedenominegeneralmente
líneadeórdenesocomandos.
Parapasarunoomásparámetrosalprogramacuandoseejecutadesdeelsistemaoperativo,
losparámetrosdebenseguiralnombredelprogramaenlalíneadeórdenes,porejemplo,
nombre-programaparámetro1parámetro2 . .parámetron
Losdatosindividualesdebenirseparadosporespaciosenblancootabuladores.Algunossiste­
masoperativospermitenincluirespaciosenblancodentrode
unparámetro,siemprequeelpará­
metroestéentrecomillas.
Elnombredelprogramaseráalmacenadocomoelprimerelementoen
argv,seguidopor
cadaunodelosparámetros.Portanto,
sielnombredelprogramaesseguidopor nparámetros,
habrá
(n+1)entradasen argv,dentrodelrangoquevadesde argv[O]hastaargv[n].
Además,
argctendráautomáticamente asignadoelvalor (n+1).Tengapresentequeelvalor
para
argcnovienedadoexplícitamentedesdelalíneadeórdenes.
EJEMPLO14.8. Consideremoselsiguienteprogramasencillo enC,queseejecutadesdeunalineade
órdenes.
#include<stdio.h>
main(intargc,char*argv[])
{
intcont;

CARACTERíSTICAS ADICIONALES DEC 561
printf("argc=%d",argc};
}
for(cont=o;cont<
printf("argv[%d]
argc;++cont)
=%s
ll
,cont,argv[cont]};
Esteprogramapermitiráintroducirunnúmeronoespecificadodeparámetrosdesdelalinea deórdenes.
Cuandoelprogramaesejecutado,elvaloractual
deargcyloselementosde argvseránmostradosen
lineas
desalidaseparadas.
Supongamos,porejemplo,queelnombredelprogramaes
muestraylalineadeórdenesqueinicia
laejecucióndelprogramaes
muestrarojoblancoazul
Entonceslaejecucióndelprogramatendrácomoresultadolasiguientesalida:
argc=4
argv[O]
argv[1]
argv[2]
argv[3]
muestra.exe
=rojo
=blanco
=azul
Lasalidanosindicaquehansidointroducidoscuatroelementosdesdelalineadeórdenes.Elprimeroesel
nombredelprograma,
muestra.exe,seguidoportresparámetros, rojo,blancoyazul.Cadauno
esunelementoenlaformación
argv.(Observeque muestra.exeeselnombredelarchivoobjeto
resultadodelacompilacióndelcódigofuente
muestra.c.)
Análogamente,silalineadeórdeneses
muestrarojoIIblancoazul
n
lasalidaresultanteserá
argc=3
argv[O]
argv[1]
argv[2]
=muestra.exe
=rojo
=blancoazul
Enestecasolacadena decaracteres"blancoazul"seráinterpretadacomounparámetrosimple,
debidoalascomillas.
Unavezquelosparámetroshansidointroducidos,puedenserutilizadosdentrodel programa
comosedesee.Unaaplicacióncomúnesespecificarnombresdearchivosdedatoscomopará­
metrosdelalíneadeórdenes.Estatécnicaestáilustradaacontinuación.
EJEMPLO14.9.Lecturadeunarchivo dedatos.Aquítenemosunavariacióndelprogramamostrado
enelEjemplo12.4,queleeunalineadetextodesdeunarchivodedatoscarácteracarácter
ymuestrael

562 PROGRAMACiÓN ENC
textoenlapantalla.Ensuformaoriginal,elprogramaleíaeltextodesdeunarchivodedatosllamado
muestra.dat,dondeelnombredelarchivoestabaincluidodentrodelprograma.Sinembargo,ahorael
nombredelarchivodedatosesintroducidocomo
unparámetrodelalíneadeórdenes.Asíelprogramaes
aplicablepara
cualquierarchivodedatos;yanoestárestringidoa muestra.dato
Aquítenemoselprogramaentero.
/ *
leerunalíneadetextodeunarchivodedatosymostrarlaen
pantalla*/
#include<stdio.h>
#defineNULL O
main(intargc,char*argv[l)
{
FILE*fpt;/*defineunpunteroalaestructurapredefinidaFILE*/
charc¡
/*abrirelarchivodedatossoloparalectura*/
if((fpt=fopen(argv[l],"r"))'==NULL)
printf("ERROR -Nosepuedeabrirelarchivodesignado");
else/*leerymostrarcadacarácterdesdeelarchivodedatos*/
do
putchar(c=getc(fpt));
while(c!='');
/*cerrarelarchivodedatos*/
fclose(fpt);
}
Observequelafunción mainincluyeahoralosargumentosformales argcyargv,definidosde la
maneradescritaanteriormente.También,lafunción fopenestáahoraescritacomo
fopen(argv[l]
,"r")
envezde
fopen(Hmuestra.datll, IIr")
comoenlaanteriorversióndeesteprograma.
Supongamosahoraqueelnombredelprogramaes
leerarchiva.Paraejecutaresteprogramay
leerelarchivodedatos
muestra.dat,lalíneadeórdenesseescribiría
leerarchivomuestra.dat
ElprogramasecomportarádelamismamaneraquelaversiónanteriormostradaenelEjemplo12.4.

CARACTERíSTICAS ADICIONALES DEC563
13.4.MÁSSOBREFUNCIONESDEBIBLIOTECA
Hastaahorahemosaprendidoquelasfunciones debibliotecadeCsonextensas,tantoennúmero
como
enpropósito.Hemostenidoevidencia deestoenlosejemplos deprogramaspresentados
previamenteenestelibroyenlalista
defuncionesdebibliotecacomúnmenteusadasdadasenel
Apéndice
H.Alolargodeestelibrohemosusadoesasfuncioneslibremente,encualquiersitio
dondehasidonecesario.
Sinembargo,debequedarclaroquetodaslasfunciones
debibliotecapresentadaseneste
libroentrandentrodealgunascategoríasbásicas.Enparticular,hanfacilitadooperaciones
de
entrada/salida,evaluación defuncionesmatemáticas,conversionesdedatos,clasificaciónycon­
versión
decaracteres,manipulación decadenasdecaracteres,gestión dememoriadinámicay
algunasoperacionesvariadasrelacionadasconelreloj.
Lamayoría
deloscompiladores comercialesdeCincluyenmuchasfunciones debiblioteca
adicionales.Algunasdeesasfuncionesentrandentro
delascategoríasdescritasantes,mientras
queotrascorrespondenacategoríasquetodavíanohansidodescritasenestelibro.Porejemplo,
lamayoría
deloscompiladoresincluyenfunciones debibliotecaquepuedenmanipularáreas de
buffer(bloques dememoriaenquelasformaciones decaracterespuedenseralmacenadostem­
poralmente),quefacilitanelmanejoygestión
dearchivosyqueproporcionanla capacidad de
realizarbúsquedasyordenaciones.Ademáspuedenexistirfuncionesdebibliotecaquepermitan
elaccesoaciertasórdenesdelsistemaoperativoyalhardwareinternodelacomputadora(espe­
cialmenteinstruccionescontenidasenlamemoriadesólolecturadelacomputadora).Finalmen­
te,algunoscompiladoresincluyenfuncionesdebibliotecaparaaplicacionesmásespecíficas,
comoelcontroldeprocesosygráficos.
Estasfunciones
debibliotecasimplifican,enunnúmeroimportante deáreas,laescritura de
programasdefácilcomprensiónen C.Porejemplo,Cseusatanto
paraescribirsistemasopera­
tivoscomoparaaplicacionesofimáticastalescomoprocesadoresdetexto, hojas
decálculoy
programas
degestióndebases dedatos.ElfamososistemaoperativoUNIXestáescritoen C.
Tambiénloestánmuchosprogramasofimáticos.
Las funcionesdecontroldeprocesospermitenaplicacionesenlasquevariosprogramasson
ejecutadosalavezdemanerajerárquica.Análogamente,lasfuncionesgráficassimplificanla
escritura
devariadasaplicacionesgráficas,talescomoprogramasde«pintura»yaplicaciones de
diseñoasistidoporcomputadora(CAD).ElusodeCparaotrostiposdeaplicacionescomercia­
lespareceestarcreciendorápidamente.
Unadiscusióndetalladadeestasaplicacionescompletas
deprogramaciónestámásalládel
ámbitodelpresentetexto.Sinembargo,ellectordebetenerencuentaque
esprácticoescribir
talesaplicacionesenC,principalmentedebidoaladisponibilidad
delaampliabiblioteca deC.
Loslectoresquequieranseguirprofundizandoenestostemasdebenfamiliarizarseconlabiblio­
teca
defuncionessuministradaconsucompilador deeparticular.
14.4.MACROS
Yahemosvistoquelainstrucción #definepuedeser
l.\sadaparadefinirconstantesdentro de
unprogramaen C.Alprincipiodelproceso decompilacióntodaslasconstantessimbólicasson
reemplazadasporsutextoequivalente(versección2.9).Así,lasconstantessimbólicas propor­
cionanunaformadenotaciónabreviadaquepuedesimplificarlaorganizacióndeunprograma.

564 PROGRAMACiÓN ENC
Sinembargo,lainstrucción #definepuedeserusadaparadefiniralgomásqueconstantes
simbólicas.
Enparticular,puedeserusadaparadefinirmacros;esdecir,identificadoressimples
quesonequivalentesaexpresiones,ainstruccionescompletaso agruposdeinstrucciones.
En
estesentidolasmacrosseparecenalasfunciones.Noobstante,sondefinidas ytratadasde
formadiferentequelasfuncionesduranteelprocesodecompilación.
EJEMPLO14.10. Consideremoselprogramasencillo enCmostradoacontinuación.
#include<stdio.h>
#definearealongitud*anchura
main()
{
intlongitud,anchura;
printf("longitud=");
scanf("%d",&longitud)
;
printf("anchura ;;;;")i
scanf(n%dur&anchura);
printf(11area ;:::%d 11,area)i
}
Esteprogramacontienela macroarea,querepresentalaexpresión longitud*anchura.Cuando
elprogramaescompilado,laexpresión longitud*anchurareemplazaráalidentificadorarea
dentrodelainstrucciónprintf,detalfonnaquelainstrucciónprint fquedará
printf("area=%d",longitud*anchura);
Observequelacadena"area =%d"noseveafectadaporlainstrucción #define(versección2.9).
Cuandoseejecutaelprograma,losvalorespara longitudyanchurasonintroducidosinteracti­
vamentedesde
eltecladoy elvalorcorrespondientepara areaesmostradoporpantalla.Acontinuación
sepresentaunasesióninteractivatípica. Lasrespuestasdelusuarioestánsubrayadas comodecostumbre.
longitud=
.:2.
anchura=1.
area=12
Lasdefinicionesdemacrosestánnormalmentecolocadasalprincipiodeunarchivo,antesde
ladefinicióndelaprimerafunción.Elámbitodeunadefinicióndemacrovadesdeelpuntode
definiciónhastaelfinaldelarchivodondehasidodefinida.Sinembargo,unamacrodefinida
en
unarchivonoesreconocidadentrodeotroarchivo.
Podemosdefinirmacros
convariaslíneascolocandounabarrainvertida ()alfinaldecada
línea,excepto
enlaúltima.Esta.caracteristicapermiteque unasolamacro(unidentificador
simple)representeunainstruccióncompuesta.

CARACTERíSTICAS ADICIONALESDEC 565
EJEMPLO 14.11. HeaquíotroprogramasencilloenCquecontiene unamacro.
#include<stdio.h>
#define
main()
{
bucle
}
for(lineas=1;lineas
for(cont=1;cont
putchar('');
for(cont=1;cont
putchar('*')¡
printf(lI
H

<=n;lineas++){ \
<=
n-lineas;cont++) \
\
<=2 *lineas-1;cont++)\
\
\
intcont,lineas,n;
printf(IInúmerodelíneas=");
scanf("%d",&n);
printf(nn);
bucle;
}
Esteprogramacontieneunamacrodevariaslíneas,querepresentaaunainstruccióncompuesta.Lains­
truccióncompuestaconsta
devariosbucles foranidados.Observelabarrainvertida ()incluidaalfinal
delaslíneas,exceptoenlaúltima.
Cuandoelprogramaescompilado,lareferenciaalamacroesreemplazadaporlasinstruccionescon­
tenidasdentrodeladefinicióndelamacro.Así,
elprogramamostradoanteriormenteseconvierteen
#include<stdio.h>
main()
{
intcont,lineas,n;
printf("númerodelíneas=");
scanf(lI%dnI&n)i
printf
(nn);
<=2 * lineas-1;cont++)
}
for
}
(lineas=1;lineas
for(cont=1;cont
putchar('');
for(cont=1;cont
putchar('*');
printf("'n");
<=nilineas++)
<=TI-lineas;
{
cont++)
Cuandoelprogramaesejecutado,muestrauntriángulodeasteriscos,conunnúmerodelíneasdeter­
minado
porelvalordadoporelusuario(elvalor den).Acontinuaciónsemuestraelresultadodeuna
ejecucióntípica.
Denuevolarespuestadelusuarioestásubrayada.

566 PROGRAMACiÓN ENC
númerodelíneas:Q
*
***
*****
*******
*********
***********
Unadefinicióndemacropuedeincluirargumentos,queestánencerradosentreparéntesis.El
paréntesisizquierdodebeaparecerinmediatamentedetrásdelnombredelamacro;
esdecir,no
puedenexistirespaciosentreelnombre
delamacroyelparéntesisizquierdo.Cuandounamacro
esdefinida
deestamanera,suaspectodentrodelprogramaessimilaralallamadaaunafunción.
EJEMPLO14.12. HeaquíunavariacióndelprogramamostradoenelEjemplo14.11.
#include<stdio.h>
\
\
\
cont++)\
\
\
<=n;lineas++){
<=TI
-lineas;cont++)
<=2 *lineas-1;
(lineas=1;lineas
for(cont=1;cont
putchar('');
for(cont=1;cont
putchar('*');
printf("") ;
forbucle(n)#define
}
main( )
{
intcont,lineas,ni
printf(lrn~mero delineas=U);
scanf("%d" I&n)i
printf(11
ll
)i
bucle(n);
}
Elprogramapasaahoraelvalordenalamacro,comosifueraunargumentorealenlallamadadeuna
función.
Esteprogramasecomportadelamismamaneraqueelprogramamostrado enelEjemplo14.11cuando
esejecutado.
Avecesseusanmacrosenlugar
defuncionesdentrodeunprograma.Eluso deunamacro
enlugardeunafuncióneliminaelretrasoasociadoconlallamadaalafunción.Sielprograma
contienemuchasllamadasafuncionesrepetidas,eltiempoahorradoporeluso
demacrospuede
sersignificativo.
]Jorotraparte,lasustitucióndelamacroserealizaráentodaslasreferenciasalamacroque
aparezcandentrodeunprograma.Así,unprogramaquecontengavariasreferenciasalamisma
macropuedevolverseexcesivamentelargo.]Jortanto,tenemosladisyuntivaentrelavelocidad

CARACTERíSTICAS ADICIONALES DEC567
deejecuciónyeltamañodelprogramaobjetocompilado.Elusodeunamacroesmásventajoso
enaplicacionesdondehayrelativamentepocasllamadasafuncionesperolafunciónes llamada
repetidamente(porejemplo,unafunciónllamadadentrode unbucle).
EJEMPLO14.13.Valorfuturodedepósitosmensuales(cálculosdeinteresescompuestos). Enel
Ejempio
10.30vimosunprogramaen equegeneraelvalorfuturodeunasumadedinerodadaduranteun
períodoespecificodetiempoparavariastasasdeinterés.Elprogramafueestructuradooriginalmentede
maneraqueilustrarácómounafunciónespasadacomoargumentoaotrafunción.Enparticular,
main
pasaotrafunción,bienmd1,md2omd3a tabla,lacualgeneraunatabladevaloresfuturosparalas
tasasdeinterés.
Presentamosahoradosvariacionesdeesteprograma.Laprimeraversiónutilizallamadasafunciones
directamentedesde
main,mientrasquelasegundahaceuso delassustitucionesdemacros.Aquíestála
primeraversión.
/*cálculosfinancierospersonales,utilizandollamadasafunciones*/
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<math.h>
/*prototiposdefunciones*/
doublemd1(doublei,intm,doublen);
doublemd2(doublei,intm,doublen);
doublemd3(doublei,doublen),
main()/*calcularelvalorfuturodeunaseriededepósitosmensuales* /
{
enum{A=1,S=2,Q=4,M=12,D=360,C}m;
/*númerodeperíodosdecomposiciónporaño*/
intcont¡ /*contadordelbucle*/
doublen' /*númerodeaños*/,
doublea, /*cantidaddecadapagomensual*/
doublei¡ /*tasadeinterésanual*/
doublef; /*valorfuturo*/
charfrec; /*indicadordefrecuenciadecomposición*/
/*entradadedatos*/
printf("VALOR FUTURODEUNASERIEDEDEPOSITaSMENSUALES ")
,
printf("Cantidaddecadapagomensual:");
scanf("%lf",&a),
printf(IINúrnerodeaños: 11)i
scanf(Il%lf
ll
I&n);
/*introducirfrecuenciadecomposición*/
do{
printf(IIFrecuenciadecomposición(A,S,Q,M,D,e):11)i
scanf(u%18lIt&frec);

/*convertiramayúsculas*/
568 PROGRAMACiÓN ENC
frec=toupper(frec);
if(frec=='A'){
ro=A¡
printf("Composiciónanual") ;
}
elseif(frec=='8'){
ro=Si
printf("Composiciónsemestral");
}
elseif(frec=='Q'){
m =
Q;
printf("Composicióntrimestral");
}
elseif(frec==
'M'){
ro=Mi
printf("Composiciónmensual");
}
elsei f(frec=='D'){
ro;;;:;Di
printf("Composicióndiaria");
}
elsei f(frec=='C'){
ro ;;;:;c¡
printf("Composicióncontinua") ;
}
else
printf("ERROR -Porfavorrepita");
}while(frec!='A'&&frec!='8'&&frec!='Q'&&
free1='M'&&free!='D'&&free!:;;:;'e');
/*realizarloscálculos*/
printf("TasadeinterésCantidadfutura");
for(cont=1;cont<=20;++cont){
i
=0.01*cont;
if(m=,=C)
f=a*md3(i,n); /*composicióncontinua*/
elseif(m==D)
f
=a*md2(i,m,n); /*composicióndiaria*/
'e1se
f ;;;:;a*rndl(i,m,n); /*composiclonanual/semestral,
trimestralomensual*/
printf(" %2d %.2f",cont,f);
}
}
doublemd1(doublei,intm,doublen)
/ *depósitosmensuales,composiciónperiódica* /

composiciónperiódica*1\
\
~1)Ii; \
CARACTERíSTICAS ADICIONALES DEC569
{
doublefactor,razon;
factor~1+i/m;
razon~12*(pow(factor,m*n)- 1)Ii;
return(razon);
}
doublemd2(doublei,intm,doublen)
1*depósitosmensuales,composicióndiaria*I
{
doublefactor,razon;
factor~1+i/m;
razon~(pow(factor,m*n)- 1)I(pow(factor,mi12)-1);
return(razon);
}
doublemd3(doublei,doublen)
1*depósitosmensuales,composicióncontinua*I
{
doublerazon;
razon~(exp(i*n)-1)I(exp(i/12)-1);
return(razon);
}
Observequelafunción tabla,queestabaincluidaenelprogramaoriginal,ahoraestácombinada
con
main,evitandoasílanecesidaddepasarunafunciónaotra.Elprogramaactualutilizaunaenmnera­
ciónparasimplificarunpocolaorganizacióninterna.
Aquíestálasegundaversión,queutilizasustitucionesdemacrosenlugardefunciones.
1*cálculosfinancierospersonales,utilizandosustitucionesdema­
cros*1
#inc1ude<stdio.h>
#inc1ude<std1ib.h>
#include<ctype.h>
#include<math.h>
#definemd1(i,m,n){/*depósitosmensuales,
factor
~1+i/m;
razon~12*(pow(factor,m*n)
}
#definemd2(i,m,n){I*depósitosmensuales,composicióndiaria*I \
factor~1+i/m; \
razon~(pow(factor,m*n)- 1)I(pow(factor,m/12)-1);\
}

570 PROGRAMACiÓN ENC
#definemd3(i,n){/*depósitosmensuales,composicióncontinua*/\
razon=(exp(i*n)-1)/(exp(i/12)-1), \
}
main()/ * calcularelvalorfuturodeunaseriededepósitosmensuales* /
{
enum{A=1,S=2,Q
intcont;
doub1en,
doublea,
doublei,
doublef,
doublefactor,razan;
charfrec;
=4,M =12,D=360,C}m,
/ *númerodeperíodosdecomposiciónpor
año*/
/*contadordelbucle*/
/*númerodeaños*/
/*cantidaddecadapagomensual*/
/*tasadeinterésanual*/
/*valorfuturo*/
/*parámetrosinternos*/
/*indicadordefrecuenciade
composición* /
/*entradadedatos*/
printf("VALOR FUTURODEUNASERIEDEDEPOSITaSMENSUALES"),
printf("Cantidaddecadapagomensual:"),
scanf(lI%lf
ll
,&a)¡
printf("Númerodeaños:");
scanf(ll%lf
ll
,&n)¡
/*introducirfrecuenciadecomposición*/
do{
printf(IIFrecuenciadecomposición(A,Sr"Q¡M,DIe):")i
scanf(11%18",&frec)i
frec=toupper(frec),/*convertiramayúsculas*/
if(frec=='A'){
ro=A¡
printf("Composiciónanual");
}
elseif(frec=='S'){
ro=Si
printf("Composiciónsemestral"),
}
elseif(frec=='Q'){
m=Q;
printf("Composicióntrimestral");
}
elseif(frec=='M'){
ro=M¡
printf("Composiciónmensual");
}
elseif(frec=='D'){
ro=Di
printf("Composicióndiaria");
}

CARACTERíSTICAS ADICIONALESDEC 571
elseif(frec~~'C'){
ro=c¡
printf(nComposición continuan)i
}
else
printf("ERROR -Porfavorrepita");
}while(frec!~'A'&&frec!~'S'&&frec!~'Q'&&
free!=IM'&&free1='D'&&free1='e');
/*realizarloscálculos*/
printf("TasadeinterésCantidadfutura");
for(cont~1;cont<~20;++cont){
i~0.01*cont;
if(m~~C)
md3(i,n) /*composicióncontinua*/
elseif(m~~D)
md2
(i,m,n)/*composicióndiaria* /
}
}
else
mdl(i,m,n)
f=a*razon¡
printf(" %2d
/*composiciónanual/semestral,
trimestralomensual*/
%.2f",cont,f);
Examinecuidadosamenteestos dosprogramas,comparandoelusodelassustitucionesdelasmacros
enlugardelasfunciones.Enparticular,observe lamaneraenqueseaccedealasfunciones enelprimer
programa
ycompárelaconlasreferenciasalasmacros enelsegundoprograma(vea lainstrucción
if-elsealfinaldemain).
Cuandoseejecutan,ambosprogramassecomportanexactamente delamismamaneraqueel
progra­
maoriginaldadoenelEjemplo10.30.
MuchoscompiladorescomercialesdeCofrecenciertasfuncionesdebiblioteca,enformade
macrosocomoverdaderasfunciones.Lasmacrosestándefinidasenlosarchivosdecabecera.El
programadorpuedeentonceselegirquéformaesmásapropiadaparacadaaplicaciónenparticu­
lar.Perodebequedarclaroquehayciertasdesventajasasociadasconelusodemacrosenlugar
defunciones,ademásdelpotencialincrementosignificativodelalongituddeunprograma.En
particular:
1.Cuandosepasanargumentosa unamacro,elnúmerodeargumentosserácomprobado,
peronosustiposdedatos.Así,hayunamenorcomprobacióndeerroresqueconuna
llamadaaunafunción.
2.
Unidentificadordemacronoestáasociadoconunadirección;portantonopuedeser
utilizadocomounpuntero.Así,unamacronopuedeserpasadaa
unafuncióncomo un

572 PROGRAMACiÓN ENC
argumentoenelmismosentidoqueunafunciónpuedeserpasadaaotrafuncióncomoun
argumento(versección10.9).Además,unamacronopuedellamarseasímismarecursi­
vamente.
3.Hayposiblesefectoslateralesindeseablesconelusodemacros,particularmentecuando
hayargumentosenlallamada.
EJEMPLO14.14. Consideremosladefinicióndemacro
#defineraiz(a,b)sqrt(a*a+b*b)
Supongamosahoraqueestamacroesutilizadadentrodeunprograma delasiguientemanera:
raiz(a+l,b+2)
Laintenciónes,porsupuesto,evaluarlafórmula
sqrt((a+l)*(a+l)+(b+2)*(b+2))
Perocadaaparicióndeaessustituidapor a+l(sinparéntesis)ycadaaparicióndebessustituidapor
b+2.Portanto,elresultadodelasnstitucióndelamacroserá
sqrt(a+l*a+l+b+2*b+2)
Estaexpresiónesequivalentea
sqrt(2*a+l+3*b+2)=sqrt(2*a+3*b+3)
queesclaramenteincorrecta.Sin embargo,lafuentedelerrorpuedesercorregidacolocandoparéntesis
adicionalesdentrodeladefinición
demacro,estoes,
#defineraiz(a,b)sqrt((a)*(a)+(b)*(b))
Unerrormássutilocurresiescribimos
raiz(a++,b++)
Lasustitucióndelamacrodacomoresultadolasiguienteexpresión:
sqrt(a*(a+l)+b*(b+l))
envezde
sqrt(a.*a+b*b)
comosepretendía.Éstees unejemplodeefectoslateralesindeseados.Colocandoparéntesisadícionales
dentrodeladefinición
delamacronocorregiremosestosproblemas.

CARACTERíSTICAS ADICIONALES DEC573
14.5.ELPREPROCESADOR DEC
Elpreprocesadorde eesunacoleccióndeinstruccionesespeciales,llamadas directivas,queson
ejecutadasalprincipiodelprocesodecompilación.Lasinstrucciones
#inc1udey#define
vistasanteriormenteenestelibrosondirectivasdelpreprocesador.Directivasadicionalesson
#if,#elif,#else,#endif,#ifdef,#ifndef,#liney#undef.Elpreprocesador
tambiénincluyetresoperadoresespeciales:
defined,#y##.
Lasdirectivasdelpreprocesadorgeneralmenteaparecenalprincipiodeunprograma,pero
estonoesobligatorio.Así,unadirectivadelpreprocesadorpuedeaparecerencualquierparte
dentrodeunprograma.Peroladirectivatendráaplicaciónsóloen
lapartedelprogramaque
sigueasuaparición.
Paralosprogramadoresconpocaexperiencia,algunasdelasdirectivasdelpreprocesador
sonrelativamentepocoimportantes.Poresto,nodescribiremoscadacaracterísticadelpreproce­
sador
endetalle.Acontinuaciónsediscutenlascaracterísticasmásimportantes.
Lasdirectivas
#if,#elif,#elsey#endifsonlasmásusadas.Permitencompilaciones
condicionalesdelprogramafuente,dependiendodelvalordeunaomáscondicionesverdadero/
falso.Avecesseutilizanjuntoaloperador
defined,queesusado paradeterminarsiuna
constantesimbólicaounamacrohasidodefinidaonodentrodeunprograma.
EJEMPLO14.15. Lassiguientesdirectivas delpreprocesadorilustranlacompilacióncondicional deun
programaenC.Lacompilacióncondicional dependedelestadodelaconstantesimbólica PRIMERPLANO.
#ifdefined(PRIMERPLANO)
#defineFONDOO
#else
#definePRIMERPLANO O
#defineFONDO7
#endif
Así,siPRIMERPLANO hasidodefinida,laconstantesimbólica FONDOrepresentaráelvalor O.Enotro
caso,PRIMERPLANO yFONDOrepresentaránlosvaloresO y7,respectivamente.
Esta
esotraforma dehacerlomismo.
#ifdefPRIMERPLANO
#defineFONDOO
#else
#definePRIMERPLANO O
#defineFONDO7
#endif
Ladirectiva#ifdefesequivalentea #ifdefined().Análogamente,ladirectiva #ifndefesequi­
valentea # i f!defined( ) ,estoes,«sinoestádefinido».Espreferiblelaprimera forma,enlacualel
operadordefinedapareceexplícitamente.
Encadaunodeestosejemplos,laúltimadirectivaes#endif.Elpreprocesadorimponequecualquier
conjunto
deinstruccionesquecomiencecon#if,#ifdefo#ifndefdebeterminarcon#endif.
Ladirectiva# e1i fesanálogaaunacláusula e1s e - i futilizandolasinstruccionesde
controlordinariasde
C.Unadirectiva#ifpuedeirseguidaporcualquiernúmerodedirectivas

574 PROGRAMACiÓN ENC
#elif,perosólopuedehaberunadirectiva #else.Laaparicióndeladirectiva #elsees
opcional,determinadaporlalógicadelprogramarequerida.
EJEMPLO14.16. Aquítenemosotrailustración delacompilacióncondicional. Enestasituaciónla
compilacióncondicionaldependerá
delvalorrepresentadoporlaconstantesimbólica FONDO.
#ifFONDO==7
#definePRIMERPLANO O
#elifFONDO==6
#definePRIMERPLANO 1
#else
#definePRIMERPLANO 6
#endif
EnesteejemplovemosquePRIMERPLANO representaráOsiFONDOrepresenta7,YPRIMERPLANO
representará1siFONDOrepresenta6.Deotraforma,PRIMERPLANO representará6.
Ladirectiva#undefanulaladefinicióndeunaconstantesimbólicao unidentificadorde
macro;esdecir,niegaelefectode
ladirectiva#definequepuedehaberaparecidoanterior­
menteenelprograma.
EJEMPLO14.17. Elsiguienteejemploilustra elusodeladirectiva#undefinedentrodeunprogra­
maenC.
#definePRIMERPLANO 7
#defineFONDO O
main()
{
#undefPRIMERPLANO
#undefFONDO
}
Lasconstantessimbólicas PRIMERPLANO yFONDOsondefinidaspor lasdosprimerasdirectivas.Estas
definiciones
sonluegonegadasporlasdirectivas #undef,cuandoaparecenposteriormente enelprogra­
ma.Antesdelasdirectivas#undef,cualquierreferenciaa PRIMERPLANO yFONDOseráasociadacon
losvalores7yO,respectivamente.Después delasdirectivas#undef,cualquierreferenciaa PRIMER­
PLANOYFONDO seráignorada.
Eloperador«decadena»#permiteconvertirunargumentoformaldentrodeunadefiniciónde
unamacro
enunacadenadecaracteres.Siunargumentoformal enladefmicióndeunamacroes
precedida
poresteoperador,elcorrespondienteargumentorealseráautomáticamenteencerrado
entrecomillas.Loscaracteresdeespaciadoconsecutivosdentrodelargumentorealseránreempla­
zados
porunsoloespacioenblanco,ycualquiercarácterespecial,talcomo' , " y \,seráreempla­
zado
porsucorrespondientesecuenciadeescape;estoes,
\',\".y \\.Además,lacadenaresul­
tanteseráautomáticamenteconcatenada(combinada)concualquiercadenaadyacente,

CARACTERíSTICAS ADICIONALESDEC 575
EJEMPLO14.18. Aquitenemosunailustracióndelusodeloperador«decadena», #.
#definemuestra(texto)printf(#texto"")
main()
(
muestra(Porfavornodormirenclase.);
muestra(Porfavor-¡noronquedurantela'explicación'!);
}
Dentrode main,lasmacrosequivalena
printf("Porfavornodormirenclase.") ;
y
printf("Porfavor-inoronquedurantela\'explicación\'!");
Observequecadaargumentorealesconvertidoacadenadecaracteresdentrodelafunción printf.
Cadaargumentoesconcatenadoconuncarácterdenuevalínea (),queesescritacomounacadena
separadadentrodeladefinicióndelamacro.Observetambiénquelosespaciosenblancoconsecutivosen
elsegundoargumentosonreemplazadosporunsoloblancoycadaapóstrofo( , )essustituidoporsu
correspondientesecuenciadeescape
(\').
Laejecucióndelprogramaproducelasiguientesalida:
Porfavornodormirenclase.
Porfavor-¡noronquedurantela[explicación'!
Eloperador«deconcatenación»# #hacequeloselementosindividualesdentrodeunama­
croseanconcatenados,formandounsoloelemento. Lasreglasquerigenelusodeesteoperador
sonunpococomplicadas.Sinembargo,vamosailustrarelpropósitogeneraldeloperadorde
concatenaciónconelsiguienteejemplo.
EJEMPLO14.19. UnprogramaenCcontienelasiguientedefinición demacro:
#definemuestra(i)printf(IIXIl#iIl==%f
ll
,xiii)
Supongamosquelamacroesaccedidaescribiendo
muestra(3);
Elresultadoserá
printf("x3=&f",x3);
Asi,laexpresiónxiiiseconvierteen x3,yaque3eselvalorrealdelargumento i.

576 PROGRAMACiÓN ENC
Observequeesteejemploilustraelusodeambosoperadores,eloperadordecadena(#)Yeloperador
deconcatenación(##).
Paramásinfonnaciónsobreelusodelpreprocesador deC,consulteelmanual dereferencia
delprogramador
desucompiladorparticular.
14.1.
14.2.
14.3.
14.4.
14.5.
14.6.
14.7.
14.8.
14.9.
14.10.
14.11.
14.12.
14.13.
14.14.
14.16.
14.17.
14.18.
14.19.
14.20.¿Quéesunaenumeración?¿Cómosedefineunaenumeración?
¿Quésonlasconstantesdeenumeración?¿Dequéfonnaestánescritas?
Mencionarlasreglasparaasignarnombresalasconstantes
deenumeración.
Mencionarlasreglasparaasignarvaloresnuméricosalasconstantesdeenumeración.
¿Quévaloresporomisiónsonasignadosalasconstantes
deenumeración?
¿Puedendosomásconstantes
deenumeracióntener elmismovalornumérico?Explicarlo.
¿Quésonlasvariables
deenumeración?¿Cómosondeclaradas?
¿Dequéfonnaspuedenserprocesadaslasvariablesdeenumeración?¿Quérestriccio­
nesseaplicanalprocesamiento
delasvariablesdeenumeración?
¿Quéventajaexistealusarvariablesdeenumeraciónenunprograma?
Mencionarlasreglasparaasignarvaloresinicialesalasvariablesdeenumeración.Com­
pararlasrespuestasconlasdelaCuestión14.4.
LamayoríadelosprogramasenCreconocendosargumentosfonnalesenladefinición
delafunciónmain.¿Cómosonllamadostradicionalmente?¿Cuálessonsusrespecti­
vostiposdedatos?
Describirlainformaciónpresentada
porcadaunodelosargumentosformalesenla
función
main.¿Esinfonnaciónpasadaexplícitamenteacadaunodelosargumentos?
Cuandosepasanparámetrosalprogramadesdelalínea
deórdenes,¿cómoesiniciada
laejecucióndelprograma?¿Dóndeaparecenlosparámetros?
¿Paraquépuedenservirlosparámetrosdelalíneadeórdenescuandoseejecutaun
programaqueinvolucraelusodearchivosdedatos?
Lasfunciones
debibliotecadiscutidasenanteriorescapítulosdeestelibrosonmiem­
bros
dealgunascategoríasdefuncionesdebiblioteca.Describircadacategoríaentér­
minosgenerales.
Describir,enténninosgenerales,otrascategoríasadicionalesdefunciones
debibliote­
caquevienenconlamayoríadeloscompiladorescomercialesdeC.¿Cuáleselpropó­
sitodecadacategoría?
¿Quéesunamacro?Mencionarlassimilitudesydiferenciasentremacrosyfunciones.
¿Cómosedefineunamacromultilínea?
Describirelusodeargumentosdentrodeunamacro.
¿Cuáleslaprincipalventajadeusarmacrosenvez
defunciones?¿Cuáleslaprincipal
desventaja?¿Quéotrasdesventajashay?
Mencionarlasotrasdirectivasdelpreprocesadordistintasde
#includey#define.
Indicarelpropósitodelasmásusadas.

14.21.
14.22.
14.23.
CARACTERíSTICAS ADICIONALESDEC 577
¿Cuáleselámbitodeunadirectivadelpreprocesadordentrodeunarchivode programa?
Mencionarlosoperadores especialesdelpreprocesador#y##.¿Cuáleselpropósito
decadaunodeellos?
¿Quéseentiendeporcompilacióncondicional?Entérminosgenerales,¿cómosereali­
zalacompilacióncondicional?¿Quédirectivasdel preprocesadorsonválidasparaeste
propósito?
14.24.
14.25.
14.26.
14.27.Definiruntipodeenumeraciónllamado indicadoresquetengálossiguientesmiembros:
primero,segundo,tercero,cuartoyquinto.
Definirunavariabledeenumeraciónllamada sucesodeltipoindicadores(verproblema
anterior).
Definirdosvariablesdeenumeración,llamadas sopranoybajo,cuyosnombresseanlossi­
guientes:
do,re,mi,fa,sol,laysi.Asignarlosisiguientesvaloresenterosaestosmiembros:
do 1
re 2
mi 3
fa 4
sol 5
la 6
si 7
Definiruntipodeenumeraciónllamado dineroquetengalossiguientesmiembros: peni­
que,nique1,dime,cuarto,medioydolar.Asignarlossiguientesvaloresenterosa
estosmiembros:
penique
1
niquel15
dime 10
cuarto25
medio 50
dolar100
14.28.Definirunavariabledeenumeraciónllamada monedadeltipodinero(verproblemaante­
rior).Asignarelvalorinicial
dimeamoneda.
14.29.Enlasiguientedeclaracióndeenumeración,determinarelvalordecadamiembro:
enum
bruju1a{norte=2,sur,este=1,oeste};
14.30.Determinarelvalorasociadoconcadaunadelassiguientesvariablesdeenumeración(verpro­
blemaanterior):
enumbrujulamover_l=sur,mover_2 =norte;

578 PROGRAMACiÓN ENC
14.31.Explicarelpropósitodelsiguienteesquema deprograma.
inttantos=O;
enumbrujulamover:
switch(mover){
casenorte:
tantos+=10;
break;
casesur:
tantos+=2O;
break;
caseeste:
tantos+=3O;
break;
caseoeste:
tantos+=40;
break;
default:
printf("ERROR -Porfavor,pruebedenuevo") ;
}
14.32.Acontinuaciónsemuestra elesquemadeunprogramaen C.
main(intargc,char*argv[])
{
}
a)Supongamosqueelprogramaobjetocompiladoesalmacenadoenunarchivollamado
demo.exeyseescribelasiguienteordenparainiciarlaejecucióndelprograma:
demodepurarrapido
Determinarelvalorde argcyloselementosnovacíos deargv.
b)Supongamosquelalíneadeórdenesestáescritacomo
demo ndepurarrapido
ll
¿Cómoafectaestecambioalosvaloresde argcyargv?
14.33.DescribirelpropósitodelprogramaenCmostradoacontinuación.
#include<stdio.h>
#include<string.h>

CARACTERíSTICAS ADICIONALES DEC579
main(intargc,char*argv[])
{
charletra[SO];
intcont,marca;
for(cont=O;(letra[con]=getchar())!='';++cont)
marca=cont;
for(cont=O;cont<marca;++cont)
if(strcmp(argv[l],"mayuscula")==O)
putchar(toupper(letra[cont]));
elseif(strcmp(argv[l],"minuscu1a")--O)
putchar(tolower(letra[cont]));
else(
puts("ERRORENLALINEADEORDENES-PRUEBE DENUEVO");
break;
}
}
14.34.Considerarelprogramamostradoacontinuación,queleeunalínea detextodeunarchivode
datosexistente,lamuestraenpantalla
ylaescribeenunnuevoarchivodedatos.
/*leerunalíneadetextodeunarchivodedatosexistente,
mostrarlaenpantallayescribirlaenunnuevoarchivo*/
#inc1ude<stdio.h>
#defineNULL O
maín(intargc,char*argv[])
{
FILE*fpt1,*fpt2;
chare;
/*abrirelarchivodedatosantiguosoloparalectura*/
if((fpt1=fopen(argv[l],"r"))==NULL)
printf("ERROR -No sepuedeabrirelarchivoindicado");
else(
/*leer,mostraryescribircadacarácterdelarchivode
datosantiguo* /
fpt2=fopen(argv[2],"w");
do(
putchar(c=getc(fpt1));
putc(c,fpt2);
}while(c!='');
/*cerrararchivosdedatos*/
fclose(fpt1);
fclose(fpt2);
}

580 PROGRAMACiÓN ENC
Supongamosqueelprogramasealmacenaenunarchivollamado transfer.exe,elarchivo
dedatosantiguo
sellamadatos.antyelnuevoarchivo datos.nue.¿Cómodebeserescri­
talalíneadeórdenesparaejecutaresteprograma?
14.35.Escribirunaconstantesimbólicaounadefinicióndemacroparacadaunadelassiguientessitua­
ciones.Noincluirargumentosamenosqueelproblema
loindique.
a)Definirunaconstantesimbólica PIpararepresentarelvalor3.1415927.
b)Definirunamacrollamada AREAquecalculeelárea deuncirculoenfuncióndesuradio.
Usarenelcálculolaconstante
PI,definidaenlaparte a).
e)Reescribirlamacrodelproblemaanterior demodoqueelradioseexpresecomounargumento.
d)DefinirunamacrollamadaCIRCUNFERENCIA quecalculelacircunferenciadeuncirculo
enfunción
desuradio.Usarenelcálculolaconstante PI,definidaenlaparte a).
e)Reescribirlamacrodelproblemaanterior demodoqueelradioseexpresecomounargumento.
l)Escribirunamacromultilíneallamada interesqueevalúelafórmuladelinteréscompuesto
F=P(l+
i)'
dondeFeslacantidadfuturadedineroqueseacumularáalcabo denaños,Peselprincipal
(lacantidadoriginaldedinero),
i=O.Olryreslatasadeinterésanualexpresadaenporcentaje.
Evaluar
ienunalíneadelamacro, yevaluarFenotralíneaseparada.Suponerquetodos
lossímbolosrepresentancantidadesencomaflotante.
g)Reescribirlamacrodefinidaenelproblemaanteriordemodoque
P,rynseanexpresadas
comoargumentos.
h)Escribirunamacrollamada maxqueutiliceeloperadorcondicional (?: )paradeterminar
elmáximodea
yb,dondea ybsoncantidadesenteras.
i)Reescribirlamacrodelproblemaanteriordemodoquea ybseexpresencomoargumentos.
14.36.Explicarelpropósito decadaunodelossiguientesgrupos dedirectivasdelpreprocesador.
a)#ifIdefined(INDICADOR)
#defineINDICADOR 1
#endif
b)#ifdefined(PASCAL)
#defineBEGIN{
.#defineEND }
#endif
e)#ifdefCELSIUS
#definetemperatura(t)0.5555555*(t-32)
#else
#definetemperatura(t)1.8*t +32
#endif
printf("x=If",x)
for(cont=1;cont<=n;++cont) \
printf("i=Idy=If",i,y[i])
d)#ifndefDEPURAR
#definesalida
#elifNIVEL==1
#definesalida
#else
#definesalida
#endif
printf("iId y=%f
ll
,i,y[i])

14.37.
14.38.
14.39.
14.40.
14.41.
14.42.
14.43.
CARACTERíSTICAS ADICIONALES DEC 581
e)#ifdefined(DEPURAR)
#undefDEPURAR
#endif
1)# i fdefCOMPROBAC I ONERROR
#definemensaje(linea)printf(#linea)
#endif
g)#ifdefined(COMPROBACION_ERROR)
#definemensaje(n)printf("%s",mensaje##n)
#endif
Escribirunaomásdirectivasdelpreprocesadorparacadaunadelassituacionessiguientes:
a)Silaconstantesimbólica LOGICAhasidodefinida,definirlasconstantessimbólicas
VERDADEROyFALSOtalesquesusvaloressean1 y O,respectivamente,ynegarlasdos
definicionesdelasconstantessimbólicas
SIyNO.
b)Siindicadortienevalor O,definirlaconstantesimbólica COLORconvalor1.Enotro
caso,sielvalorde
indicadoresmenorque 3,definirCOLORconvalor2;ysielvalorde
indicadoresmayoroigualque
3,definirCOLORconvalor3.
e)Silaconstantesimbólica TAMANOtieneelmismovalorquelaconstantesimbólica AM­
PLIO,definirlaconstantesimbólica ANCHOconelvalor 132;enotrocaso,definir ANCHO
convalorde 80.
d)Usareloperador de«cadena»paradefinirunamacrollamada error(texto)queescribi­

textocomounacadena.
e)Usareloperadorde«concatenación»paradefinirunamacrollamada error(i)queescri­
biráelvalordelavariable
decadenaerrori(porejemplo,errorl).
Familiarizarseconlabiblioteca defuncionesyconlosarchivos decabeceraqueacompañanasu
compiladorparticularde
C.¿Hayalgunasfuncionesqueestándisponiblestantocomomacrosy
comoverdaderasfunciones?
¿Incluyelabiblioteca
defuncionesdesucompiladorde erutinasgráficaso decontroldeproce­
sos?¿Estánincluidasotrasrutinasespeciales?Enesecaso,¿cuálesson?
ModificarelprogramadadoenelEjemplo14.13(valorfuturo
dedepósitosmensuales)talque
acepteunparámetrode
lalíneadeórdenesqueindiquelafrecuenciadecomposición.Elparáme­
trodelalíneadeórdenesdebe
seruncarácterseleccionadode A,S,Q,M,D o C(mayúsculao
minúscula),comoseexplicóenelejemplo.
Modificarelprogramadado
enelEjemplo6.22(solucióndeunaec.uaciónalgebraica)demodo
que
indicadorseaunavariable deenumeracióncuyovalorsea verdaderoofalso.
ModificarelprogramadadoenelEjemplo6.32(búsquedadepalíndromos)demodoque
indicadorseaunavariable deenumeracióncuyovalorsea verdaderoofalso.
ModificarelprogramadadoenelEjemplo7.9 (elmayordetresenteros)demodoquelafunción
maximoseaescritacomounamacromultilínea.

582
14.44.
14.45.
14.46.
14.47.
14.48.
14.49.
14.50.
14.51.
14.52.
PROGRAMACiÓN ENC
ModificarelprogramadadoenelEjemplo7.10(cálculo defactoriales)demodoquelafunción
factorialseaescritacomounamacromultilínea.
Modificarelprogramadadoen
elEjemplo7.11(juego dedados«Craps»)demodoquelafun­
ción
lanzarseaescritacomounamacromultilínea.¿Puedeusarsedeformaefectivaunavaria­
ble
deenumeraciónenesteproblema?
EscribirunprogramacompletoenCpararesolverelproblemadescritoenelProblema7.42(raíces
deunaecuacióndesegundogrado).Incluirunavariabledeenumeracióndentrodelprograma.
EscribirunprogramacompletoenCpararesolverelproblemadescritoenelProblema9.46
(nombresdepaísesysuscapitales).Usarunavariabledeenumeraciónparadistinguirentredos
opcionesdelprograma(encontrarelnombredelacapitalparaunpaísespecificado,oencontrar
elpaíscuyacapitalhasidoespecificada).
ModificarelprogramadadoenelEjemplo10.28(presentacióndel díadelaño)demodoqueuse
unavariabledeenumeraciónparalosmesesdelaño.
EscribirunprogramacompletoenCpararesolverelproblemadescritoenelProblema11.67
(mantenimientodeestadísticasdeequiposdefútbol/béisbol).Incluirunavariabledeenumera­
ciónparadistinguirentrefútbolybéisbol.
EscribirunprogramacompletoenCpararesolverelproblemadescritoenelProblema11.71
(unacalculadoraRPN).Incluirunavariabledeenumeraciónparaidentificarlostiposdeopera­
cionesaritméticasquepuedenserrealizadasporlacomputadora.
RepetirelProblema14.50,utilizandomacros
enlugardefunciones.
Modificarelprogramadadoencadaunodelossiguientesejemplos
demodoquelosnombres de
archivosrequeridosseanintroducidoscomoparámetros delalíneadeórdenes:
a)Ejemplo12.3(creacióndeunarchivodedatos).
b)Ejemplo12.4(lectura deunarchivodedatos).
14.53.Modificarelprogramadadoencadauno delossiguientesejemplos demodoquelosnombres de
archivosrequeridosseanintroducidoscomoparámetros delalíneadeórdenes.Utilizarunavaria­
bledeenumeraciónpararepresentarlascondicionesinternascierto/falsodentro
decadaprograma.
a)Ejemplo12.5(creación deunarchivodedatosquecontieneregistrosdeclientes).
b)Ejemplo12.6(actualizacióndeunarchivodedatosquecontieneregistrosdeclientes).
e)Ejemplo12.7(creación deunarchivodedatossinformatoquecontieneregistrosdeclientes).
d)Ejemplo12.8(actualizacióndeunarchivodedatossinformatoquecontieneregistrosde
clientes).
14.54.EscribirunprogramacompletoenCpararesolvercadaunodelossiguientesproblemas.
a)Problema12.50(editordetextoorientadoalíneas).
b)Problema12.51(mantenimientodeestadísticasdeequiposdefútbol/béisbolenunarchivo
dedatos).
Paracadaprogramaintroducirlosnombresdearchivosrequeridoscomoparámetrosdelalínea
deórdenes.
14.55.Cadaunodelossiguientesproblemasrequierequeunoomásvaloresnuméricosseanespecificados
comoparámetrosdelalíneadeórdenes.Usarlasfunciones
debibliotecaatoiyatofparacon­
vertirlosparámetrosdelalínea
deórdenesenenterosyvaloresencomaflotante,respectivamente.
a)EscribirunprogramacompletoenCpararesolverelproblemadescritoenelProblema 7.49(a)
(generaciónrecursivadepolinomiosdeLegendre).Introducirlosvaloresde nyxcomo
parámetrosdelalínea
deórdenes.

CARACTERíSTICAS ADICIONALES DEC583
b)Escribirunprogramacompletoen epararesolverelproblemadescritoen elProblema7.49(b)
(calcularrecursivamentelasumadennúmerosencomaflotante).Introducir elvalorden
comounparámetrodelalínea
deórdenes(perolaintroduccióndedatos sehaceenmodo
interactivocomoantes).
e)Escribirunprogramacompletoen epararesolverelproblemadescritoenelProblema7.49(e)
(calcularrecursivamentelosprimerosntérminosdeunaserie).Introducirelvalordencomo
unparámetrodelalínea
deórdenes.
d)Escribirunprogramacompletoen epararesolverelproblemadescritoenelProblema7.49(d)
(calculardeformarecursivaelproducto dennúmerosencomaflotante).Introducir elvalor
dencomounparámetro delalíneadeórdenes.(Sinembargo,laintroducción delosnúme­
rosencomaflotantesehaceenmodointeractivocomoantes.)
e)ModificarelprogramadadoenelEjemplo8.4(búsquedadelmáximo) delasiguientemanera:
i)IntroducirvaloresparaCN8T,a ybcomoparámetrosdelalínea deórdenes.
ii)Escribirlafunción curvacomounamacro.
j)ModificarelprogramadadoenelEjemplo8.7(generacióndenúmeros deFibonacci)de
modoqueelvalor
denseaintroducidocomounparámetrodelalíneadeórdenes.
g)ModificarelprogramadadoenelEjemplo9.13(reordenación
deunalistadenúmeros)de
modoqueelvalor
denseaintroducidocomounparámetrodelalínea deórdenes.
h)ModificarelprogramadadoenelEjemplo9.19(sumadedostablasdenúmeros) demodo
quelosvaloresde
nfilasyncolumnasseanintroducidoscomoparámetros delalínea
deórdenes.
14.56.Escribirunprogramacompletoen
eparagenerarlatabladescritaenelProblema9.43.Usaruna
macroparaevaluarlafórmula
y=2e-o·
1
'
sen0.51
14.57.Escribirunprogramacompletoen eparagenerarlatabladescritaenelProblema9.44.Usaruna
macroparaevaluarlafórmula
FIP=(1+mOO)"
14.58.Escribirunprogramacompletoen epararesolverelproblemadescritoenelProblema7.44(evaluar
lafórmula
y=
x").Usarunamacromultilíneaenlugar delafunciónpararealizarlapotenciación.

Sistemasderepresentacióndenúmeros
APÉNDICE
P7T fi1&
A
'"
jit
==
Decimal Binario Octal Hexadecimal
O 0000 O O
1 0001 1 1
2 0010 2 2
3 0011 3 3
4 0100 4 4
5 0101 5 5
6 0110 6 6
7 0111 7 7
8 1000 10 8
9 1001 11 9
10 1010 12 A
11 1011 13 B
12 1100 14 C
13 1101 15 D
14 1110 16 E
15 1111 17 F
Observequehayochodígitosoctalesy 16hexadecimales.Losdígitosoctalesvande Oa7;losdígitos
hexadecimalesvande
OaF.
Cadadígitooctalesequivalenteatresdigitosbinarios(3bits),ycadadígitohexadecimalesequiva­
lenteacuatrodígitosbinarios(4bits).
Portanto,losnúmerosoctalesyhexadecimalesproporcionanuna
formaconvenieuteyconcisa
pararepresentarpatronesbinarios. Porejemplo,elpatrónbinario 1011O111
serepresentaenhexadecimalcomoB 7.Paravermásclaramenteestarelaciónsereordenanlosbits en
gruposdecuatroycadagruposerepreseutamediante undígitohexadecimal; porejemplo,10110111
serepresentaconB 7.
Análogamente,estemismopatrónbinario (10110111)puederepresentarse enoctalcomo 267.Para
vermásclarameuteestarelaciónseleañade unceroala izquierda(demodoqueeluúmerodebitsdel
patrónseamúltiplode3),sereordenanlosbits
engruposdetresyserepresentacadagrupocomoundígito
octal;
porejemplo,O1 O110111serepresentacon2 6 7.
Lamayoríadelascomputadorasutilizannúmeroshexadecimalespararepresentarpatronesdebits,si
bienalgunasusannúmerosoctalesparaestepropósito.
585

APÉNDICEB
Secuenciasdeescape
o/==ti-
..
Carácter Secuencia deescape ValorASCII
sonido(alerta) \a 007
retroceso(espacioatrás) 008
tabuladorhorizontal 009
nuevalinea(cambiodelinea) 010
tabuladorvertical \v 011
nuevapágina 012
retomodecarro 013
comillas(") \" 034
apóstrofo(') \' 039
interrogación(?) \? 063
barrainvertida() \ 092
nulo \0 000
númerooctal \000(orepresentaun
digitooctal)
Normalmentenosepermitenmásdetresdigitosoctales.
Ejemplos:
númerohexadecimal
\5,\005,\123,\177
\xhh(hrepresentaundígitohexadecimal)
Normalmentesepermitecualquiernúmerodedígitoshexadecimales.
Ejemplos:\x5,\x05, \x53,\x7f
Lamayoríadeloscompiladorespermitenqueelapóstrofo (')ylainterrogación(?)aparezcandentrode
unacadenadecaracteresconstantebiencomouncarácterordinarioobiencomounasecuenciadeescape.
587

APÉNDICEe
Resumendeoperadores
_______rm "''''''''. rm:d''''_,, "'_
589
Nota:Losgruposdeprecedenciaestánordenadosdemayoramenorprecedencia.Algunoscompiladores
deetambiénincluyenunoperadormásunario( +)paracomplementareloperadormenosunario(- ).
Portanto,unaexpresiónconelmásunarioesequivalentealvalor desuoperando:porejemplo, +v
tieneelmismovalorque v.
Grupodeprecedencia
función,array,miembro
deestructura,punteroa
miembro
deestructura
operadoresunarios
multiplicación,división
yrestoaritméticos
sumayrestaaritméticas
operadoresdedesplazamiento
aniveldebits
operadoresrelacionales
operadoresdeigualdad
yaniveldebits
oexclusivaaniveldebits
oaniveldebits
ylógica
ológica
operadorcondicional
operadores
deasignación
operadorcoma
Operadores
()[ ] .->
-++--!
-
*&sizeof(tipo)
* /%
+ -
« »
<<=>>=
!=
&
A
&&
11
?
=+=-=*=/=%=
&=A=1=«=»=
Asociatividad
1--->D
D--->1
1--->D
I--->D
1--->D
1--->D
1--->D
1--->D
1--->D
1--->D
1--->D
1--->D
D--->1
D--->1
1--->D

APÉNDICED
Tiposdedatos yreglasdeconversióndedatos
5P*3'm ,11i1t¡WJii m1i JM •
i'&111W!W§
Tipodedato Descripción
int Cantidadentera
short Cantidadenteracorta(puede
contenermenosdígitosque
int)
long Cantidadenteralarga(puede
contenermásdígitosqne
int)
unsigned Cantidadenterasinsigno(nonegativa)
(lacantidadmáximapermisiblees
aproximadamenteeldoble que
int)
char Carácter
signedcharCarácter,convaloresenelrango
de-128a+127
unsignedcharCarácter,convaloresenelrango
deOa255
float Númeroencoma flotante(unnúmero
quecontieneunpuntodecimaly/o
unexponente)
double Númeroencoma flotanteendoble
precisión(mascifrassignificativas
yunexponentequepuedesermayor
envalorabsoluto)
longdouble Númeroencomaflotanteendoble
precisión(puedetenermayor
precisiónqueun
double)
voi d Tipodedatoespecialparafunciones
quenodevuelvenningúnvalor
enum Constantedeenumeración(tipo
especialde
int)
Requisitostípicosdememoria
2byteso 1palabra
(varía
deunacomputadoraaotra)
2byteso 1palabra
(varía
deunacomputadoraaotra)
1o2palabras
(varía
deunacomputadoraaotra)
2byteso 1palabra
(varíadeunacomputadoraa otra)
1byte
1byte
1byte
1palabra
2palabras
2 omáspalabras
(varíadeunacompntadoraa.otra)
(noaplicable)
2byteso 1palabra
(varíadeunacomputadoraaotra)
Nota:Elcualificadorunsignedpuedeaparecercon shortintoconlongint,porejemplo,
unsignedshortint(ounsignedshort),ounsignedlongint(ounsigned
long).
591

592 PROGRAMACiÓN ENC
REGLASDECONVERSIÓN
Estasreglas seaplicanaoperacionesaritméticasentredosoperadorescondistintostiposdedatos.Puede
existiralgunavariacióndeunaversiónde
eaotra.
1.Siunodelosoperandoses longdouble,elotroseráconvertidoa longdoubleyelresul­
tadoseráun
longdouble.
2.Enotrocaso,siunodelosoperandoses double,elotroseráconvertidoa doubleyelresultado
será
double.
3.Enotrocaso,siunodelosoperandoses float,elotroseráconvertidoa floatyelresultado
será
float.
4.Enotrocaso,siunodelosoperandoses unsignedlongint,elotroseráconvertidoa
unsignedlongintyelresultadoserá unsignedlongint.
5.Enotrocaso,siunodelosoperandoses longintyelotroes unsignedint,entonces:
a)Siunsignedintsepuedeconvertira longint,eloperandounsignedintserá
convertido
yelresultadoserá longint.
b)Enotrocaso,ambosoperandosseránconvertidosa unsignedlongintyelresultado
será
unsignedlongint.
6.Enotrocaso,siunodelosoperandoses longint,elotroseráconvertidoa longintyel
resultadoserá
longint.
7.Enotrocaso,siunodelosoperandoses unsignedint,elotroseráconvertidoa unsigned
intyelresultadoserá unsignedint.
8.Sinosepuedeaplicarningunadelascondicionesanteriores,entoncesambosoperandosserán
convertidosa
int(siesnecesario) yelresultadoserá int.
Tengaencuentaquealgunasversionesde econviertenautomáticamentetodoslosoperandosencoma
flotanteadobleprecisión.
REGLASDEASIGNACIÓN
Silosdosoperandosenunaexpresióndeasignación SOl)detiposdistintos,entonceselvalordeloperando
deladerechaseráautomáticamenteconvertidoaltipo
delpperandodejaizquierda.Laexpresióndeasig-
nacióncompletaserádeestemismotipo.Además:
.
1.Unvalorencomaflotantepuedetruncarsesiseasignaaunidentificadorentero.
2.Unvalorendobleprecisiónpuedeserredondeadosiseasignaaunidentificadorencomaflotante
(simpleprecisión).
3.Unacantidadentera
puedeseralteradasiseasigna
Elunidentificadordeenteromáscortoo aun
identificadordecarácter(algunosdelosbitsmássignificativospuedenperderse).

APÉNDICEE
ElconjuntodecaracteresASCII
~rr "7 .,·;;Gb&12idG-
o NUL 32 espacioen 64 @ 96
blanco
1 SOH 33 65 A 97 a
2 STX 34 66 B 98 b
3 ETX 35 # 67 e 99 e
4
EOT 36 $ 68 D 100 d
5 ENQ 37
% 69 E 101 e
6 ACK 38 & 70 F 102 f
7 BEL 39 71 G 103 g
8 BS 40 ( 72 H 104 h
9 HT 41 ) 73 1 105 i
10 LF 42 * 74 J 106 j
11 VT 43 + 75 K 107 k
12 FF 44 76 L 108 1
13 CR 45 77 M 109 ID
14 SO 46 78 N 110 n
15 SI 47 / 79 O 111 o
16 DLE 48 O 80 p 112 p
17 DCl 49 1 81 Q 113 q
18 DC2 50 2 82 R 114 r
19 DC3 51 3 83 S 115 s
20 DC4 52 4 84 T 116 t
21 NAK 53 5 85 U 117 u
22 SYN 54 6 86 V 118 v
23 ETB 55 7 87 W 119 w
24 CAN 56 8 88 X 120 x
25 EM 57 9 89 Y 121 Y
26 SUB 58 90 Z 122 z
27 ESC 59 91 [ 123 {
28 FS 60 < 92 \ 124 I
29 GS 61 = 93 ] 125 }
30 RS 62 > 94
A
126
31 US 63 ? 95 127 DEL
Losprimeros32caracteresyelúltimosoncaracteresdecontrol.Normalmentenosevisualizan.Sin
embargo,algunasversionesde
e(enalgunascomputadoras)soportancaracteresgráficosespeciales
paraestosvaloresASCII.Porejemplo, 001puederepresentarelcarácter
g,002puederepresentar
eJ,yasísucesivamente. .
593

APÉNDICEF
Resumende instrucciones decontrol
:::::::z::z:z&WG· *'íP*~7E7;:rrmrrrc•
InstrucciónFormageneral Ejemplo
break break; for(n=1;n<=100;++n) (
scanf( 11%fti,&x)i
if(x<O) (
printf("ERROR-NEGATIVO");
break;
}
}
continuecontinue¡ for(n=1;n<=100;
scanf("%f",&x);
if(x<O) {
printf("ERROR­
continue¡
}
}
++n) (
NEGATIVO");
do-while
for
goto
if
do
instrucción
whi1e(expresión);
for(exp1;exp2;exp3)
instrucción
gotoetiqueta;
etiqueta:instrucción
if(expresión)
instrucción
do
printf("%d"digito++);
while(digito<=9);
for(digito=O;digito<=9;++digito
printf("%d",digito);
if(x<O)
gotoindicador;
indicador:printf("ERROR");
if(x<O)
printf(lI%f
U
,
x)¡
595

596 PROGRAMACiÓN ENC
InstrucciónFormageneral
if-e1seif(expresión)
instrucción1
e1se
instrucción2
return returnexpresión¡
switchswitch(expresión){
caseexpresión1 :
instrucción1
instrucción2
instrucciónm
break;
caseexpresión2:
instrucción1
instrucción2
instrucciónn
break;
defau1t:
instrucción1
instrucción2
instrucciónk
}
Ejemplo
if(estado=='8')
tasa=0.20*pago;
e1se
tasa=0.14*pago;
return(ni+n2);
switch(e1eccion=getchar()){
case'R':
printf("ROJO");
break;
case'B':
printf("BLANCO");
break;
case'A':
printf("AZUL");
break;
defau1t:
printf("ERROR");
}
whi1e whi1e(expresión)
instrucción
whi1e(digito<=9)
printf("'l;d",digito++);

APÉNDICEG
Caracteresdeconversiónmásusados
descanfyprintf
Caracteresdeconversiónde scanf
Carácterde conversión
c
d
e
f
g
h
i
o
s
u
x
[..]
Significado
eldatoesuncarácter
eldatoesunenterodecimal
eldatoesunvalorencomaflotante
eldatoesunvalorencomaflotante
eldatoesunvalorencoma flotante
eldatoesunenterocorto
eldato
eSunenterodecimal,hexadecimaluoctal
eldatoesunenterooctal
eldatoesunacadena
decaracteresseguidoporunespacio
enblanco(elcarácternulo\ Oseañadeautomáticamente
alfinal)
eldatoesunenterodecimalsinsigno
eldatoesunenterohexadecimal
eldatoesunacadenadecaracteresquepuedeconteneres­
paciosenblanco
Un
prefijopuedeprecederaciertoscaracteresdeconversión.
Prefijo
h
1
L
Ejemplo:
inta¡
shortb;
longc;
unsignedd;
doublex;
charcad[8O]
;
Significado
datocorto(enterocortooenterosinsignocorto)
datolargo(enterolargo,enterolargosinsignoorealen
dobleprecisión)
datolargo(realendobleprecisiónlargo)
597

598 PROGRAMACiÓN ENC
scanf("%5d%3hd %121d %12lu%15lf",&a,&b,&c,&d,&x);
scanf("%[A]",cad);
Caracteresdeconversiónde printf
Carácterdeconversión
c
d
e
f
g
i
o
s
u
x
Significado
eldatosemuestracomouncarácter
eldatosemuestracomounenterodecimal
eldatosemuestracomounvalorencomaflotanteconex­
ponente
eldatosemuestracomounvalor encomaflotantesinex­
ponente
eldatosemuestracomounvalorencomaflotanteusando
laconversióndetipoe o
f,dependiendodelvalor;no
semuestrancerosnosignificativosnielpuntodecimal
sinoessignificativo
eldatosemuestracomounenterodecimalconsigno
eldatosemuestracomounenterooctal,sinelceroinicial
eldatosemuestracomounacadenadecaracteres
eldatosemuestracomounenterodecimalsinsigno
eldatosemuestracomounenterohexadecimal,sinel
Ox
delprincipio
Observequealgunosdeestoscaracteresseinterpretandemododiferentequeconlafunción
scanf.
Unprefijopuedeprecederaciertoscaracteresdeconversión.
Prefijo
h
1
L
Ejemplo:
inta¡
shortb;
longc;
unsignedd;
doublex;
charcad[ 8O];
Significado
datocorto(enterocortooenterocortosinsigno)
datolargo(enterolargo,enterolargosinsignoorealen
dobleprecisión)
datolargo(realendobleprecisiónlargo)
printf("%5d%3hd%12ld %121u %15.71e
ll
,a,b
le,d,x)¡
printf("%40s",cad);

Indicador
+
o
, ,
(espacioenblanco)
#
(conconversiones
detipo
0-yx-)
#
(conconversiones
detipo
e-,f-yg-)
Ejemplo:
inta¡
short
b;
longe;
unsignedd;
doubleX;
CARACTERES DECONVERSiÓN MÁSUSADOS DEscanfYprintf599
Indicadores
Significado
Eldatoesjustificadoalaizquierdadentrodelcampo(losespacios enblanco
necesarios
pararellenarlalongituddecampominimaseañadirán detrás
deldatoenvezde delante).
Unsigno(+o -)precederáacadavalornuméricoconsigno.Sinesteindica­
dor,sólolosvaloresnegativosestaránprecedidos
porunsigno.
Producelaaparicióndecerosinicialesenvezdeespacios
enblanco.Seaplica
sóloadatosqueestánjustificadosaladerechaencampos
cuyalongitud
minimaesmayorqueeldato.
(Nota:algunoscompiladoresconsideranelindicadorcerocomo unapartede
laespecificaciónde
lalongituddecampoenvezdecomo unindicador
real.EstoaseguraqueelOseproceseelúltimosiestánpresentesmúlti­
plesindicadores.)
Unespacioenblancoprecederáacadavalorpositivo.Esteindicadoresanulado
porelindicador
+siambosestánpresentes.
HacequelosdatosoctalesyhexadecimalesseanprecedidosporO y
Ox,respecti­
vamente.
Hacequeestépresenteelpuntodecimalentodoslosnúmerosencomaflotante,
inclusosielnúmeronotienedecimales.Tambiéntruncaloscerosnosignifi­
cativos
enunaconversióndeltipog -.
printf("%+5d %+5hd %+12ld%-12lu%#15.71e"
1a,b
le,d,x)¡

APÉNDICEH
Funcionesdebibliotecamásusadas
Función Tipo Propósito Archivo include
abs(i) int Devuelveelvalorabsoluto dei. stdlib.h
acos(d) doubleDevuelveelarcocoseno ded. math.h
asin(d) doubleDevuelveelarcosenoded. math.h
atan(d) doubleDevuelvelaarcotangente ded. math.h
atan(dl,d2) doubleDevuelveelarcotangente dedi!d2. math.h
atof(s) doubleConviertelacadenas aunacantidaden stdlib.h
dobleprecisión.
atoi(s) int Conviertelacadenas aunentero. stdlib.h
atol(s) long Conviertelacadenas aunenterolargo. stdlib.h
calloc(ul,u2)void*Reservamemoriaparaunarray deul malloc.ho
elementos,cadaunode
u2bytes. stdlib.h
Devuelveunpunteroalprincipiodel
espacioreservado.
ceil(d) doubleDevuelveunvalorredondeadoporexcesoal math.h
siguienteenteromayor.
cos(d) doubleDevuelveelcosenoded. math.h
cosh(d) doubleDevuelveelcosenohiperbólicoded. math.h
difftime(ll,12)doubleDevuelveladiferencia detiempo11-12, time.h
donde11y12representaneltiempo
transcurridodespuésdeuntiempobase
(verlafunción
time).
exit(u) void Cierratodoslosarchivosybúffersytermina stdlib.h
elprograma.Elvalor deuesasignadopor
lafunciónparaindicarelestadode
terminación.)
exp(d) doubleElevae alapotenciad
(e=2.7182818...math.h
eslabasedelsistema delogaritmos
naturales(Neperianos)).
601

602 PROGRAMACiÓN ENC
Función Tipo Propósito Archivo include
fabs(d) doubleDevuelveelvalorabsoluto ded. math.h
fclose(f) int Cierraelarchivo f.DevuelveOsielarchivo stdio.h
sehacerradoconéxito.
feof(f) int Determinasisehaencontradounfinde stdio.h
archivo.Siesasi,devuelveunvalor
distintodecero;enotrocasodevuelve
O
fgetc(f) int Leeuncarácterdelarchivo f. stdio.h
fegts(s,i,f)char*Leeunacadena s,conicaracteres,del stdio.h
archivof
floor(d) doubleDevuelveunvalorredondeadopordefecto math.h
alenteromenormáscercano.
fmod(di,d2) doubleDevuelveelresto dedi/d2(conelmismo math.h
signoque di).
fopen(si,s2) file*Abreunarchivollamado si,deltipos2. stdio.h
Devuelveunpuntero alarchivo.
fprintf(f,...)int Escribedatosenelarchivo f(elrestodelos stdio.h
argumentossoncomplicados;ver
ApéndiceG).
fputc(c,f) int Escribeuncarácterenelarchivo f. stdio.h
fputs(s,f) int Escribeunacadena decaracteresenel stdio.h
archivof.
fread(s,ii,i2,f)int Leei 2elementos,cadauno detamañoi 1 stdio.h
bytes,desdeelarchivo fhastala
cadena
s.
free(p) void Liberaunbloquedememoriareservadacuyo malloc.ho
principioestáindicadopor
p. stdlib.h
fscanf
(f,...)int Leedatosdelarchivo f(elrestodelos math.h
argnmentossoncomplicados;ver
ApéndiceG).
fseek(f,1,i)int Mueveelpunteroalarchivo funadistancia stdio.h
de1bytesdesdelaposición i(ipuede
representarelprincipiodelarchivo,la
posiciónactualdelpunterooelfindel
archivo).
ftell(f) long Devuelvelaposiciónactualdelpuntero stdio.h
int dentrodelarchivo f.
fwrite(s,ii,i2,f)int Escribei 2elementos,cadaunodetamaño stdio.h
i 1bytes,desdelacadena shastael
archivo
f.

Función
getc(f)
getchar()
gets(s)
isalnum(c)
isalpha(c)
isascii(c)
iscntrl(c)
isdigit(c)
isgraph(c)
islower(c)
isodigit(c)
isprint(c)
ispunct(c)
Tipo
int
int
char*
int
int
int
int
int
int
int
int
int
int
FUNCIONES DEBIBLIOTECAMÁSUSADAS 603
Propósito Archivo include
Leeuncarácterdelarchivo f. stdio.h
Leeuncarácterdesdeeldispositivode s
tdio. h
entradaestándar.
Leeunacadenadecaracteresdesdeel
stdio.h
dispositivodeentradaestándar.
Determinasielargumentoesalfanumérico.
ctype.h
Devuelve
unvalordistintodecerosies
cierto;
enotrocasodevuelve O.
Determinasielargumentoesalfabético. ctype.h
Devuelve
unvalordistintodecerosies
cierto;enotrocasodevuelve
O.
Determinasielargumentoesuncarácter ctype.h
ASCn.Devuelveunvalordistintode
cerosiescierto;
enotrocasodevuelve O.
Determinasielargumentoes uncarácter ctype.h
ASCndecontrol.Devuelve unvalor
distintodecerosiescierto;enotrocaso
devuelve
O.
Determinasielargumentoesundigito ctype. h
decimal.Devuelve
unvalordistintode
cerosiescierto;
enotrocasodevuelve O.
Determinasielargumentoes uncarácter e t ype . h
ASCngráfico(hex Ox21-Ox7e;octal
041-176).Devuelveunvalordistintode
cerosiescierto;
enotrocasodevuelve O.
Determinasielargumentoes unaminúscula.ctype.h
Devuelve
unvalordistintodecerosies
cierto;
enotrocasodevuelve O.
Determinasielargumentoesundígitooctal.e t ype . h
Devuelveunvalordistintodecerosies
cierto;enotrocasodevuelve
O.
Determinasielargumentoes uncarácter e type. h
ASCnimprimible(hex Ox2O-Ox7 e;
octalO4 O-176).Devuelveunvalor
distintodecerosiescierto;enotrocaso
devuelve
O.
Determinasielargumentoes uncarácterde ctype.h
puntuación.Devuelveunvalordistintode
cerosiescierto;
enotrocasodevuelve O.

604 PROGRAMACiÓN ENC
Función Tipo Propósito Archivo include
isspace(c) int Determinasielargumento esunespacioen ctype.h
blanco.Devuelveunvalordistinto de
cerosiescierto;enotrocasodevuelve O.
isupper(c) int Determinasielargumentoesunamayúscula.c type . h
Devuelveunvalordistinto
decerosies
cierto;enotrocasodevuelve
O.
isxdigit(c)int Determinasielargumentoesundígito ctype.h
hexadecimal.Devuelveunvalordistintode
cerosiescierto;enotrocasodevuelve
O.
longintDevuelveelvalorabsoluto del.
sin(d) double
sinh(d) double
sqrt(d) double
srand(u) void
strcmp(sl,s2)int
putc(c,f) int
putchar(c) int
puts(s) int
rand() int
rewind(f) void
scanf(...) int
math.h
math.h
math.h
stdio.h
stdlib.h
stdio.h
math.h
stdlib.h
stdio.h
stdio.h
math.h
stdio.h
stdio.h
string.h
stdlib.h
math.h
math.h
Escribeuncaráctereneldispositivode
salidaestándar.
Devuelveellogaritmonaturalded.
Devuelveellogaritmo(enbase
ID)ded.
Reservaubytesdememoria.Devuelveun
punteroalprincipiodelespacioreservado.
Devuelve
d1elevado'alapotenciad2.
Escribedatosendispositivodesalida
estándar(losargumentossoncomplicados;
verApéndiceG).
Escribeuncarácterenelarchivo
f.
Escribeunacadenadecaracteresenel
dispositivodesalidaestándar.
Devuelveunenteropositivoaleatorio.
Mueveelpunteroalprincipiodelarchivo
f.
Leedatosendispositivodeentradaestándar
(losargumentossoncomplicados;ver
ApéndiceG).
Devuelveelsenoded.
Devuelveelsenohiperbólicoded.
Devuelvelaraízcuadradaded.
Inicializaelgeneradordenúmerosaleatorios.
Comparadoscadenasdecaractereslexico­
gráficamente.Devuelveunvalor
negativosi
sl<s2;Osislys2son
idénticas;
yunvalorpositivo sis 1>s2.
int
double
double
void*
double
labs(l)
log(d)
log10(d)
malloc(u)
pow(d1,d2)
printf(...)

FUNCIONESDEBIBLIOTECAMÁSUSADAS 605
Función Tipo Propósito Archivo inelude
strempi(sl,s2)int
strepy(sl,s2)ehar*
Comparadoscadenas decaractereslexico- string.h
gráficamente,sindiferenciarmayúsculas
deminúsculas.Devuelveunvalor
negativosi
si<s2;Osisiys2son
idénticas;yunvalorpositivosi
si>s 2 .
Copialacadenadecaracteres s2enla string.h
cadenas1.
strlen(s) int Devuelveelnúmero decaracteresdeuna
cadena. string.h
longintDevuelveelnúmerodesegundos time.h
transcurridosdespuésdeuntiempobase
designado.
int ConvierteelvalordelargumentoaASCn. etype.h
int Convierteunaletraaminúscula. etype,
ostdlib.h
int Convierteunaletraamayúscula. etype,
ostdlib.h
strset(e,s)
system(s)
tan(d)
tanh(d)
time(p)
toaseii
tolower
toupper
char*
int
double
double
Ponetodosloscaracteres desae(excluyendostring.h
elcarácternulodelfinal\ O l.
Pasalaordenalsistemaoperativo.Devuelve string. h
Osilaordenseejecutacorrectamente;
enotrocasodevuelveunvalordistintode
cero,típicamente
-1.
Devuelvelatangentede d. math.h
Devuelvelatangentehiperbólicade d. math.h
Notas:tipo serefierealtipo dedatodelacantidaddevueltaporlafunción.Unasterisco(*ldenotaun
puntero.
edenotaunargumentodetipocarácter
ddenotaunargumentoendobleprecisión
fdenotaunargumentoarchivo
idenotaunargumentoentero
1denotaunargumentoenterolargo
.pdenotaunargumentopuntero
sdenotaunargumentocadena
decaracteres
udenotaunargumentoenterosinsigno
LamayoríadeloscompiladorescomercialesdeCvienenacompañadosdemuchasmásfuncionesde
biblioteca.Consulteelmanualdereferenciadesucompiladorparticularparaunainformaciónmásdeta­
lladadelasfuncionesanterioresyparatenerunalistadelasfuncionesadicionales.

Respuestasaproblemasseleccionados
Capítulo1
1.31.a)Esteprogramaescribeelmensaje iBienvenidoalaInformática!.Elprograma
nocontieneningunavariable.Lalíneaquecontiene
printfesunainstruccióndesalida.No
hayinstruccionesdeentradanideasignación.
b)Esteprogramatambiénescribe elmensajeiBienvenidoalaInformática!.El
programanocontieneningunavariable.
(MENSAJEesunaconstantesimbólica,nounavaria·
ble.)Lalíneaquecontiene
printfesunainstruccióndesalida.Nohayinstruccionesde
entradanideasignación.
e)Esteprogramacalculaelárea deuntriángnloapartirdesubaseysualtura.Lasvariablesson
base,alturayarea.Lasinstruccionesprintfscanfalternativasgeneranla
entradainteractiva.Lainstrucción
printffinalesunainstruccióndesalida.Lainstrucción
quecomienzacon
area=esunainstruccióndeasignación.
d)Esteprogramacalculaelsalarioneto(descontandoimpuestos),dadoelsalariobrutoyel
tantoporcientodeimpuestos(queesunaconstante,14%).Lasvariablesson
bruto,im­
puestoyneto.Lasinstruccionesprintf-scanfinicialesgeneranlaentradainte·
ractiva.Lasdosinstrucciones
printffinalessoninstrucciones desalida.Lasinstrucciones
quecontienen
impuesto=yneto=soninstruccionesdeasignación.
e)Esteprogramautilizaunafunciónparacalcularelmenordedosnúmerosenteros.Lasvariables
son
a,byminoLosparesdeinstrucciones printfscanfalternativasgeneranla
entradainteractiva.Lainstrucción
printffinalesunainstrucción desalida.Lainstrucción
min=menor(a,b)hacereferenciaalafunciónllamada menor.Estafuncióncontiene
unainstrucción
if -e 1s equedevuelvelamenordelasdoscantidadesalaparteprincipal
delprograma.
1)Esteprogramaprocesanpares decantidadesenterasydeterminalacantidadmenor decada
par.Seutilizaunbucle
forparaprocesarlosmúltiplespares decantidadesenteras.Encuan·
toalresto,elprogramaesanálogoalmostradoenlaparte
(e).
g)Esteprogramaprocesaunnúmeroindeterminadodepares decantidadesenterasydetermina
lamenordecadapar.Laejecucióncontinúahastaqueseintroduceunpardeceros.Seutiliza
unbucle
whileparaprocesarlosmúltiplesparesdecantidadesenteras.Encuantoalresto,
elprogramaesanálogoalmostradoenlaparte
(j).
h)Esteprogramaprocesaunnúmeroindeterminadodeparesdecantidadesenterasydetermina
lamenordecadapar.Losvaloresoriginalesylosmínimoscorrespondientessealmacenanen
losarrays
a,byminoCadaarraypuedealmacenarhasta 100valoresenteros.
Unavezquesehanintroducidotodoslosdatosysehandeterminadotodoslosmínimos,
elnúmerodeconjuntosdedatoses«apuntado»mediantelainstrucciónn
=
~-i;seutiliza
entoncesunbucle
forparavisualizarlosdatos.Encuantoalresto, elprogramaesanálogoal
mostradoenlaparte
(g).
Capítulo2
2.39.a)Válido.
b)Unidentificadordebecomenzarconunaletra.
e)Válido.
607

60S PROGRAMACiÓN ENC
ti)returnesunapalabrareservada.
e)Unidentificadordebecomenzarconunaletra.
1)Válido.
g)Noestánpermitidoslosespaciosenblanco.
h)Válido.
i)Noestápermitidoelsignomenos.j)Unidentificadordebecomenzarconunaletraouncarácter desubrayado.
2.40.a)Distinto
b)Distinto
e)Idéntico ti)Distinto
e)Distinto
1)Distinto
2.41.a)Válido(real).
b)Carácterilegal
(,).
e)Válido(real).
ti)Válido(real).
e)Válido(enterodecimal).
1)Válido(enterolargo).
g)Válido(real).
h)Carácterilegal(espacioenblanco).
i)Válido(constanteoctal).j)Caracteresilegales (C,D,F)enunaconstanteoctal.Siseinterpretacomoconstantehexade­
cimal,esnecesarioincluirx o
X(porejemplo, OXICDF).
k)Válido(enterolargohexadecimal).
1)Carácterilegal(h).
2.42.a)Válido.
b)Válido.
e)Válido.
ti)Lassecuenciasdeescapesedebenescribirconunabarrainvertida.
e)Válido.
1)Válido.
g)Válido.
h)Válido(secuencia deescapedelcarácternulo).
i)Unaconstantedecarácternopuedeconstardevarioscaracteres.
j)Válido(secuenciadeescapeenoctal).Notarqueeloctal52esequivalentealdecimal42.En
elconjuntodecaracteresASCn,elvalorrepresentaunasterisco(*).
2.43.a)Unaconstantedecadena decaracteresdebeencontrarseencerradaentrecomillasdobles.
b)Válido.
e)Faltanlascomillasfinales.
ti)Válido.
e)Válido.
1)Válido.
g)Lascomillasy(opcionalmente)elapóstrofodentrodelascadenasdeCaracteressedeben
expresarcomosecuenciasdeescape;porejymplo,
"Elprofesordijo,\"Porfa­
vor,noseduermanenclase\"";
2.44.a)int
p,q;
floatX,y,z¡
chara,b,c;
b)floatraizl,raiz2;
longcont;
shortindicador;

RESPUESTAS APROBLEMAS SELECCIONADOS 609
e)intindice;
unsignednum_cliente;
doublebruto,impuesto,neto;
el)charactual,ultimo;
unsigt;ledcont;
floaterror;
2.45.a)floata=-S.2,b=0.005;
intx=129,Y=S7,z=-22;
charcl='w
/
,
c2=
f&I ;
b)doubledI=2.SSe-S,d2=-S.4e5;
intu=0711,v=Oxffff;
e)longgrande=l234567S9L;
doublec=0.3333333333;
chareol=r'i
el)charmensaje[]=
IIERRüRII;
e)charprimero,ultimo;
charmensaje[SO];
2.46.a)
b)
e)
el)
e)
.f)
g)
2.47.a)
b)
e)
el)
e)
Restarelvalordebalde a.
Multiplicarporalasumadelosvaloresdeb y c.
Multiplicarporalasumadelosvaloresdeb y c.Asignarelresultadoad.
Determinarsielvalordeaesmayoroigualqueelde
b.Elresultadoseráciertoofalso,
representadoporlosvalores1(cierto)y O(falso).
Dividirelvalordea
por5 ydeterminarsielrestoesigualacero.Elresultadoseráciertoo
falso.
Dividirelvalordeb
porelvalordec ydeterminarsielvalordeaesmenorqueelcociente.
Elresultadoseráciertoofalso.
Decrementarelvalorde
a;porejemplo,decrementarelvalordeaen l.
Instruccióndeexpresión
Instruccióndecontrolquecontieneunainstruccióncompuesta.(Lainstruccióncompuesta
estáencerradaentrellaves.)
Instruccióndecontrol
Instruccióncompuestaquecontieneinstruccionesdeexpresiónyunainstruccióndecontrol.
Instruccióncompuestaquecontieneunainstruccióndeexpresiónyunainstruccióndecon­
trol.
Lainstruccióndecontrolcontienedosinstruccionescompuestas.
2.48.
a)#define
b)#define
e)#define
#define
FACTOR
ERROR
BEGIN
END
-lS
0.0001
{
}
el)#define
e)#define
.f)#define
NOMBRE
EOLN
COSTE
11AdriánIt
1 r
1I$~_9.9511
Capítulo3
3.36.a)6
b)45
e)2

610 PROGRAMACiÓN ENC
d)2
e)-1
j)3
g)-4
h)O(porqueb / eescero)
i)-1
j)-16
3.37.a)7.1
b)49
e)2.51429
d)Laoperaciónrestonoestádefinida paraoperandosencomaflotante.
e)-5.17647
j)-2.68571
g)20.53333
h)1.67619
3.38.a)69
b)79
e)51
d)3
e)98
j)6
g)lOO
h)63
i)159
j)2703
3.39.a)entero
b)comaflotante(algunasversionesde eloconvertiránadobleprecisión)
e)dobleprecisión
d)enterolargo
e)comaflotante(odobleprecisión)
j)entero
g)enterolargo
h)entero
i)enterolargo
3.40.
a)14
b)18
e)-466.6667
d)-13
e)9
j)9
g)4
h)1.005
i)-1.01
j)O
k)O
T)1

RESPUESTAS APROBLEMAS SELECCIONADOS 611
m)O
n)I
o)I
p)O
q)I
r)0.01
s)I
t)I
u)O
v)O
w)O
x)I
y)I
z)O
3.41.a)k=13
b)z=-0.005
e)i=5
d)k=O
e)k=99
j)z=1.0
g)b=IOO,a=IOO(Observeque lOOeselvalorde 'd'enelconjuntodecaracteresASCII)
h)j=l,i=1
i)k=O,z=0.0
j)z=0.005,k=O[compararcon i)anterior]
k)i=IO
l)i=-0.015
m)x=O.OIO
n)i=1
o)i=3
p)i=II
q)k=8
r)k=5
s)k=0.005
t)z=O.O
u)a='c'
v)i=3
3.42.a)Devuelveelvalorabsolutodelaexpresiónentera (i- 2*j).
b)Devuelveelvalorabsolutodelaexpresiónencomaflotante (x+y).
e)DeterminasielcarácterrepresentadoporeesuncarácterASCIIimprimible.
d)Determinasielcarácterrepresentadoporeesundigitodecimal.
e)Convierteelcarácterrepresentado pore amayúscula.
j)Redondeaelvalordexalvalorenterosuperiorpróximo.
g)Redondeaelvalorde
(x+y)alvalorenteroinferiorpróximo.
h)Determinasielcarácterrepresentadoporeesunaminúscula.
i)Determinasielcarácterrepresentadoporjesunamayúscula.
j)Devuelveelvalorde
ex.
k)Devuelveellogaritmonaturalde x.

612 PROGRAMACiÓN ENC
1)Devuelvelaraizcuadradadelaexpresión (x*x+y*y).
m)Determinasielvalordelaexpresión (10*j)sepuedeinterpretarcomouncarácter
alfanumérico.
n)Determinasielvalordelaexpresión (10*j)sepuedeinterpretarcomo uncarácter
alfabético.
o)Determinasielvalordelaexpresión (10*j)sepuedeinterpretarcomouncarácterASCII.
p)Convierteelvalordelaexpresión (10*j)auncarácterASCII.
q)Divideelvalordexporelde y,ydevuelveelrestoconelmismosignoque x.
r)ConvierteelcarácterASCIIcuyocódigoes 65aminúscula.
s)Determinaladiferenciaentreelvalordex yelvalorde y,ylaelevaalapotencia3 . O.
t)Evalúalaexpresión (x-y)ydevuelvesuseno.
u)Devuelveelnúmerodecaracteresdelacadena "ho1a ".
v)Devuelvelaposicióndelaprimeraaparicióndelaletra oenlacadena"hola".
3.43.a)2
b)0.005
e)1
el)O
e)'D'
i)1.0
g)0.0
h)0.0
i)
-1.0
j)1
k)OT)1.005013
m)-5.298317
n)0.005
o)0.011180
p)1
q)O
r)1
s)'2'
t)0.005
u)'a'
v)3.375e-6
w)0.014999
x)5
y)1(Oindicalaprimeraposición)
z)1.002472
Capítulo4
4.50.a)a~getchar( );
b~getchar();
e ~getchar( );
b)putchar(a);
putchar(b);
putchar(c);

RESPUESTAS APROBLEMAS SELECCIONADOS 613
4.51.a)scanf("%c%c%c" , &a,&b,&e);
o
scanf(11%c%e%c
ll
,&a,&b,&e);
b)printf(11%c%c%c
11,a,b,e);
o
printf("%e%e%cn/a,b,e);
4.52.a)for(eont=O;
texto[eont]
eont<60;++eont)
=getehar( ) ;
b)for(eont=O;eont<60;++eont)
putehar(texto[eontl);
(Nota:sesuponeque eontesunavariableentera.)
4.53.for(eont=O;(texto[eont]=getehar(»!='';++eont)
4.54.seanf("%
[A]",texto);
Elmétodoutilizado enelProblema4.53indicaelnúmerodecaracteresquesehanleído.
4.55.
4.56.a)seanf("%d%d%dll/ &i,&j,&k);
b)scanf(11%d%0%x
tir&i,&j,&k);
e)
scanf(n%x%x%0ni&i,&j/&k);
a)seanf("%6d%6d %6d" I&i,&j,&k);
b)seanf("%8d%80 %8x" I&i,&j,&k);
e)
scanf(II%7x%7x%70
11
1&i,&j/&k);
4.57.a)A aseleasignaráunenterolargodecimalcon unalongituddecampomáximade 12;a bse
leasignaráunenterocortodecimalconunalongituddecampomáximade
5;a eydseles
asignaráncantidadesdedobleprecisiónconlongituddecampomáximade
15.
b)A aseleasignará unenterolargohexadecimalconunalongituddecampomáximade 10;a
bseleasignaráunenterocortooctalconunalongituddecampomáximade6;a esele
asignaráunenterocortosinsignoconunalongituddecampomáximade6;a dseleasignará
unenterolargosinsignoconunalongituddecampomáximade
14.
e)A aseleasignaráunenterolargodecimalcon unalongituddecampomáximade 12;a bse
leasignaráunenterocortodecimalconunalongituddecampomáximanoespecificada;a e
ydselesasignaráncantidadesencomaflotanteconlongituddecampomáximade 15.
d)A aseleasignaráunenterodecimalconunalongituddecampomáximade8;acontinuación
seleeráotroenterodecimal
ynoseasignaráaningunavariable;a e ydselesasignarán
cantidadesdedobleprecisiónconlongituddecampomáximade
12.
4.58.a)seanf("%d%d%e%le",
&i,&j,&x,&dx);
oseanf("%d%d%f%lf",&i, &j,&x,&dx);
b)seanf("%d%ld%d%f%u",&i,&ix,&j,&x,&u);
e)seanf("%d%u%e",&i,&u,&e);
d)seanf("%e%f%lf%hd", &e,&x,&dx,&s);
oscanf(11%c %e%le%hd 11l.&c1&X¡.&dx
r,&8)i
4.59.a)seanf("%4d%4d%8e %151e",&i, &j,&x,&dx);
oseanf("%4d%4d%8f%151f",&i,~j,&x.&dx);

12-80.011-2.2e6
12-80.011-2.2e6
12-80.011-2.2e6
12-80.011-2.2e6
614 PROGRAMACiÓN ENC
b)scanf("%5d%121d%5d%10f%5u",&i,&ix,&j,&x,&u);
e)scanf("%6d%6u%c
n
/
&i,&u,&c);
d)scanf("%c%9f%16lf%6hd",&c,&x,&dx,&s);
oscanf("%c%ge%161e%6hd",&c,&x,&dx,&s);
4.60.scanf(11%811,texto);
4.61.scanf("%[abcdefghijklmnopqrstuvwxyz"]",texto);
4.62.scanf("%[ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$"]", texto);
4.63.scanf(l!%[A*]",texto);
4.64.a)$*@(loscaracteressinseparar porespacios)
b)$ * @(unoomásespacios enblancoentreloscaracteres)
e)$ * @ (unoomáscaracteresdeespaciadoentreloscaracteresdeentrada)
d)$ * @(unoomásespaciosenblancoentreloscaracteres.Puedenaparecerotroscaracteres
deespaciado entreellos)
e)$*@(loscaracteressinsepararporespacios)
4.65.
a)
b)
e)
d)
Observequenosepuedeexcederlalongituddecampomáximaespecificada yqueunoomás
espacios
enblancodebensepararlascantidadesnuméricassucesivas. Larepresentaciónde
valores
encomaflotantemásconvenienteeslaquesemuestra,independientementedelos
caracteresdeconversiónparticularesdecadafunción
scanf.
4.66.
4.67
4.68a)printf("%d%d%dll,
i,j ,k);
b)printf("%d%d",(i+j ) ,(i-k)) ;
e)printf(n%f%dl1,sqrt(i+j ) ,abs(i-k)) ;
a)printf("%3d%3d %3d",i,j,k);
b)printf("%5d%5d
n
,
(i+j ) ,(i-k)) ;
e)printf("%9f%7d" Isqrt(i+j),abs(i-k)) ;
a)printf("%f%f %f
ll
lx,y,z);
b)printf("%f%fn,(x+y),(x-z)) ;
e)printf("%f%fl1Isqrt(x+y),fabs(x-z);
Nota:sepodríautilizartambiénlaconversióntipoe Otipog,porejemplo,
printf(lI%e%e%e",XIy,z)¡
4.69.a)printf("%6f%6f%6f",x,Yoz);
b)printf("%8f%8f"o(x+y)o(x-z));
e)printf("%12f%9f"osqrt(x+y)ofabs(x-z);
4.70.a)printf("%6e%6e%6e",XoYoz);
b)printf("%8e%8e"o(x+y),(x-z));
e)printf("%12e%ge",sqrt(x+y)ofabs(x-z);
Encadacaso,losvaloresnuméricosincluiránexponentes.

RESPUESTAS APROBLEMAS SELECCIONADOS 615
4.71.a)printf("%8.4f%8.4f%8.4f",x,
b)printf("%9.3f%9.3f",(x+y),
e)printf("%12.4f%10.4f",sqrt(x
y,z);
(x-z));
+y),fabs(x-z);
4.72.a)printf("%12.4e%12.4e%12.4e",x,y,z);
b)printf("%14.5e%14.5e",(x+y),(x-z));
e)printf("%12.7e%15.7e",sqrt(x+y),fabs(x-z);
4.73.oprintf("%o%0%x%x",a,
b)printf("%o%x",(a+b),
b,e,d)¡
(e-d));
4.74.a)printf("%d%d%g %gll,i,j ,x,dx);
b)printf("%d%ld%d%g%u
ll
Ii,ix,j,x,u);
e)printf("%d%u%c 11Ii,u,e);
ti)printf("%e%g %g%ld",e,x,dx,ix);
Nota:sepuedeutilizarconversióntipoeenlugardelatipo g.
4.75.a)printf("%4d%4d%14.8e%14.8e",i,j ,x,dx);
b)printf("%4d%4d%14.8e %14.8e
ll
,i,j,x,dx);
e)printf("%5d%121d%5d%10.5f%5u
ll
Ii,ix,j ,x,u);
ti)printf("%5d%121d%5d %10.5f%5u",i,ix,j ,x,u);
e)printf("%6d %6u %c
ll
ri,u,e);
fJprintf("%5d%5u %11.4f",j ,u,x)i
g)printf("%-5d%-5u%-11.4f",j ,u,x);
h)printf("%+5d%5u%+11.4f",j ,u,x);
i)printf("%05d%05u%11.4f",j ,u,x);
j)printf("%5d%5u%#11.4f",j ,u,x);
4.76.a)printf("%80%8d%8x
ll
,i,j ,k);
b)printf("%-80%-8d%-8x",i,j ,k);
e)printf("%#80%08d%#8x
ll
Ii,j ,k);
4.77.a)12345-13579-24680123456789-22225555
b)12345-13579 -24680
123456789-22225555
e) 12345 -13579 -24680
123456789 -2222 5555
ti)12345 -13579
-24680123456789
-2222 5555
e)+12345 -13579
-24680 +123456789
-2222 5555
fJ00012345-0013579
-0024680000000123456789
-000222200005555

616 PROGRAMACiÓN ENC
77777
77777
77777
077777
77777
77777
abcd9
abcd9
abcd9
Oxabcd9
a)12345abcd9
b)12345abcd9
e) 12345
d)12345
e) +12345
1)00012345
4.78.
4.79.
a)2.5000000.0005003000.000000
b)2.5000000.0005003000.000000
e)2.5000000.0005003000.000000
d)2.5000 0.00053000.0000
e) 2.500 0.0013000.000
1)2.500000e+0005.000000e-0043.000000e+003
g)2.500000e+0005.000000e-0043.000000e+003
h)2.500000e+0005.000000e-0043.000000e+003
o2.5000e+0005.0000e-0043.0000e+003
j)2.50e+0005.00e-0043.00e+003
~2.5000000.0005003000.000000
1)+2.500000+0.000500+3000.000000
m)2.5000000.0005003000.000000
n)2.5000000.0005003000.000000
o)2.50.00053000
p)2.5000000.0005003000.000000
4.80.a)A Be
b)ABe
e) A B e
d) A B e
e)cl=Ac2=Bc3=e
4.81.a)printf("%s",texto);
b)printf("%.8s",texto);
e)printf("%13.8s",texto);
d)printf("%-13.8s",texto):
4.82.a) Programarenepuedeserunaactividadenormementecreativa.
b)Programarenepuedeserunaactividadenormementecreativa.
e)Programarenepue
d) Program
e)Program
4.83.a)printf("Porfavor,introducetunombre:"):
scanf("%[A]",nombre);
b)printf("xl=%4.1f x2=%4.1f",xl,x2):
e)printf("Porfavor,introduceelvalordea:");
scanf("%d",&a);
printf("Porfavor,introduceelvalordeb:"):
scanf("%d",&b);
printf("Lasumaes%d",(a+b));
Laúltimainstruccióntambiénsepodriaescribirasí:
printf("%s%d","Lasumaes",(a+b)):

RESPUESTAS APROBLEMAS SELECCIONADOS 617
Capítulo5
5.30.a)/*programa"iHOLA!"* /
#include<stdio.h>
main()
(
printf(lI%sl1,II¡HOLA!II)¡
}
b)/*programa"BIENVENIDO -SEAMOSAMIGOS" * /
#include<stdio.h>
main()
(
charnombre[2O];
printf("%s","HOLA,¿COMOTELLAMAS?");
scanf("%[A]",nombre);
printf("%s%s%s", "BIENVENIDO",nombre,"SEAMOSAMIGOS");
}
e)/*conversióndetemperaturas-fahrenheitacelsius*/
#include<stdio.h>
main()
{
floatc,f·,
printf("%s","IntroducelatemperaturaengradosF:");
scanf("%f",&f);
c=(5./9.)*(f-32.)
printf("%s%5.1f","ElvalorcorrespondientedeCes:"c);
}
~/*problemadelahucha*/
#include<stdio.h>
main()
{
intmedios,cuartos,dimes,niqueles,peniques;
floatdolares;
printf(11%8
11
,
scanf(11%dI!I
printf("%s",
scanf(11%d111
printf(lI%s",
11¿Cuantos
&medios);
11¿Cuantos
&cuartos);
11¿Cuantos
mediosdólares?
cuartos?");
dimes?11);
-11)i

618 PROGRAMACiÓN ENC
scanf("%d",&dimes);
printf("%8
11
,"¿Cuantosníqueles?H)i
scanf("%d",&niqueles);
printf(H%8 11I 11¿Cuantospeniques?11);
scanf("%d",&peniques);
dolares=0.5*medios+0.25*cuartos+0.1*dimes+
0.05*niqueles+0.01*peniques;
printf(n%s%6. 2f%s 11,11Eltotales11,dolares, 1Idólares11);
}
#include<stdio.h>
#definePI3.1415927
11) ;introduceelvalordelradio:UPorfavor
&radio);
printf(II%SIl,
scanf("%f
1l
1
floatradio,volumen,area¡
main()
{
e)/*volumenyáreadeunaesfera*/
volumen=
area=4.
(4./3.)*PI*radio*radio*radio;
*PI*radio*radio;
printf("%s%.3e%s%.3e", "Elvolumenes
"Eláreaes
11volumen,
area)i
}
fl/*masadeairedeunneumático*/
#include<stdio.h>
main()
{
floatP,VIm,ti
printf(11%8
11
,
scanf("%fll,
printf(n%8" I
scanf("%f",
printf("%8
11
1
scanf("%fll/
11Introduce
&v);
11Introduce
&p);
11Introduce
&t);
elvolumenenpiescúbicos:11);
elvalordelapresiónenpsi:");
latemperaturaengradosF:");
m=(p*v)/(0.37*(t+460.));
printf("Masadeaire:%glibras",m);
}

RESPUESTAS APROBLEMAS SELECCIONADOS 619
g)/*codificacióndeunapalabrade5letras*/
#include<stdio.h>
main()
{
charel,c2,c3, c4,eS;
príntf(lI%sll/IlPorfavor,introduceunapalabrade5letras:1I)¡
scanf("%c%c%c%c%c", &cl,&c2,&c3, &c4,&c5);
printf("%c%c%c%c%c",(cl-30),(c2-30), (c3-30), (c4-30),(c5-30));
}
h)/*decodificacióndeunapalabrade5letras*/
#include<stdio.h>
main()
{
charel,c2,c3, c4,eS;
printf("%s","Introducelap\,labrade5letrascodificada:");
scanf("%c%c%c%c%c", &cl,&c2,&c3, &c4,&c5);
printf("%c%c%c%c%c", (cl+30),(c2+30), (c3+30),(c4+30),
(c5+30));
}
D/*codificarydecodificarunalíneadetexto*/
#include<stdio.h>
main()
{
intcont,aux¡
chartexto[80];
/*leerycodificarlalíneadetexto*/
printf(11%8"/ 11PorfavorIintroduceunalíneadet~xto: 11) ;
for(cont=O;(texto[cont]=getchar()-30)!=(''
30); ++cont)
,.
aux=cont¡
/*escribireltextocodificado*/
printf("Textocodificádo:");
for(cont=O;cont<aux;++cont)
putchar(texto[cont]);
/*decodificaryescribir,recuperandoeltextooriginal*/
printf("Texto decodificado(original):");
for(cont=O;cont<aux;++cont)
putchar(texto[cont]+30);
}

620 PROGRAMACiÓN ENC
j)/*intercambiarlasmayúsculasyminúsculasdeunalíneade
texto* /
#include<stdio.h>
#include<ctype.h>
main()
{
intcont,aux;
charc,texto[80];
/*leerlalíneadeentrada*/
printf("%slll
for(cont=
aux=cont;
nPorfavor,introduceunalíneadetexto:1I);
O;(texto[cont]=getchar())!='';++cont)
/*escribirlalíneadesalida*/
for(cont=O;cont<aux;++cont)(
c
=islower(texto[cont])?toupper(texto[cont])
:tolower(texto[cont]);
putchar(c);
}
}
Capítulo6
6.43.
6.44. Sielvalorabsolutode xesmenorque eldexmin.entonceselvalorde xminesasignadoa x
sixtienevalorpositivo,ysielvalorde xesnegativooigualacero,seleasignaa xelvalorde
-xmin.Éstanoesunainstruccióncompuestaynohayinstruccionescompuestasincluidas.
1)Elfragmentodelprogramaesunainstruccióncompuesta.
2)Lainstrucción
do-while,queestáincluida enelfragmentodelprograma,contieneuna
instruccióncompuesta.
3)Lainstrucción
if,queestáincluidaenlainstrucción do-while,contieneunainstrucción
compuesta.
6.45.a)suma=O;
i=2;
while(i<100)
suma+=i¡
i+=3;
}
b)suma=O;
i=2';
do{
{
suma+=i¡
i+=3;
}while(i<100);

RESPUESTAS APROBLEMAS SELECCIONADOS 621
e)suma=o;
for(i=2;i <100;i+=3)
suma+=i;
6.46.a)suma=O;
i=neoro;
whi1e(i<=nfin){
suma+=i;
i+=ni
}
b)suma=O;
i=nCOffi¡
do{
suma+=i¡
i+=ni
}while(i<=nfin);
e)suma=O;
for(i=ncom;i<=nfin;i+=n)
suma+=i¡
6.47.a)cont=O;
while(cont<n).
printf("%d"
++cont;
}
o
cont=O;
whi1e(cont<n)
printf("%d
b)cont=O;
do{
{
texto[cont]);
texto[cont++]);
printf("%d"texto[cont]);
++cont;
}whi1e(cont<n);
o
cont=O;
do
printf("%d"texto[cont++]) ;
while(cont<n);
e)for(cont=O;cont<n;++cont)
printf("%d"texto[cont]);

622 PROGRAMACiÓN ENC
6.48.a)cont=O;
while(texto[cont}
printf("%d
++cont¡
}
o
cont=O;
while(texto[cont]
printf("%d
b)cont=O;
do{
!= /*,) {
texto[cont]} ;
!=1*1)
texto[cont++]);
printf("%d texto[cont]) ;
++cont¡
}while(texto[contl!='*');
o
cont=O;
do
printf("%dtexto[cont++]);
while(texto[cont]!='*');
e)for(cont=O;texto[cont]!='*';++cont)
printf("%d",texto[cont]);
6.49.a)for(j=2 ;j <=13;++j) {
suma=O;
i=2 ;
while(i<lOO) {
suma+=i·,
i+= j ;
)
printf(lI%d",suma);
}
b)for( j=2 ;j <=13;++j) {
suma=O;
i=2 ;
do {
suma+=ii
i+= j ;
}while(i<100)
printf("%d",suma);
)
e)for( j=2 ;j <=13;++j) {
suma=O;
for(i=2 ; i < 100;i+=j)
suma+=ii
printf("%d",suma);
}

RESPUESTAS APROBLEMAS SELECCIONADOS 623
6.50.a)suma=O,
for(i=2 ;i< lOO,i+= 3 )
suma=(i%5--O)?+=i:+=O,
{
texto[cont] ,A'
11
texto[cont]--'E'
11
texto[cont]--'1'
11
texto[cont]--'O'
11
texto[cont]--'U')
b)suma=O;
for(i=2,i <100,i+=3)
if(i%5== O)suma+=i;
6.51.a)suma=O,
for(i=ncom,i<=nfin,i+= n)
suma=(i%k== O)?+=i:+= O,
b)suma=O,
for(i=neoro;i<=nfin¡i+=n)
if(i%k--O)suma+=ii
L52.letras=digitos=blancos=otros=O,
for(cont=O,cont<80;++cont){
if((texto[cont]>='a'&&texto[cont]<='z')11
(texto[cont]>='A'&&texto[cont]<='Z'))
++letras¡
elseif(texto[cont]>='O'&&texto[cont]<='9')
++digitos,
elseif(texto[cont]== 11texto[cont]=='' 11
texto[cont]==' ')
++blancos;
else++otrosi
}
6.53.vocales=consonantes=O;
for(cont=O,cont<80,++cont)
i f(isalpha(texto[cont])
if(texto[cont]--'a'11
texto[cont]'e'11
texto[cont]--'i'11
texto[cont]--'o'11
texto[cont]--'u'11
++vocales¡
else++consonantes;
}
Elbucletambiénsepuedeescribirasí:
vocales=consonantes=O;
for(cont=O;cont<80;++cont){
if(isalpha(texto[cont])
if(tolower(texto[cont])--'a'11
tolower(texto[cont])'e'11
tolower(texto[cont])--'i'11

624 PROGRAMACiÓN ENC
tolower(texto[cont])--'0'11
tolower(texto[cont])'u')
++vocalesi
alsa++consonantes;
}
6.54.switch(indicador){
case1:printf("CALOR");
break;
case2:printf("TEMPLADO") ;
break;
case3:printf("FRIa");
break;
default:printf("FUERADERANGO");
}
6.55.switch(color)
case'r/:
case'R
/
:
(
printf("ROJO");
break;
case'v':
case'V':
printf("VERDE");
break;
case'a':
case
rA':
printf("AZUL");
break;
default:
printf("NEGRO");
break;
}
6.56.i f(temp<O.)
printf("HIELO");
elseif(temp<=100.)
printf("AGUA");
else
printf("VAPOR");
Nosepuedeutilizarunainstrucción switchporque:

RESPUESTAS APROBLEMAS SELECCIONADOS 625
a)Lascomprobacionesinvolucrancantidadesencomaflotante ynoenteras.
b)Lascomprobacionesinvolucranintervalosdevalores ynovaloresexactos.
6.57.for(i=O,j=79;i<80;++i,--j)
inverso[j]=texto[i];
6.58.a)O51530 g)O13 5 8 12 15192430
x=30 x=30
b)1 234 h)O13 6
x=4 x=6
e)1 23 4 i)O
x=4 x=O
d)1O3 2 7 6131221 j)O O2 4 5 910 141420
x=21 x=20
e)1O3 2 76 131221 k)1 3 5 79 12 141720 23
x=21 x=23
fJ1 l)16 11162124 29 3235 38
x=1 x=38
Capítulo7
7.32.a)
b)
e)
d)
e)
7.33.a)
b)
e)
d)
faceptaunargumentoentero ydevuelveunacantidadentera.
faceptadosargumentos ydevuelveunacantidad endobleprecisión.Elprimerargumentoes
unacantidadendobleprecisión
yelsegundounentero.
faceptatresargumentos ynodevuelvenada.Elprimerargumentoes U1lenterolargo,el
segundounenterocorto
yeltercerounenterosinsigno.
fnoaceptaningúnargumento ydevuelveuncarácter.
faceptadosargumentosenterossinsigno ydevuelveunenterosinsigno.
faceptadosargumentos encomaflotante ydevuelveunvalor encomaflotante.
faceptaunenterolargo ydevuelveunenterolargo.
faceptaunentero ynodevuelvenada.
fnoaceptanada ydevuelveuncarácter.
7.34.a)y=formula(x);
b)escribe(a,b);
7.35.a)intmuestra(void);
b)floatraiz(inta,intb);
e)ehareonvertir(ehare)
d)ehartransferir(longi)
e)longinversa(ehare)
fJdoubleproeesar(inti,floata,floatb)
g)voidvalor(doublex,doubley,shorti)

626 PROGRAMACiÓN ENC
7.36.a)intfuncl(inta,intb);
b)doublefuncl(doublea,doubleb);
e)longintfuncl(inta,floatb);
á)doublefuncl(doublea,doubleb);
doublefunc2(doublea,doubleb);
7.37.a)1 4 9 1625
b)#include<stdio.h>
intfuncl(intcont);
main()
{
intconti
for(cont=1;
printf("%d
}
intfuncl(intx)
{
cont<=5;++cont)
",funcl(cont));
return(x*x);
}
e)55
á)30
n-1
7.38.a)y=x"+1:Xio
i=l
Y
I=Xl'eY,=X,+Y'_Iparan >1
n-1
b)y=(-l)'x,/n!+1:H)'xi/i!o
i=O
Y
=1ey=(-l)'x/n!+yparan>O
o' n n n-l
1-1
e)P=f,*Ilio
,j=lJ
PI=1;,yP,=f,*P'_Iparan >1
Capítulo8
8.25.a)1
b)1
e)6
2 3 4 5
3 6 1015
15284566

RESPUESTAS APROBLEMAS SELECCIONADOS 627
8.26.a)externfloatresolver(floata,floatb)
Tengaencuentaque externpuedeseromitido;esdecir,laprimeralíneasepuedeescribirasi:
floatresolver(floata,floatb)
b)staticfloatresolver(floata,floatb)
8.27.a)Primerarchivo:
externdoublefuncl(doublea,doubleb);/*añadida*/
main()
{
doublex,y,Z',
z=funcl(x,y);
}
Segundoarchivo:
doublefuncl(doublea,doubleb)
{
}
b)Primerarchivo:
externdoublefuncl(doublex,doubley);/*añadida*/
externdoublefunc2(doublex,doubley);/*añadida*/
main()
{
doublex,y,z',
zfuncl(x,y);
}
Segundoarchivo:
doublefuncl(doublea,doubleb)
{
doublee;
e=func2(a,b);
}
staticdoublefunc2(doublea,doubleb)
{
}
8.28.a)4 6
b)100
9
196
13
80
18
184601644013620100

100
200
628 PROGRAMACiÓN ENC
e)104116136136
d)101 102 106 124
e)611 16 21 26
1)611 16 21 26
g)92557121249
h)Esteprogramadevolveráelnúmerodecaracteresdeunalíneadetextointroducida portecla­
do.Elcarácterfindelíneanoseincluiráenlasuma.
Capítulo9
9.27.a)
b)
e)d)
e)
1)
nombreesunarrayunidimensionaldecaracteresde3 Oelementos.
ces
unarrayunidimensionalde6elementosencomaflotante.
aesunarrayunidimensionalde5 Oelementosenteros.
parametrosesunarraybidimensionalde 25elementosenteros(5filas,5columnas).
memoes
unarraybidimensionaldecaracteresde S712elementos(66filasy 132columnas).
cuentasesunarraytridimensionalde SO.000elementosdedobleprecisión (50páginas,
20filasy SOcolumnas).
9.28.a)cesunarrayunidimensionaldeSelementosen comaflotante.
c[O]=2.
c[4]=12.
c[l]=5.
c[5]=12.
c[2]=3.
c[6]=O.
c[3]=-4.
c[7]=S.
b)cesunarrayunidimensionaldeSelementos encomaflotante.
c[O]=2.
c[4]=O.
c[l]=5.
c[5]=o.
c[2]3.
c[6]=O.
c[3]=-4.
c[7]=O.
e)zes unarrayunidimensionalde 12elementosenteros.
z
[2]=S z [ 5 ]=6Elrestodeloselementos tienenasignadosceros.
d)indicadoresunarrayunidimensionaldecaracteresde9elementos.
indicador[ O]='V'indicador[1]= 'E'
indicador[2]='R'indicador[3]= 'D'
indicador[4]='A'indicador[5]='D'
indicador[6]='G'indicador[7]='R'
indicador[S]='O'
e)indicadoresunarrayunidimensionaldecaracteresde 10elementos.
indicador[O]='V'indicador[1]'F'
indicador[2]'R'indicador[3]='D'
indicador[4]='A'indicador[5]='D'
indicador[6]='8'indicador[7]='R'
indicador[S]='O'indicador[9]tieneasignadocero
1)indicadoresunarrayunidimensionaldecaracteresde5elementos.
indicador[O]='V'indicador[1]='F'
indicador[2]='R'indicador[3]='D'
indicador[4]='A'indicador[5]='D'
indicador[6]='8'indicador[7]'R'
indicador[S]='o'indicador[9]='\0'

RESPUESTAS APROBLEMAS SELECCIONADOS 629
g)indicadoresunarrayunidimensionaldecaracteresde 6elementos.
indicador[O]='F'
indicador[2]='L'
indicador[4]='o'
indicador[lJ='A'
indicador[3J 'S'
indicador[SJ='\0'
h)pesunarrayunidimensionalde2 x4enteros.
prO][O]=1
p[l][O]=O
pro][1]=3
p[l][1]=O
prO][2] 5
p[l][2]=O
prO][3]=7
p[l][3] O
i)pesunarraybidimensionalde2 x4enteros.
prO][O]=1
p[l][O]=5
prO][1]=1
p[l][1]=5
prO][2]=3
p[l][2]=7
p[0][3] 3
p[l][3]=7
j)pesunarraybidimensionalde2 x4enteros.
prO][O]=1
p[l][O]=2
prO][1]=3
p[l][1]=4
prO][2] 5
p[l][2]=6
prO][3]=7
p[l][3]=8
k)pesunarraybidimensionalde2 x4enteros.
prO][O]=1
p[l][O]=5
prO][1]=3
p[l][1]=7
prO][2] O
p[lJ[2]=O
prO][3]=O
p[l][3]=O
T)cesunarraytridimensionalde2 x3 x4enteros.
c[O][O] [O]
c[O][1][O]
c[O][2][O]
c[1][O][O]
c[1][1][O]
c[1][2][O]
=1c[O][O][1]=2
=4c[O][l][l]=5
6c[O][2] [1]=7
=10c[l][O][1]=11
=O c[1] [1][1]=O
=12c[l][2][1]=13
c[O][O][2]
c[O][1] [2]
c[OJ[2] [2]
c[1][O][2]
c[l][1][2]
c[l][2][2]
=3c[O][O][3] O
=Oc[0][1][3]=O
=8c[0][2][3J=9
O
c[l][O][3]=O
=Oc[l][1] [3]=O
=14c[1][2][3]=O
m)coloresesunarraybidimensional de3 x 6caracteres.
colores[O] [O]=
colores[O][3]=
colores[1][O]
colores[1][3]=
colores[2][O]=
colores[2] [3]=
'R'colores[O][1]='o'
'o'colores[O][4]=O
'V'colores[1] [1]='E'
'D'colores[1][4]'E'
'A'colores[2][1]='Z'
'L'colores[2] [4]=O
colores[O][2]='J'
colores[O][5]=O
colores[1][2]='R'
colores[l][5]=O
colores[2][2]='V'
colores[2][5]=O
9.29.a)intc[12]={1,4,7,10, 13,16, 19,22,25, 28,31,34};
b)charpunto[]="NORTE";
d)floatconstantes[6]={O.OOS,-0.032,le-6,0.167,-0.3e8,
O.OlS};

630 PROGRAMACiÓN ENC
e)intn[3][4]={la,12,14, 16,20,22, 24,26,30,32,34,36};
Otraformadeasignarvaloresiniciales eslasiguiente:
intn[3][4]= {
{la,12,14,16L
{20,22, 24,26L
{30,32, 34,36}
};
1)intn[3][4]
o
{la,12, 14,O,O, 20,22,O,O, 30,32,O};
intn[3][4] {
{la,12,14L
{O,20,22L
{O,30,32}
};
g)intn[3][4]={la,12, 14, 16,20,22};
9.30.a)floatmuestra(floata,floatb,intjstar[]);
main()
{
floata,b,c¡
intjstar[20];
x=muestra(a¡b
ljstar)¡
}
floatmuestra(floata,floatb,intjstar[])
{
}
b)floatmuestra(intn,chare,doublevalores[]);
main()
{
intn;
charc¡
floatx;
doublevalores[50];
x=muestra(n,e,valores);
}

RESPUESTAS APROBLEMAS SELECCIONADOS 631
floatmuestra(intn,charc,doublevalores[])
{
}
e)floatmuestra(chartexto[][80]);
main()
(
floatx;
chartexto[12][80];
x=muestra(texto);
}
f10atmuestra(chartexto[][80])
{
}
d)floatmuestra(charmensaje
[],floatcuentas[][100]);
main()
(
floatx;
charmensaje[4O];
floatcuentas[50][100];
x=muestra(mensaje
lcuentas);
}
floatmuestra(charmensaje[],floatcuentas[][100])
{
}
9.31.a)2 O(sumadeloselementosdearrayscuyosvaloressonpares)
b)25(sumadeloselementosparesdelarray)
e)Nofuncionará(losarraysautomáticosnopuedeninicializarse)
d)25(sumadeloselementosdevalorimpar deunarrayexterno)
e)1(elvalormáspequeño)

632 PROGRAMACiÓN ENC
j)1 5 9 (valormáspequeñodentro decadafila)
g)9
101112(valormásgrandedentro decadacolumna)
h)O 2 2 4
4 6 6 8
810 1012(sielvalor deunelementoesimpar,reducirsu valoren 1;mostrara
continuaciónelarraycompleto)
i)PPoorrmmrree uuddeeuu iieettdd!!(saltarloselementoscon
índiceimpardelarray;imprimircadaelementoconíndicepardosveces)
Capítulo10
10.44.
a)pxesunpunteroaunacantidadentera.
b)aybsonvariablesencomaflotante; paypbsonpunterosacantidadesencomaflotante
(aunquenonecesariamentea a y ab).
e)
aesunavariableencomaflotante devalorinicial-O.167;paesunpunteroauna cantidad
encomaflotante;ladirección
deaseasignaa pacomovalorinicial.
d)el,e2ye3sonvariablesdetipocarácter; pe1,pe2ype3sonpunterosacaracteres;la
direcciónde
e 1seasignaa pe3.
e)funeesunafunciónqueaceptatresargumentosydevuelveunacantidad dedobleprecisión.
Losdosprimerosargumentossonpunterosacantidadesdedobleprecisión;eltercerargu­
mentoesunpunteroaunacantidadentera.
j)funeesunafunciónqueaceptatresargumentosydevuelveunpunteroaunacantidad de
dobleprecisión.Losdosprimerosargumentossonpunterosacantidades dedobleprecisión;
eltercerargumentoesunpunteroauna cantidadentera.
g)aesunpunteroaungrupo
dearraysunidimensionales,dedobleprecisión,contiguos;estoes
equivalentea
doub1ea[][12];
h)aesunarrayunidimensionaldepunterosacantidadesdedobleprecisión(equivalenteaun
arraybidimensionaldecantidades
dedobleprecisión).
i)aesunarrayunidimensionaldepunterosacaracteressimplesocadenasdecaracteres(equi­
valenteaunarraybidimensional
decaracteres).
j)desunarrayunidimensionaldepunterosalascadenas" norte
ll
,IIsurll,"este"y
"oestell.
k)pesunpunteroaungrupodearraysbidimensionales,deenteroslargos,contiguos;equiva­
lentea p
[][10][2O];
l)pesunarraybidimensional depunterosacantidadesenteraslargas(equivalenteaunarray
tridimensionaldeenteroslargos).
m)muestraesunafunciónqueaceptaunargumentoqueesunafunciónydevuelveuncarác­
ter.Lafunciónpasadacomoargumentoaceptadosargumentoscarácterydevuelveunacan­
tidadentera.
n)pfesunpunteroaunafunciónquenoaceptaargumentosperoquedevuelveuna cantidad
entera.
o)pfesunpunteroaunafunciónqueaceptadosargumentoscarácterydevuelveunacantidad
entera.
p)pfesunpunteroaunafunciónqueaceptadospunterosacaracterescomoargumentosy
devuelveunacantidadentera.
10.45.a)inti,j';
int*pi=&i¡
int*pj=&ji

RESPUESTAS APROBLEMAS SELECCIONADOS 633
b)float*pf;
double*pd;
e)long*fune(inta,intb);
d)longfune(int*a,int*b);
e)float*x;
1)float(*x)[30];ofloat*x[15]
g)char*color[3];;::{lIrojo" I11verde11I"azul"};
h)ehar*fune(int(*pf)(inta));
i)float(*pf)(inta,intb,inte);
j)float*(*pf)(int*a,int*b,int*e);
10.46.a)F8D
b)F8D
e)'B'
d)'C'
e)F8c
1)F8C
g)'C'
10.47.a)F9C
b)F9E
e)F9E
d)3 O(observequeestocambiaelvalorde j)
e)35
1)F9E
g)(i+j)=35+30=65
h)FA2
i)67
j)noespecificado
10.48.a)1130 d)1130 g)1134
b)1134 e)0.002 h)0.003
e)1138 1)&(*pa)=pa=1130 i)0.003
10.49.a)80 e)a=88 b=89
b)81 d)a=80 b=81
10.50.a)
b)
e)
d)
e)
10.51.a)
b)
e)
d)
e)
10.52.a)
b)
e)
Unpunteroa unentero.
Nosedevuelvenada.
Unpunteroaunacantidadentera.
Calculalasumadeloselementosdep
(pesunarraydecincoelementosenteros).
suma=150
Unpunteroaunentero.
Nosedevuelvenada.
Losdosúltimoselementosdeunarraydecincoelementosenteros.
Calcula.lasumade.Iosdosúltimoselementosdeunarraydecincoelementos.enteros.
suma=90
Unpunteroaunentero.
Unpunteroaunentero.
Ladireccióndelelementodepcuyovaloreselmayor (pesrealmenteunarraydecinco
elementosenteros).

634 PROGRAMACIÓN ENC
d)Determinarelmayorvalordeloselementosde p.
e)max=SO
10.53.a)Direccióndex [O]
b)Direccióndex [ 2 ]
e)
10
d)12(estoes, 10+2)
e)30(ésteeselvalordex [2])
10.54.a)Direcciónde tabla[O][O]
b)Direccióndefila1(lasegundafila)de tabla
e)Direcciónde tabla[1][O]
d)Direcciónde tabla[1] [1]
e)Direcciónde tabla[O][1]
j)2.2
g)1.2
h)2.1i)2.2(estoes,1.2+1)
Direcciónde color[O](comienzodelaprimeracadena)
Direcciónde
color[2](comienzodelaterceracadena)
IIro
jo
ll
l1azu
ll1
Losdosrefierenalmismoelementodelarray(punteroa "amari11o ")
a
ybsonvariablesordinariasencomaflotante. uno,dosytressonfunciones,cadauna
delascualesdevuelve
unacantidadencomaflotante. unoydosaceptan,cadauna,dos
cantidadesencomaflotantecomoargumentos.
tresaceptaunafuncióncomoargumento;la
funciónargumentoaceptarádoscantidades
encomaflotantecomosuspropiosargumentosy
devolveráunacantidad
encomaflotante.(Observequetanto unocomodospuedenapare­
cercomoargumentosde
tres.)
b)unoydossondefinicionesdefuncionesconvencionales.Cadaunaaceptadoscantidadesen
comaflotanteydevuelveunacantidadencomaflotantequesecalculadentrodelanmción.
e)
tresaceptaunpunteroaunafuncióncomoargumento. Lafunciónargumentoaceptados
cantidadesencomaflotanteydevuelveunacantidad
encomaflotante.Dentrode tresse
accedealafunciónargumento
yelresultadocalculadoseasignaa c.Elvalordecesluego
devueltoa
main.
d)Cadavezqueseaccedea tressepasaunafuncióndiferente. Portanto,elvalordevuelto por
tressecalcularádemododistintocadavezqueseaccedaadichafunción.
10.55.a)
b)
e)
d)
e)
10.56.a)
10.57.a)aybsonpunterosacantidadesencomaflotante. uno,dosytressonfunciones;unoy
dosdevuelven,cadauna,unacantidad encomaflotante ytresdevuelveunpunteroauna
cantidadencomaflotante.
unoydosaceptan,cadauna,dospunterosacantidadesencoma
flotantecomoargumentos.
tresaceptaunafuncióncomoargumento;lafunciónargumento
aceptarádospunterosacantidadesencomaflotantecomosuspropiosargumentosydevolve­
ráunacantidad
encomaflotante.(Observequetanto unocomodospuedenaparecercomo
argumentosde
tres.)
b)unoydossondefinicionesdefuncionesconvencionales.Cadaunaaceptadospunterosa
cantidadesencomaflotanteydevuelveunacantidad
encomaflotantequesecalculadentro
delafunción.

10.58.a)
b)
e)
d)
e)
j)
g)
h)
i)
j)
k)
RESPUESTAS APROBLEMAS SELECCIONADOS 635
e)tresaceptaunpunteroaunafuncióncomoargumento.Lafunciónargumentoaceptados
punterosacantidadesencomaflotanteydevuelveunacantidadencomaflotante.Dentrode
tresseaccedealafunciónargumentoyelresultadocalculadoseasignaa c.Ladirección
deeesluegodevueltaa
main.
d)Cadavezqueseaccedea tressepasaunafuncióndiferente.Portanto,elvalorcuyadirec­
ciónesdevueltapor
tressecalcularádemododistintocadavezqueseaccedaadichafun­
ción.
e)Enesteesquema unoydosaceptanpunteroscomoargumentos,mientrasque enelesquema
anterioraceptabanvariablesordinariasencomaflotantecomoargumentos.Tambiéneneste
esquema
tre sdevuelveunpuntero,mientrasqueenelanteriordevolvía unacantidaden
comaflotanteordinaria.
xesunpunteroaunafunciónqueaceptaunpunteroaunacantidadenteracomoargumentoy
devuelveunacantidad
encomaflotante.
xesunafunciónqueaceptaunpunteroaunacantidadenteracomoargumentoydevuelveun
punteroaunarrayde2 Oelementos
encomaflotante.
xesunafunciónqueaceptaunpunteroaunarraydeenteroscomoargumentoydevuelveuna
cantidadencomaflotante.
xesunafunciónqueaceptaunarraydepunterosaenteroscomoargumentoydevuelve
una
cantidadencomaflotante.
xesunafunciónqueaceptaunarraydeenteroscomoargumentoydevuelve
unpunteroauna
cantidadencomaflotante.
xesunafunciónqueaceptaunpunteroa
Unarraydeenteroscomoargumentoydevuelveun
punteroaunacantidad
encomaflotante.
xesunafunciónqueacepta
unarraydepunterosacantidadesenterascomoargumentoy
devuelveunpunteroaunacantidad
encomaflotante.
xesunpunteroaunafunciónqueaceptaunpunteroaunarraydeenteroscomoargumentoy
devuelveunacantidad
encomaflotante.
xesunpunteroaunafunciónqueaceptaunarraydepunterosacantidadesenterascomo
argumentoydevuelveunpunteroa
unacantidadencomaflotante.
xesunarraydepunterosafuncionesde2 Oelementos;cadafunciónacepta
unenterocomo
argumentoydevuelveunacantidad
encomaflotante.
xesunarraydepunterosafuncionesde2 Oelementos;cadafunciónaceptaunpun­
teroaunacantidadenteracomoargumentoydevuelveunpunteroa
unacantidadencoma
flotante.
10.59.a)char(*p(int*a))[G]);
b)charp (int ( *a)[]) ;
e)charp(int*a[]);
d)char*p(int a [ ] ) ;
e)char*p(int(*a)[]);
j)char*p(int*a[]);
g)char(*p)(int(*a)[]);
h)char*(*p)(int(*a)[]);
i)char* (*p)(int *a[]) ;
j)double(*f[12])(doublea,doubleb);
k)double*(*f[12])(doublea,doubleb);
!)double*(*f[12])(double*a,double*b);

636 PROGRAMACiÓN ENC
Capítulo11
11.34.struct
float
float
};
complejo{
real¡
imaginario;
11.35.structcomplejoxl,x2,x3;
11.36.structcomplejo {
floatreal;
floatimaginario;
}xl,x2,x3;
Esopcionalenestasituaciónincluir lamarca(compl ejo).
11.37.structcomplejox={lo3,-2.2);
Recordarque xpuedesertanto staticcomoexterna1.
11.38.structcomplejo*pX¡
Losmiembrosde laestructurason px->realypx->imaginario.
11.39.structcomplejocx[IOO];
11.40.structcomplejo {
floatreal;
floatimaginario;
}cx[lOO];
Esopcionalenestasituaciónincluirlamarca (complejo).
11.41.Losmiembrosdelaestructurason cx[17].realycx[17].imaginario.
11.42.typedef struct {
intganados;
intperdidos;
floatporcentaje;
}registro;
11.43.typedefstruct{
charnombre[4O]
;
registroposicion¡
}equipo;
dondeeltipodeestructura registroestádefinidoenelProblema11.42.
11.44.
equipoti
Todoslosmiembrosdelaestructurason t.nombre;t.posicion.ganados,
t.posicion.perdidosyt.posicion.porcentaje.Loscaracteresqueconstituyen
t .nombrepuedenseraccedidosindividualmente;porejemplo, t .nombre[O],t .nombre[1],
t .nombre[2],...,etc.

RESPUESTAS APROBLEMAS SELECCIONADOS 637
11.45.equipot={"OsosdeChicago",14,2,87.S};
11.46.printf("%d",sizeoft);
o
printf("%d",sizeof(equipo));
11.47.equipo*pt¡
Todoslosmiembrosdelaestructurason pt->nombre,pt->posicion.ganados,
pt->posicion.perdidosypt->posicion.porcentaje.Loscaracteresquecompo­
nen
pt->nombrepuedenseraccedidosindividualmente;porejemplo, pt->nombre[O],etc.
11.48.equipoliga[48];
Loselementosindividualesson liga[4].nombreyliga[4J.posicion.porcentaje.
11.49.structequipo{
charnombre[4O];
registroposicion¡
structequipo*sig¡
};
11.50.Sedandossoluciones yambassoncorrectas.
a)structequipo*pt¡
pt=(structequipo*)malloc(sizeof(structequipo));
ciudad;equipob)typedefstruct
ciudad*pt;
pt=(ciudad*)malloc(sizeof(ciudad));
11.51.Sedandossoluciones yambassoncorrectas.
a)struct
int
int
int
hms {
hora;
minuto;
segundo;
};
union{
structhmslocal;
structhmscasa;
}*hora¡
b)typedef
int
int
int
}hms;
struct
hora;
minuto;
segundo;
{
union{
hmslocal;
hmscasa;
}*hora;

638 PROGRAMACiÓN ENC
11.52.Sedandossoluciones yambasson'correctas.
a)unianres{
interesi
flaatfres;
daubledres;
};
struct{
unianresrespuesta;
charindicadori
inta¡
intb¡
}x,y;
b)typedefunian{
interes;
flaatfres;
daubledres;
}res;
struct{
resrespuesta;
charindicadori
inta¡
intb;
}X,Yi
11.53.unianres{
interesi
flaatfres;
daubledres;
};
structmuestra{
unianresrespuesta;
charindicador;
inta¡
intb¡
};
structmuestrav;;;;;{14,'el,-2,5};
11.54.unianres{
interesi
flaatfres;
daubledres;
};
structmuestra{
unianresrespuesta;
charindicador;
inta¡
intb¡
structmuestra*sig¡
};

typedefstruet
tipo_estructura
muestra
x,*px=
RESPUESTAS APROBLEMAS SELECCIONADOS 639
tipo_estructura;
&x¡
11.55.a)rojoverdeazul
eianmagentaamarillo
rojoverdeazul
Lavariabledeestructura muestraespasadaa funeporvalor.Portanto,lasreasignacio­
nesdentrode
funenosonreconocidasdentrode main.
b)rojoverdeazul
eianmagentaamarillo
eianmagentaamarillo
Lavariabledeestructnra muestraespasadaa funeporreferencia.(Enrealidadsepasaa
funeunpunteroalcomienzode muestra.)Portanto,lasreasignacionesdentro defune
sonreconocidasdentro demain.
e)rojoverdeazul
eianmagentaamarillo
eianmagentaamarillo
Lavariabledeestructura muestraespasadaa funeporvalor,cornoen a).Ahora,sin
embargo,sedevuelvea
mainlavariabledeestructuramodificada.
11.56.8
1000.000000-0.000000
O0.500000-0.000000
-25098391364288.0000000.016667
Laprimeralínearepresentaeltamaño delaunión(8bytesparaacomodarunnúmero dedoble
precisión).Enlasegundalíneasólotienesentido
elprimervalor (100).Enlaterceralineasólo
tienesentidoelsegundovalor
(O.
SOOOOb).Yenlaúltimalíneasólotienesentidoelúltimo
valor
(0.016667).
11.57.a)2000.500012
O0.500000
Lavariabledeuniónusepasaa funeporvalor.Portanto,nosereconocedentrode main
lareasignacióndentrode fune.Observequesóloelprimervalortienesentidoenlaprimera
líneadesalidaysóloelsegundoenlaúltimalínea.
b)-26214-0.300000
O0.500000
Lavariabledeuniónusepasadenuevoa funeporvalor.Luego,dentro demainnose
reconocelareasignaciónefectuadadentro
defune.Elprimervalordecadalíneanotiene
sentido.
e)-26214-0.300000
-26214-O.300000
Lavariabledeuniónusepasaa tuneporvalor,peroa mainsedevuelvelavariablede
uniónmodificada.Portanto,lareasignaciónefectnadadentrode
tuneseráreconocidaden­
trode
main.Elprimervalordecadalíneanotienesentido.

640 PROGRAMACiÓN ENC
Capítulo12
12.21.#inelude<stdio.h>
FILE*puntr;
puntr=fopen(11estudian.dat
ll
r "W")i
12.22.#inelude<stdio.h>
FILE*puntr;
puntr=fopen("estudian.dat",llr+II);
felose(puntr);
12.23.#inelude<stdio.h>
FILE*puntr;
puntr=fopen( "muestra.dat11f Ilw+n )i
felose(puntr);
12.24.#inelude<stdio.h>
FILE*puntr;
puntr=fopen(Hmuestra.dat"lIIr+");
felose(puntr);
12.25.#inelude<stdio.h>
#defineNULL O
FILE*puntr;
puntr ~fopen(llmuestra.dat", 11r+11)i
if(puntr==NULL)
printf("ERROR -Nosepuedeabrirelarchivodesignado");
felose(puntr);
Amenudosecombinanlasinstrucciones fopeneif,porejemplo:
if((puntr=fopen("muestra.dat","r+"))==NULL)
printf("ERROR -Nosepuedeabrirelarchivodesignado");
12.26.printf("Introducirvaloresparaa,bye:");
scanf(lI%d%f%c
l1
,&a,&b
l&c)¡
fprintf(fpt,"%d%.2f%e",a,b,e);
Sepuedenincluir,sisedesea,loscaracteresdenueva línea (\n)enlacadenadecontrolde
fprintf.
12.27.fseanf(fpt,"%d%f %e",&a,&b, &e);
printf("a=%d b=%f e =%e",a,b,e);

RESPUESTAS APROBLEMAS SELECCIONADOS 641
12.28.a)fseanf(pt1,"%d%f%c"/ &a,&b,&e);
b)
printf("a=%d Nuevovalor: a);
scanf(
11%d 11f&a);
printf("b=%f Nuevovalor: b);
scanf("%f",&b);
printf("e=%e Nuevovalor: e);
scanf(11%c 11,&e);
e)fprintf(pt2,lI%d%.2f%c11,a,b,e);
Sepuedenincluir,sisedesea,loscaracteresdenuevalínea ()enlacadenadecontrolde
fprintf.
12.29.a)fseanf(ptl,"%s",nombre);
b)printf("Nombre:%s",nombre);
e)printf("Nuevonombre:");
seanf("%[AJ",nombre);
d)fprintf(pt2,"%s",nombre);
Heaquíotrasolución:
fgets(nombre,20,ptl);
printf("Nombre:%s",nombre);
puts("Nuevonombre:");
gets(nombre);
fputs(nombre,pt2);
a)
b)
e)
d)
12.30,a)
b)
fseanf(ptl,
printf(n%sll/
printf("a=
scanf(lI%dll,
printf("b=
scanf("%f
ll
,
printf("e=
scanf(lI%C
U
,
e)fprintf(pt2,
o
11%8ti,valores.nombre);
valores.nombre);
11) ;
&valores.a);
11)i
&valores.b);
n )i
&valores.e);
"%s%d%f%e",valores.nombre,valores.a,
valores.b.valores.e);
fprintf(pt2,"%s%d%f%e", valores.nombre,valores.a,
valores.b,valores.e);
o
fprintf(pt2,
fprintf(pt2,
fprintf(pt2,
fprintf(pt2,
n%s
ll
/
lI%d
ll
,
Il%f",
lI%c
ll
,
valores.nombre);
valores.a);
valores.b);
valores.e);
12.31.a)fread(&valores,sizeofvalores,1,ptl);
printf(n%8nivalores.nombre)i

642 PROGRAMACiÓN ENC
b)printf("a ~");
scanf(n%dHf&valores.a);
printf("b~");
scanf(n%f"f&valores.b);
printf(11e :;::11);
scanf(11%c 11I&valores.e);
e)fwrite(&valores,sizeofvalores,1,pt2);
Capítulo13
13.36.registerunsignedu,v;
13.37.intu~1,v 2 ;
registerintx~3,Y~4;
13.38.unsigned*func(registerunsigned*pt1);
main()
{
/*prototipodefunción*/
registerunsigned*pt1;
unsigned*pt2;
pt2~func(ptl);
}
unsigned*func(registerunsigned*pt1)
{
.unsigned*pt2;
/*declaracióndepuntero*/
/*declaracióndepuntero*/
/*definicióndefunción*/
}
pt2~.
return(pt2);
.;
13.39.Patróndebitscorrespondiente aa:101 O001011000011
a)5d3c 0101110100111100
b)2202 001000100000 0010
e)9dc5 1001110111000101
d)bfc71011111111000111
e)80c1 1000000011000001
1)623a 01100010 00111010
g)e2fb1110001011111011
h)1458 00010100 01011000

RESPUESTAS APROBLEMAS SELECCIONADOS 643
i)5860 0101100001100000
j)O 0000000000000000 (válidoparacualquiervalorde a)
k)ffff111111111111 1111(válidoparacualquiervalorde a)
1)ffff1111111111111111 (válidoparacualquiervalorde a)
m)aOOO 1010000000000000
n)c100 1100000100000000
o)aOc3 1010000011000011
p)5bc3 0101101111000011
q)3aOO 0011101000000000
r)5b3c 0101101100111100
s)fbc3 1111 101111000011
t)fbOO 111110110000 0000
u)fbff111110111111 1111
13.40.a)a&=Ox3f06 d)a»=3 g)a&=-(Ox3f06«8)
b)
al\=Ox3f06 e)a«=5
e)a1=-Ox3f06 j)a
A_
-a
13.41.a)v&Oxaaaaov&-Ox5555 e)v
1
Ox5555
b)c&Ox7f d)v
A_
Ox42
13.42.a) Observequevrepresentaunnúmeropositivo,yaqueelbitdelextremoizquierdo esO(el
valordecimalequivalentees
1398O).Portanto,losbitsdesocupadoscomoresultadode
ambasoperacionesdedesplazamientoserellenaránconceros.Losvaloresresultantesson
i)
Ox69cO ii)Ox369
b)Ahoravrepresentaunnúmeronegativo,yaqueelbitdelextremoizquierdoes1(elvalor
decimalequivalentees
-15511).Portanto,losbitsdesocupadosenlaoperacióndedespla­
zamientoalaizquierdaserellenaránconceros,perolosbitsdesocupadosenlaoperaciónde
desplazamientoaladerechaserellenaránconunos.Losvaloresresultantesson
i)
Ox3690 ii)Oxfc36
13.43.Cadaestructuradefinevarioscamposdebits.
a)uconstade 3bits,vde1bit,wde7bitsy xde5bits.Eltotaldebitses 16.Portanto,todos
loscamposdebitsocuparánunapalabra.
b)Loscamposdebitsindividualessonlosmismosqueenlapartea).Sinembargo,ahoraacada
campodebitsseleasignaunvalorinicial.Observequecadavaloreslosuficientemente
pequeñoparaacomodarsedentrodesucorrespondientecampodebits(porejemplo,2requie­
redosbits,
1unbit,16cincobitsy 8cuatrobits).
e)
u,v ywsonde7bitsdetamañocadauno.Senecesitarándospalabrasdememoria.u y vse
acomodaránenunapalabra,pero
wseráforzadoalcomienzodelasiguientepalabra.
d)u,v ywsonde7bitsdetamañocadauno.Senecesitarándospalabras.usecolocaráenla
primerapalabra,seguidopor9bitsvacíos.v y
wseacomodaránen'lasegundapalabra,sepa­
rados
pordosbitsvacíos.
e)u,v ywsonde7bitsdetamañocadauno.Seutilizarántrespalabrasparaalmacenarestos
camposdebits.usecolocaráenlaprimerapalabra,vseráforzadoalcomienzodelasegunda
palabra,y
wseráforzadoalcomienzodelatercerapalabra.Cadacampodebitsvaseguido
por9bitsvacíos.

644 PROGRAMACiÓN ENC
13.44.a)structcampos {
unsigneda 6 ;
unsignedb 4 .,
unsignedc 6 ;
};
b)staticstructcamposv={3,5,7};
o
staticstruct{
unsigneda 6 i
unsignedb 4;
unsignedc 6;
} v ={3,5,7};
Cadavalorpuedeacomodarseenuncampodetresbits.
e)Loscampode6bitspuedenacomodarcualquiervalorhasta
63,yaque
63
~2
6
-l~1X2'+1 x2
4
+1 x2
3
+1 x2
2
+1 x2
1+lx2°
Loscamposde4bitspuedenacomodarcualquiervalorhasta 15,yaque15=2
4
-1=1 x
X2
3
+1 x2
2
+1 x2
1
+1 x2°
d)staticstruct{
unsigneda8;
unsignedb 6;
unsignedc5;
};
a y bsealmacenaránenunapalabrade 16bits,y csealmacenaráenunasegundapalabra de
16bits.
e)staticstruct{
unsigneda 8 ;
unsigned 2 .,
unsignedb 6 ;
unsignedc 5 ;
};
1)staticstruct{
unsigneda 8 ;
unsigned O;
unsignedb 6 ;
unsigned 2 .,
unsignedc 5 ;
};
Capítulo14
14.24.enumindicadores{primero
lsegundo,tercero,cuarto,quinto};
14.25.enumindicadores
o
suceso;
enurn{primero,segundo,tercero,cuarto,quinto}suceso;

RESPUESTAS APROBLEMAS SELECCIONADOS 645
14.26.enum{do=1,re,mi,fa,sol,la,si}soprano,bajo;
14.27.enumdinero{penique=1,niquel=5,dime=
cuarto=25,medio=50,dolar
10,
lOO},
14.28.enumdineromoneda=dime,
o
enum{penique=1,niquel=5,
medio=50,dolar=lOO}
dime=10,cuarto=25,
moneda =:dime¡
14.29.norte= 2
sur= 3
este= 1
oeste= 2
14.30.mover1 = 3
mover2 = 2
14.31.Estainstrucciónswitchcalculalostantosacumulados,utilizandolasreglasquedependende
losvaloresasignadosa
lavariabledeenumeración mover.Lasreglassonlassiguientes:si
mover=nortesumar10puntosa tantos;simover=sursumar20puntosa tan­
tos;simover=estesumar30puntosa tantos;simover=oestesumar40puntos
a
tantos.Semuestraunmensajedeerrorsia moverseleasignaunvalordiferentede norte,
sur,esteuoeste.1432.a)argc=3,
b)argc=2,
argv[O]=demo,argv[l]=depurar,argv[2]=rapido
argv[OJ=demoyargv[l]=depurarrapido
14.33.Esteprogramaleeráunalíneadetexto ylamostraráenmayúsculasominúsculas,dependiendo
delsegundoparámetrodelalíneadeórdenes.Esteparámetrodebesero
mayuscu1aominus­
cula.Sinoesningunodelosdos,segeneraunmensajedeerror ynosemuestraeltexto.
14.34.transfer.exedatos.antdatos.nue
o,conalgunoscompiladores,
transferdatos.antdatos.nue
14.35.a)#define
b)#define
e)#define
d)#define
e)#define
1)#define
PI3.1415927
AREAPI*radio*radio
AREA(radio)PI*radio*radio
CIRCUNFERENCIA 2 *PI*radio
CIRCUNFERENCIA (radio)2 *PI*radio
interes{ \
i-0.01*r, \
f = p *
pow((1+i),n);\
}
Sesuponequelasvariables i,r,f,pynhansidodeclaradascomovariablesdedobleprecisión.

646 PROGRAMACiÓN ENC
g)#defineinteres(p,r,n){ \
i~O.Ol*r; \
f~p *pow((1+i),n);\
?a :b
}
h)#definemax
o
#definemax
(a>~b)
(((a)>~(b))?(a) (b))
Lasegundaversiónminimizarálaprobabilidaddeefectoslateralesnodeseables.
?a :bi)#definemax(a,b)
o
#definemax(a,b)
(a>~b)
(((a)>~(b))?(a) (b))
14.36.a)SilaconstantesimbólicaINDICADORnohasidodefinidapreviamente, sedefineINDICA­
DORpararepresentarelvalor 1.
b)SilaconstantesimbólicaPASCALhasidodefinidapreviamente,sedefinenlasconstantes
simbólicasBEGINy
ENDpararepresentarlossimbolos{ y},respectivamente.
e)Silaconstantesimbólica
CELSIUShasidodefinidapreviamente,sedefinelamacro
temperatura(t)pararepresentarlaexpresión 0.5555555*(t-32);enotro
caso,sedefine temperaturademodoquerepresentelaexpresión 1.8* t +32.
d)SilaconstantesimbólicaDEPURARnohasidodefinidapreviamente,sedefinelamacro
salidacomo
printf(lIX=%f
ll
,x)
Enotrocaso,silaconstantesimbólicaNIVELtieneunvalorde 1,sedefinesalidacomo
printf("i
~%d y ~%f",Ly[i])
ysiNIVELnotieneelvalor 1,sedefinesalidacomolamacromultilínea
for(cont~1;cont<~n;++cont) \
printf("i~%d Y ~%f",i,y[i])
(Sesuponequelasvariables x,i,y,contynhansidodeclaradasadecuadamente.)
e)«Anula»ladefinicióndelaconstantesimbólica DEPURARsiéstahasidodefinidapreviamente.
1)Esteproblemailustraelusodeloperador«decadena» (#).Silaconstantesimbólica
COMPROBACION_ERROR hasidodefinidapreviamente,entoncessedefine
lamacro
mensaje(linea)detalmaneraqueelargumento lineaseconvierteenunacadenade
caracteres
yluegosemuestraenpantalla.
g)Esteproblemailustraelusodeloperador«deconcatenacióll}>(##).Silaconstantesimbólica
COMPROBACION_ERROR hasidodefinidapreviamente,entoncessedefinelamacro
mensaje(n)detalmaneraquesemuestraenpantallaelvalorde mensajen(porejem­
plo,
mensaje3) .
14.37.
a)#ifdefined(LOGICA) o
#defineVERDADERO 1
#defineFALSO O
#undefSI
#undef NO
#endif
#ifdefLOGICA
#defineVERDADERO 1
#defineFALSO O
#undefSI
#undef NO
#endif

RESPUESTAS APROBLEMAS SELECCIONADOS 647
b)#ifindicador==O
#defineCOLOR 1
#elifindicador<3
#defineCOLOR 2
#else
#defineCOLOR 3
#endif
e)#ifTAMANO==AMPLIO
#defineANCHO 132
#else
#defineANCHO 80
#endif
d)#defineerror(texto)printf(#texto)
e)#defineerror(i)printf(U%s
U
Ierror##i)

índice
#define,52,564,573
#elif,573
#else,573
#endif,573
#if,573
#ifdef,573
#ifndef,573
#include,80,283,573
#line,573
#undef,573
Accesoamiembrosdeunaestructura, 421, 437,
440
Accesoauncampodebits, 541
Accesoaunafunción, 223
Actualizaciónderegistros declientes,426, 449,
508
Actualizaciónde unarchivoquecontieneregistros
declientes,499
Aislamientodelerror,
141,147
Almacenamientodenombres yfechasdenaci­
miento,
541
Ámbito:
denombres
demiembros,421
variableautomática, 261
Análisisdeunalineadetexto,353
ANSI
C,estándar,10,127
Aperturadeunarchivodedatos, 490
Árbol,454
binario,455
Árbolbinario, 455
Archivodedatos, 489
apertura,490
bajonivel,489
cierre,490
creación,492
detexto,489
estándar,489
lectura,493
orientadoalsistema, 489
procesamiento,499
secuencial,490,
~92
sinformato,489, 492,505
Archivodedatosdebajonivel, 489
Archivodedatosestándar, 489
Archivodedatosorientadoalsistema, 489
Archivodedatossecuencial, 490,492
Archivodedatossinformato, 489,492,505
Archivodedatossinformatoquecontieneregis-
tros
declientes:
'
actualización,508
creación,
506
Archivodetexto,489
Archivos,272
debiblioteca,
282
decabecera,282
dedatos,489
desalida,110,599
Archivosaincluir(funcionesdebiblioteca),
601-605
Archivosdebiblioteca,282
Archivosdecabecera, 282
ÁreadeEdicióndeTurbo C++,132
Áreadeuncírculo, 11-23
Áreasdecírculos, 11, 12,13-14,15,16,17-18,
19-20,21-22
Argumentos,11,219
estructura,425,441,446
649

650 íNDICE
Argumentos(cont.)
formación,240
formales,219
línea
deórdenes.553
pasoaunafunción,235,308
pasoporreferencia,309,312,350
pasoporvalor,235,236
reales,220,
223
Ydefinicionesdemacros,566
Argumentosdelalínea
deórdenes,553
Argumentosarray,240,308
pasoporreferencia,309,312,356
Argumentosformales,219
Argumentospuntero,pasoporreferencia,350
Argumentosreales,220,
223
Array:
deestructuras,418-419,424
deunadimensión,299
definición,300
especificacióndeltamaño,300,303
índice,44
multidimensional,299-300
procesamiento,305
retomodesdeunafuoción,314
tamaño,432
Arrays,43-44,299
automáticas,268,301,
321
decadenasdecaracteres,303
decaracteres,303
depunteros,375
desiguales,382
estáticas,302
externas,268,301, 322,328
inicialización,301, 305, 307, 322, 323,
361
multidimensionales,321,372
pasoafuociones,240,308,324,353,356
Ycadenasdecaracteres,45,328
Ypunteros,353,358
Arraysdecadenasdecaracteres,303
inicialización,383
Arrays
decaracteres,303
asignación
delosvaloresiniciales, 361
Arraysdepunterosycadenásdecaracteres,379,
382
Arraysunidimensionalesypunteros,358
Arraysdesiguales,382
Arraysestáticos,302
Arraysglobales,267
Arraysmultidimensionales,321,372
inicialización,322,323
pasoaunafunción,324-325
ypunteros,369,375
Arraysnuméricos,asignación
devaloresinicia­
les,361,363
ASCII,Conjuntodecaracteres,39-40,
593
Asignación:
aniveldebits,533
tipos
dedatosdiferentes,72
Asignación,instrucción, 12
Asignación,saltodeuna, 99
Asignacióndedatos,reglas,592
Asignacióndeestructurascompletas,425-426
Asignacióndevaloresaelementos
deunaforma-
ción,360
Asignacióndinámicadememoria,363, 365,
461-462
Asignación,operadores,71,73,
156
Asociatividad,63
AspectosinteresantesdeTurboC++, 133
Automáticas,formaciones,268,301,322
Automático,tipodealmacenamiento,257
BarradeestadodeTurboC++,132
BarrademenúdeTurboC++,
131
BarradetítulosdeTurboC++, 131
Barrasdedesplazamiento depantallaenTurbo
C++,132
BASIC,8
Bibliotecapersonal,217
Bits,3
desplazamientode,519
emnascarados,519
invertidos,519
posicióndedesplazamiento,530-531
Bits
dedesplazamiento,530-531
BorlandInternational,127
Bucle,153,159, 163,166-167
Bucles:
anidados,170
do-while,163
for,166
while,159
Buclesanidados,170
Buffer,archivodedatos,490
Búsquedadepalindromos, 195
Búsquedadelmáximo, 262,279
Bytes,3

C:
características,9
estándarANSI,
10
historia,10
introducción,9
K&R,IO
portabilidad,10
C++,lO
C,conjuntodecaracteres,31
C,preprocesador,573
C,programa:
borrarlosresultadosanteriores,129-130
claridad,129-130
escritura,129-130
estructura,
11
introducciónenlacomputadora, 131
lógica,129
mensajesparalaintroducción
dedatos,129-130
planificación,127
utilizacióndecomentarios,129
utilizacióndesangrados,
130
Cadenadecaracteres:
decaracteres,codificación,174
deentrada,114
desalida,114
Cadena
decontrol,91,102
caracteresnoreconocidosen
scanf,100
etiquetas
desalida114
lecturadecaracteresconsecutivos,99-100
saltodeunaasignaciónen
scanf,99
Cadenasdecaracteres,303
presentación,104
Yformaciones,45,328
Yformacionesdepunteros,379,382
Cálculodefactoriales,227,241,258
Cálculodeladepreciación,184,236
Cálculosrepetidosdelinteréscompuesto,175
Calificacionesmediasdelosestudiantes,
115
Campo,96,105
Campos
debits,535
acceso,
541
Camposdebits,535-541
Cantidadesenterasconsecutivas,
160, 164,167,168
Caracteresdeconversión,92,102
entradadedatos,92
prefijos,98,109
printf,598
salidadedatos,102;109
scanf,597
íNDICE 651
Caracteresnulos, 43
Característicasdelacomputadora,2
Característicasdeseablesdeunprograma,
23
Cierredeunarchivo dedatos,491
Círculo, áreadel,11-23
Circulos,áreas
de,11, 12,13-14,15, 16,17-18,
19-20,21-22
Circunflejo
(A),enlecturasdecadenasdecaracte­
res,
95
Claridad,23
programaC,129-130
Codificacióndeunacadenadecaracteres,174
Coma,operador,
195
Comentarios,11
enunprogramaC,129
Comparación
devariablespuntero,368
CompilacióndeunprogramaenTurboC++,
133
Compilador,9
Complementación
e),operador,524
Compresióndedatos(almacenamientode
nombres
yfechasdenacimiento), 541
Computacióninteractiva,7
Computadora,características,2
Computadorapersonal,1
Computadorasportátiles,1
Computadoras,introducciónalas,1
Concatenación:
cadena
decaracteres,329
macro,575
Condicióndefin
dearchivo,89,508
Condicional,operador,154
Conectivaslógicas,154
Conjuntodecaracteres,
31
ASCn,39,40,593
EBCDIC,
41
ConjuntodecaracteresEBCDIC, 41
Constante,35
cadenadecaracteres, 41
decarácter,39
decimal,
35
encomaflotante,37
entera,
35
enteralarga, 37
enumeración,554
hexadecimal,
36
octal,36
simbólica,
51
sinsigno,36

652 íNDICE
Constanteencomaflotante,35,37
exponente,38
precisión,39
rangode,
38
Constantesdecadena decaracteres,35,42
Ycaracteresnulos,
43
Constantesdecarácter,35,39
Constantesenteras,
35
Constantesenteraslargas, 37
Constantesenteras,rango, 37
Constanteshexadecimales, 37
Constantesoctales, 36
Constantessimbólicas, 51
Constantessinsigno,36
Control,estructurasanidadas,170
Control,transferenciadel,
199
Conversióndecaracteresenminúsculaa
mayúscula,80,218
Conversióndedatos,61-62
reglas,592
Conversióndetexto
enminúsculaamayúscula,
90,161,164,168,172,200,300,492
Conversionesdeltipo dedatos(<<casts»),62-63,
66-67
Creaciónde
unarchivodedatos,492
Creacióndeunarchivo
dedatossinformatoque
contieneregistrosdeclientes,506
Creacióndeunarchivoquecontengaregistros
declientes,494
CSMP,8
Cualificadores,34
Datos,2
Datos:
carácter,2
deentrada,3
Datos(cont.)
desalida,3
gráfico,2
numérico,2
Datosdeentrada,3
mensajes,130
Datosdesalida,3
Datosencomaflotante,redondeodesalida,107
.
Datosmúltiples:
entrada,
91
salida,102
Declaraciones,45-48
argumento,
II
estructura,415,436
array,48,305
función,273
puntero,349,397
variable,278
variablesexternas,261,278
Declaracionesdeargumentos,
11
Declaracionesdearrays,48,304
Yvaloresiniciales,47
default,enlainstrucciónswitch,
183
Definicióndemacro,argumentos,566
Definicióndeunaestructura,415,436
Definicióndeunarray,300
Definiciones:
función,272-273
variable,278
variablesexternas,261,278,
281
Definicióndeunafunción,219,272
Definicionesdearrays,300
Depuración:
aislamientodelerror,
141
pasoapaso,146
puntosdeinterrupción,
145
seguimientodelatrazadeejecución,142
valoresdeinspección,
145
Depuracióncon undepuradorinteractivo,
146
Depuracióndeunprograma,
142
Depuradorinteractivo, 145
depuracióncon, 146
Desplazamientodeelementosdeunarray,
359
Desviacionesrespectodelamedia,305,307
Devolverunaestructura,443,446
Direccióndeundato,345
Direcciones,ylafunción
scanf,91,355
Dispositivoapuntador,132
Dispositivosauxiliaresdememoria,5
Divisióndeenteros,59
Ecuaciónalgebraica,solución
de,177
EdiciónenTurboC++,132-133
Editor,pantalla,
131
Efectoslateralesyvariablesexternas,268
Eficiencia,
23

Ejecución:
errores,
138
programadecomputadora,3
Ejecucióncondicional,153,156
EjecucióndeunprogramaenTurboC++,
133
Ejecuciónpasoapaso,46
Elementosdeunarray,44,299
asignacióndevalores,360
Elevaciónde
unnúmeroaunapotencia,472,
557
else,157
Encabezamientodefunción,
11
Enmascaramiento,526-530
Enterodecimal,
35
Entrada:
cadenadecaracteres,94
caracteresdeconversión,92
datosmúltiples,
91
unsolocarácter, 88
Entradadeunsolocarácter,88
Enumeraciones,553
definición,554
Enumeradas,constantes,35,554
valoresequivalentes,555
Enumeradas,variables,553
procesamiento,555
utilizaciónde,556
Error,aislamiento,141,147-148
Error,mensajes:
compilación,135
diagnóstico,
135
ejecución,138
Error,detección, 175
Error,mensajes, 135
Errores:
decompilación,
135
deejecución,138
lógicos,140,147-148
sintácticos,
135
sintácticos,137
Erroresdecompilación, 135
Erroresgramaticales,
135
Erroreslógicos,140,
147"148
Erroressintácticos, 135
Escrituradeunprogramaen C,129
Escriturainversa,243
Espacioenblanco,
13
Estacióndetrabajo,1
íNDICE 653
Estructura:
definición,415,436
devueltadesdeunafunción,443,446
procesamiento,421
tamaño,432
Estructura,argumentos,425,441,446
Estructuradeunprogramaen
C,11
Estructura,miembros:
acceso,421,437,440
comopunteros,438
inicialización,418
procesamiento,425
Estructura,submiembros,
423
Estructura,variables,416
Estructuras,415
asignación, 425
autorreferenciadoras,453,456
definidasporelusuario,434
arrayde,418-419,424
incluidasdentrodeotras,417
pasoafunciones,426, 441,442,446
Ypunteros,436
yuniones,468
Estructurasautorreferenciadoras,453,456
Estructurasdecontrolanidadas,170,174
Estructurasdedatosenlazadas,453
Estructurasdefinidasporelusuario,434
Estructurasincluidasdentrodeotras,417
Etiquetadeinstrucción,
199
Etiquetascase,182
Exactitud,5
Exponentedeunaconstanteencomaflotante,38
Expresión,instrucciones,11,50,
155
Expresiones,49
conversionesdetiposdedatos,62-63,66-67
operandosdetiposdiferentes,61-62
Externos,arrays,268,301,322
Externas,funciones,272
Externas,variables,261,278,
281
efectoslaterales,268
valoresiniciales,266,278
Externo,tipodealmacenamiento,257
false,valorde, 68
fclose,función,491
Fechas
denacimiento,almacenamiento, 541
feof,función,508
Fibonacci,generarnúmeros
de,270,281,520

654 íNDICE
float,tipodedato,33-34
fopen,función490
for,instrucción,166
Fortran,9
fread,función,505
free,función,365,463
Función:
acceso,223
anfitriona,388
declaración,273
definición,219
estática,272,275
externa,272
huésped,388
retomo
deunpuntero,357
tipodealmacenamiento,273
Funciónanfitriona,388
declaración,389
Funciónanfitriona,declaracióndefunción,388-
389
Función,definición,272
Función,encabezamiento,
11
Funciónestática,272,275
Funciónhuésped,388
Función,llamadasmúltiples,225
Función,prototipos,217,226
argumentos
deunarray,308
yeltipodealmacenamientoregistro,
522
Funciones,
11
argumentosestructura,425-426
biblioteca,77, 78,282,563,601-605
enprogramasdevariosarchivos,272
pasoaotrasfunciones,388
pasodeestructuras,441, 442,446
paso
dearrays,308,325, 353,356
pasodepunteros,350
utilización,217
ymacros,566,
571
Funcionesdebiblioteca,9,77, 78,282,563,
601-605
cadena
decaracteres,328
fwrite,función,505
GeneracióndenúmerosdeFibonacci,
270,281,
520
Generadorde«piglatin»,314
Generalidad,24
getchar,función,88
gets,función,114
goto,instrucción,199
utilización,200
Grabación
deunarchivoenTurboC++, 133
Hanoi,lastorres de,244
Historiadel
C,10
Identificadores,32
longitud,
32
capitalización(mayúsculasyminúsculas),32
if,instrucción,156
if-else,instruccionesanidadas, 158
if-else,introducción,157
Independenciadelamáquina,284
Indicadoresde
printf,599
Índicedeunarray,44-45
Índicesde
unarray,44,299
Indirección,347
Indirección,operador,346, 371,380
Instrucción:
compuesta,
11
deasignación,12
deexpresión,11
Instrucciónbreak,190
Instruccióncompuesta,
11,50,155
Instrucción
continue,193
Instruccióndo-whi1e,163
Instrucciones,50
compuestas,50, 155
decontrol,51, 155
deexpresión,50, 155
Instruccionesdecontrol,51, 155
resumen,595-596
Instrucciones
if-elseanidadas,158
int,tipodedato,34
Integridad,23
Irtteréscompuesto,127, 130,133,175,392,567
Intérprete,9
Introducciónalascomputadoras,
1
Introduccióndeunprogramaenlacomputadora,
131
K&RC, 10
Kernighan,Brian, 10

Lecturadeunarchivodedatos,493
Lecturadeunarchivodedatos, 493,561
Lecturayescrituradeunalíneadetexto,105,
114
Lenguajesdeprogramación.
dealtonivel,8
depropósitoespecial,8
depropósitogeneral,8
tiposde,8
Lenguajesdeprogramacióndealtonivel,9
Líneadetexto:
análísis,353
lecturayescritura,
105,114
Líneasdetexto:
longitudmedia,
259,267
conversiónamayúsculas, 172,200
LI8P,7
Listacircularenlazada,454-455
Listadecadenasdecaracteres,reordenación
de,329,380
Listadenúmeros:
media,162,
166,169, 170,194
reordenación,312,364
Listaenlazada,453
árbol,454
circular,454
lineal,454
procesamiento,456
punterosmúltiples,454
Listalinealenlazada,454-455
Localízaciónderegistrosdeclientes,444
Longituddecampo:
entradadedatos,96
salida,106,107-109
Longituddelcampo(salida),109-110
lectura,95-96
Longitudmediadevariaslíneasdetexto, 259,267
LlamadaaunarchivoenTurboC++, 133
Llamadaaunafunción,223
Llamadasmúltiplesaunafunción,225
Macros,563
enlugardefunciones,566,571
devariaslíneas,564
Macrosdevariaslíneas,564
main,función,11
«Mainframe»,1
malloc,función,363, 365,462
íNDICE 655
Marca:
deestructura,415
deunión,468
enumerada,
553
Mayordetrescantidadesenteras,225
Mayordetresnúmerosenteros,225
Mayordeunalistadeenteros,225
Mayúscula/minúscula,diferencia,32
Media:
delascalificacionesdelosestudiantes,
115
deunalistadenúmeros, 162, 166,169170,
194
deunalistadenúmerosnonegativos, 194
Mediadelascalificacionesdelosestudiantes,
115
Memoria,asignacióndinámica,363,365,462
Memoria,requisitos
delostiposdedatos,33-34
Memoriadelacomputadora,3
Mensajes:
decompilación,135
deejecución,138
deerror,135
Mensajes,
135
Mensajesdeejecución,138
Mensajesdeerror,
135
Mensajesparalapeticióndedatosdeentrada,
130
MenúdedepuracióndeTurboC++,
133
Menúsdesplegables, 131
Microsegundo,5
Miembros:
comopunteros,438
enumerados,
553
estructurasyuniones,415
unión,467
Miembrosdeunaunión,inicialización,470
Minicomputadora,1
Minúsculasamayúsculas:
conversióndecaracteres,
80,218
conversióndetexto, 90,161, 164, 168,172,
200,300,492
Módem,6
Modosdeoperación,5
Modularidad,24
Nanosegundo,5
Nombresdemiembros,ámbito,421
NULL,350

656 íNDICE
Números:
binarios,585
hexadecimales,585
Números(cont.)
mediadeunalista,162, 166, 169,170,194
octales,585
Númerosbinarios,585
Númeroshexadecimales585
Númerosnonegativos,mediadeunalista
de,
194
Númerosoctales,585
o,operadoraniveldebits (1),525-526
Operaciones:
aniveldebits,523
depunteros,365,367,368-369
lógicasaniveldebits,525
Operacionesaniveldebits,523
Operacioneslógicasaniveldebits,525
Operador:
coma,195
complementación
C),524
complementoa lC),523
condicional(?:),75,155
decadena
(#),574
deconcatenación
(##),575
decremento(-
-),65
dirección,436
dirección
(&),345,347
flecha
(-»,437,440,469
incremento
(++),65
indirección(*),346, 371,380
oaniveldebits
(1),525-526
oexclusivoaniveldebits
(A),525-526
punto,422,437,440,469
restodivisiónentera
(%),59
sizeof,66,432
Yaniveldebits (&),525-526
Operadordecadena
(#),574
Operadordecomplementoa l (),523
Operadordeconcatenación
(##),575
Operadordedesplazamientoaladerecha
(»),
530
Operadordedesplazamientoalaizquierda
«<),
530
Operadordecremento,65
Operadordirección(&),345,347,436
Operadorflecha
(-»,437,440,469
Operadorincremento,
65
Operadoroaniveldebits
(1),525-526
Operadoroexclusivoaniveldebits(A),525-526
Operadorrestodedivisióndeenteros
(%),
59
Operador
yaniveldebits (&),525-526
Operadores,49
aritméticos,59
deasignación,71-72, 73-74,156
deasignaciónaniveldebits,533
dedesplazamiento,530
deigualdad,68,153
lógicos,69,154
lógicosaniveldebits,525-526
precedencia,63, 70, 75,76
relacionales,68,153-154
resumen,589
Operadoresaritméticos,59
Operadoresdeasignaciónaniveldebits,533
Operadoresdedesplazamiento,530
Operadoresdeigualdad,68,153
Operadoreslógicos,69,154
Operadoreslógicosaniveldebits,525-526
Operadoresunarios,
65
Operandos,59
mezcladetiposdedatos,61-62
Ordenación:
deunalistadecadenasdecaracteres,329,
380
deunalistadenúmeros,312,364
Palabras,4
Palabrasreservadas,9,32
Palindromos,búsquedade,195
Pantalladecomputadora,
3
Pantalladeleditor,131
Parámetro
argc,560-562
Parámetro
argv,560-562
Parámetros,11,220
estructura,425,441,446
array,239-240
formales,220
líneadeórdenes,560-562
pasoaunafunción,235,308
paso
porreferencia,309,312,350
pasoporvalor,235-236
reales,220,223
Ydefmicionesdemacro,566

Parámetrosdelalíneadeórdenes,559
Parámetrosformales,220
Parámetrosreales,220,223
Paréntesis:
anidados,64
utilizaciónde,64
Paréntesisanidados,64
Pascal,8
Pasodeestructurasafunciones,426
Paso
defuncionesaotrasfunciones,388
Patronesdebits,presentación,533
Pila,242
Planificación
deunprogramaen e,127
Plataforma,independenciade,284
Portabilidad,9
programa,217
programa
e,129-130
Potenciación,
59
Precedencia,63,70,75,76
Precisión:
datosdesalida,107
deconstantesencomaflotante,38
numérica,3
Precisiónnumérica,39
Prefijos:
case,182
deentrada,98,597
desalida,110,598
Preprocesador
dee,573
Presentacióndepatronesdebits,533
Presentacióndeldíadelaño,383
printf:
caracteresdeconversión,598
función,101-102,107
Procesamientodelosmiembros
deunaestructu-
ra,425
Procesamientodeunarchivodedatos,499
Procesamiento
deunaestructura,421
Procesamientodeunarray,305
Procesamientodeunalistaenlazada,456
Procesamientodevariablesenumeradas,555
Procesamientoporlotes,5
Programa:
deunsoloarchivo,268
devariosarchivos,268,272
depuración,142
ejecución,3
fuente,9
objeto,9
íNDICE 657
Programa,2
Programa,caracteristicasdeseables,23
Programa
decomputadora,3
Programade unúnicoarchivo,268
Programadevariosarchivos,268,272
Programafuente,9
Programa,lógicadel,129-130
Programaobjeto,9
Programa,portabilidad,217
Programación:
abajonivel,519
aplicaciones,9
ascendente,129
desistemas,9
descendente,127,226
interactiva,114
orientadaaobjetos,
10
planificación,127
Programaciónascendente,129
Programaciónconversacional,114
Programacióndeaplicaciones,9
Programacióndebajonivel,519
Programación
desistemas,9
Programacióndescendente,127,226
Programacióninteractiva,114
Programaciónorientadaaobjetos,
10
Programasconversacionales,8
Prototipos
defunción,217,226
Pseudocódigo,127
Puntero,variable,346,349
valorinicial,349
Puntero,variables:
asignacióndevaloresenteros,350
comparación,368
declaraciones,349
Punterodevueltoporunafunción,357
Punteros,345
avariablesregistro,522
comomiembros
deunaestructura,438
operaciones,365, 367,369
pasoaunafunción,350
yestructuras,436
yarrays,353
yarraysmultidimensionales,369,375
Yarraysunidimensionales,358
ylafunción
scanf,91
Punteros,declaraciones,349,397
Punto,operador,422-423,437,440,469
utilizaciónreiterada,422,469

658 íNDICE
Puntosdeinterrupcióndelaejecución,145
putchar,función,89
puts,función,114
Raícesdeunaecuacióndesegundogrado, 138­
139,142-143
Raícesrealesdeunaecuacióndesegundo
grado,
138-139,142-143
rand,función,229
Rango
deconstantesencomaflotante,37
Rangodeconstantesenteras,36-37
Ratón,132
Recursividad,218,
241
Reddecomputadoras,2
Redondeodelosresultados,
107
Registro,tipodealmacenamiento,257
yprototiposdefunción,522
Registro,variables,519
punterosa,522
Registrosdeclientes:
creacióndeunarchivoquecontiene,494
localización,444
actualizacíón,
426,448
actualizacióndeunarchivoquecontiene,499
Reglasdeasignación dedatos,592
Reglasdeconversión
dedatos,592
Relacionales,operadores,68,
153
Reordenacióndeunalistadecadenasde
caracteres,
329,380
Reordenacióndeunalistadenúmeros, 312,364
Repeticióndelamediadeunalistadenúmeros,
170
Reservadas,palabras,32-33
Resumen:
instruccionesdecontrol,595-596
operadores,589
return,instrucción,220-221
yarrays,314
Ritchie,Dennis,
10
Salida:
borrar,129-130
cadenasdecaracteres,104
datos
múltipks,101-102
unsolocarácter,88-89
Salidadedatos:
caracteresdeconversión,
102
comaflotante,103
Salidadeunsolocarácter,89
Salidanumérica,precisión,
107
Sangradoenunprogramaen e,129-130
scanf,caracteresdeconversión,597
scanf,función,91,96
Ydirecciones;355
Secuencial(archivodedatos),489
Secuencias
deescape,31,41, 587
Seguimiento
delatrazadeejecución,142
Seguimientodelerror, 141
Selecpión,153, 181
Senci'lez,23
Short,tipodedato,34
signed,tipodedato,34
SIMAN,8
Simulaciónde
j1jegosdeazar,228,275
Simulacióndejuegosdedados, 229,275
Sistemadetiempocompartido,6
Sistemasdenumeración,585
sizeof,operador,66,432
Solucióndeunaecuaciónalgebraica, 177
srand,función,231
s
trcmp,función,329
s
trcp'¡,función,329
Stroupstrup,Bjarne,
10
Submiembrosdeunaestructura,422-423
Sumadedostablasdenúmeros, 325, 372,
377
Sumadetablasdenúmeros, 325,372,377
Supercomputadora,1
Sustitución
deunamacro,566
switch,instrucción,181
Técnicasdedepuración,140
Texto:
lectura
yescritura,105,114
longitudmediadevariaslíneas, 259,267
Tipoarchivo,490
Tipo
dealmacenamiento,49,257·
automático,257
estático,257
externo,257
función,272
registro,257,519
Tipodealrhacenamientoestático,257
Tipodedatoarchivo,490
Tipodedato
char,34
Tipo
dedatodouble,34
Tipodedato
long,34

Tiposdedatos,33, 591
definidosporelusuario,433
Tiposdedatos(cont.)
requisitosdememoria,33-34
Tiposdedatosdefinidosporelusuario,433
Tiposdelenguajesdeprogramación,8
TorresdeHanoi,244
Transformacióndevariaslíneasdetextoa
mayúsculas,172,200
TurboC++,127,
131
áreadeedición,132
barradeestado,132
barrademenú,
131
barradetítulos, 131
barrasdedesplazamientode lapantalla,
132
característicasdestacadas,132-133
compilacióndeunprograma,
133
depuradorinteractivo,145-146
edición,132
ejecucióndeunprograma,133
grabarunarchivo,
133
llamadaaunarchivo, 133
menúdedepuración, 133
typedef,433
Unión,definición,468
Uniones,415,467
Yestructuras,468
unsigned,tipodedatos,34
Utilizacióndeparéntesis,64
Valor"verdadero",
68
Valorfuturodedepósitosmensuales,392,567
Valorinicialdeunavariabledetipopuntero,
349
Valoresdeinspección,145
Valoresiniciales:
asignadosaelementosdeunaformación,321­
322
íNDICE 659
endeclaraciones,47
array,301,304,306,
361
arraydeestructuras,419
miembrosdeunaestructura,417
miembrosdeunaunión,470
variablesautomáticas,258
variablesestáticas,269
variablesexternas,266
Variable:
declaración,278
definición,278
puntero,346,349
Variableautomática,ámbitode,
261
Variables,43
automáticas,258
deestructura,415
encomaflotante,
12
enprogramasdevariosarchivos,278
enumeradas,553-554
estáticas,268,
281
externas,261,278, 281
globales,257, 261, 278, 281
locales,257
registro,519
Variablesautomáticas,258
valoresiniciales,259
Variablesencomaflotante,
12
Variablesestáticas,268, 281
valoresiniciales,269
Variablesglobales,257, 261, 278,
281
valoresiniciales,266
efectoslaterales,268
Variableslocales,257
Velocidad,5
void,223
while,instrucción,159
y,operadoraniveldebits
(&),525-526

¡Estudiaatupropioritmoy
apruebatuexamenconSchaum!
LosSchaumsonlaherramientaesencialparalapreparacióndetusexámenes.
CadaSchauminduye:
@Teoríadelaasignaturacondefiniciones,
principiosyteoremasclaves.
@Problemasresueltosytotalmenteexplicados,
engradocrecientededificultad.
@Problemaspropuestosconsusrespuestas.
11111
9788448198466
www.mcgraw-hill.es
ISBN:84-481-9846-8
TheMcGraw·HiIICompan/es (~~t.'i1 ""
Tags