Source

PensarEnC++ / V1-C03.xml

The branch 'PensarEnC++' does not exist.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
<?xml  version="1.0" encoding="utf-8"?>
<!-- -*- sgml -*- -->
<!--
  Editor:               Emacs 21/PSGML
  Traducción original:  Bárbara Teruggi

  1ª Revisión:
   - Ortografía:                David Villa Alises
   - DocBook:                    "
   - Traducción y Terminología:  "
-->

<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
                 "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">

<chapter
  xmlns:xi="http://www.w3.org/2001/XInclude"
  id="C03">

  <title>C en C++</title>

  <!--
  Since C++ is based on C, you must be familiar with the syntax of
  C in order to program in C++, just as you must be reasonably fluent in
  algebra in order to tackle calculus.
  -->

  <!-- [PAG:121] -->
  <highlights>
    <para>
      Como C++ está basado en C, debería estar familiarizado con la
      sintaxis de C para poder programar en C++, del mismo modo que
      debería tener una fluidez razonable en álgebra para poder hacer
      cálculos.
    </para>
  </highlights>

  <!--
  If you've never seen C before, this chapter will give you a decent
  background in the style of C used in C++. If you are familiar with the
  style of C described in the first edition of Kernighan & Ritchie
  (often called K&R C), you will find some new and different features in
  C++ as well as in Standard C. If you are familiar with Standard C, you
  should skim through this chapter looking for features that are
  particular to C++. Note that there are some fundamental C++ features
  introduced here, which are basic ideas that are akin to the features
  in C or often modifications to the way that C does things. The more
  sophisticated C++ features will not be introduced until later
  chapters.
  -->

  <!-- [PAG:122] -->
  <para>
    Si nunca antes ha visto C, este capítulo le dará una buena base
    sobre el estilo de C usado en C++. Si está familiarizado con el
    estilo de C descrito en la primera edición de Kernighan &amp;
    Ritchie (también llamado K&amp;R) encontrará algunas
    características nuevas o diferentes tanto en C++ como en el
    estándar C. Si está familiarizado con el estándar C debería
    echar un vistazo al capítulo en busca de las características
    particulares de C++. Note que hay algunas características
    fundamentales de C++ que se introducen aquí, que son ideas
    básicas parecidas a características de C o a menudo
    modificaciones en el modo en que C hace las cosas. Las
    características más sofisticadas de C++ se explicarán en
    capítulos posteriores
  </para>


  <!--
  This chapter is a fairly fast coverage of C constructs and
  introduction to some basic C++ constructs, with the understanding that
  you've had some experience programming in another language. A more
  gentle introduction to C is found in the CD ROM packaged in the back
  of this book, titled Thinking in C: Foundations for Java & C++ by
  Chuck Allison (published by MindView, Inc., and also available at
  www.MindView.net). This is a seminar on a CD ROM with the goal of
  taking you carefully through the fundamentals of the C language. It
  focuses on the knowledge necessary for you to be able to move on to
  the C++ or Java languages rather than trying to make you an expert in
  all the dark corners of C (one of the reasons for using a higher-level
  language like C++ or Java is precisely so we can avoid many of these
  dark corners). It also contains exercises and guided solutions. Keep
  in mind that because this chapter goes beyond the Thinking in C CD,
  the CD is not a replacement for this chapter, but should be used
  instead as a preparation for this chapter and for the book.
  -->

  <para>
    Este capítulo trata por encima las construcciones de C e introduce
    algunas construcciones básicas de C++, suponiendo que tiene alguna
    experiencia programando en otro lenguaje. En el CD-ROM que acompaña
    a este libro hay una introducción más suave a C,
    titulada <citetitle>Thinking in C: Foundations for Java &amp;
    C++</citetitle> de Chuck Alison (publicada por MidView, Inc. y
    disponible también en <ulink
    url="http://www.MindView.net">www.MindView.net</ulink>). Se trata de
    un seminario en CD-ROM cuyo objetivo es guiarle
    cuidadosamente a través de los fundamentos del lenguaje C. Se
    concentra en el conceptos necesarios para permitirle pasarse a C++
    o a Java, en lugar de intentar convertirle en un experto en todos los
    oscuros recovecos de C (una de las razones para usar un lenguaje de
    alto nivel como C++ o Java es precisamente evitar muchos de estos
    recovecos). También contiene ejercicios y soluciones guiadas. Tenga
    presente que este capítulo va después del CD <citetitle>Thinking in
      C</citetitle>, el CD no reemplaza a este capítulo, sino que debería
    tomarse como una preparación para este capítulo y para el libro.
  </para>





  <sect1>
    <!-- Creating functions -->
    <title>Creación de funciones</title>

    <!--
    In old (pre-Standard) C, you could call a function with any number
    or type of arguments and the compiler wouldn't complain. Everything
    seemed fine until you ran the program. You got mysterious results
    (or worse, the program crashed) with no hints as to why. The lack of
    help with argument passing and the enigmatic bugs that resulted is
    probably one reason why C was dubbed a 'high-level assembly
    language.' Pre-Standard C programmers just adapted to it.
    -->

    <para>
      En el antiguo C (previo al estándar), se podía invocar una función
      con cualquier número y tipo de argumentos sin que el compilador se
      quejase. Todo parecía ir bien hasta que ejecutabas el programa. El
      programa acababa con resultados misteriosos (o peor, el programa
      fallaba) sin ninguna pista del motivo. La falta de ayuda
      acerca del paso de argumentos y los enigmáticos bugs que
      resultaban es, probablemente, la causa de que C se considerase
      <quote>un lenguaje ensamblador de alto nivel</quote>. Los
      programadores de pre-Estándar C simplemente se adaptaron.
    </para>
    <!-- [PAG:123] -->

    <!--
    Standard C and C++ use a feature called function prototyping. With
    function prototyping, you must use a description of the types of
    arguments when declaring and defining a function. This description
    is the 'prototype.' When the function is called, the compiler uses
    the prototype to ensure that the proper arguments are passed in and
    that the return value is treated correctly. If the programmer makes
    a mistake when calling the function, the compiler catches the
    mistake.
    -->

    <para>
      C y C++ Estándar usan una característica llamada
      <emphasis>prototipado de funciones</emphasis>. Con esta
      herramienta se han de describir los tipos de argumentos al
      declarar y definir una función. Esta descripción es el
      <quote>prototipo</quote>. Cuando la función es llamada, el
      compilador usa el prototipo para asegurar que los argumentos
      pasados son los apropiados, y que el valor retornado es tratado
      correctamente. Si el programador comete un error al llamar a la
      función, el compilador detecta el error.
    </para>

    <!--
    Essentially, you learned about function prototyping (without
    naming it as such) in the previous chapter, since the form of
    function declaration in C++ requires proper prototyping. In a
    function prototype, the argument list contains the types of
    arguments that must be passed to the function and (optionally for
    the declaration) identifiers for the arguments. The order and type
    of the arguments must match in the declaration, definition, and
    function call. Here's an example of a function prototype in a
    declaration:
    -->

    <para>
      Esencialmente, aprendió sobre prototipado de funciones
      (sin llamarlas de ese modo) en el capítulo previo, ya que la forma
      de declararlas en C++ requiere de un prototipado apropiado. En un
      prototipo de función, la lista de argumentos contiene los tipos de
      argumentos que se deben pasar a la función y (opcionalmente
      para la declaración), identificadores para los argumentos. El
      orden y tipo de los argumentos debe coincidir en la declaración,
      definición y llamada a la función. A continuación se muestra un
      ejemplo de un prototipo de función en una declaración:
    </para>


<programlisting>
int translate(float x, float y, float z);
</programlisting>


    <!--
    You do not use the same form when declaring variables in function
    prototypes as you do in ordinary variable definitions. That is, you
    cannot say: float x, y, z. You must indicate the type of each
    argument. In a function declaration, the following form is also
    acceptable:
    -->

    <para>
      No se puede usar la misma sintaxis para declarar los argumentos en
      el prototipo de una función que en las definiciones ordinarias de
      variables. Esto significa que no se puede escribir: <code>float x, y,
      z.</code> Se debe indicar el tipo de cada argumento. En una declaración
      de función, lo siguiente también es correcto:
    </para>


<programlisting>
int translate(float, float, float);
</programlisting>


    <!--
    Since the compiler doesn't do anything but check for types when the
    function is called, the identifiers are only included for clarity
    when someone is reading the code.
    -->

    <para>
      Ya que el compilador no hace más que chequear los tipos cuando se
      invoca la función, los identificadores se incluyen solamente para
      mejorar la claridad del código cuando alguien lo está leyendo.
    </para>

    <!--
    In the function definition, names are required because the arguments
    are referenced inside the function:
    -->

    <para>
      En la definición de la función, los nombres son necesarios ya que
      los argumentos son referenciados dentro de la función:
    </para>


<programlisting>
int translate(float x, float  y, float z) {
    x = y = z;
    // ...
}
</programlisting>


    <!--
    It turns out this rule applies only to C. In C++, an argument may be
    unnamed in the argument list of the function definition. Since it is
    unnamed, you cannot use it in the function body, of course. Unnamed
    arguments are allowed to give the programmer a way to 'reserve
    space in the argument list.' Whoever uses the function must still
    call the function with the proper arguments. However, the person
    creating the function can then use the argument in the future
    without forcing modification of code that calls the function. This
    option of ignoring an argument in the list is also possible if you
    leave the name in, but you will get an annoying warning message
    about the value being unused every time you compile the
    function. The warning is eliminated if you remove the name.
    -->

    <para>
      Esta regla sólo se aplica a C. En C++, un argumento puede no tener
      nombrado en la lista de argumentos de la definición de la
      función. Como no tiene nombre, no se puede utilizar en el cuerpo
      de la función, por supuesto. Los argumentos sin nombre se permiten
      para dar al programador una manera de <quote>reservar espacio en
      la lista de argumentos</quote>. De cualquier modo, la persona que
      crea la función aún así debe llamar a la función con los
      parámetros apropiados. Sin embargo, la persona que crea la función
      puede utilizar el argumento en el futuro sin forzar una
      modificación en el código que llama a la función. Esta opción de
      ignorar un argumento en la lista también es posible si se indica
      el nombre, pero siempre aparecería un molesto mensaje de
      advertencia, informando que el valor no se utiliza, cada vez que se
      compila la función. La advertencia desaparece si se quita el
      nombre del argumento.
    </para>

    <!--
    C and C++ have two other ways to declare an argument list. If you
    have an empty argument list, you can declare it as func( ) in C++,
    which tells the compiler there are exactly zero arguments. You
    should be aware that this only means an empty argument list in
    C++. In C it means 'an indeterminate number of arguments (which is
    a 'hole' in C since it disables type checking in that case). In
    both C and C++, the declaration func(void); means an empty argument
    list. The void keyword means 'nothing' in this case (it can also
    mean 'no type'in the case of pointers, as you'll see later in
    this chapter).
    -->

    <para>
      C y C++ tienen otras dos maneras de declarar una lista de
      argumentos. Si se tiene una lista de argumentos vacía, se puede
      declarar esta como <function>func()</function> en C++, lo que
      indica al compilador que hay exactamente cero argumentos. Hay que
      tener en cuenta que esto sólo significa una lista de argumentos
      vacía en C++. En C significa <quote>un número indeterminado de
      argumentos</quote> (lo que es un <quote>agujero</quote> en C ya
      que deshabilita la comprobación de tipos en ese caso). En ambos, C
      y C++, la declaración <function>func(void);</function> significa
      una lista de argumentos vacía. La palabra clave <type>void</type>
      significa <quote>nada</quote> en este caso (también puede
      significar <quote>sin tipo</quote> en el caso de los punteros,
      como se verá mas adelante en este capítulo).
    </para>


    <!--
    The other option for argument lists occurs when you don't know how
    many arguments or what type of arguments you will have; this is
    called a variable argument list. This 'uncertain argument list' is
    represented by ellipses (...). Defining a function with a variable
    argument list is significantly more complicated than defining a
    regular function. You can use a variable argument list for a
    function that has a fixed set of arguments if (for some reason) you
    want to disable the error checks of function prototyping. Because of
    this, you should restrict your use of variable argument lists to C
    and avoid them in C++ (in which, as you'll learn, there are much
    better alternatives). Handling variable argument lists is described
    in the library section of your local C guide.
    -->

    <para>
      La otra opción para las listas de argumentos se produce cuando no
      se sabe cuantos argumentos o qué tipos tendrán los argumentos;
      esto se conoce como <emphasis>lista de argumentos
      variable</emphasis>. Esta <quote>lista incierta de
      argumentos</quote> se representada con puntos suspensivos
      (...). Definir una función con una lista de argumentos variable es
      significativamente más complicado que definir una función
      normal. Se puede utilizar una lista de argumentos variable para
      una función que tiene un grupo de argumentos fijos si (por alguna
      razón) se quiere deshabilitar la comprobación del prototipo
      de función. Por eso, se debe restringir el uso de listas
      de argumentos variables en C y evitarlas en C++ (en el cual, como
      aprenderá, hay alternativas mucho mejores). El manejo de listas
      de argumentos variables se describe en la sección de librerías de
      la documentación de su entorno C particular.
    </para>


    <sect2>
      <!--Function return values-->
      <title>Valores de retorno de las funciones</title>

      <!--
      A C++ function prototype must specify the return value type of the
      function (in C, if you leave off the return value type it defaults
      to int). The return type specification precedes the function
      name. To specify that no value is returned, use the void
      keyword. This will generate an error if you try to return a value
      from the function. Here are some complete function prototypes:
      -->

      <para>
        Un prototipo de función C++ debe especificar el tipo de valor
        devuelto de la función (en C, si no se especifica será por
        defecto un <type>int</type>). La especificación del tipo de
        retorno precede al nombre de la función. Para especificar que no
        se devolverá valor alguno, se utiliza la palabra reservada
        <type>void</type>. Esto provocará un error si se intenta devolver
        un valor desde la función. A continuación hay algunos prototipos
        completos de funciones:
      </para>


<programlisting>
int f1(void); // Devuelve un entero, no tiene argumentos
int f2(); //  igual que f1() en C++ pero no en C Stantard
float f3(float, int, char, double); // Devuelve un float
void f4(void); // No toma argumentos, no devuelve nada
</programlisting>


      <!--
      To return a value from a function, you use the return
      statement. return exits the function back to the point right after
      the function call. If return has an argument, that argument
      becomes the return value of the function. If a function says that
      it will return a particular type, then each return statement must
      return that type. You can have more than one return statement in a
      function definition:
      -->

      <para>
        Para devolver un valor desde una función, se utiliza la
        sentencia <kw>return</kw>. Esta sentencia termina la función y
        salta hasta la sentencia que se halla justo después de la
        llamada a la función. Si <kw>return</kw> tiene un argumento, se
        convierte en el valor de retorno de la función. Si una función
        indica que retornara un tipo en particular, entonces cada
        sentencia <kw>return</kw> debe retornar un valor de ese
        tipo. Puede haber más de una sentencia <kw>return</kw> en una
        definición de función:
      </para>


//: V1C03:Return.cpp


      <!--
      In cfunc(), the first if that evaluates to true exits the
      function via the return statement. Notice that a function
      declaration is not necessary because the function definition
      appears before it is used in main( ), so the compiler knows about
      it from that function definition.
      -->

      <para>
        En <function>cfunc()</function>, el primer <kw>if</kw> que
        comprueba que la condición sea <kw>true</kw> sale de la función
        con la sentencia <kw>return</kw>. Fíjese que la declaración de
        la función no es necesaria puesto que la definición aparece
        antes de ser utilizada en <function>main()</function>, de modo
        que el compilador sabe de su existencia desde dicha definición.
      </para>

    </sect2>

    <sect2>
      <title>Uso de funciones de librerías C</title>

      <!--
      All the functions in your local C function library are available
      while you are programming in C++. You should look hard at the
      function library before defining your own function ? there's a
      good chance that someone has already solved your problem for you,
      and probably given it a lot more thought and debugging.
      -->

      <para>
        Todas las funciones en la librería local de funciones de C están
        disponibles cuando se programa en C++. Se debería buscar bien en
        la librería de funciones antes de definir una propia - hay muchas
        probabilidades de que alguien haya resuelto el problema antes, y
        probablemente haya dedicado más tiempo pensando y depurando.
      </para>

      <!--
      A word of caution, though: many compilers include a lot of extra
      functions that make life even easier and are tempting to use, but
      are not part of the Standard C library. If you are certain you
      will never want to move the application to another platform (and
      who is certain of that?), go ahead ?use those functions and make
      your life easier. If you want your application to be portable, you
      should restrict yourself to Standard library functions. If you
      must perform platform-specific activities, try to isolate that
      code in one spot so it can be changed easily when porting to
      another platform. In C++, platform-specific activities are often
      encapsulated in a class, which is the ideal solution.
      -->

      <para>
        Una advertencia, del mismo modo: muchos compiladores incluyen
        muchas funciones extra que hacen la vida mucho mas fácil y
        resultan tentadoras, pero no son parte de la Librería C
        Estándar. Si está seguro de que jamás deseará portar la
        aplicación a otra plataforma (¿y quién está seguro de eso?),
        adelante -utilice esas funciones y haga su vida más fácil. Si
        desea que la aplicación pueda ser portada, debería ceñirse
        únicamente al uso de funciones de la Librería Estándar. Si
        debe realizar actividades específicas de la plataforma,
        debería intentar aislar este código de tal modo que pueda
        cambiarse fácilmente al migrarlo a otra plataforma. En C++,
        las actividades de una plataforma específica a menudo se
        encapsulan en una clase, que es la solución ideal.
      </para>

      <!--
      The formula for using a library function is as follows: first,
      find the function in your programming reference (many programming
      references will index the function by category as well as
      alphabetically). The description of the function should include a
      section that demonstrates the syntax of the code. The top of this
      section usually has at least one #include line, showing you the
      header file containing the function prototype. Duplicate this
      #include line in your file so the function is properly
      declared. Now you can call the function in the same way it appears
      in the syntax section. If you make a mistake, the compiler will
      discover it by comparing your function call to the function
      prototype in the header and tell you about your error. The linker
      searches the Standard library by default, so that's all you need
      to do: include the header file and call the function.
      -->

      <para>
        La fórmula para usar una librería de funciones es la siguiente:
        primero, encontrar la función en la referencia de programación
        (muchas referencias de programación ordenan las funciones por
        categoría además de alfabéticamente). La descripción de la
        función debería incluir una sección que demuestre la sintaxis
        del código. La parte superior de esta sección tiene al menos una
        línea <kw>#include</kw>, mostrando el fichero principal que
        contiene el prototipo de función. Debe copiar este
        <kw>#include</kw> en su fichero para que la función esté
        correctamente declarada. Ahora puede llamar la función de la
        misma manera que aparece en la sección de sintaxis. Si comete un
        error, el compilador lo descubrirá comparando la llamada a la
        función con el prototipo de la cabecera e informará de dicho
        error. El enlazador busca en la Librería Estándar por defecto,
        de modo que lo único que hay que hacer es: incluir el fichero de
        cabecera y llamar a la función.
      </para>
    </sect2>


    <sect2>
      <!-- Creating your own libraries with the librarian -->
      <title>Creación de librerías propias</title>

      <!--
      You can collect your own functions together into a library. Most
      programming packages come with a librarian that manages groups of
      object modules. Each librarian has its own commands, but the
      general idea is this: if you want to create a library, make a
      header file containing the function prototypes for all the
      functions in your library. Put this header file somewhere in the
      preprocessor's search path, either in the local directory (so it
      can be found by #include 'header') or in the include directory
      (so it can be found by #include <header>). Now take all the object
      modules and hand them to the librarian along with a name for the
      finished library (most librarians require a common extension, such
      as .lib or .a). Place the finished library where the other
      libraries reside so the linker can find it. When you use your
      library, you will have to add something to the command line so the
      linker knows to search the library for the functions you call. You
      must find all the details in your local manual, since they vary
      from system to system.
      -->

      <para>
        Puede reunir funciones propias juntas en una librería. La
        mayoría de paquetes de programación vienen con un
        FIXME:bibliotecario que maneja grupos de módulos objeto. Cada
        FIXME:bibliotecario tiene sus propios comandos, pero la idea
        general es la siguiente: si se desea crear una librería, se debe
        hacer un fichero cabecera que contenga prototipos de todas las
        funciones de la librería. Hay que ubicar este fichero de
        cabecera en alguna parte de la ruta de búsqueda del
        preprocesador, ya sea en el directorio local (de modo que se
        podrá encontrar mediante <code>#include "header"</code>) o bien
        en el directorio <filename>include</filename> (por lo que se
        podrá encontrar mediante <code>#include
        &lt;header&gt;</code>). Luego se han de juntar todos los módulos
        objeto y pasarlos al FIXME:bibliotecario junto con un nombre
        para la librería recién construida (la mayoría de los
        bibliotecarios requieren una extensión común, como por ejemplo
        <filename>.lib</filename> o <filename>.a</filename>). Se ha de
        ubicar la librería completa donde residan todas las demás, de
        manera que el enlazador sabrá buscar esas funciones en dicha
        librería al ser invocadas. Pueden encontrar todos los detalles
        en su documentación particular, ya que pueden variar de un
        sistema a otro.
      </para>
    </sect2>
  </sect1>

  <sect1>
    <!-- Controlling execution  -->
    <title>Control de flujo</title>

    <!--
    This section covers the execution control statements in C++. You
    must be familiar with these statements before you can read and write
    C or C++ code.
    -->

    <para>
      Esta sección cubre las sentencias de control de flujo en C++. Debe
      familiarizarse con estas sentencias antes de que pueda leer o
      escribir código C o C++.
    </para>


    <!--
    C++ uses all of C's execution control statements. These include
    if-else, while, do-while, for, and a selection statement called
    switch. C++ also allows the infamous goto, which will be avoided in
    this book.
    -->

    <para>
      C++ usa todas las sentencias de control de ejecución de C. Esto
      incluye <kw>if-else</kw>, <kw>do-while</kw>, <kw>for</kw>, y una
      sentencia de selección llamada <kw>switch</kw>. C++ también admite
      el infame <kw>goto</kw>, el cual será evitado en este libro.
    </para>

    <sect2>
      <title>Verdadero y falso</title>

      <!--
      All conditional statements use the truth or falsehood of a
      conditional expression to determine the execution path. An example
      of a conditional expression is A == B. This uses the conditional
      operator == to see if the variable A is equivalent to the variable
      B. The expression produces a Boolean true or false (these are
      keywords only in C++; in C an expression is 'true' if it
      evaluates to a nonzero value). Other conditional operators are >,
      <, >=, etc. Conditional statements are covered more fully later in
      this chapter.
      -->

      <para>
        Todas las sentencias condicionales utilizan la veracidad o la
        falsedad de una expresión condicional para determinar el camino
        de ejecución. Un ejemplo de expresión condicional es <code>A ==
        B</code>. Esto utiliza el operador condicional <oper>==</oper>
        para saber si la variable <varname>A</varname> es equivalente a
        la variable <varname>B</varname>. La expresión produce un
        booleano <kw>true</kw> o <kw>false</kw> (estas son palabras
        reservadas sólo en C++; en C una expresión es
        verdadera(<foreignphrase>true</foreignphrase>) si se evalúa con
        un valor diferente de cero). Otros operadores condicionales son
        <oper>&gt;</oper>, <oper>&lt;</oper>, <oper>&gt;=</oper>,
        etc. Las sentencias condicional se tratarán a fondo más
        adelante en este capítulo.
      </para>
    </sect2>

    <sect2>
      <title><kw>if</kw>-<kw>else</kw></title>

      <!--
      The if-else statement can exist in two forms: with or without the
      else. The two forms are:
      -->

      <para>
        La sentencia <kw>if-else</kw> puede existir de dos formas: con o
        sin el <kw>else</kw>. Las dos formas son:
      </para>


<programlisting>
if (expresión)
    sentencia
</programlisting>


      <para>
        ó
      </para>


<programlisting>
if (expresión)
    sentencia
else
    sentencia
</programlisting>


      <!--
      The 'expression' evaluates to true or false. The 'statement'
      means either a simple statement terminated by a semicolon or a
      compound statement, which is a group of simple statements enclosed
      in braces. Any time the word 'statement' is used, it always
      implies that the statement is simple or compound. Note that this
      statement can also be another if, so they can be strung together.
      -->

      <para>
        La <quote>expresión</quote> se evalúa como <kw>true</kw> o
        <kw>false</kw>. La <quote>sentencia</quote> puede ser una simple
        acabada en un punto y coma, o bien una compuesta, lo que no es
        más que un grupo de sentencias simples encerradas entre
        llaves. Siempre que se utiliza la palabra
        <quote>sentencia</quote>, implica que la sentencia es simple o
        compuesta. Tenga en cuenta que dicha sentencia puede ser incluso
        otro <kw>if</kw>, de modo que se pueden anidar.
      </para>


//: V1C03:Ifthen.cpp


      <!--
      It is conventional to indent the body of a control flow statement
      so the reader may easily determine where it begins and ends[30].
      -->

      <para>
        Por convenio se indenta el cuerpo de una sentencia de control de
        flujo, de modo que el lector puede determinar fácilmente donde
        comienza y dónde acaba
	<footnote>
	  <!--
	  Note that all conventions seem to end after the agreement that
	  some sort of indentation take place. The feud between styles
	  of code formatting is unending. See Appendix A for the
	  description of this book's coding style.
	  -->
	  <para>
	    Fíjese en que todas las convenciones parecen acabar estando
	    de acuerdo en que hay que hacer algún tipo de
	    indentación. La pelea entre los estilos de formateo de
	    código no tiene fin. En el Apéndice A se explica el estilo
	    de codificación que se usa en este libro.
	  </para>
	</footnote>.
      </para>
    </sect2>



    <sect2>
      <title><kw>while</kw></title>

      <!--
      while, do-while, and for control looping. A statement repeats
      until the controlling expression evaluates to false. The form of a
      while loop is
      -->

      <para>
        En los bucles de control <kw>while</kw>, <kw>do-while</kw>, y
        <kw>for</kw>, una sentencia se repite hasta que la expresión de
        control sea <kw>false</kw>. La estructura de un bucle
        <kw>while</kw> es:
      </para>


<programlisting>
while(expresión) sentencia
</programlisting>


      <!--
      The expression is evaluated once at the beginning of the loop and
      again before each further iteration of the statement.
      -->

      <para>
        La expresión se evalúa una vez al comienzo del bucle y cada
        vez antes de cada iteración de la sentencia.
      </para>


      <!--
      This example stays in the body of the while loop until you type
      the secret number or press control-C.
      -->

      <para>
        Este ejemplo se mantiene en el cuerpo del bucle <kw>while</kw>
        hasta que introduzca el número secreto o presione <keycombo
        action="press"><keycap>Control</keycap>
        <keycap>C</keycap></keycombo>.
      </para>


//: V1C03:Guess.cpp


      <!--
      The whiles conditional expression is not restricted to a simple
      test as in the example above; it can be as complicated as you like
      as long as it produces a true or false result. You will even see
      code where the loop has no body, just a bare semicolon:
      -->

      <para>
        La expresión condicional del <kw>while</kw> no está restringida
        a una simple prueba como en el ejemplo anterior; puede ser tan
        complicada como se desee siempre y cuando se produzca un
        resultado <kw>true</kw> o <kw>false</kw>. También puede
        encontrar código en el que el bucle no tiene cuerpo, sólo un
        simple punto y coma:
      </para>


<programlisting>
while(/* hacer muchas cosas */)
;
</programlisting>


      <!--
      In these cases, the programmer has written the conditional
      expression not only to perform the test but also to do the work.
      -->

      <para>
        En estos casos, el programador ha escrito la expresión
        condicional no sólo para realizar la evaluación, sino también
        para hacer el trabajo.
      </para>

    </sect2>

    <sect2>
      <title><kw>do-while</kw></title>

      <!--
      The form of do-while is
      -->

      <para>
        El aspecto de <kw>do-while</kw> es
      </para>


<programlisting>
do
    sentencia
while(expresión);
</programlisting>


      <!--
      The do-while is different from the while because the statement
      always executes at least once, even if the expression evaluates to
      false the first time. In a regular while, if the conditional is
      false the first time the statement never executes.
      -->

      <para>
        El <kw>do-while</kw> es diferente del <kw>while</kw> ya que la
        sentencia siempre se ejecuta al menos una vez, aún si la
        expresión resulta <kw>false</kw> la primera vez. En un
        <kw>while</kw> normal, si la condición es falsa la primera vez,
        la sentencia no se ejecuta nunca.
      </para>


      <!--
      If a do-while is used in Guess.cpp, the variable guess does not
      need an initial dummy value, since it is initialized by the cin
      statement before it is tested:
      -->

      <para>
        Si se utiliza un <kw>do-while</kw> en
        <filename>Guess.cpp</filename>, la variable
        <varname>guess</varname> no necesitaría un valor ficticio
        inicial, ya que se inicializa por la sentencia <kw>cin</kw>
        antes de que la variable sea evaluada:
      </para>


//: V1C03:Guess2.cpp


      <!--
      For some reason, most programmers tend to avoid do-while and just
      work with while.
      -->

      <para>
        Por alguna razón, la mayoría de los programadores tienden a
        evitar el <kw>do-while</kw> y se limitan a trabajar con
        <kw>while</kw>.
      </para>
    </sect2>

    <sect2>
      <title><kw>for</kw></title>

      <!--
      A for loop performs initialization before the first
      iteration. Then it performs conditional testing and, at the end of
      each iteration, some form of 'stepping.' The form of the for
      loop is:
      -->

      <para>
        Un bucle <kw>for</kw> realiza una inicialización antes de la
        primera iteración. Luego ejecuta una evaluación condicional y,
        al final de cada iteración, efectúa algún tipo de
        <quote>siguiente paso</quote>. La estructura del bucle
        <kw>for</kw> es:
      </para>



<programlisting>
for(initialización; condición; paso)
    sentencia
</programlisting>

      <!--
      Any of the expressions initialization, conditional, or step may be
      empty. The initialization code executes once at the very
      beginning. The conditional is tested before each iteration (if it
      evaluates to false at the beginning, the statement never
      executes). At the end of each loop, the step executes.

      for loops are usually used for 'counting' tasks:
      -->

      <para>
        Cualquiera de las expresiones de <quote>inicialización</quote>,
        <quote>condición</quote>, o <quote>paso</quote> pueden estar
        vacías. El código de <quote>inicialización</quote> se ejecuta
        una única vez al principio. La expresión
        <quote>condicional</quote> se evalúa antes de cada iteración (si
        se evalúa a <kw>false</kw> desde el principio, el cuerpo del
        bucle nunca llega a ejecutarse). Al final de cada iteración del
        bucle, se ejecuta <quote>paso</quote>.
      </para>

      <para>
        Los bucles <kw>for</kw> se utilizan generalmente para tareas de
	<quote>conteo</quote>:
      </para>


//: V1C03:Charlist.cpp


      <!--
      You may notice that the variable i is defined at the point where
      it is used, instead of at the beginning of the block denoted by
      the open curly brace '{'. This is in contrast to traditional
      procedural languages (including C), which require that all
      variables be defined at the beginning of the block. This will be
      discussed later in this chapter.
      -->

      <para>
        Puede ocurrir que la variable <varname>i</varname> sea definida
        en el punto en el que se utiliza, en vez de al principio del
        bloque delimitado por la apertura de la llave
        <token>{</token>. Esto difiere de los lenguajes procedurales
        tradicionales (incluyendo C), en los que se requiere que todas
        las variables se definan al principio del bloque. Esto se
        discutirá más adelante en este capítulo.
      </para>
    </sect2>

    <sect2>
      <!-- The break and continue keywords -->
      <title>Las palabras reservadas <kw>break</kw> y <kw>continue</kw></title>

      <!--
      Inside the body of any of the looping constructs while, do-while,
      or for, you can control the flow of the loop using break and
      continue. break quits the loop without executing the rest of the
      statements in the loop. continue stops the execution of the
      current iteration and goes back to the beginning of the loop to
      begin a new iteration.
      -->

      <para>
        Dentro del cuerpo de cualquiera de las estructuras de bucle
        <kw>while</kw>, <kw>do-while</kw>, o <kw>for</kw>, se puede
        controlar el flujo del bucle utilizando <kw>break</kw> y
        <kw>continue</kw>. <kw>break</kw> interrumpe el bucle sin
        ejecutar el resto de las sentencias de esa
        iteración. <kw>continue</kw> detiene la ejecución de la
        iteración actual, vuelve al principio del bucle y comienza la
        siguiente iteración.
      </para>

      <!--
      As an example of break and continue, this program is a very
      simple menu system:
      -->

      <para>
        A modo de ejemplo de <kw>break</kw> y <kw>continue</kw>, este
        programa es un menu de sistema muy simple:
      </para>


//: V1C03:Menu.cpp


      <!--
      If the user selects 'q' in the main menu, the break keyword is
      used to quit, otherwise the program just continues to execute
      indefinitely. After each of the sub-menu selections, the continue
      keyword is used to pop back up to the beginning of the while loop.
      -->

      <para>
        Si el usuario selecciona <token>q</token> en el menu principal,
        se utiliza la palabra reservada <kw>break</kw> para salir, de
        otro modo, el programa continúa ejecutándose
        indefinidamente. Después de cada selección de sub-menu, se usa
        la palabra reservada <kw>continue</kw> para volver atrás hasta
        el comienzo del bucle <kw>while</kw>.
      </para>

      <!--
      The while(true) statement is the equivalent of saying 'do this
      loop forever.' The break statement allows you to break out of
      this infinite while loop when the user types a 'q.'
      -->

      <para>
        La sentencia <kw>while(true)</kw> es el equivalente a decir
        <quote>haz este bucle para siempre</quote>.  La sentencia
        <kw>break</kw> permite romper este bucle infinito cuando el
        usuario teclea <token>q</token>.
      </para>
    </sect2>


    <sect2>
      <title><kw>switch</kw></title>

      <!--
      A switch statement selects from among pieces of code based on the
      value of an integral expression. Its form is:
      -->

      <para>
        Una sentencia <kw>switch</kw> selecciona un fragmento de código
        entre varios posibles en base al valor de una expresión
        entera. Su estructura es:
      </para>


<programlisting>
switch(selector) {
case valor-entero1 : sentencia; break;
case valor-entero2 : sentencia; break;
case valor-entero3 : sentencia; break;
case valor-entero4 : sentencia; break;
case valor-entero5 : sentencia; break;
    (...)
default: sentencia;
}
</programlisting>


      <!--
      Selector is an expression that produces an integral value. The
      switch compares the result of selector to each integral value. If
      it finds a match, the corresponding statement (simple or compound)
      executes. If no match occurs, the default statement executes.
      -->

      <para>
        <varname>selector</varname> es una expresión que produce un
        valor entero. El <kw>switch</kw> compara el resultado de
        <varname>selector</varname> para cada valor entero. Si encuentra
        una coincidencia, se ejecutará la sentencia correspondiente (sea
        simple o compuesta). Si no se encuentra ninguna coincidencia se
        ejecutará la sentencia <kw>default</kw>.
      </para>

      <!--
      You will notice in the definition above that each case ends with a
      break, which causes execution to jump to the end of the switch
      body (the closing brace that completes the switch). This is the
      conventional way to build a switch statement, but the break is
      optional. If it is missing, your case 'drops through' to the one
      after it. That is, the code for the following case statements
      execute until a break is encountered. Although you don't usually
      want this kind of behavior, it can be useful to an experienced
      programmer.
      -->

      <para>
        Se puede observar en la definición anterior que cada
        <kw>case</kw> acaba con un <kw>break</kw>, lo que causa que la
        ejecución salte hasta el final del cuerpo del <kw>switch</kw>
        (la llave final que cierra el <kw>switch</kw>). Esta es la forma
        convencional de construir una sentencia <kw>switch</kw>, pero la
        palabra <kw>break</kw> es opcional. Si no se indica, el
        <kw>case</kw> que se ha cumplido <quote>cae</quote> al siguiente
        de la lista. Esto significa, que el código del siguiente
        <kw>case</kw>, se ejecutara hasta que se encuentre un
        <kw>break</kw>. Aunque normalmente no se desea este tipo de
        comportamiento, puede ser de ayuda para un programador
        experimentado.
      </para>

      <!--
      The switch statement is a clean way to implement multi-way
      selection (i.e., selecting from among a number of different
      execution paths), but it requires a selector that evaluates to an
      integral value at compile-time. If you want to use, for example, a
      string object as a selector, it won't work in a switch
      statement. For a string selector, you must instead use a series of
      if statements and compare the string inside the conditional.
      -->

      <para>
        La sentencia <kw>switch</kw> es una manera limpia de implementar
        una selección multi-modo (por ejemplo, seleccionando de entre un
        número de paths de ejecución), pero requiere un selector que
        pueda evaluarse como un entero en el momento de la
        compilación. Si quisiera utilizar, por ejemplo, un objeto
        <kw>string</kw> como selector, no funcionará en una sentencia
        <kw>switch</kw>. Para un selector de tipo <kw>string</kw>, se
        debe utilizar una serie de sentencias <kw>if</kw> y comparar el
        <kw>string</kw> dentro de la condición.
      </para>

      <!--
      The menu example shown above provides a particularly nice example
      of a switch:
      -->

      <para>
        El ejemplo del menu demostrado anteriormente proporciona un
        ejemplo particularmente interesante de un <kw>switch</kw>:
      </para>


//: V1C03:Menu2.cpp


      <!--
      The quit flag is a bool, short for 'Boolean,' which is a type
      you'll find only in C++. It can have only the keyword values true
      or false. Selecting 'q' sets the quit flag to true. The next
      time the selector is evaluated, quit == false returns false so the
      body of the while does not execute.
      -->

      <para>
        El flag <varname>quit</varname> es un <type>bool</type>,
        abreviatura para <quote>booleano</quote>, que es un tipo que
        sólo se encuentra en C++. Puede tener únicamente los valores
        <kw>true</kw> o <kw>false</kw>. Seleccionando <token>q</token>
        se asigna el valor <kw>true</kw> al flag <quote>quit</quote>. La
        próxima vez que el selector sea evaluado, <code>quit ==
        false</code> retornará <kw>false</kw> de modo que el cuerpo del
        bucle <kw>while</kw> no se ejecutará.
      </para>
    </sect2>


    <sect2>
      <!-- Using and misusing goto -->
      <title>Uso y maluso de <kw>goto</kw></title>

      <!--
      The goto keyword is supported in C++, since it exists in C. Using
      goto is often dismissed as poor programming style, and most of the
      time it is. Anytime you use goto, look at your code and see if
      there's another way to do it. On rare occasions, you may discover
      goto can solve a problem that can't be solved otherwise, but
      still, consider it carefully. Here's an example that might make a
      plausible candidate:
      -->

      <para>
        La palabra clave <kw>goto</kw> está soportada en C++, dado que
        existe en C. El uso de <kw>goto</kw> a menudo es considerado
        como un estilo de programación pobre, y la mayor parte de las
        veces lo es. Siempre que se utilice <kw>goto</kw>, se debe
        revisar bien el código para ver si hay alguna otra manera de
        hacerlo. En raras ocasiones, <kw>goto</kw> puede resolver un
        problema que no puede ser resuelto de otra manera, pero, aún
        así, se debe considerar cuidadosamente. A continuación aparece
        un ejemplo que puede ser un candidato plausible:
      </para>


//: V1C03:gotoKeyword.cpp


      <!--
      The alternative would be to set a Boolean that is tested in the
      outer for loop, and then do a break from the inner for
      loop. However, if you have several levels of for or while this
      could get awkward.
      -->

      <para>
        La alternativa sería dar valor a un booleano que sea evaluado en
        el <kw>for</kw> externo, y luego hacer un <kw>break</kw> desde
        el <kw>for</kw> interno. De todos modos, si hay demasiados
        niveles de <kw>for</kw> o <kw>while</kw> esto puede llegar a ser
        pesado.
      </para>
    </sect2>

    <sect2>
      <title>Recursividad</title>

      <!--
      Recursion is an interesting and sometimes useful programming
      technique whereby you call the function that you're in. Of
      course, if this is all you do, you'll keep calling the function
      you're in until you run out of memory, so there must be some way
      to 'bottom out' the recursive call. In the following example,
      this 'bottoming out' is accomplished by simply saying that the
      recursion will go only until the cat exceeds 'Z':[31]
      -->

      <para>
        La recursividad es una técnica de programación interesante y a
        veces útil, en donde se llama a la función desde el cuerpo de la
        propia función. Por supuesto, si eso es todo lo que hace, se
        estaría llamando a la función hasta que se acabase la memoria de
        ejecución, de modo que debe existir una manera de
        <quote>escaparse</quote> de la llamada recursiva. En el
        siguiente ejemplo, esta <quote>escapada</quote> se consigue
        simplemente indicando que la recursión sólo continuará hasta que
        <varname>cat</varname> exceda <token>Z</token>:
	<footnote>
	  <!--
	  Thanks to Kris C. Matson for suggesting this exercise
	  topic.
	  -->
	  <para>
	    Gracias a Kris C. Matson por proponer este ejercicio.
	  </para>
	</footnote>
      </para>


//: V1C03:CatsInHats.cpp


      <!--
      In removeHat(), you can see that as long as cat is less than 'Z',
      removeHat( ) will be called from within removeHat( ), thus
      effecting the recursion. Each time removeHat( ) is called, its
      argument is one greater than the current cat so the argument keeps
      increasing.
      -->

      <para>
        En <function>removeHat()</function>, se puede ver que mientras
        <varname>cat</varname> sea menor que <token>Z</token>,
        <function>removeHat()</function> se llamará a sí misma,
        efectuando así la recursividad. Cada vez que se llama
        <function>removeHat()</function>, su argumento crece en una
        unidad más que el <varname>cat</varname> actual de modo que el
        argumento continúa aumentando.
      </para>

      <!--
      Recursion is often used when evaluating some sort of arbitrarily
      complex problem, since you aren't restricted to a particular
      'size' for the solution ? the function can just keep recursing
      until it's reached the end of the problem.
      -->

      <para>
        La recursividad a menudo se utiliza cuando se evalúa algún tipo
        de problema arbitrariamente complejo, ya que no se restringe la
        solución a ningún tamaño particular - la función puede
        simplemente efectuar la recursividad hasta que se haya alcanzado
        el final del problema.
      </para>
    </sect2>
  </sect1>


  <sect1>
    <!-- Introduction to operators -->
    <title>Introducción a los operadores</title>

    <!--
    You can think of operators as a special type of function (you'll
    learn that C++ operator overloading treats operators precisely that
    way). An operator takes one or more arguments and produces a new
    value. The arguments are in a different form than ordinary function
    calls, but the effect is the same.
    -->

    <para>
      Se pueden ver los operadores como un tipo especial de función
      (aprenderá que en C++ la sobrecarga de operadores los trata
      precisamente de esa forma). Un operador recibe uno o más
      argumentos y produce un nuevo valor. Los argumentos se pasan de
      una manera diferente que en las llamadas a funciones normales,
      pero el efecto es el mismo.
    </para>

    <!--
    From your previous programming experience, you should be reasonably
    comfortable with the operators that have been used so far. The
    concepts of addition (+), subtraction and unary minus (-),
    multiplication (*), division (/), and assignment(=) all have
    essentially the same meaning in any programming language. The full
    set of operators is enumerated later in this chapter.
    -->

    <para>
      Por su experiencia previa en programación, debe estar
      razonablemente cómodo con los operadores que se han
      utilizados. Los conceptos de adición (<oper>+</oper>),
      substracción y resta unaria (<oper>-</oper>), multiplicación
      (<oper>*</oper>), división (<oper>/</oper>), y asignación
      (<oper>=</oper>) tienen todos el mismo significado en cualquier
      lenguaje de programación. El grupo completo de operadores se
      enumera más adelante en este capítulo.
    </para>


    <sect2>
      <!-- Precedence -->
      <title>Precedencia</title>

      <!--
      Operator precedence defines the order in which an expression
      evaluates when several different operators are present. C and C++
      have specific rules to determine the order of evaluation. The
      easiest to remember is that multiplication and division happen
      before addition and subtraction.  After that, if an expression
      isn't transparent to you it probably won't be for anyone reading
      the code, so you should use parentheses to make the order of
      evaluation explicit. For example:
      -->

      <para>
	La precedencia de operadores define el orden en el que se evalúa
	una expresión con varios operadores diferentes. C y C++ tienen
	reglas específicas para determinar el orden de evaluación. Lo
	más fácil de recordar es que la multiplicación y la división se
	ejecutan antes que la suma y la resta. Luego, si una expresión
	no es transparente al programador que la escribe, probablemente
	tampoco lo será para nadie que lea el código, de modo que se
	deben usar paréntesis para hacer explícito el orden de la
	evaluación. Por ejemplo:
      </para>

<programlisting>
A = X + Y - 2/2 + Z;
</programlisting>


      <!--
      has a very different meaning from the same statement with a
      particular grouping of parentheses:
      -->

      <para>
	Tiene un significado muy distinto de la misma expresión pero con
	un configuración de paréntesis particular:
      </para>

<programlisting>
A = X + (Y - 2)/(2 + Z);
</programlisting>


      <!--
      evaluating the result with X = 1, Y = 2, and Z = 3.)
      -->

      <para>
	(Intente evaluar el resultado con X =1, Y = 2, y Z = 3.)
      </para>


    </sect2>

    <sect2>
      <!-- Auto increment and decrement -->
      <title>Auto incremento y decremento</title>


      <!--
      C, and therefore C++, is full of shortcuts. Shortcuts can make
      code much easier to type, and sometimes much harder to
      read. Perhaps the C language designers thought it would be easier
      to understand a tricky piece of code if your eyes didn't have to
      scan as large an area of print.
      -->

      <para>
	C, y por tanto C++, está lleno de atajos. Los atajos pueden hacer
	el código mucho mas fácil de escribir, y a veces más difícil de
	leer. Quizás los diseñadores del lenguaje C pensaron que sería
	más fácil entender un trozo de código  complicado si los ojos no
	tienen que leer una larga línea de letras.
      </para>


      <!--
      One of the nicer shortcuts is the auto-increment and
      auto-decrement operators. You often use these to change loop
      variables, which control the number of times a loop executes.
      -->

      <para>
	Los operadores de auto-incremento y auto-decremento son de los
	mejores atajos. Se utilizan a menudo para modificar las
	variables que controlan el número de veces que se ejecuta un
	bucle.
      </para>


      <!--
      The auto-decrement operator is '- -' and means "decrease by one
      unit."  The auto-increment operator is '++' and means "increase by
      one unit." If A is an int, for example, the expression ++A is
      equivalent to (A = A + 1). Auto-increment and auto-decrement
      operators produce the value of the variable as a result. If the
      operator appears before the variable, (i.e., ++A), the operation
      is first performed and the resulting value is produced. If the
      operator appears after the variable (i.e. A++), the current value
      is produced, and then the operation is performed. For example:
      -->

      <para> El operador de auto-decremento es <oper>--</oper> que
	significa <quote>decrementar de a una unidad</quote>. El
	operador de auto-incremento es <oper>++</oper> que significa
	<quote>incrementar de a una unidad</quote>. Si es un entero, por
	ejemplo, la expresión <code>++A</code> es equivalente a <code>(A
	= A + 1)</code>. Los operadores de auto-incremento y
	auto-decremento producen el valor de la variable como
	resultado. Si el operador aparece antes de la variable (p.ej,
	<code>++A</code>), la operación se ejecuta primero y después se
	produce el valor resultante. Si el operador aparece a
	continuación de la variable (p.ej, <code>A++</code>), primero se
	produce el valor actual, y luego se realiza la operación. Por
	ejemplo:
      </para>


//: V1C03:AutoIncrement.cpp


      <!--
      If you've been wondering about the name "C++," now you understand. It
      implies "one step beyond C."
      -->

      <para>
	Si se ha estado preguntando acerca del nombre
	<quote>C++</quote>, ahora lo entenderá. Significa <quote>un
	paso más allá de C</quote>
	<footnote>
	  <para>
	    (N. de T.) ...aunque se evalúa como <quote>C</quote>.
	  </para>
	</footnote>
      </para>

    </sect2>
  </sect1>



  <sect1>
    <title>Introducción a los tipos de datos</title>

    <!--
    Data types define the way you use storage (memory) in the programs
    you write. By specifying a data type, you tell the compiler how to
    create a particular piece of storage, and also how to manipulate
    that storage.
    -->

    <para>
      Los <emphasis>tipos de datos</emphasis> definen el modo en que se
      usa el espacio (memoria) en los programas.  Especificando un tipo
      de datos, está indicando al compilador como crear un espacio de
      almacenamiento en particular, y también como manipular este
      espacio.
    </para>

    <!--
    Data types can be built-in or abstract. A built-in data type is one
    that the compiler intrinsically understands, one that is wired
    directly into the compiler. The types of built-in data are almost
    identical in C and C++. In contrast, a user-defined data type is one
    that you or another programmer create as a class. These are commonly
    referred to as abstract data types. The compiler knows how to handle
    built-in types when it starts up; it "learns" how to handle abstract
    data types by reading header files containing class declarations
    (you'll learn about this in later chapters).
    -->

    <para>
      Los tipos de datos pueden estar predefinidos o abstractos. Un tipo
      de dato predefinido es intrínsecamente comprendido por el
      compilador. Estos tipos de datos son casi idénticos en C y C++. En
      contraste, un tipo de datos definido por el usuario es aquel que
      usted o cualquier otro programador crea como una clase. Estos se
      denominan comúnmente tipos de datos abstractos. El compilador sabe
      como manejar tipos predefinidos por si mismo; y
      <quote>aprende</quote> como manejar tipos de datos abstractos
      leyendo los ficheros de cabeceras que contienen las declaraciones
      de las clases (esto se verá con más detalle en los siguientes
      capítulos).
    </para>



    <sect2>
      <title>Tipos predefinidos básicos</title>

      <!--
      The Standard C specification for built-in types (which C++
      inherits) doesn't say how many bits each of the built-in types
      must contain. Instead, it stipulates the minimum and maximum
      values that the built-in type must be able to hold. When a machine
      is based on binary, this maximum value can be directly translated
      into a minimum number of bits necessary to hold that
      value. However, if a machine uses, for example, binary-coded
      decimal (BCD) to represent numbers, then the amount of space in
      the machine required to hold the maximum numbers for each data
      type will be different. The minimum and maximum values that can be
      stored in the various data types are defined in the system header
      files limits.h and float.h (in C++ you will generally #include
      climits> and cfloat> instead).
      -->


      <para>
        La especificación del Estándar C para los tipos predefinidos
        (que hereda C++) no indica cuantos bits debe contener cada uno
        de ellos. En vez de eso, estipula el mínimo y máximo valor que
        cada tipo es capaz de almacenar. Cuando una máquina se basa en
        sistema binario, este valor máximo puede ser directamente
        traducido a un numero mínimo necesario de bits para alojar ese
        valor. De todos modos, si una maquina usa, por ejemplo, el
        código binario decimal (BCD) para representar los números,
        entonces el espacio requerido para alojar el máximo número para
        cada tipo de datos será diferente. El mínimo y máximo valor que
        se puede almacenar en los distintos tipos de datos se define en
        los ficheros de cabeceras del sistema
        <filename>limits.h</filename> y <filename>float.h</filename> (en
        C++ normalmente será <code>#include &lt;climits></code> y
        <code>&lt;cfloat></code>).
      </para>


      <!--
      C and C++ have four basic built-in data types, described here for
      binary-based machines. A char is for character storage and uses a
      minimum of 8 bits (one byte) of storage, although it may be
      larger. An int stores an integral number and uses a minimum of two
      bytes of storage. The float and double types store floating-point
      numbers, usually in IEEE floating-point format. float is for
      single-precision floating point and double is for double-precision
      floating point.
      -->

      <para>
        C y C++ tienen cuatro tipos predefinidos básicos, descritos aquí
        para máquinas basadas en sistema binario. Un <type>char</type>
        es para almacenar caracteres y utiliza un mínimo de 8 bits (un
        byte) de espacio, aunque puede ser mas largo. Un
        <type>int</type> almacena un número entero y utiliza un mínimo
        de dos bytes de espacio. Los tipos <type>float</type> y el
        <type>double</type> almacenan números con coma flotante,
        usualmente en formato IEEE. el <type>float</type> es para
        precisión simple y el <type>double</type> es para doble
        precisión.
      </para>


      <!--
      As mentioned previously, you can define variables anywhere in
      a scope, and you can define and initialize them at the same
      time. Here's how to define variables using the four basic data
      types:
      -->

      <para>
        Como se ha mencionado previamente, se pueden definir variables
        en cualquier sitio en un ámbito determinado, y puede definirlas
        e inicializarlas al mismo tiempo.  A continuación se indica cómo
        definir variables utilizando los cuatro tipos básicos de datos:
      </para>


//: V1C03:Basic.cpp



      <!--
      The first part of the program defines variables of the four
      basic data types without initializing them. If you don't
      initialize a variable, the Standard says that its contents are
      undefined (usually, this means they contain garbage). The second
      part of the program defines and initializes variables at the same
      time (it's always best, if possible, to provide an initialization
      value at the point of definition). Notice the use of exponential
      notation in the constant 6e-4, meaning "6 times 10 to the minus
      fourth power."
      -->

      <para>
        La primera parte del programa define variables de los cuatro
        tipos básicos sin inicializarlas. Si no se inicializa una
        variable, el Estándar dice que su contenido es indefinido
        (normalmente, esto significa que contienen basura). La segunda
        parte del programa define e inicializa variables al mismo tiempo
        (siempre es mejor, si es posible, dar un valor inicial en el
        momento de la definición). Note que el uso de notación
        exponencial en la contante 6e-4, significa <quote>6 por 10
        elevado a -4</quote>.
      </para>

    </sect2>

    <sect2>
      <!-- bool, true, & false -->
      <title>booleano, verdadero y falso</title>

      <!--
      Before bool became part of Standard C++, everyone tended to use
      different techniques in order to produce Boolean-like
      behavior. These produced portability problems and could introduce
      subtle errors.
      -->

      <para>
        Antes de que <type>bool</type> se convirtiese en parte del
        Estándar C++, todos tendían a utilizar diferentes técnicas para
        producir comportamientos similares a los booleanos. Esto produjo
        problemas de portabilidad y podían acarrear errores sutiles.
      </para>


      <!--
      The Standard C++ bool type can have two states expressed by the
      built-in constants true (which converts to an integral one) and
      false (which converts to an integral zero). All three names are
      keywords. In addition, some language elements have been adapted:
      -->

      <para>
        El tipo <type>bool</type> del Estándar C++ puede tener dos
        estados expresados por las constantes predefinidas <kw>true</kw>
        (lo que lo convierte en el entero 1) y <kw>false</kw> (lo que lo
        convierte en el entero 0). Estos tres nombres son palabras
        reservadas. Además, algunos elementos del lenguaje han sido
        adaptados:
      </para>


     <table>
	<!-- TABLA  -->
	<title>Expresiones que utilizan booleanos</title>

	<tgroup cols="2">
	  <thead>
	    <row>
	      <entry>Elemento</entry>
	      <entry>Uso con booleanos</entry>
	    </row>
	  </thead>
	  <tbody>
	    <row>
	      <entry>&amp;&amp; || !</entry>
	      <entry>
		Toman argumentos booleanos y producen valores
		<type>bool</type>
	      </entry>
	    </row>
	    <row>
	      <entry>&lt; > &lt;= >= == !=</entry>
	      <entry>
		Producen resultados <type>bool</type>
	      </entry>
	    </row>
	    <row>
	      <entry>
		<kw>if</kw>, <kw>for</kw>, <kw>while</kw>, <kw>do</kw>
	      </entry>
	      <entry>
		Las expresiones condicionales se convierten en
		valores <type>bool</type>
	      </entry>
	    </row>
	    <row>
	      <entry>?:</entry>
	      <entry>
		El primer operando se convierte a un valor
		<type>bool</type>
	      </entry>
	    </row>
	  </tbody>
	</tgroup>
      </table>


      <!--
      Because there's a lot of existing code that uses an int to
      represent a flag, the compiler will implicitly convert from an int
      to a bool (nonzero values will produce true while zero values
      produce false). Ideally, the compiler will give you a warning as a
      suggestion to correct the situation.
      -->

      <para>
        Como hay mucho código existente que utiliza un <type>int</type>
        para representar una bandera, el compilador lo convertirá
        implícitamente de <type>int</type> a <type>bool</type> (los
        valores diferentes de cero producirán <kw>true</kw>, mientras
        que los valores cero, producirán <kw>false</kw>). Idealmente, el
        compilador le dará un aviso como una sugerencia para corregir la
        situación.
      </para>


      <!--
      An idiom that falls under "poor programming style" is the use of
      ++ to set a flag to true. This is still allowed, but deprecated,
      which means that at some time in the future it will be made
      illegal. The problem is that you're making an implicit type
      conversion from bool to int, incrementing the value (perhaps
      beyond the range of the normal bool values of zero and one), and
      then implicitly converting it back again.
      -->

      <para>
        Un modismo que se considera <quote>estilo de programación
        pobre</quote> es el uso de <oper>++</oper> para asignar a una
        bandera el valor <kw>true</kw>. Esto aún se permite, pero está
        obsoleto, lo que implica que en el futuro será ilegal. El
        problema es que se está haciendo una conversión implícita de un
        <type>bool</type> a un <type>int</type>, incrementando el valor
        (quizá más allá del rango de valores booleanos cero y uno), y
        luego implícitamente convirtiéndolo otra vez a
        <type>bool</type>.
      </para>


      <!--
      Pointers (which will be introduced later in this chapter)
      will also be automatically converted to bool when necessary.
      -->

      <para>
        Los punteros (que se describen más adelante en este capitulo)
        también se convierten automáticamente a <type>bool</type> cuando
        es necesario.
      </para>
    </sect2>


<!-- a partir de aquí falta comprobar el formato respecto al original -->


    <sect2>
      <title>Especificadores</title>

      <!--
      Specifiers modify the meanings of the basic built-in types and
      expand them to a much larger set. There are four specifiers: long,
      short, signed, and unsigned.
      -->

      <para>
        Los especificadores modifican el significado de los tipos
        predefinidos básicos y los expanden a un conjunto más
        grande. Hay cuatro especificadores: <kw>long</kw>,
        <kw>short</kw>, <kw>signed</kw> y <kw>unsigned</kw>.
      </para>

      <!--
      long and short modify the maximum and minimum values that a
      data type will hold. A plain int must be at least the size of a
      short. The size hierarchy for integral types is: short int, int,
      long int. All the sizes could conceivably be the same, as long as
      they satisfy the minimum/maximum value requirements. On a machine
      with a 64-bit word, for instance, all the data types might be 64
      bits.
      -->

      <para>
        <kw>long</kw> y <kw>short</kw> modifican los valores máximos y
        mínimos que un tipo de datos puede almacenar. Un
        <type>int</type> plano debe tener al menos el tamaño de un
        <type>short</type>. La jerarquía de tamaños para tipos enteros
        es: <type>short int</type>, <type>int</type>, <type>long
        int</type>.  Todos pueden ser del mismo tamaño, siempre y cuando
        satisfagan los requisitos de mínimo/máximo. En una maquina
        con una palabra de 64 bits, por defecto, todos los tipos de
        datos podrían ser de 64 bits.
      </para>


      <!--
      The size hierarchy for floating point numbers is: float, double,
      and long double. "long float" is not a legal type. There are no
      short floating-point numbers.
      -->

      <para>
        La jerarquía de tamaño para los números en coma flotante es:
        <type>float</type>, <type>double</type> y <type>long
        double</type>. <quote>long float</quote> no es un tipo
        válido. No hay números en coma flotantes de tamaño
        <kw>short</kw>.
      </para>

      <!--
      The signed and unsigned specifiers tell the compiler how to
      use the sign bit with integral types and characters
      (floating-point numbers always contain a sign). An unsigned number
      does not keep track of the sign and thus has an extra bit
      available, so it can store positive numbers twice as large as the
      positive numbers that can be stored in a signed number. signed is
      the default and is only necessary with char; char may or may not
      default to signed. By specifying signed char, you force the sign
      bit to be used.
      -->

      <para>
        Los especificadores <kw>signed</kw> y <kw>unsigned</kw> indican
        al compilador cómo utilizar el bit del signo con los tipos
        enteros y los caracteres (los números de coma flotante siempre
        contienen un signo). Un número <kw>unsigned</kw> no guarda el
        valor del signo y por eso tiene un bit extra disponible, de modo
        que puede guardar el doble de números positivos que pueden
        guardarse en un número <kw>signed</kw>. <kw>signed</kw> se
        supone por defecto y sólo es necesario con <type>char</type>,
        <type>char</type> puede ser o no por defecto un
        <kw>signed</kw>. Especificando <type>signed char</type>, se está
        forzando el uso del bit del signo.
      </para>

      <!--
      The following example shows the size of the data types in bytes by
      using the sizeof operator, introduced later in this chapter:
      -->

      <para>
        El siguiente ejemplo muestra el tamaño de los tipos de datos en
        bytes utilizando el operador <oper>sizeof</oper>, descripto más
        adelante en ese capítulo:
      </para>


//: V1C03:Specify.cpp


      <!--
      Be aware that the results you get by running this program will
      probably be different from one machine/operating system/compiler
      to the next, since (as mentioned previously) the only thing that
      must be consistent is that each different type hold the minimum
      and maximum values specified in the Standard.
      -->

      <para>
        Tenga en cuenta que es probable que los resultados que se
        consiguen ejecutando este programa sean diferentes de una
        maquina/sistema operativo/compilador a otro, ya que (como se
        mencionaba anteriormente) lo único que ha de ser consistente es
        que cada tipo diferente almacene los valores mínimos y máximos
        especificados en el Estándar.
      </para>

      <!--
      When you are modifying an int with short or long, the keyword int
      is optional, as shown above.
      -->

      <para>
        Cuando se modifica un <type>int</type> con <kw>short</kw> o
        <kw>long</kw>, la palabra reservada <type>int</type> es
        opcional, como se muestra a continuación.
      </para>
    </sect2>


    <sect2>
      <!-- Introduction to pointers -->
      <title>Introducción a punteros</title>

      <!--
      Whenever you run a program, it is first loaded (typically
      from disk) into the computer's memory. Thus, all elements of your
      program are located somewhere in memory. Memory is typically laid
      out as a sequential series of memory locations; we usually refer
      to these locations as eight-bit bytes but actually the size of
      each space depends on the architecture of the particular machine
      and is usually called that machine's word size. Each space can be
      uniquely distinguished from all other spaces by its address. For
      the purposes of this discussion, we'll just say that all machines
      use bytes that have sequential addresses starting at zero and
      going up to however much memory you have in your computer.
      -->

      <para>
        Siempre que se ejecuta un programa, se carga primero
        (típicamente desde disco) a la memoria del ordenador. De este
        modo, todos los elementos del programa se ubican en algún lugar
        de la memoria. La memoria se representa normalmente como series
        secuenciales de posiciones de memoria; normalmente se hace
        referencia a estas localizaciones como bytes de ocho bits, pero
        realmente el tamaño de cada espacio depende de la arquitectura
        de cada máquina particular y se llamada normalmente tamaño de
        palabra de la máquina. Cada espacio se puede distinguir
        unívocamente de todos los demás espacios por su dirección. Para
        este tema en particular, se establecerá que todas las máquinas
        usan bytes que tienen direcciones secuenciales, comenzando en
        cero y subiendo hasta la cantidad de memoria que posea la
        máquina.
      </para>

      <!--
      Since your program lives in memory while it's being run, every element
      of your program has an address. Suppose we start with a simple program:
      -->

      <para>
	Como el programa reside en memoria mientras se está ejecutando,
	cada elemento de dicho programa tiene una dirección. Suponga que
	empezamos con un programa simple:
      </para>


//: V1C03:YourPets1.cpp



      <!--
      Each of the elements in this program has a location in storage when the
      program is running. Even the function occupies storage. As you'll see,
      it turns out that what an element is and the way you define it usually
      determines the area of memory where that element is placed.
      -->

      <para>
        Cada uno de los elementos de este programa tiene una
        localización en memoria mientras el programa se está
        ejecutando. Incluso las funciones ocupan espacio. Como verá,
        se da por sentado que el tipo de un elemento y la forma
        en que se define determina normalmente el área de memoria en la
        que se ubica dicho elemento.
      </para>


      <!--
      There is an operator in C and C++ that will tell you the address
      of an element. This is the '&amp;' operator. All you do is precede
      the identifier name with '&' and it will produce the address of
      that identifier.  YourPets1.cpp can be modified to print out the
      addresses of all its elements, like this:
      -->

      <para>
	Hay un operador en C y C++ que permite averiguar la dirección de
	un elemento. Se trata del operador <oper>&amp;</oper>. Sólo hay
	que anteponer el operador <oper>&amp;</oper> delante del nombre
	identificador y obtendrá la dirección de ese identificador. Se
	puede modificar <filename>YourPets1.cpp</filename> para mostrar
	las direcciones de todos sus elementos, del siguiente modo:
      </para>


//: V1C03:YourPets2.cpp


      <!--
      The (long) is a cast. It says "Don't treat this as if it's normal
      type, instead treat it as a long." The cast isn't essential, but
      if it wasn't there, the addresses would have been printed out in
      hexadecimal instead, so casting to a long makes things a little
      more readable.
      -->

      <para>
	El <code>(long)</code> es una molde. Indica <quote>No tratar
	como su tipo normal, sino como un <type>long</type></quote>. El
	molde no es esencial, pero si no existiese, las direcciones
	aparecerían en hexadecimal, de modo que el moldeado a
	<type>long</type> hace las cosas más legibles.
      </para>

      <!--
      The results of this program will vary depending on your computer, OS,
      and all sorts of other factors, but it will always give you some
      interesting insights. For a single run on my computer, the results
      looked like this:
      -->

      <para>
	Los resultados de este programa variarán dependiendo del
	computador, del sistema operativo, y de muchos otros tipos de
	factores, pero siempre darán un resultado interesante. Para una
	única ejecución en mi computador, los resultados son como estos:
      </para>


<programlisting>
f(): 4198736
dog: 4323632
cat: 4323636
bird: 4323640
fish: 4323644
i: 6684160
j: 6684156
k: 6684152
</programlisting>


      <!--
      You can see how the variables that are defined inside main( )
      are in a different area than the variables defined outside of
      main( ); you'll understand why as you learn more about the
      language. Also, f( ) appears to be in its own area; code is
      typically separated from data in memory.
      -->

      <para>
	Se puede apreciar como las variables que se han definido dentro
	de <function>main()</function> están en un área distinta que las
	variables definidas fuera de <function>main()</function>;
	entenderá el porque cuando se profundice más en el
	lenguaje. También, <function>f()</function> parece estar en su
	propia área; el código normalmente se separa del resto de los
	datos en memoria.
      </para>

      <!--
      Another interesting thing to note is that variables defined
      one right after the other appear to be placed contiguously in
      memory. They are separated by the number of bytes that are
      required by their data type.  Here, the only data type used is
      int, and cat is four bytes away from dog, bird is four bytes away
      from cat, etc. So it would appear that, on this machine, an int is
      four bytes long.
      -->

      <para>
	Otra cosa a tener en cuenta es que las variables definidas una a
	continuación de la otra parecen estar ubicadas de manera
	contigua en memoria. Están separadas por el número de bytes
	requeridos por su tipo de dato. En este programa el único tipo
	de dato utilizado es el <type>int</type>, y la variable
	<varname>cat</varname> está separada de <varname>dog</varname>
	por cuatro bytes, <varname>bird</varname> está separada por
	cuatro bytes de <varname>cat</varname>, etc. De modo que en el
	computador en que ha sido ejecutado el programa, un entero ocupa
	cuatro bytes.
      </para>

      <!--
      Other than this interesting experiment showing how memory is
      mapped out, what can you do with an address? The most important
      thing you can do is store it inside another variable for later
      use. C and C++ have a special type of variable that holds an
      address. This variable is called a pointer.
      -->

      <para>
	¿Qué se puede hacer con las direcciones de memoria, además de
	este interesante experimento de mostrar cuanta memoria ocupan?
	Lo más importante que se puede hacer es guardar esas direcciones
	dentro de otras variables para su uso posterior. C y C++ tienen
	un tipo de variable especial para guardar una dirección. Esas
	variables se llaman <emphasis>punteros</emphasis>.
      </para>


<!-- FIXME: Por añadir el formateado original -->

      <!--
      The operator that defines a pointer is the same as the one used for
      multiplication: '*'. The compiler knows that it isn't multiplication
      because of the context in which it is used, as you will see.
      -->

      <para>
	El operador que define un puntero es el mismo que se utiliza
	para la multiplicación: <token>*</token>. El compilador sabe que
	no es una multiplicación por el contexto en el que se usa, tal
	como podrá comprobar.
      </para>

      <!--
      When you define a pointer, you must specify the type of variable
      it points to. You start out by giving the type name, then instead
      of immediately giving an identifier for the variable, you say
      "Wait, it's a pointer" by inserting a star between the type and
      the identifier. So a pointer to an int looks like this:
      -->

      <para>
	Cuando se define un puntero, se debe especificar el tipo de
	variable al que apunta. Se comienza dando el nombre de dicho
	tipo, después en lugar de escribir un identificador para la
	variable, usted dice <quote>Espera, esto es un puntero</quote>
	insertando un asterisco entre el tipo y el identificador. De
	modo que un puntero a <type>int</type> tiene este aspecto:
      </para>


<programlisting>
int* ip; // ip apunta a una variable int
</programlisting>


      <!--
      The association of the '*' with the type looks sensible and reads
      easily, but it can actually be a bit deceiving. Your inclination
      might be to say "intpointer" as if it is a single discrete
      type. However, with an int or other basic data type, it's possible
      to say:
      -->

      <para>
	La asociación del <token>*</token> con el tipo parece práctica y
	legible, pero puede ser un poco confusa. La tendencia podría ser
	decir <quote>puntero-entero</quote> como un si fuese un tipo
	simple. Sin embargo, con un <type>int</type> u otro tipo de
	datos básico, se puede decir:
      </para>


<programlisting>
int a, b, c;
</programlisting>


      <!--
      whereas with a pointer, you'd like to say:
      -->

      <para>
	así que con un puntero, diría:
      </para>


<programlisting>
int* ipa, ipb, ipc;
</programlisting>


      <!--
      C syntax (and by inheritance, C++ syntax) does not allow such
      sensible expressions. In the definitions above, only ipa is a
      pointer, but ipb and ipc are ordinary ints (you can say that "*
      binds more tightly to the identifier"). Consequently, the best
      results can be achieved by using only one definition per line; you
      still get the sensible syntax without the confusion:
      -->

      <para>
	La sintaxis de C (y por herencia, la de C++) no permite
	expresiones tan cómodas. En las definiciones anteriores, sólo
	<varname>ipa</varname> es un puntero, pero
	<varname>ipb</varname> e <varname>ipc</varname> son
	<type>ints</type> normales (se puede decir que
	<quote><oper>*</oper> está mas unido al
	identificador</quote>). Como consecuencia, los mejores resultados
	se pueden obtener utilizando sólo una definición por línea; y
	aún se conserva una sintaxis cómoda y sin la confusión:
      </para>


<programlisting>
int* ipa;
int* ipb;
int* ipc;
</programlisting>


      <!--
      Since a general guideline for C++ programming is that you should
      always initialize a variable at the point of definition, this form
      actually works better. For example, the variables above are not
      initialized to any particular value; they hold garbage. It's much
      better to say something like:
      -->

      <para>
	Ya que una pauta de programación de C++ es que siempre se debe
	inicializar una variable al definirla, realmente este modo
	funciona mejor. Por ejemplo, Las variables anteriores no se
	inicializan con ningún valor en particular; contienen basura. Es
	más fácil decir algo como:
      </para>


<programlisting>
int a = 47;
int* ipa = &amp;a;
</programlisting>


      <!-- Now both a and ipa have been initialized, and ipa holds the
      address of a.  -->

      <para>
	Ahora tanto <varname>a</varname> como <varname>ipa</varname>
	están inicializadas, y <varname>ipa</varname> contiene la
	dirección de <varname>a</varname>.
      </para>


      <!--
      Once you have an initialized pointer, the most basic thing you can
      do with it is to use it to modify the value it points to. To
      access a variable through a pointer, you dereference the pointer
      using the same operator that you used to define it, like this:
      -->

      <para>
	Una vez que se inicializa un puntero, lo más básico que se puede
	hacer con Él es utilizarlo para modificar el valor de lo que
	apunta. Para acceder a la variable a través del puntero, se
	<emphasis>dereferencia</emphasis> el puntero utilizando el mismo
	operador que se usó para definirlo, como sigue:
      </para>


<programlisting>
*ipa = 100;
</programlisting>


      <!--
        Now a contains the value 100 instead of 47.
      -->

      <para>
	Ahora <varname>a</varname> contiene el valor 100 en vez de 47.
      </para>

      <!--
      These are the basics of pointers: you can hold an address, and you
      can use that address to modify the original variable. But the
      question still remains: why do you want to modify one variable
      using another variable as a proxy?
      -->

      <para>
	Estas son las normas básicas de los punteros: se puede guardar
	una dirección, y se puede utilizar dicha dirección para
	modificar la variable original. Pero la pregunta aún
	permanece: ¿por qué se querría cambiar una variable utilizando
	otra variable como intermediario?
      </para>

      <!--
      For this introductory view of pointers, we can put the answer into two
      broad categories:
      -->

      <para>
	Para esta visión introductoria a los punteros, podemos dividir la
	respuesta en dos grandes categorías:
      </para>


      <orderedlist>
	<listitem>
	  <!--
	  To change "outside objects" from within a function. This
	  is perhaps the most basic use of pointers, and it will be
	  examined here.  -->
  	  <para>
	    Para cambiar <quote>objetos externos</quote> desde dentro de
	    una función. Esto es quizás el uso más básico de los
	    punteros, y se examinará más adelante.
	  </para>
	</listitem>
	<listitem>
	  <!--
	  2. To achieve many other clever programming techniques,
	  which you'll learn about in portions of the rest of the book.
	  -->
	  <para>
	    Para conseguir otras muchas técnicas de programación
	    ingeniosas, sobre las que aprenderá en el resto del libro.
	  </para>
	</listitem>
      </orderedlist>
    </sect2>


    <sect2>
      <!-- Modifying the outside object -->
      <title>Modificar objetos externos</title>


      <!--
      Ordinarily, when you pass an argument to a function, a copy of that
      argument is made inside the function. This is referred to as
      pass-by-value. You can see the effect of pass-by-value in the
      following program:
      -->

      <para>
        Normalmente, cuando se pasa un argumento a una función, se hace
        una copia de dicho argumento dentro de la función. Esto se llama
        <emphasis>paso-por-valor</emphasis>. Se puede ver el efecto de
        un paso-por-valor en el siguiente programa:
      </para>


//: V1C03:PassByValue.cpp


      <!--
        In f( ), a is a local variable, so it exists only for the duration of
        the function call to f( ). Because it's a function argument, the value
        of a is initialized by the arguments that are passed when the function
        is called; in main( ) the argument is x, which has a value of 47, so
        this value is copied into a when f( ) is called.
      -->

      <para>
	En <function>f()</function>, <varname>a</varname> es una
	variable local, de modo que existe únicamente mientras dura la
	llamada a la función <function>f()</function>. Como es un
	argumento de una función, el valor de <varname>a</varname> se
	inicializa mediante los argumentos que se pasan en la invocación
	de la función; en <function>main()</function> el argumento es
	<varname>x</varname>, que tiene un valor 47, de modo que el
	valor es copiado en <varname>a</varname> cuando se llama a
	<function>f()</function>.
      </para>

      <!--
      When you run this program you'll see:
      -->

      <para>
	Cuando ejecute el programa verá:
      </para>


<screen>
x = 47
a = 47
a = 5
x = 47
</screen>


      <!--
      Initially, of course, x is 47. When f( ) is called, temporary
      space is created to hold the variable a for the duration of the
      function call, and a is initialized by copying the value of x,
      which is verified by printing it out. Of course, you can change
      the value of a and show that it is changed. But when f( ) is
      completed, the temporary space that was created for a disappears,
      and we see that the only connection that ever existed between a
      and x happened when the value of x was copied into a.
      -->

      <para>
	Por supuesto, inicialmente <varname>x</varname> es 47. Cuando se
	llama <function>f()</function>, se crea un espacio temporal para
	alojar la variable <varname>a</varname> durante la ejecución de
	la función, y el valor de <varname>x</varname> se copia a
	<varname>a</varname>, el cual es verificado mostrándolo por
	pantalla. Se puede cambiar el valor de <varname>a</varname> y
	demostrar que ha cambiado. Pero cuando <function>f()</function>
	termina, el espacio temporal que se había creado para
	<varname>a</varname> desaparece, y se puede observar que la
	única conexión que existía entre <varname>a</varname> y
	<varname>x</varname> ocurrió cuando el valor de
	<varname>x</varname> se copió en <varname>a</varname>.
      </para>


      <!--
      When you're inside f( ), x is the outside object (my terminology),
      and changing the local variable does not affect the outside
      object, naturally enough, since they are two separate locations in
      storage. But what if you do want to modify the outside object?
      This is where pointers come in handy. In a sense, a pointer is an
      alias for another variable.  So if we pass a pointer into a
      function instead of an ordinary value, we are actually passing an
      alias to the outside object, enabling the function to modify that
      outside object, like this:
      -->

      <para>
	Cuando está dentro de <function>f()</function>,
	<varname>x</varname> es el <emphasis>objeto externo</emphasis>
	(mi terminología), y cambiar el valor de la variable local no
	afecta al objeto externo, lo cual es bastante lógico, puesto que
	son dos ubicaciones separadas en la memoria. Pero ¿y si quiere
	modificar el objeto externo? Aquí es donde los punteros entran
	en acción. En cierto sentido, un puntero es un alias de otra
	variable. De modo que si a una función se le pasa un puntero en
	lugar de un valor ordinario, se está pasando de hecho un alias
	del objeto externo, dando la posibilidad a la función de que
	pueda modificar el objeto externo, tal como sigue:
      </para>


//: V1C03:PassAddress.cpp


      <!--
      Now f( ) takes a pointer as an argument and dereferences the pointer
      during assignment, and this causes the outside object x to be modified.
      The output is:
      -->

      <para>
	Ahora <function>f()</function> toma el puntero como un argumento
	y dereferencia el puntero durante la asignación, lo que modifica
	el objeto externo <varname>x</varname>. La salida es:
      </para>


<screen>
x = 47
&amp;x = 0065FE00
p = 0065FE00
*p = 47
p = 0065FE00
x = 5
</screen>


      <!--
      Notice that the value contained in pis the same as the address of
      x - the pointer p does indeed point to x. If that isn't convincing
      enough, when p is dereferenced to assign the value 5, we see that
      the value of x is now changed to 5 as well.
      -->

      <para>
	Tenga en cuenta que el valor contenido en <varname>p</varname>
	es el mismo que la dirección de <varname>x</varname> - el
	puntero <varname>p</varname> de hecho apunta a
	<varname>x</varname>. Si esto no es suficientemente convincente,
	cuando <varname>p</varname> es dereferenciado para asignarle el
	valor 5, se ve que el valor de <varname>x</varname> cambia a 5
	también.
      </para>

      <!--
      Thus, passing a pointer into a function will allow that function
      to modify the outside object. You'll see plenty of other uses for
      pointers later, but this is arguably the most basic and possibly
      the most common use.
      -->

      <para>
	De ese modo, pasando un puntero a una función le permitirá a esa
	función modificar el objeto externo. Se verán muchos otros usos
	de los punteros más adelante, pero podría decirse que éste es el
	más básico y posiblemente el más común.
      </para>
    </sect2>


   <sect2>
      <!-- Introduction to C++ references -->
      <title>Introducción a las referencias de C++</title>

      <!--
      Pointers work roughly the same in C and in C++, but C++ adds an
      additional way to pass an address into a function. This is
      pass-by-reference and it exists in several other programming
      languages so it was not a C++ invention.
      -->

      <para>
	Los punteros funcionan más o menos igual en C y en C++, pero C++
	añade un modo adicional de pasar una dirección a una función. Se
	trata del <emphasis>paso-por-referencia</emphasis> y existe en
	otros muchos lenguajes, de modo que no es una invención de C++.
      </para>

      <!--
      Your initial perception of references may be that they are
      unnecessary, that you could write all your programs without
      references. In general, this is true, with the exception of a few
      important places that you'll learn about later in the book. You'll
      also learn more about references later, but the basic idea is the
      same as the demonstration of pointer use above: you can pass the
      address of an argument using a reference.  The difference between
      references and pointers is that calling a function that takes
      references is cleaner, syntactically, than calling a function that
      takes pointers (and it is exactly this syntactic difference that
      makes references essential in certain situations). If
      PassAddress.cpp is modified to use references, you can see the
      difference in the function call in main( ):
      -->

      <para>
	La primera impresión que dan las referencias es que no son
	necesarias, que se pueden escribir cualquier programa sin
	referencias. En general, eso es verdad, con la excepción de unos
	pocos casos importantes que se tratarán más adelante en el
	libro, pero la idea básica es la misma que la demostración
	anterior con el puntero: se puede pasar la dirección de un
	argumento utilizando una referencia. La diferencia entre
	referencias y punteros es que <emphasis>invocar</emphasis> a una
	función que recibe referencias es mas limpio, sintácticamente,
	que llamar a una función que recibe punteros (y es exactamente
	esa diferencia sintáctica la que hace a las referencias
	esenciales en ciertas situaciones). Si
	<filename>PassAddress.cpp</filename> se modifica para utilizar
	referencias, se puede ver la diferencia en la llamada a la
	función en <function>main()</function>:
      </para>


//: V1C03:PassReference.cpp


      <!--
      In f( )'s argument list, instead of saying int* to pass a pointer,
      you say int& to pass a reference. Inside f( ), if you just say 'r'
      (which would produce the address if r were a pointer) you get the
      value in the variable that r references. If you assign to r, you
      actually assign to the variable that r references. In fact, the
      only way to get the address that's held inside r is with the '&'
      operator.
      -->

      <para>
        En la lista de argumentos de <function>f()</function>, en lugar
        de escribir <type>int*</type> para pasar un puntero, se escribe
        <type>int&amp;</type> para pasar una referencia. Dentro de
        <function>f()</function>, si dice simplemente
        <varname>r</varname> (lo que produciría la dirección si
        <varname>r</varname> fuese un puntero) se obtiene <emphasis>el
        valor en la variable que <varname>r</varname> está
        referenciando</emphasis>. Si se asigna a <varname>r</varname>,
        en realidad se está asignado a la variable a la que que
        <varname>r</varname> referencia.  De hecho, la única manera de
        obtener la dirección que contiene <varname>r</varname> es con el
        operador <oper>&amp;</oper>.
      </para>

      <!--
      In main( ), you can see the key effect of references in the syntax
      of the call to f( ), which is just f(x). Even though this looks
      like an ordinary pass-by-value, the effect of the reference is
      that it actually takes the address and passes it in, rather than
      making a copy of the value. The output is:
      -->

      <para>
	En <function>main()</function>, se puede ver el efecto clave de
	las referencias en la sintaxis de la llamada a
	<function>f()</function>, que es simplemente
	<code>f(x)</code>. Aunque eso parece un paso-por-valor
	ordinario, el efecto de la referencia es que en realidad toma la
	dirección y la pasa, en lugar de hacer una copia del valor. La
	salida es:
      </para>


<screen>
x = 47
&amp;x = 0065FE00
r = 47
&amp;r = 0065FE00
r = 5
x = 5
</screen>


      <!--
      So you can see that pass-by-reference allows a function to modify
      the outside object, just like passing a pointer does (you can also
      observe that the reference obscures the fact that an address is
      being passed; this will be examined later in the book). Thus, for
      this simple introduction you can assume that references are just a
      syntactically different way (sometimes referred to as "syntactic
      sugar") to accomplish the same thing that pointers do: allow
      functions to change outside objects.
      -->

      <para>
	De manera que se puede ver que un paso-por-referencia permite a
	una función modificar el objeto externo, al igual que al pasar
	un puntero (también se puede observar que la referencia esconde
	el hecho de que se está pasando una dirección; esto se verá más
	adelante en el libro). Gracias a esta pequeña introducción se
	puede asumir que las referencias son sólo un modo
	sintácticamente distinto (a veces referido como <quote>azúcar
	sintáctico</quote>) para conseguir lo mismo que los punteros:
	permitir a las funciones cambiar los objetos externos.
      </para>
    </sect2>

    <sect2>
      <!-- Pointers and references as modifiers -->
      <title> Punteros y Referencias como modificadores </title>

      <!--
      So far, you've seen the basic data types char, int, float, and
      double, along with the specifiers signed, unsigned, short, and
      long, which can be used with the basic data types in almost any
      combination. Now we've added pointers and references that are
      orthogonal to the basic data types and specifiers, so the possible
      combinations have just tripled:
      -->

      <para>
	Hasta ahora, se han visto los tipos básicos de datos
	<type>char</type>, <type>int</type>, <type>float</type>, y
	<type>double</type>, junto con los especificadores
	<type>signed</type>, <type>unsigned</type>, <type>short</type>,
	y <type>long</type>, que se pueden utilizar con los tipos
	básicos de datos en casi cualquier combinación. Ahora hemos
	añadido los punteros y las referencias, que son lo ortogonal a
	los tipos básicos de datos y los especificadores, de modo que
	las combinaciones posibles se acaban de triplicar:
      </para>


//: V1C03:AllDefinitions.cpp


      <!--
      Pointers and references also work when passing objects into
      and out of functions; you'll learn about this in a later chapter.
      -->

      <para>
	Los punteros y las referencias entran en juego también cuando se
	pasan objetos dentro y fuera de las funciones; aprenderá sobre
	ello en un capítulo posterior.
      </para>

      <!--
      There's one other type that works with pointers: void. If you
      state that a pointer is a void*, it means that any type of address
      at all can be assigned to that pointer (whereas if you have an
      int*, you can assign only the address of an int variable to that
      pointer). For example:
      -->

      <para>
	Hay otro tipo que funciona con punteros: <type>void</type>. Si
	se establece que un puntero es un <type>void*</type>, significa
	que cualquier tipo de dirección se puede asignar a ese puntero
	(en cambio si tiene un <type>int*</type>, sólo puede asignar la
	dirección de una variable <type>int</type> a ese puntero). Por
	ejemplo:
      </para>


//: V1C03:VoidPointer.cpp



      <!--
      Once you assign to a void* you lose any information about what
      type it is. This means that before you can use the pointer, you
      must cast it to the correct type:
      -->

      <para>
	Una vez que se asigna a un <type>void*</type> se pierde
	cualquier información sobre el tipo de la variables. Esto
	significa que antes de que se pueda utilizar el puntero, se debe
	moldear al tipo correcto:
      </para>


//: V1C03:CastFromVoidPointer.cpp



      <!--
      The cast (int*)vp takes the void* and tells the compiler to treat
      it as an int*, and thus it can be successfully dereferenced. You
      might observe that this syntax is ugly, and it is, but it's worse
      than that - the void* introduces a hole in the language's type
      system. That is, it allows, or even promotes, the treatment of one
      type as another type. In the example above, I treat an int as an
      int by casting vp to an int*, but there's nothing that says I
      can't cast it to a char* or double*, which would modify a
      different amount of storage that had been allocated for the int,
      possibly crashing the program. In general, void pointers should be
      avoided, and used only in rare special cases, the likes of which
      you won't be ready to consider until significantly later in the
      book.
      -->

      <para>
	El molde <code>(int*)vp</code> toma el <type>void*</type> y le
	dice al compilador que lo trate como un <type>int*</type>, y de
	ese modo se puede dereferenciar correctamente.  Puede observar
	que esta sintaxis es horrible, y lo es, pero es peor que eso -
	el <type>void*</type> introduce un agujero en el sistema de
	tipos del lenguaje.  Eso significa, que permite, o incluso
	promueve, el tratamiento de un tipo como si fuera otro tipo. En
	el ejemplo anterior, se trata un <type>int</type> como un
	<type>int</type> mediante el moldeado de <varname>vp</varname> a
	<type>int*</type>, pero no hay nada que indique que no se lo
	puede moldear a <type>char*</type> o <type>double*</type>, lo
	que modificaría una cantidad diferente de espacio que ha sido
	asignada al <type>int</type>, lo que posiblemente provocará que
	el programa falle.. En general, los punteros <type>void</type>
	deberían ser evitados, y utilizados únicamente en raras
	ocasiones, que no se podrán considerar hasta bastante más
	adelante en el libro.
      </para>

      <!--
      You cannot have a void reference, for reasons that will be
      explained in Chapter 11.
      -->

      <para>
	No se puede tener una referencia <type>void</type>, por razones
	que se explicarán en el capítulo 11.
      </para>
    </sect2>
  </sect1>

  <sect1>
    <!-- Scoping -->
    <!-- FIXME:Estableciendo ámbitos] -->
    <title>Alcance</title>

    <!--
    Scoping rules tell you where a variable is valid, where it is
    created, and where it gets destroyed (i.e., goes out of scope). The
    scope of a variable extends from the point where it is defined to
    the first closing brace that matches the closest opening brace
    before the variable was defined. That is, a scope is defined by its
    "nearest" set of braces. To illustrate:
    -->

    <para>
      Las reglas de ámbitos dicen cuando es válida una variable, dónde
      se crea, y cuándo se destruye (es decir, sale de ámbito).  El
      ámbito de una variable se extiende desde el punto donde se define
      hasta la primera llave que empareja con la llave de apertura antes
      de que la variable fuese definida. Eso quiere decir que un ámbito
      se define por su juego de llaves <quote>más cercanas</quote>. Para
      ilustrarlo:
    </para>


//: V1C03:Scope.cpp



    <!--
    The example above shows when variables are visible and when they are
    unavailable (that is, when they go out of scope). A variable can be
    used only when inside its scope. Scopes can be nested, indicated by
    matched pairs of braces inside other matched pairs of
    braces. Nesting means that you can access a variable in a scope that
    encloses the scope you are in.  In the example above, the variable
    scp1 is available inside all of the other scopes, while scp3 is
    available only in the innermost scope.
    -->

    <para>
      El ejemplo anterior muestra cuándo las variables son visibles y
      cuando dejan de estar disponibles (es decir, cuando
      <emphasis>salen del ámbito</emphasis>). Una variable se puede
      utilizar sólo cuando se está dentro de su ámbito. Los ámbitos
      pueden estar anidados, indicados por parejas de llaves dentro de
      otras parejas de llaves. El anidado significa que se puede acceder
      a una variable en un ámbito que incluye el ámbito en el que se
      está.  En el ejemplo anterior, la variable <varname>scp1</varname>
      está disponible dentro de todos los demás ámbitos, mientras que
      <varname>scp3</varname> sólo está disponible en el ámbito más
      interno.
    </para>

    <sect2>
      <!-- Defining variables on the fly -->
      <title>Definición de variables <quote>al vuelo</quote></title>

      <!--
      As noted earlier in this chapter, there is a significant
      difference between C and C++ when defining variables. Both
      languages require that variables be defined before they are used,
      but C (and many other traditional procedural languages) forces you
      to define all the variables at the beginning of a scope, so that
      when the compiler creates a block it can allocate space for those
      variables.
      -->

      <para>
	Como se ha mencionado antes en este capítulo, hay una diferencia
	importante entre C y C++ al definir variables. Ambos lenguajes
	requieren que las variables estén definidas antes de utilizarse,
	pero C (y muchos otros lenguajes procedurales tradicionales)
	fuerzan a que se definan todas las variables al principio del
	bloque, de modo que cuando el compilador crea un bloque puede
	crear espacio para esas variables.
      </para>

      <!--
      While reading C code, a block of variable definitions is usually
      the first thing you see when entering a scope. Declaring all
      variables at the beginning of the block requires the programmer to
      write in a particular way because of the implementation details of
      the language.  Most people don't know all the variables they are
      going to use before they write the code, so they must keep jumping
      back to the beginning of the block to insert new variables, which
      is awkward and causes errors.  These variable definitions don't
      usually mean much to the reader, and they actually tend to be
      confusing because they appear apart from the context in which they
      are used.
      -->

      <para>
	Cuando uno lee código C, normalmente lo primero que encuentra
	cuando empieza un ámbito, es un bloque de definiciones de
	variables.  Declarar todas las variables al comienzo de un
	bloque requiere que el programador escriba de un modo particular
	debido a los detalles de implementación del lenguaje.  La
	mayoría de las personas no conocen todas las variables que van a
	utilizar antes de escribir el código, de modo que siempre están
	volviendo al principio del bloque para insertar nuevas
	variables, lo cual resulta pesado y causa errores.  Normalmente
	estas definiciones de variables no significan demasiado para el
	lector, y de hecho tienden a ser confusas porque aparecen
	separadas del contexto en el cual se utilizan.
      </para>


      <!--
      C++ (not C) allows you to define variables anywhere in a scope, so
      you can define a variable right before you use it. In addition,
      you can initialize the variable at the point you define it, which
      prevents a certain class of errors. Defining variables this way
      makes the code much easier to write and reduces the errors you get
      from being forced to jump back and forth within a scope. It makes
      the code easier to understand because you see a variable defined
      in the context of its use. This is especially important when you
      are defining and initializing a variable at the same time - you
      can see the meaning of the initialization value by the way the
      variable is used.
      -->

      <para>
	C++ (pero no C) permite definir variables en cualquier sitio
	dentro de un ámbito, de modo que se puede definir una variable
	justo antes de usarla.  Además, se puede inicializar la variable
	en el momento de la definición, lo que previene cierto tipo de
	errores. Definir las variables de este modo hace el código más
	fácil de escribir y reduce los errores que provoca estar
	forzado a volver atrás y adelante dentro de un ámbito. Hace el
	código más fácil de entender porque es una variable definida en
	el contexto de su utilización. Esto es especialmente importante
	cuando se está definiendo e inicializando una variable al mismo
	tiempo - se puede ver el significado del valor de inicialización
	por el modo en el que se usa la variable.
      </para>


      <!--
      You can also define variables inside the control expressions of
      for loops and while loops, inside the conditional of an if
      statement, and inside the selector statement of a switch. Here's
      an example showing on-the-fly variable definitions:
      -->

      <para>
	También se pueden definir variables dentro de expresiones de
	control tales como los bucles <kw>for</kw> y <kw>while</kw>,
	dentro de las sentencias de condiciones <kw>if</kw>, y dentro de
	la sentencia de selección <kw>switch</kw>. A continuación hay un
	ejemplo que muestra la definición de variables al-vuelo:
      </para>


//: V1C03:OnTheFly.cpp


      <!--
      In the innermost scope, p is defined right before the scope ends,
      so it is really a useless gesture (but it shows you can define a
      variable anywhere). The p in the outer scope is in the same
      situation.
      -->

      <para>
	En el ámbito más interno, se define <varname>p</varname> antes
	de que acabe el ámbito, de modo que realmente es un gesto inútil
	(pero demuestra que se puede definir una variable en cualquier
	sitio).  La variable <varname>p</varname> en el ámbito exterior
	está en la misma situación.
      </para>

      <!--
      The definition of i in the control expression of the for loop is
      an example of being able to define a variable exactly at the point
      you need it (you can do this only in C++). The scope of i is the
      scope of the expression controlled by the for loop, so you can
      turn around and re-use i in the next for loop. This is a
      convenient and commonly-used idiom in C++; i is the classic name
      for a loop counter and you don't have to keep inventing new names.
      -->

      <para>
	La definición de <varname>i</varname> en la expresión de control
	del bucle <kw>for</kw> es un ejemplo de que es posible definir
	una variable exactamente en el punto en el que se necesita (esto
	sólo se puede hacer en C++). El ámbito de <varname>i</varname>
	es el ámbito de la expresión controlada por el bucle
	<kw>for</kw>, de modo que se puede re-utilizar
	<varname>i</varname> en el siguiente bucle <kw>for</kw>. Se
	trata de un modismo conveniente y común en C++;
	<varname>i</varname> es el nombre habitual para el contador de
	un <kw>for</kw> y así no hay que inventar nombres nuevos.
      </para>

      <!--
      Although the example also shows variables defined within while,
      if, and switch statements, this kind of definition is much less
      common than those in for expressions, possibly because the syntax
      is so constrained.  For example, you cannot have any
      parentheses. That is, you cannot say:
      -->

      <para>
	A pesar de que el ejemplo también muestra variables definidas
	dentro de las sentencias <kw>while</kw>, <kw>if</kw> y
	<kw>switch</kw>, este tipo de definiciones es menos común que
	las de expresiones <kw>for</kw>, quizás debido a que la sintaxis
	es más restrictiva.  Por ejemplo, no se puede tener ningún
	paréntesis. Es decir, que no se puede indicar:
      </para>


<programlisting>
while((char c = cin.get()) != 'q')
</programlisting>


      <!--
      The addition of the extra parentheses would seem like an innocent
      and useful thing to do, and because you cannot use them, the
      results are not what you might like. The problem occurs because
      '!=' has a higher precedence than '=', so the char c ends up
      containing a bool converted to char. When that's printed, on many
      terminals you'll see a smiley-face character.
      -->

      <para>
	Añadir los paréntesis extra parecería una acción inocente y
	útil, y debido a que no se pueden utilizar, los resultados no
	son los esperados. El problema ocurre porque <oper>!=</oper>
	tiene orden de precedencia mayor que <oper>=</oper>, de modo que
	el <code>char c</code> acaba conteniendo un <type>bool</type>
	convertido a <type>char</type>. Cuando se muestra, en
	muchos terminales se vería el carácter de la cara sonriente.
      </para>

      <!--
      In general, you can consider the ability to define variables
      within while, if, and switch statements as being there for
      completeness, but the only place you're likely to use this kind of
      variable definition is in a for loop (where you'll use it quite
      often).
      -->

      <para>
	En general, se puede considerar la posibilidad de definir
	variables dentro de las sentencias <kw>while</kw>, <kw>if</kw> y
	<kw>switch</kw> por completitud, pero el único lugar donde se
	debería utilizar este tipo de definición de variables es en el
	bucle <kw>for</kw> (dónde usted las utilizará más a menudo).
      </para>
    </sect2>
  </sect1>


  <sect1>
    <!-- Specifying storage allocation -->
    <title> Especificar la ubicación del espacio de almacenamiento</title>

    <!--
    When creating a variable, you have a number of options to specify
    the lifetime of the variable, how the storage is allocated for that
    variable, and how the variable is treated by the compiler.
    -->

    <para>
      Al crear una variable, hay varias alternativas para especificar
      la vida de dicha variable, la forma en que se decide la ubicación
      para esa variable y cómo la tratará el compilador.
    </para>

    <sect2>
      <!-- Global variables -->
      <title> Variables globales</title>

      <!--
      Global variables are defined outside all function bodies and are
      available to all parts of the program (even code in other
      files). Global variables are unaffected by scopes and are always
      available ( i.e., the lifetime of a global variable lasts until
      the program ends). If the existence of a global variable in one
      file is declared using the  extern keyword in another file, the
      data is available for use by the second file. Here's an example of
      the use of global variables:
      -->

      <para>
	Las variables globales se definen fuera de todos los cuerpos de
	las funciones y están disponibles para todo el programa (incluso
	el código de otros ficheros). Las variables globales no están
	afectadas por ámbitos y están siempre disponibles (es decir, la
	vida de una variable global dura hasta la finalización del
	programa). Si la existencia de una variable global en un fichero
	se declara usando la palabra reservada <kw>extern</kw> en otro
	fichero, la información está disponible para su utilización en
	el segundo fichero. A continuación, un ejemplo del uso de
	variables globales:
      </para>


//: V1C03:Global.cpp


      <!--
      Here's a file that accesses globe as an extern:
      -->

      <para>
	Y el fichero que accede a <varname>globe</varname> como un
	<kw>extern</kw>:
      </para>


//: V1C03:Global2.cpp {O}


      <!--
      Storage for the variable globe is created by the definition in
      Global.cpp, and that same variable is accessed by the code in
      Global2.cpp. Since the code in Global2.cpp is compiled separately
      from the code in Global.cpp, the compiler must be informed that
      the variable exists elsewhere by the declaration
      -->

      <para>
	El espacio para la variable <varname>globe</varname> se crea
	mediante la definición en <filename>Global.cpp</filename>, y esa
	misma variable es accedida por el código de
	<filename>Global2.cpp</filename>. Ya que el código de
	<filename>Global2.cpp</filename> se compila separado del código
	de <filename>Global.cpp</filename>, se debe informar al
	compilador de que la variable existe en otro sitio mediante
	la declaración
      </para>


<programlisting>
extern int globe;
</programlisting>


      <!--
      When you run the program, you'll see that the call to func( ) does
      indeed affect the single global instance of globe.
      -->

      <para>
	Cuando ejecute el programa, observará que la llamada
	<function>fun()</function> afecta efectivamente a la única
	instancia global de <varname>globe</varname>.
      </para>


      <!--
      In Global.cpp, you can see the special comment tag (which is my
      own design):
      -->

      <para>
	En <filename>Global.cpp</filename>, se puede ver el comentario
	con una marca especial (que es diseño mío):
      </para>

<programlisting>
//{L} Global2
</programlisting>

      <!--
      This says that to create the final program, the object file with
      the name Global2 must be linked in (there is no extension because
      the extension names of object files differ from one system to the
      next). In Global2.cpp, the first line has another special comment
      tag {O}, which says "Don't try to create an executable out of this
      file, it's being compiled so that it can be linked into some other
      executable." The ExtractCode.cpp program in Volume 2 of this book
      (downloadable at www.BruceEckel.com) reads these tags and creates
      the appropriate makefile so everything compiles properly (you'll
      learn about makefiles at the end of this chapter).
      -->

      <para>
	Eso indica que para crear el programa final, el fichero objeto
	con el nombre <filename>Global2</filename> debe estar enlazado
	(no hay extensión ya que los nombres de las extensiones de los
	ficheros objeto difieren de un sistema a otro). En
	<filename>Global2.cpp</filename>, la primera línea tiene otra
	marca especial <code>{O}</code>, que significa <quote>No
	intentar crear un ejecutable de este fichero, se compila para
	que pueda enlazarse con otro fichero</quote>. El programa
	<filename>ExtractCode.cpp</filename> en el Volumen 2 de este
	libro (que se puede descargar de <ulink
	url="http://www.bruceeckel.com">www.BruceEckel.com</ulink>) lee
	estas marcas y crea el <filename>makefile</filename> apropiado
	de modo que todo se compila correctamente (aprenderá sobre
	makefiles al final de este capítulo).
      </para>
    </sect2>

    <sect2>
      <!-- Local variables -->
      <title>Variables locales</title>

      <!--
      Local variables occur within a scope; they are "local" to a
      function. They are often called automatic variables because they
      automatically come into being when the scope is entered and
      automatically go away when the scope closes. The keyword auto
      makes this explicit, but local variables default to auto so it is
      never necessary to declare something as an auto.
      -->

      <para>
	Las variables locales son las que se encuentran dentro de un
	ámbito; son <quote>locales</quote> a una función. A menudo se
	las llama variables automáticas porque aparecen automáticamente
	cuando se entra en un ámbito y desaparecen cuando el ámbito se
	acaba. La palabra reservada <kw>auto</kw> lo enfatiza, pero las
	variables locales son <kw>auto</kw> por defecto, de modo que
	nunca se necesita realmente declarar algo como <kw>auto</kw>.
      </para>


      <sect3>
        <!-- Register variables -->
        <title>Variables registro</title>

	<!--
        A register variable is a type of local variable. The register
        keyword tells the compiler "Make accesses to this variable as
        fast as possible." Increasing the access speed is implementation
        dependent, but, as the name suggests, it is often done by
        placing the variable in a register. There is no guarantee that
        the variable will be placed in a register or even that the
        access speed will increase. It is a hint to the compiler.
	-->

        <para>
	  Una variable registro es un tipo de variable local. La palabra
	  reservada <kw>register</kw> indica al compilador <quote>Haz
	  que los accesos a esta variable sean lo más rápidos
	  posible</quote>. Aumentar la velocidad de acceso depende de la
	  implementación, pero, tal como sugiere el nombre, a menudo se
	  hace situando la variable en un registro del
	  microprocesador. No hay garantía alguna de que la variable
	  pueda ser ubicada en un registro y tampoco de que la velocidad de
	  acceso aumente. Es una ayuda para el compilador.
        </para>

	<!--
        There are restrictions to the use of register variables. You
        cannot take or compute the address of a register variable. A
        register variable can be declared only within a block (you
        cannot have global or static register variables). You can,
        however, use a register variable as a formal argument in a
        function ( i.e., in the argument list).
        -->

        <para>
	  Hay restricciones a la hora de utilizar variables registro. No
	  se puede consular o calcular la dirección de una variable
	  registro. Una variable registro sólo se puede declarar
	  dentro de un bloque (no se pueden tener variables de registro
	  globales o estáticas). De todos modos, se pueden utilizar
	  como un argumento formal en una función (es decir, en la lista de
	  argumentos).
        </para>

	<!--
        In general, you shouldn't try to second-guess the compiler's optimizer,
        since it will probably do a better job than you can. Thus, the
        register keyword is best avoided.
	-->

        <para>
	  En general, no se debería intentar influir sobre el
	  optimizador del compilador, ya que probablemente él hará mejor
	  el trabajo de lo que lo pueda hacer usted. Por eso, es mejor
	  evitar el uso de la palabra reservada <kw>register</kw>.
        </para>
      </sect3>
    </sect2>

    <sect2>
      <title>Static</title>

      <!--
        The static keyword has several distinct meanings. Normally,
        variables defined local to a function disappear at the end of
        the function scope. When you call the function again, storage
        for the variables is created anew and the values are
        re-initialized. If you want a value to be extant throughout the
        life of a program, you can define a function's local variable to
        be static and give it an initial value. The initialization is
        performed only the first time the function is called, and the
        data retains its value between function calls. This way, a
        function can "remember" some piece of information between
        function calls.
      -->

      <para>
        La palabra reservada <kw>static</kw> tiene varios
        significados. Normalmente, las variables definidas localmente a
        una función desaparecen al final del ámbito de ésta. Cuando se
        llama de nuevo a la función, el espacio de las variables se
        vuelve a pedir y las variables son re-inicializadas. Si se desea
        que el valor se conserve durante la vida de un programa, puede
        definir una variable local de una función como <kw>static</kw> y
        darle un valor inicial.  La inicialización se realiza sólo la
        primera vez que se llama a la función, y la información se
        conserva entre invocaciones sucesivas de la función. De este
        modo, una función puede <quote>recordar</quote> cierta
        información entre una llamada y otra.
      </para>

      <!--
        You may wonder why a global variable isn't used instead. The
        beauty of a static variable is that it is unavailable outside
        the scope of the function, so it can't be inadvertently
        changed. This localizes errors.
      -->

      <para>
        Puede surgir la duda de porqué no utilizar una variable global
        en este caso. El encanto de una variable <kw>static</kw> es que
        no está disponible fuera del ámbito de la función, de modo que
        no se puede modificar accidentalmente. Esto facilita la
        localización de errores.
      </para>

      <!--
      Here's an example of the use of static variables:
      -->

      <para>
        A continuación, un ejemplo del uso de variables <kw>static</kw>:
      </para>


//: V1C03:Static.cpp


      <!--
        Each time func() is called in the for loop, it prints a
        different value. If the keyword static is not used, the value
        printed will always be '1'.
      -->

      <para>
        Cada vez que se llama a <function>func()</function> dentro del
        bucle, se imprime un valor diferente. Si no se utilizara la
        palabra reservada <kw>static</kw>, el valor mostrado sería
        siempre <literal>1</literal>.
      </para>

      <!--
        The second meaning of static is related to the first in the
        "unavailable outside a certain scope" sense. When static is
        applied to a function name or to a variable that is outside of
        all functions, it means "This name is unavailable outside of
        this file." The function name or variable is local to the file;
        we say it has  file scope. As a demonstration, compiling and
        linking the following two files will cause a linker error:
      -->

      <para>
        El segundo significado de <kw>static</kw> está relacionado con
        el primero en el sentido de que <quote>no está disponible fuera
        de cierto ámbito</quote>. Cuando se aplica <kw>static</kw> al
        nombre de una función o de una variable que está fuera de todas
        las funciones, significa <quote>Este nombre no está disponible
        fuera de este fichero</quote>. El nombre de la función o de la
        variable es local al fichero; decimos que tiene ámbito de
        fichero. Como demostración, al compilar y enlazar los dos
        ficheros siguientes aparece un error en el enlazado:
      </para>


//: V1C03:FileStatic.cpp


      <!--
        Even though the variable fs is claimed to exist as an extern  in
        the following file, the linker won't find it because it has been
        declared static in FileStatic.cpp.
      -->

      <para>
        Aunque la variable <varname>fs</varname> está destinada a
        existir como un <kw>extern</kw> en el siguiente fichero, el
        enlazador no la encontraría porque ha sido declarada
        <kw>static</kw> en <filename>FileStatic.cpp</filename>.
      </para>


//: V1C03:FileStatic2.cpp {O}



      <!--
        The static specifier may also be used inside a class. This
        explanation will be delayed until you learn to create classes,
        later in the book.
      -->

      <para>
        El especificador <kw>static</kw> también se puede usar dentro de
        una clase. Esta explicación se dará más adelante en este
        libro, cuando aprenda a crear clases.
      </para>
    </sect2>

    <sect2>
      <title>extern</title>

      <!--
        The extern keyword has already been briefly described and
        demonstrated. It tells the compiler that a variable or a
        function exists, even if the compiler hasn't yet seen it in the
        file currently being compiled. This variable or function may be
        defined in another file or further down in the current file. As
        an example of the latter:
      -->

      <para>
	La palabra reservada <kw>extern</kw> ya ha sido brevemente
	descripta. Le dice al compilador que una variable o
	una función existe, incluso si el compilado aún no la ha visto
	en el fichero que está siendo compilado en ese momento. Esta
	variable o función puede definirse en otro fichero o más abajo
	en el fichero actual. A modo de ejemplo:
      </para>


//: V1C03:Forward.cpp


      <!--
      When the compiler encounters the declaration 'extern int i', it
      knows that the definition for i must exist somewhere as a global
      variable. When the compiler reaches the definition of i, no other
      declaration is visible, so it knows it has found the same i
      declared earlier in the file. If you were to define i as static,
      you would be telling the compiler that i is defined globally (via
      the extern), but it also has file scope (via the static), so the
      compiler will generate an error.
      -->

      <para>
	Cuando el compilador encuentra la declaración <code>extern int
	i</code> sabe que la definición para <varname>i</varname> debe
	existir en algún sitio como una variable global. Cuando el
	compilador alcanza la definición de <varname>i</varname>,
	ninguna otra declaración es visible, de modo que sabe que ha
	encontrado la misma <varname>i</varname> declarada anteriormente
	en el fichero. Si se hubiera definido <varname>i</varname> como
	<kw>static</kw>, estaría indicando al compilador que
	<varname>i</varname> se define globalmente (por
	<kw>extern</kw>), pero también que tiene el ámbito de fichero
	(por <kw>static</kw>), de modo que el compilador generará un
	error.
      </para>

      <sect3>
        <!--Linkage-->
        <title>Enlazado</title>

        <!--
	To understand the behavior of C and C++ programs, you need to
	know about linkage. In an executing program, an identifier is
	represented by storage in memory that holds a variable or a
	compiled function body. Linkage describes this storage as it is
	seen by the linker. There are two types of linkage: internal
	linkage and external linkage.
        -->
        <para>
	  Para comprender el comportamiento de los programas C y C++, es
	  necesario saber sobre <emphasis>enlazado</emphasis>. En un
	  programa en ejecución, un identificador se representa con
	  espacio en memoria que aloja una variable o un cuerpo de
	  función compilada. El enlazado describe este espacio tal como
	  lo ve el enlazador. Hay dos formas de enlazado:
	  <emphasis>enlace interno</emphasis> y <emphasis>enlace
	  externo</emphasis>.
        </para>

	<!-- Internal linkage means that storage is created to represent
	the identifier only for the file being compiled. Other files may
	use the same identifier name with internal linkage, or for a
	global variable, and no conflicts will be found by the linker -
	separate storage is created for each identifier. Internal
	linkage is specified by the keyword static in C and C++.  -->
        <para>
	  Enlace interno significa que el espacio se pide para
	  representar el identificador sólo durante la compilación del
	  fichero. Otros ficheros pueden utilizar el mismo nombre de
	  identificador con un enlace interno, o para una variable
	  global, y el enlazador no encontraría conflictos - se pide un
	  espacio separado para cada identificador. El enlace interno se
	  especifica mediante la palabra reservada <kw>static</kw> en C
	  y C++.
        </para>

	<!--
	External linkage means that a single piece of storage is
	created to represent the identifier for all files being
	compiled. The storage is created once, and the linker must
	resolve all other references to that storage. Global variables
	and function names have external linkage. These are accessed
	from other files by declaring them with the keyword
	extern. Variables defined outside all functions (with the
	exception of const in C++) and function definitions default to
	external linkage. You can specifically force them to have
	internal linkage using the static keyword. You can explicitly
	state that an identifier has external linkage by defining it
	with the extern keyword. Defining a variable or function with
	extern is not necessary in C, but it is sometimes necessary for
	const in C++.
	-->
	<para>
	  Enlace externo significa que se pide sólo un espacio para
	  representar el identificador para todos los ficheros que se
	  estén compilando. El espacio se pide una vez, y el enlazador
	  debe resolver todas las demás referencias a esa ubicación. Las
	  variables globales y los nombres de función tienen enlace
	  externo. Son accesibles desde otros ficheros declarándolas con
	  la palabra reservada <kw>extern</kw>. Por defecto, las
	  variables definidas fuera de todas las funciones (con la
	  excepción de <kw>const</kw> en C++) y las definiciones de las
	  funciones implican enlace externo. Se pueden forzar
	  específicamente a tener enlace interno utilizando
	  <kw>static</kw>. Se puede establecer explícitamente que un
	  identificador tiene enlace externo definiéndolo como
	  <kw>extern</kw>. No es necesario definir una variable o una
	  función como <kw>extern</kw> en C, pero a veces es necesario
	  para <kw>const</kw> en C++.
        </para>

	<!--
	Automatic (local) variables exist only temporarily, on the stack,
	while a function is being called. The linker doesn't know about
	automatic variables , and so these have no linkage.
	-->

	<para>
	  Las variables automáticas (locales) existen sólo
	  temporalmente, en la pila, mientras se está ejecutando una
	  función. El enlazador no entiende de variables automáticas, de
	  modo que no tienen enlazado.
	</para>
      </sect3>
    </sect2>

    <sect2>
      <title>Constantes</title>

      <!--
      In old (pre-Standard) C, if you wanted to make a constant, you had
      to use the preprocessor :
      -->

      <para>
	En el antiguo C (pre-Estándar), si se deseaba crear una
	constante, se debía utilizar el preprocesador:
      </para>


<programlisting>
#define PI 3.14159
</programlisting>


      <!--
      Everywhere you used PI, the value 3.14159 was substituted by the
      preprocessor (you can still use this method in C and C++).
      -->

      <para>
	En cualquier sitio en el que utilizase PI, el preprocesador lo
	substituía por el valor 3.14159 (aún se puede utilizar este
	método en C y C++).
      </para>

      <!--
      When you use the preprocessor to create constants, you place
      control of those constants outside the scope of the compiler. No
      type checking  is performed on the name PI and you can't take the
      address of PI (so you can't pass a pointer or a reference to
      PI). PI cannot be a variable of a user-defined type. The meaning
      of PI lasts from the point it is defined to the end of the file;
      the preprocessor doesn't recognize scoping.
      -->

      <para>
	Cuando se utiliza el preprocesador para crear constantes, su
	control queda fuera del ámbito del compilador. No existe ninguna
	comprobación de tipo y no se puede obtener la dirección de PI
	(de modo que no se puede pasar un puntero o una referencia a
	PI). PI no puede ser una variable de un tipo definido por el
	usuario. El significado de PI dura desde el punto en que es
	definida, hasta el final del fichero; el preprocesador no
	entiende de ámbitos.
      </para>


      <!--
      C++ introduces the concept of a named constant that is just like a
      variable, except that its value cannot be changed. The modifier
      const tells the compiler that a name represents a constant. Any
      data type, built-in or user-defined, may be defined as const. If
      you define something as const and then attempt to modify it, the
      compiler will generate an error.
      -->
      <para>
	C++ introduce el concepto de constantes con nombre que es lo
	mismo que variable, excepto que su valor no puede cambiar. El
	modificador <kw>const</kw> le indica al compilador que el nombre
	representa una constante. Cualquier tipo de datos predefinido o
	definido por el usuario, puede ser definido como
	<kw>const</kw>. Si se define algo como <kw>const</kw> y luego se
	intenta modificar, el compilador generará un error.
      </para>

      <!--
      You must specify the type of a const, like this:
      -->
      <para>
	Se debe especificar el tipo de un <kw>const</kw>, de este modo:
      </para>


<programlisting>
const int x = 10;
</programlisting>


      <!--
      In Standard C and C++, you can use a named constant in an argument
      list, even if the argument it fills is a pointer or a reference (
      i.e., you can take the address of a const). A const has a scope,
      just like a regular variable, so you can "hide" a const inside a
      function and be sure that the name will not affect the rest of the
      program.
      -->
      <para>
	En C y C++ Estándar, se puede usar una constante en una lista de
	argumentos, incluso si el argumento que ocupa es un puntero o
	una referencia (p.e, se puede obtener la dirección de una
	constante). Las constantes tienen ámbito, al igual que una
	variable ordinaria, de modo que se puede <quote>esconder</quote>
	una constante dentro de una función y estar seguro de que ese
	nombre no afectará al resto del programa.
      </para>


      <!--
      The const was taken from C++ and incorporated into Standard C,
      albeit quite differently. In C, the compiler treats a const just
      like a variable that has a special tag attached that says "Don't
      change me." When you define a const in C, the compiler creates
      storage for it, so if you define more than one const with the same
      name in two different files (or put the definition in a header
      file), the linker will generate error messages about
      conflicts. The intended use of const in C is quite different from
      its intended use in C++ (in short, it's nicer in C++).
      -->
      <para>
	<kw>const</kw> ha sido tomado de C++ e incorporado al C Estándar
	pero un modo un poco distinto. En C, el compilador trata a
	<kw>const</kw> del mismo modo que a una variable que tuviera
	asociado una etiqueta que dice <quote>No me
	cambies</quote>. Cuando se define un <kw>const</kw> en C, el
	compilador pide espacio para él, de modo que si se define más de
	un <kw>const</kw> con el mismo nombre en dos ficheros distintos
	(o se ubica la definición en un fichero de cabeceras), el
	enlazador generará mensajes de error sobre del conflicto. El
	concepto de <kw>const</kw> en C es diferente de su utilización
	en C++ (en resumen, es más bonito en C++).
      </para>

      <sect3>
	<!-- Constant values -->
	<title>Valores constantes</title>

	<!--
	In C++, a const must always have an initialization value (in C,
	this is not true). Constant values for built-in types are
	expressed as decimal, octal, hexadecimal, or floating-point
	numbers (sadly, binary numbers were not considered important),
	or as characters.
	-->
	<para>
	  En C++, una constante debe tener siempre un valor inicial (En
	  C, eso no es cierto). Los valores de las constantes para tipos
	  predefinidos se expresan en decimal, octal, hexadecimal, o
	  números con punto flotante (desgraciadamente, no se consideró
	  que los binarios fuesen importantes), o como caracteres.
	</para>


	<!--
	In the absence of any other clues, the compiler assumes a
	constant value is a decimal number. The numbers 47, 0, and 1101
	are all treated as decimal numbers.
	-->
	<para>
	  A falta de cualquier otra pista, el compilador assume que el
	  valor de una constante es un número decimal. Los números 47,
	  0 y 1101 se tratan como números decimales.
	</para>


	<!--
	A constant value with a leading 0 is treated as an octal number
	(base 8). Base 8 numbers can contain only digits 0-7; the
	compiler flags other digits as an error. A legitimate octal
	number is 017 (15 in base 10).
	-->
	<para>
	  Un valor constante con un cero al principio se trata como un
	  número octal (base 8). Los números con base 8 pueden contener
	  únicamente dígitos del 0 al 7; el compilador interpreta otros
	  dígitos como un error. Un número octal legítimo es 017 (15 en
	  base 10).
	</para>

	<!--
	A constant value with a leading 0x is treated as a hexadecimal
	number (base 16). Base 16 numbers contain the digits 0-9 and a-f
	or A-F. A legitimate hexadecimal number is 0x1fe (510 in base
	10).
	-->
	<para>
	  Un valor constante con <literal>0x</literal> al principio se
	  trata como un número hexadecimal (base 16). Los números con
	  base 16 pueden contener dígitos del 0 al 9 y letras de la
	  <token>a</token> a la <token>f</token> o
	  <token>A</token> a <token>F</token>. Un número
	  hexadecimal legítimo es 0x1fe (510 en base 10).
	</para>


	<!--
	Floating point numbers can contain decimal points and
	exponential powers (represented by e, which means "10 to the
	power of"). Both the decimal point and the e are optional. If
	you assign a constant to a floating-point variable, the compiler
	will take the constant value and convert it to a floating-point
	number (this process is one form of what's called implicit type
	conversion). However, it is a good idea to use either a decimal
	point or an e to remind the reader that you are using a
	floating-point number; some older compilers also need the hint.
	-->
	<para>
	  Los números en punto flotante pueden contener comas decimales
	  y potencias exponenciales (representadas mediante
	  <literal>e</literal>, lo que significa <quote>10 elevado
	  a</quote>). Tanto el punto decimal como la
	  <literal>e</literal> son opcionales. Si se asigna una
	  constante a una variable de punto flotante, el compilador
	  tomará el valor de la constante y la convertirá a un número en
	  punto flotante (este proceso es una forma de lo que se conoce
	  como conversión implícita de tipo). De todos modos, es una
	  buena idea el usar el punto decimal o una <literal>e</literal>
	  para recordar al lector que está utilizando un número en
	  punto flotante; algunos compiladores incluso necesitan esta
	  pista.
	</para>

	<!--
	Legitimate floating-point constant values are: 1e4, 1.0001,
	47.0, 0.0, and -1.159e-77. You can add suffixes to force the
	type of floating-point number: f or F forces a float, L or l
	forces a long double; otherwise the number will be a double.
	-->
	<para>
	  Algunos valores válidos para una constante en punto flotante
	  son: 1e4, 1.0001, 47.0, 0.0 y 1.159e-77.  Se pueden añadir
	  sufijos para forzar el tipo de número de punto flotante:
	  <literal>f</literal> o <literal>F</literal> fuerza que sea
	  <type>float</type>, <literal>L</literal> o
	  <literal>l</literal> fuerza que sea un <type>long
	  double</type>; de lo contrario, el número será un
	  <type>double</type>.
	</para>

	<!--
	Character constants are characters surrounded by single quotes,
	as: 'A', '0', ' '. Notice there is a big difference between the
	character '0' (ASCII 96) and the value 0. Special characters are
	represented with the "backslash escape": ' \n' (newline), '\t'
	(tab), '\\' (backslash), '\r' (carriage return), '\"' (double
	quotes), '\'' (single quote), etc. You can also express char
	constants in octal: '\17 ' or hexadecimal: '\xff'.
	-->

	<para>
	  Las constantes de tipo <type>char</type> son caracteres entre
	  comillas simples, tales como: <literal>'A'</literal>,
	  <literal>'o'</literal>, <literal>''</literal>. Fíjese en que
	  hay una gran diferencia entre el carácter
	  <literal>'o'</literal> (ASCII 96) y el valor 0. Los caracteres
	  especiales se representan con la <quote>barra
	  invertida</quote>: <literal>'\n'</literal> (nueva línea),
	  <literal>'\t'</literal> (tabulación), <literal>'\\'</literal>
	  (barra invertida), <literal>'\r'</literal> (retorno de carro),
	  <literal>'\"'</literal> (comilla doble),
	  <literal>'\''</literal> (comilla simple), etc. Incluso se
	  puede expresar constantes de tipo <type>char</type> en octal:
	  <literal>'\17'</literal> o hexadecimal:
	  <literal>'\xff'</literal>.
	</para>
      </sect3>
    </sect2>

    <sect2>
      <title>Volatile</title>

      <!--
      Whereas the qualifier const tells the compiler "This never
      changes" (which allows the compiler to perform extra
      optimizations), the qualifier volatile tells the compiler "You
      never know when this will change," and prevents the compiler from
      performing any optimizations based on the stability of that
      variable. Use this keyword when you read some value outside the
      control of your code, such as a register in a piece of
      communication hardware. A volatile variable is always read
      whenever its value is required, even if it was just read the line
      before.
      -->
      <para>
	Mientras que el calificador <kw>const</kw> indica al compilador
	<quote>Esto nunca cambia</quote> (lo que permite al compilador
	realizar optimizaciones extra), el calificador <kw>volatile</kw>
	dice al compilador <quote>Nunca se sabe cuando cambiará
	esto</quote>, y evita que el compilador realice optimizaciones
	basadas en la estabilidad de esa variable.  Se utiliza esta
	palabra reservada cuando se lee algún valor fuera del control
	del código, algo así como un registro en un hardware de
	comunicación. Una variable <kw>volatile</kw> se lee siempre que
	su valor es requerido, incluso si se ha leído en la línea
	anterior.
      </para>


      <!--
      A special case of some storage being "outside the control of your
      code" is in a multithreaded program. If you're watching a
      particular flag that is modified by another thread or process,
      that flag should be volatile so the compiler doesn't make the
      assumption that it can optimize away multiple reads of the flag.
      -->
      <para>
	Un caso especial de espacio que está <quote>fuera del control
	del código</quote> es en un programa multi-hilo. Si está
	comprobando una bandera particular que puede ser modificada por
	otro hilo o proceso, esta bandera debería ser <kw>volatile</kw>
	de modo que el compilador no asuma que puede optimizar múltiples
	lecturas de la bandera.
      </para>


      <!--
      Note that volatile may have no effect when a compiler is not
      optimizing, but may prevent critical bugs when you start
      optimizing the code (which is when the compiler will begin looking
      for redundant reads).
      -->
      <para>
	Fíjese en que <kw>volatile</kw> puede no tener efecto cuando el
	compilador no está optimizando, pero puede prevenir errores
	críticos cuando se comienza a optimizar el código (que es cuando
	el compilador empezará a buscar lecturas redundantes).
      </para>


      <!--
      The const and volatile keywords will be further illuminated in a
      later chapter.
      -->
      <para>
	Las palabras reservadas <kw>const</kw> y <kw>volatile</kw> se
	verán con más detalle en un capítulo posterior.
      </para>
    </sect2>
  </sect1>


  <sect1>
    <!-- Operators and their use -->
    <title>Los operadores y su uso</title>

    <!--
    This section covers all the operators in C and C++.
    -->

    <para>
      Esta sección cubre todos los operadores de C y C++.
    </para>

    <!--
    All operators produce a value from their operands. This value is
    produced without modifying the operands, except with the assignment,
    increment, and decrement operators. Modifying an operand is called a
    side effect. The most common use for operators that modify their
    operands is to generate the side effect, but you should keep in mind
    that the value produced is available for your use just as in
    operators without side effects.
    -->

    <para>
      Todos los operadores producen un valor a partir de sus
      operandos. Esta operación se efectúa sin modificar los operandos,
      excepto con los operadores de asignación, incremento y
      decremento. El hecho de modificar un operando se denomina
      <emphasis>efecto colateral</emphasis>. El uso más común de los
      operadores que modifican sus operandos es producir el efecto
      colateral, pero se debería tener en cuenta que el valor producido
      está disponible para su uso al igual que el de los operadores sin
      efectos colaterales.
    </para>

    <sect2>
      <!-- Assignment -->
      <title>Asignación</title>

      <!--
      Assignment is performed with the operator =. It means "Take the
      right-hand side (often called the rvalue) and copy it into the
      left-hand side (often called the lvalue)." An rvalue is any
      constant, variable, or expression that can produce a value, but an
      lvalue must be a distinct, named variable (that is, there must be
      a physical space in which to store data). For instance, you can
      assign a constant value to a variable ( A = 4;), but you cannot
      assign anything to constant value - it cannot be an lvalue (you
      can't say 4 = A;).
      -->

      <para>
	La asignación se realiza mediante el operador
	<oper>=</oper>. Eso significa <quote>Toma el valor de la derecha
	(a menudo llamado <emphasis>rvalue</emphasis>) y cópialo en la
	variable de la izquierda (a menudo llamado
	<emphasis>lvalue</emphasis>).</quote> Un
	<emphasis>rvalue</emphasis> es cualquier constante, variable o
	expresión que pueda producir un valor, pero un
	<emphasis>lvalue</emphasis> debe ser una variable con un nombre
	distintivo y único (esto quiere decir que debe haber un espacio
	físico dónde guardar la información). De hecho, se puede asignar
	el valor de una constante a una variable (<code>A = 4;</code>),
	pero no se puede asignar nada a una constante - es decir, una
	constante no puede ser un <emphasis>lvalue</emphasis> (no se
	puede escribir <code>4 = A;</code>).
      </para>
    </sect2>


    <sect2>
      <!--Mathematical operators -->
      <title>Operadores matemáticos</title>

      <!--
      The basic mathematical operators are the same as the ones available
      in most programming languages: addition (+), subtraction (-),
      division (/), multiplication (*), and modulus (%; this produces the
      remainder from integer division). Integer division truncates the
      result (it doesn't round). The modulus operator cannot be used with
      floating-point numbers.
      -->

      <para>
	Los operadores matemáticos básicos son los mismos que están
	disponibles en la mayoría de los lenguajes de programación:
	adición (<oper>+</oper>), substracción (<oper>-</oper>),
	división (<oper>/</oper>), multiplicación (<oper>*</oper>), y
	módulo (<oper>%</oper>; que produce el resto de una división
	entera). La división entera trunca el resultado (no lo
	redondea). El operador módulo no se puede utilizar con
	números con punto flotante.
      </para>

      <!--
      C and C++ also use a shorthand notation to perform an operation
      and an assignment at the same time. This is denoted by an operator
      followed by an equal sign, and is consistent with all the
      operators in the language (whenever it makes sense). For example,
      to add 4 to the variable x and assign x to the result, you say: x
      += 4;.
      -->
      <para>
	C y C++ también utilizan notaciones abreviadas para efectuar una
	operación y una asignación al mismo tiempo. Esto se denota por
	un operador seguido de un signo igual, y se puede aplicar a
	todos los operadores del lenguaje (siempre que tenga
	sentido). Por ejemplo, para añadir <constant>4</constant> a la
	variable <varname>x</varname> y asignar <varname>x</varname> al
	resultado, se escribe: <code>x += 4;</code>.
      </para>

      <!--
      This example shows the use of the mathematical operators:
      -->

      <para>
	Este ejemplo muestra el uso de los operadores matemáticos:
      </para>

//: V1C03:Mathops.cpp

      <!--
      The rvalues of all the assignments can, of course, be much more complex.
      -->

      <para>
	Los <emphasis>rvalues</emphasis> de todas las asignaciones
	pueden ser, por supuesto, mucho mas complejos.
      </para>

      <sect3>
	<!-- Introduction to preprocessor macros -->
	<title>Introducción a las macros del preprocesador</title>

	<!--
      Notice the use of the macro PRINT( ) to save typing (and typing
      errors!). Preprocessor macros are traditionally named with all
      uppercase letters so they stand out - you'll learn later that macros
      can quickly become dangerous (and they can also be very useful).
	-->

	<para>
	  Observe el uso de la macro <function>PRINT()</function> para
	  ahorrar líneas (y errores de sintaxis!). Las macros de
	  preprocesador se nombran tradicionalmente con todas sus letras
	  en mayúsculas para que sea fácil distinguirlas - aprenderá más
	  adelante que las macros pueden ser peligrosas (y también
	  pueden ser muy útiles).
	</para>

      <!--
      The arguments in the parenthesized list following the macro name
      are substituted in all the code following the closing
      parenthesis. The preprocessor removes the name PRINT and
      substitutes the code wherever the macro is called, so the compiler
      cannot generate any error messages using the macro name, and it
      doesn't do any type checking on the arguments (the latter can be
      beneficial, as shown in the debugging macros at the end of the
      chapter).
      -->

	<para>
	  Los argumentos de de la lista entre paréntesis que sigue al
	  nombre de la macro son sustituidos en todo el código que sigue
	  al paréntesis de cierre. El preprocesador elimina el nombre
	  <function>PRINT</function> y sustituye el código donde se
	  invoca la macro, de modo que el compilador no puede generar
	  ningún mensaje de error al utilizar el nombre de la macro, y
	  no realiza ninguna comprobación de sintaxis sobre los
	  argumentos (esto lo último puede ser beneficioso, como se
	  muestra en las macros de depuración al final del capítulo).
	</para>
      </sect3>
    </sect2>

    <sect2>
      <!-- Relational operators -->
      <title>Operadores relacionales</title>

      <!--
      Relational operators establish a relationship between the values
      of the operands. They produce a Boolean (specified with the bool
      keyword in C++) true if the relationship is true, and false if the
      relationship is false. The relational operators are: less than
      (<), greater than ( >), less than or equal to (<=), greater than
      or equal to (>=), equivalent ( ==), and not equivalent (!=). They
      may be used with all built-in data types in C and C++. They may be
      given special definitions for user-defined data types in C++
      (you'll learn about this in Chapter 12, which covers operator
      overloading).
      -->

      <para>
	Los operadores relacionales establecen una relación entre el
	valor de los operandos. Producen un valor booleano (especificado
	con la palabra reservada <type>bool</type> en C++)
	<constant>true</constant> si la relación es verdadera, y
	<constant>false</constant> si la relación es falsa. Los
	operadores relacionales son: menor que (<oper>&lt;</oper>),
	mayor que (<oper>></oper>), menor o igual a
	(<oper>&lt;=</oper>), mayor o igual a (<oper>>=</oper>),
	equivalente (<oper>==</oper>), y distinto (<oper>!=</oper>). Se
	pueden utilizar con todos los tipos de datos predefinidos en C y
	C++. Se pueden dar definiciones especiales para tipos definidos
	por el usuario en C++ (aprenderá más sobre el tema en el
	Capítulo 12, que cubre la sobrecarga de operadores).
      </para>
    </sect2>



    <sect2>
      <!-- Logical operators -->
      <title>Operadores lógicos</title>

      <!--
      The logical operators and ( &&) and or (||) produce a true or
      false based on the logical relationship of its arguments. Remember
      that in C and C++, a statement is true if it has a non-zero value,
      and false if it has a value of zero. If you print a bool, you'll
      typically see a '1' for true and '0' for false.
      -->

      <para>
	Los operadores lógicos <emphasis>and</emphasis>
	(<oper>&amp;&amp;</oper>) y <emphasis>or</emphasis>
	(<oper>||</oper>) producen <constant>true</constant> o
	<constant>false</constant> basándose en la relación lógica de
	sus argumentos. Recuerde que en C y C++, una condición es cierta
	si tiene un valor diferente de cero, y falsa si vale cero. Si se
	imprime un <type>bool</type>, por lo general verá un
	<constant>1</constant>' para <constant>true</constant> y
	<constant>0</constant> para <constant>false</constant>.
      </para>

      <!--
      This example uses the relational and logical operators:
      -->

      <para>
	Este ejemplo utiliza los operadores relacionales y lógicos:
      </para>


//: V1C03:Boolean.cpp


      <!--
      You can replace the definition for int with float or double in the
      program above. Be aware, however, that the comparison of a
      floating-point number with the value of zero is strict; a number
      that is the tiniest fraction different from another number is
      still "not equal." A floating-point number that is the tiniest bit
      above zero is still true.
      -->

      <para>
	Se puede reemplazar la definición de <type>int</type> con
	<type>float</type> o <type>double</type> en el programa
	anterior. De todos modos, dese cuenta de que la comparación de
	un número en punto flotante con el valor cero es estricta; un
	número que es la fracción más pequeña diferente de otro número
	aún se considera <quote>distinto de</quote>. Un número en punto
	flotante que es poca mayor que cero se considera verdadero.
      </para>
    </sect2>

    <sect2>
      <!--Bitwise operators-->
      <title>Operadores para bits</title>

      <!--
      The bitwise operators allow you to manipulate individual bits in a
      number (since floating point values use a special internal format,
      the bitwise operators work only with integral types: char, int and
      long). Bitwise operators perform Boolean algebra on the
      corresponding bits in the arguments to produce the result.
      -->

      <para>
	Los operadores de bits permiten manipular bits individuales y
	dar como salida un número (ya que los valores con punto flotante
	utilizan un formato interno especial, los operadores de bitS
	sólo funcionan con tipos enteros: <type>char</type>,
	<type>int</type> y <type>long</type>). Los operadores de bitS
	efectúan álgebra booleana en los bits correspondientes de los
	argumentos para producir el resultado.
      </para>

      <!--
      The bitwise and operator ( &) produces a one in the output bit if
      both input bits are one; otherwise it produces a zero. The bitwise
      or operator (|) produces a one in the output bit if either input
      bit is a one and produces a zero only if both input bits are
      zero. The bitwise exclusive or, or xor (^) produces a one in the
      output bit if one or the other input bit is a one, but not
      both. The bitwise not (~, also called the ones complement
      operator) is a unary operator - it only takes one argument (all
      other bitwise operators are binary operators ). Bitwise not
      produces the opposite of the input bit - a one if the input bit is
      zero, a zero if the input bit is one.
      -->

      <para>
	El operador <emphasis>and</emphasis> (<oper>&amp;</oper>) para
	bits produce uno en la salida si ambos bits de entrada valen
	uno; de otro modo produce un cero. El operador
	<emphasis>or</emphasis> (<oper>|</oper>) para bits produce un
	uno en la salida si cualquiera de los dos valores de entrada
	vale uno, y produce un cero sólo si ambos valores de entrada son
	cero. El operador <emphasis>or exclusivo</emphasis> o
	<emphasis>xor</emphasis> (<oper>^</oper>) para bits produce uno
	en la salida si uno de los valores de entrada es uno, pero no
	ambos. El operador <emphasis>not</emphasis> (<oper>~</oper>)
	para bits (también llamado operador de <emphasis>complemento a
	uno</emphasis>) es un operador unario - toma un único argumento
	(todos los demás operadores son binarios). El operador
	<emphasis>not</emphasis> para bits produce el valor contrario a
	la entrada - uno si el bit de entrada es cero, y cero si el bit
	de entrada es uno.
      </para>

      <!--
      Bitwise operators can be combined with the = sign to unite the
      operation and assignment: &=, |=, and ^= are all legitimate
      operations (since ~ is a unary operator it cannot be combined with
      the = sign).
      -->
      <para>
	Los operadores de bits pueden combinarse con el signo
	<oper>=</oper> para unir la operación y la asignación:
	<oper>&amp;=</oper>, <oper>|=</oper>, y <oper>^=</oper> son
	todas operaciones legales (dado que <oper>~</oper> es un
	operador unario no puede combinarse con el signo
	<oper>=</oper>).
      </para>
    </sect2>


    <sect2>
      <!-- Shift operators -->
      <title>Operadores de desplazamiento</title>

      <!--

      The shift operators also manipulate bits. The left-shift operator
      (<<) produces the operand to the left of the operator shifted to
      the left by the number of bits specified after the operator. The
      right-shift operator ( &gt;&gt;) produces the operand to the left
      of the operator shifted to the right by the number of bits
      specified after the operator. If the value after the shift
      operator is greater than the number of bits in the left-hand
      operand, the result is undefined. If the left-hand operand is
      unsigned, the right shift is a logical shift so the upper bits
      will be filled with zeros. If the left-hand operand is signed, the
      right shift may or may not be a logical shift (that is, the
      behavior is undefined).
      -->


      <para>
	Los operadores de desplazamiento también manipulan bits. El
	operador de desplazamiento a izquierda (<oper>&lt;&lt;</oper>)
	produce el desplazamiento del operando que aparece a la
	izquierda del operador tantos bits a la izquierda como indique
	el número a la derecha del operador. El operador de
	desplazamiento a derecha (<oper>&gt;&gt;</oper>) produce el
	desplazamiento del operando de la izquierda hacia la derecha
	tantos bits como indique el número a la derecha del operador. Si
	el valor que sigue al operador de desplazamiento es mayor que el
	número de bits del lado izquierdo, el resultado es
	indefinido. Si el operando de la izquierda no tiene signo, el
	desplazamiento a derecha es un desplazamiento lógico de modo que
	los bits del principio se rellenan con ceros. Si el operando de
	la izquierda tiene signo, el desplazamiento derecho puede ser un
	desplazamiento lógico (es decir, significa que el comportamiento
	es indeterminado).
      </para>

      <!--
      Shifts can be combined with the equal sign (<<= and &gt;&gt;=) . The
      lvalue is replaced by the lvalue shifted by the rvalue.
      -->

      <para>
	Los desplazamientos pueden combinarse con el signo igual
	(<oper>&lt;&lt;=</oper> y <oper>&gt;&gt;=</oper>). El
	<emphasis>lvalue</emphasis> se reemplaza por
	<emphasis>lvalue</emphasis> desplazado por el
	<emphasis>rvalue</emphasis>.
      </para>

      <!--
      What follows is an example that demonstrates the use of all the
      operators involving bits. First, here's a general-purpose function
      that prints a byte in binary format, created separately so that it
      may be easily reused. The header file declares the function:
      -->

      <para>
	Lo que sigue a continuación es un ejemplo que demuestra el uso
	de todos los operadores que involucran bits. Primero, una
	función de propósito general que imprime un byte en formato
	binario, creada para que se pueda reutilizar fácilmente. El
	fichero de cabecera declara la función:
      </para>


//: V1C03:printBinary.h


      <!--
      Here's the implementation of the function:
      -->

      <para>
	A continuación la implementación de la función:
      </para>

//: V1C03:printBinary.cpp {O}

      <!--
      The printBinary( ) function takes a single byte and displays
      it bit-by-bit. The expression
      -->

      <para>
	La función <function>printBinary()</function> toma un único
	byte y lo muestra bit a bit. La expresión:
      </para>


<programlisting>
(1 &lt;&lt; i)
</programlisting>


      <!--
      produces a one in each successive bit position; in binary:
      00000001, 00000010, etc. If this bit is bitwise anded with val and
      the result is nonzero, it means there was a one in that position
      in val.
      -->

      <para>
	produce un uno en cada posición sucesiva de bit; en binario:
	<constant>00000001</constant>, <constant>00000010</constant>,
	etc. Si se hace <emphasis>and</emphasis> a este bit con
	<varname>val</varname> y el resultado es diferente de cero,
	significa que había un uno en esa posición de
	<varname>val</varname>.
      </para>

      <!--
      Finally, the function is used in the example that shows the
      bit-manipulation operators:
      -->

      <para>
	Finalmente, se utiliza la función en el ejemplo que muestra los
	operadores de manipulación de bits:
      </para>


//: V1C03:Bitwise.cpp


      <!--
      Once again, a preprocessor macro is used to save typing. It prints
      the string of your choice, then the binary representation of an
      expression, then a newline.
      -->

      <para>
	Una vez más, se usa una macro de preprocesador para ahorrar
	líneas. Imprime la cadena elegida, luego la representación
	binaria de una expresión, y luego un salto de línea.
      </para>

      <!--
      In main( ), the variables are unsigned. This is because, in
      general, you don't want signs when you are working with bytes. An
      int must be used instead of a char for getval because the " cin
      >>" statement will otherwise treat the first digit as a
      character. By assigning getval to a and b, the value is converted
      to a single byte (by truncating it).
      -->

      <para>
	En <function>main()</function>, las variables son
	<type>unsigned</type>. Esto es porque, en general, no se desean
	signos cuando se trabaja con bytes. Se debe utilizar un
	<type>int</type> en lugar de un <type>char</type> para
	<varname>getval</varname> porque de otro modo la sentencia
	<code>cin &gt;&gt;</code> trataría el primer dígito como un
	carácter. Asignando <varname>getval</varname> a
	<varname>a</varname> y <varname>b</varname>, se convierte el
	valor a un solo byte (truncándolo).
      </para>

      <!--
      The << and >> provide bit-shifting behavior, but when they shift
      bits off the end of the number, those bits are lost (it's commonly
      said that they fall into the mythical bit bucket, a place where
      discarded bits end up, presumably so they can be reused...). When
      manipulating bits you can also perform rotation, which means that
      the bits that fall off one end are inserted back at the other end,
      as if they're being rotated around a loop. Even though most
      computer processors provide a machine-level rotate command (so
      you'll see it in the assembly language for that processor), there
      is no direct support for "rotate" in C or C++. Presumably the
      designers of C felt justified in leaving "rotate" off (aiming, as
      they said, for a minimal language) because you can build your own
      rotate command. For example, here are functions to perform left
      and right rotations:
      -->

      <para>
	Los operadores <oper>&lt;&lt;</oper> y <oper>&gt;&gt;</oper>
	proporcionan un comportamiento de desplazamiento de bits, pero
	cuando desplazan bits que están al final del número, estos bits
	se pierden (comúnmente se dice que se caen en el mítico
	<emphasis>cubo de bits</emphasis>, el lugar donde acaban los
	bits descartados, presumiblemente para que puedan ser
	utilizados...). Cuando se manipulan bits también se pueden
	realizar <emphasis>rotaciones</emphasis>; es decir, que los bits
	que salen de uno de los extremos se pueden insertar por el otro
	extremo, como si estuviesen rotando en un bucle. Aunque la
	mayoría de los procesadores de ordenadores ofrecen un comando de
	rotación a nivel máquina (se puede ver en el lenguaje
	ensamblador de ese procesador), no hay un soporte directo para
	<emphasis>rotate</emphasis> en C o C++. Se supone que a los
	diseñadores de C les pareció justificado el hecho de prescindir
	de <emphasis>rotate</emphasis> (en pro, como dijeron, de un
	lenguaje minimalista) ya que el programador se puede construir
	su propio comando <emphasis>rotate</emphasis>. Por ejemplo, a
	continuación hay funciones para realizar rotaciones a izquierda
	y derecha:
      </para>


//: V1C03:Rotation.cpp {O}


      <!--
      Try using these functions in Bitwise.cpp. Notice the definitions (or
      at least declarations) of rol( ) and ror( ) must be seen by the
      compiler in Bitwise.cpp before the functions are used.
      -->

      <para>
	Al intentar utilizar estas funciones en
	<filename>Bitwise.cpp</filename>, advierta que las definiciones
	(o cuando menos las declaraciones) de <function>rol()</function>
	y <function>ror()</function> deben ser vistas por el compilador
	en <filename>Bitwise.cpp</filename> antes de que se puedan
	utilizar.
      </para>

      <!--
      The bitwise functions are generally extremely efficient to use
      because they translate directly into assembly language
      statements. Sometimes a single C or C++ statement will generate a
      single line of assembly code.
      -->

      <para>
	Las funciones de tratamiento de bits son por lo general
	extremadamente eficientes ya que traducen directamente las
	sentencias a lenguaje ensamblador. A veces una sentencia de C o
	C++ generará una única línea de código ensamblador.
      </para>
    </sect2>


    <sect2>
      <!--Unary operators -->
      <title>Operadores unarios</title>

      <!--
      Bitwise not isn't the only operator that takes a single
      argument. Its companion, the logical not (!), will take a true
      value and produce a false value. The unary minus (-) and unary
      plus (+) are the same operators as binary minus and plus; the
      compiler figures out which usage is intended by the way you write
      the expression. For instance, the statement
      -->

      <para>
	El <emphasis>not</emphasis> no es el único operador de bits que
	toma sólo un argumento. Su compañero, el
	<emphasis>not</emphasis> lógico (<oper>!</oper>), toma un valor
	<constant>true</constant> y produce un valor
	<constant>false</constant>. El menos unario (<oper>-</oper>) y
	el más unario (<oper>+</oper>) son los mismos operadores que los
	binarios menos y más; el compilador deduce que uso se le
	pretende dar por el modo en el que se escribe la expresión. De
	hecho, la sentencia:
      </para>


<programlisting>
x = -a;
</programlisting>


      <!--
      has an obvious meaning. The compiler can figure out:
      -->

      <para>
	tiene un significado obvio. El compilador puede deducir:
      </para>


<programlisting>
x = a * -b;
</programlisting>


      <!--
      but the reader might get confused, so it is safer to say:
      -->

      <para>
	pero el lector se puede confundir, de modo que es más seguro
	escribir:
      </para>


<programlisting>
x = a * (-b);
</programlisting>


      <!--
      The unary minus produces the negative of the value. Unary plus
      provides symmetry with unary minus, although it doesn't actually
      do anything.
      -->

      <para>
	El menos unario produce el valor negativo. El más unario ofrece
	simetría con el menos unario, aunque en realidad no hace nada.
      </para>

      <!--
      The increment and decrement operators (++ and ) were
      introduced earlier in this chapter. These are the only operators
      other than those involving assignment that have side effects
      . These operators increase or decrease the variable by one unit,
      although "unit" can have different meanings according to the data
      type - this is especially true with pointers.
      -->

      <para>
	Los operadores de incremento y decremento (<oper>++</oper> y
	<oper>--</oper>) se comentaron ya en este capítulo. Son los
	únicos operadores, además de los que involucran asignación, que
	tienen efectos colaterales. Estos operadores incrementan o
	decrementan la variable en una unidad, aunque
	<quote>unidad</quote> puede tener diferentes significados
	dependiendo del tipo de dato - esto es especialmente importante en
	el caso de los punteros.
      </para>

      <!--
      The last unary operators are the address-of (&), dereference (*
      and ->), and cast operators in C and C++, and new and delete in
      C++. Address-of and dereference are used with pointers , described
      in this chapter. Casting is described later in this chapter, and
      new and delete are introduced in Chapter 4.
      -->

      <para>
	Los últimos operadores unarios son dirección-de
	(<oper>&amp;</oper>), indirección (<oper>*</oper> y
	<oper>-></oper>), los operadores de moldeado en C y C++, y
	<oper>new</oper> y <oper>delete</oper> en C++. La dirección-de y
	la indirección se utilizan con los punteros, descriptos en este
	capítulo. El moldeado se describe mas adelante en este capítulo,
	y <oper>new</oper> y <oper>delete</oper> se introducen en el
	Capítulo 4.
      </para>
    </sect2>


    <sect2>
      <!--The ternary operator-->
      <title>El operador ternario</title>

      <!--
      The ternary if-else is unusual because it has three operands. It
      is truly an operator because it produces a value, unlike the
      ordinary if-else statement. It consists of three expressions: if
      the first expression (followed by a ?) evaluates to true, the
      expression following the ? is evaluated and its result becomes the
      value produced by the operator. If the first expression is false,
      the third expression (following a :) is executed and its result
      becomes the value produced by the operator.
      -->

      <para>
	El <kw>if-else</kw> ternario es inusual porque tiene tres
	operandos. Realmente es un operador porque produce un valor, al
	contrario de la sentencia ordinaria <kw>if-else</kw>. Consta de
	tres expresiones: si la primera expresión (seguida de un
	<literal>?</literal>) se evalúa como cierto, se devuelve el
	resultado de evaluar la expresión que sigue al
	<literal>?</literal>. Si la primera expresión es falsa, se
	ejecuta la tercera expresión (que sigue a <literal>:</literal>)
	y su resultado se convierte en el valor producido por
	el operador.
      </para>

      <!--
      The conditional operator can be used for its side effects or for
      the value it produces. Here's a code fragment that demonstrates
      both:
      -->

      <para>
	El operador condicional se puede usar por sus efectos colaterales
	o por el valor que produce. A continuación, un fragmento de
	código que demuestra ambas cosas:
      </para>


<programlisting>
a = --b ? b : (b = -99);
</programlisting>


      <!--
      Here, the conditional produces the rvalue. a is assigned to the
      value of b if the result of decrementing b is nonzero. If b became
      zero, a and b are both assigned to -99. b is always decremented,
      but it is assigned to -99 only if the decrement causes b to become
      0. A similar statement can be used without the "a =" just for its
      side effects:
      -->

      <para>
	Aquí, el condicional produce el <emphasis>rvalue</emphasis>. A
	<varname>a</varname> se le asigna el valor de
	<varname>b</varname> si el resultado de decrementar
	<varname>b</varname> es diferente de cero. Si
	<varname>b</varname> se queda a cero, <varname>a</varname> y
	<varname>b</varname> son ambas asignadas a
	-99. <varname>b</varname> siempre se decrementa, pero se asigna
	a -99 sólo si el decremento provoca que <varname>b</varname>
	valga 0. Se puede utilizar un sentencia similar sin el <code>a
	=</code> sólo por sus efectos colaterales:
      </para>


<programlisting>
--b ? b : (b = -99);
</programlisting>


      <!--
      Here the second B is superfluous, since the value produced by the
      operator is unused. An expression is required between the ? and
      :. In this case, the expression could simply be a constant that
      might make the code run a bit faster.
      -->

      <para>
	Aquí la segunda <varname>b</varname> es superflua, ya que no se
	utiliza el valor producido por el operador. Se requiere una
	expresión entre el <literal>?</literal> y
	<literal>:</literal>. En este caso, la expresión puede ser
	simplemente una constante, lo que haría que el código se ejecute
	un poco más rápido.
      </para>
    </sect2>

    <sect2>
      <!--The comma operator-->
      <title>El operador coma</title>

      <!--
      The comma is not restricted to separating variable names in
      multiple definitions, such as
      -->

      <para>
	La coma no se limita a separar nombres de variables en
	definiciones múltiples, tales como
      </para>


<programlisting>
int i, j, k;
</programlisting>


      <!--
      Of course, it's also used in function argument lists. However, it
      can also be used as an operator to separate expressions - in this
      case it produces only the value of the last expression. All the
      rest of the expressions in the comma-separated list are evaluated
      only for their side effects. This example increments a list of
      variables and uses the last one as the rvalue:
      -->

      <para>
	Por supuesto, también se usa en listas de argumentos de
	funciones. De todos modos, también se puede utilizar como un
	operador para separar expresiones - en este caso produce el
	valor de la última expresión. El resto de expresiones en la
	lista separada por comas se evalúa sólo por sus efectos
	colaterales. Este ejemplo incrementa una lista de variables y
	usa la última como el <emphasis>rvalue</emphasis>:
      </para>


//: V1C03:CommaOperator.cpp


      <!--
      In general, it's best to avoid using the comma as anything
      other than a separator, since people are not used to seeing it as
      an operator.
      -->

      <para>
	En general, es mejor evitar el uso de la coma para cualquier
	otra cosa que no sea separar, ya que la gente no está acostumbrada
	a verla como un operador.
      </para>
    </sect2>


    <sect2>
      <!--Common pitfalls when using operators-->
      <title>Trampas habituales cuando se usan operadores</title>

      <!--
      As illustrated above, one of the pitfalls when using operators is
      trying to get away without parentheses when you are even the least
      bit uncertain about how an expression will evaluate (consult your
      local C manual for the order of expression evaluation).
      -->

      <para>
	Como se ha ilustrado anteriormente, una de las trampas al usar
	operadores es tratar de trabajar sin paréntesis incluso cuando
	no se está seguro de la forma en la que se va a evaluar la
	expresión (consulte su propio manual de C para comprobar el
	orden de la evaluación de las expresiones).
      </para>

      <!--
      Another extremely common error looks like this:
      -->

      <para>
	Otro error extremadamente común se ve a continuación:
      </para>


//: V1C03:Pitfall.cpp


      <!--
      The statement a = b will always evaluate to true when b is
      non-zero. The variable a is assigned to the value of b, and the
      value of b is also produced by the operator =. In general, you
      want to use the equivalence operator == inside a conditional
      statement, not assignment. This one bites a lot of programmers
      (however, some compilers will point out the problem to you, which
      is helpful).
      -->

      <para>
	La sentencia <code>a = b</code> siempre se va a evaluar como
	cierta cuando <varname>b</varname> es distinta de cero. La
	variable <varname>a</varname> obtiene el valor de
	<varname>b</varname>, y el valor de <varname>b</varname> también
	es producido por el operador <oper>=</oper>. En general, lo que
	se pretende es utilizar el operador de equivalencia
	(<oper>==</oper> dentro de una sentencia condicional, no la
	asignación. Esto le ocurre a muchos programadores (de todos
	modos, algunos compiladores advierten del problema, lo cual es
	una ayuda).
      </para>

      <!--
      A similar problem is using bitwise and and or instead of their
      logical counterparts. Bitwise and and or use one of the characters
      (& or |), while logical and and or use two (&& and ||). Just as
      with = and ==, it's easy to just type one character instead of
      two. A useful mnemonic device is to observe that "Bits are
      smaller, so they don't need as many characters in their
      operators."
      -->

      <para>
	Un problema similar es usar los operadores
	<emphasis>and</emphasis> y <emphasis>or</emphasis> de bits en
	lugar de sus equivalentes lógicos. Los operadores
	<emphasis>and</emphasis> y <emphasis>or</emphasis> de bits usan
	uno de los caracteres (<oper>&amp;</oper> o <oper>|</oper>),
	mientras que los operadores lógicos utilizan dos
	(<oper>&amp;&amp;</oper> y <oper>||</oper>). Al igual que con
	<oper>=</oper> y <oper>==</oper>, es fácil escribir simplemente
	un carácter en vez de dos. Una forma muy fácil de recordarlo es
	que <quote>los bits son mas pequeños, de modo que no necesitan
	tantos caracteres en sus operadores</quote>.
      </para>
    </sect2>


    <sect2>
      <!--Casting operators-->
      <title>Operadores de moldeado</title>

      <!--
      The word cast is used in the sense of "casting into a mold." The
      compiler will automatically change one type of data into another
      if it makes sense. For instance, if you assign an integral value
      to a floating-point variable, the compiler will secretly call a
      function (or more probably, insert code) to convert the int to a
      float. Casting allows you to make this type conversion explicit,
      or to force it when it wouldn't normally happen.
      -->

      <para>
	La palabra molde(<emphasis>cast</emphasis>) se usa en el sentido
	de "colocar dentro de un molde". El compilador cambiará
	automáticamente un tipo de dato a otro si tiene sentido. De
	hecho, si se asigna un valor entero a una variable de punto
	flotante, el compilador llamará secretamente a una función (o
	más probablemente, insertará código) para convertir el
	<type>int</type> a un <type>float</type>. El molde permite
	hacer este tipo de conversión explicita, o forzarla cuando
	normalmente no pasaría.
      </para>

      <!--
      To perform a cast, put the desired data type (including all
      modifiers) inside parentheses to the left of the value. This value
      can be a variable, a constant, the value produced by an
      expression, or the return value of a function. Here's an example:
      -->

      <para>
	Para realizar un molde, se debe situar el tipo deseado
	(incluyendo todos los modificadores) dentro de paréntesis a la
	izquierda del valor. Este valor puede ser una variable, una
	constante, el valor producido por una expresión, o el valor
	devulto por una función. A continuación, un ejemplo:
      </para>


//: V1C03:SimpleCast.cpp


      <!--
      Casting is powerful, but it can cause headaches because in some
      situations it forces the compiler to treat data as if it were (for
      instance) larger than it really is, so it will occupy more space
      in memory; this can trample over other data. This usually occurs
      when casting pointers, not when making simple casts like the one
      shown above.
      -->

      <para>
	El moldeado es poderoso, pero puede causar dolores de cabeza
	porque en algunas situaciones fuerza al compilador a tratar
	datos como si fuesen (por ejemplo) más largos de lo que
	realmente son, de modo que ocupará más espacio en memoria; lo
	que puede afectar a otros datos. Esto ocurre a menudo cuando se
	moldean punteros, no cuando se hacen moldes simples como los
	que ha visto anteriormente.
      </para>

      <!--
      C++ has an additional casting syntax, which follows the function
      call syntax. This syntax puts the parentheses around the argument,
      like a function call, rather than around the data type:
      -->

      <para>
	C++ tiene una sintaxis adicional para moldes, que sigue a la
	sintaxis de llamada a funciones. Esta sintaxis pone los
	paréntesis alrededor del argumento, como en una llamada a
	función, en lugar de a los lados del tipo:
      </para>


//: V1C03:FunctionCallCast.cpp


      <!--
      Of course in the case above you wouldn't really need a cast; you
      could just say 200.f or 200.0f(in effect, that's typically what
      the compiler will do for the above expression). Casts are
      generally usually used instead with variables, rather than with
      constants.
      -->

      <para>
	Por supuesto, en el caso anterior, en realidad no se necesitaría
	un molde; simplemente se puede decir <constant>200.f</constant>
	o <constant>200.0f</constant> (en efecto, eso es típicamente lo
	que el compilador hará para la expresión anterior). Los moldes
	normalmente se utilizan con variables, en lugar de con constantes.
      </para>
    </sect2>


    <sect2>
      <!-- C++ explicit casts -->
      <title>Los moldes explícitos de C++</title>

      <!--
      Casts should be used carefully, because what you are actually
      doing is saying to the compiler "Forget type checking - treat it
      as this other type instead." That is, you're introducing a hole in
      the C++ type system and preventing the compiler from telling you
      that you're doing something wrong with a type. What's worse, the
      compiler believes you implicitly and doesn't perform any other
      checking to catch errors. Once you start casting, you open
      yourself up for all kinds of problems. In fact, any program that
      uses a lot of casts should be viewed with suspicion, no matter how
      much you are told it simply "must" be done that way. In general,
      casts should be few and isolated to the solution of very specific
      problems.
      -->

      <para>
        Los moldes se deben utilizar con cuidado, porque lo que está
        haciendo en realidad es decir al compilador <quote>Olvida la
        comprobación de tipo - trátalo como si fuese de este otro
        tipo.</quote> Esto significa, que está introduciendo un agujero
        en el sistema de tipos de C++ y evitando que el compilador
        informe de que está haciendo algo erróneo con un tipo. Lo que es
        peor, el compilador lo cree implícitamente y no realiza ninguna
        otra comprobación para buscar errores. Una vez ha comenzado a
        moldear, está expuesto a todo tipo de problemas. De hecho,
        cualquier programa que utilice muchos moldes se debe revisar con
        detenimiento, no importa cuanto haya dado por sentado que
        simplemente <quote>debe</quote> hacerse de esta manera. En
        general, los moldes deben ser pocos y aislados para solucionar
        problemas específicos.
      </para>

      <!--
      Once you understand this and are presented with a buggy program,
      your first inclination may be to look for casts as culprits. But
      how do you locate C-style casts? They are simply type names inside
      of parentheses, and if you start hunting for such things you'll
      discover that it's often hard to distinguish them from the rest of
      your code.
      -->


      <para>
	Una vez se ha entendido esto y se presente un programa con
	errores, la primera impresión puede que sea mirar los moldes
	como si fuesen los culpables. Pero, ¿cómo encontrar los moldes
	estilo C? Son simplemente nombres de tipos entre paréntesis, y
	si se empieza a buscar estas cosas descubrirá que a menudo es
	difícil distinguirlos del resto del código.
      </para>

      <!--
      Standard C++ includes an explicit cast syntax that can be used to
      completely replace the old C-style casts (of course, C-style casts
      cannot be outlawed without breaking code, but compiler writers
      could easily flag old-style casts for you). The explicit cast
      syntax is such that you can easily find them, as you can see by
      their names:
      -->

      <para>
	El C++ Estándar incluye una sintaxis explícita de molde que se
	puede utilizar para reemplazar completamente los moldes del
	estilo antiguo de C (por supuesto, los moldes de estilo C no se
	pueden prohibir sin romper el código, pero los escritores de
	compiladores pueden advertir fácilmente acerca de los moldes
	antiguos). La sintaxis explícita de moldes está pensada para que
	sea fácil encontrarlos, tal como se puede observar por sus
	nombres:
      </para>


      <table>
        <!-- TABLA  -->
        <title>Moldes explícitos de C++</title>

        <tgroup cols="2">
          <tbody>
            <row>
              <entry><kw>static_cast</kw></entry>
              <!--
              For "well-behaved" and "reasonably well-behaved"
              casts, including things you might now do without a cast
              (such as an automatic type conversion).
              -->
              <entry>
                Para moldes que se <emphasis>comportan bien</emphasis> o
                <emphasis>razonablemente bien</emphasis>, incluyendo
                cosas que se podrían hacer sin un molde (como una
                conversión automática de tipo).
              </entry>
            </row>
            <row>
              <entry><kw>const_cast</kw></entry>
              <!--
              To cast away const and/or volatile
              -->
              <entry>
                Para moldear <kw>const</kw> y/o <kw>volatile</kw>
              </entry>
            </row>
            <row>
              <entry><kw>reinterpret_cast</kw></entry>
              <!--
              To cast to a completely different meaning. The key is
              that you'll need to cast back to the original type to
              use it safely. The type you cast to is typically used
              only for bit twiddling or some other mysterious
              purpose. This is the most dangerous of all the casts.
              -->
              <entry>
                Para moldear a un significado completamente
                diferente. La clave es que se necesitará volver a
                moldear al tipo original para poderlo usar con
                seguridad. El tipo al que moldee se usa típicamente sólo
                para jugar un poco o algún otro propósito
                misterioso. Éste es el más peligroso de todos los
                moldes.
              </entry>
            </row>
            <row>
              <entry><kw>dynamic_cast</kw></entry>
              <!--
              For type-safe downcasting (this cast will be described in
              Chapter 15).
              -->
              <entry>
                Para realizar un <emphasis>downcasting</emphasis> seguro
                (este molde se describe en el Capítulo 15).
              </entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <!--
      The first three explicit casts will be described more completely
      in the following sections, while the last one can be demonstrated
      only after you've learned more, in Chapter 15.
      -->

      <para>
	Los primeros tres moldes explícitos se describirán completamente
	en las siguientes secciones, mientras que los últimos se
	explicarán después de que haya aprendido más en el Capítulo 15.
      </para>

      <sect3>
        <title><kw>static_cast</kw></title>

        <!--
        A static_cast is used for all conversions that are
        well-defined. These include "safe" conversions that the compiler
        would allow you to do without a cast and less-safe conversions
        that are nonetheless well-defined. The types of conversions
        covered by static_cast include typical castless conversions,
        narrowing (information-losing) conversions, forcing a conversion
        from a void*, implicit type conversions, and static navigation
        of class hierarchies (since you haven't seen classes and
        inheritance yet, this last topic will be delayed until Chapter
        15):
        -->

        <para>
	  El <kw>static_cast</kw> se utiliza para todas las conversiones
	  que están bien definidas. Esto incluye conversiones
	  <quote>seguras</quote> que el compilador permitiría sin
	  utilizar un molde, y conversiones menos seguras que están sin
	  embargo bien definidas. Los tipos de conversiones que cubre
	  <kw>static_cast</kw> incluyen las conversiones típicas sin
	  molde, conversiones de estrechamiento (pérdida de
	  información), forzar una conversión de un <type>void*</type>,
	  conversiones de tipo implícitas, y navegación estática de
	  jerarquías de clases (ya que no se han visto aún clases ni
	  herencias, este último apartado se pospone hasta el Capítulo
	  15):
        </para>


//: V1C03:static_cast.cpp


      <!--
        In Section (1), you see the kinds of conversions you're used to
        doing in C, with or without a cast. Promoting from an int to a
        long or float is not a problem because the latter can always
        hold every value that an int can contain. Although it's
        unnecessary, you can use static_cast to highlight these
        promotions.
	-->

        <para>
          En la sección (FIXME:xref:1), se pueden ver tipos de
          conversiones que eran usuales en C, con o sin un
          molde. Promover un <type>int</type> a <type>long</type> o
          <type>float</type> no es un problema porque el último puede
          albergar siempre cualquier valor que un <type>int</type>
          pueda contener. Aunque es innecesario, se puede utilizar
          <kw>static_cast</kw> para remarcar estas promociones.
        </para>

        <!--
        Converting back the other way is shown in (2). Here, you can
        lose data because an int is not as "wide" as a long or a float;
        it won't hold numbers of the same size. Thus these are called
        narrowing conversions. The compiler will still perform these,
        but will often give you a warning. You can eliminate this
        warning and indicate that you really did mean it using a cast.
        -->

        <para>
	  Se muestra en (2) como se convierte al revés. Aquí, se puede
	  perder información porque un <type>int</type> no es tan
	  <quote>ancho</quote> como un <type>long</type> o un
	  <type>float</type>; no aloja números del mismo tamaño. De
	  cualquier modo, este tipo de conversión se llama conversión de
	  estrechamiento. El compilador no impedirá que ocurran, pero
	  normalmente dará una advertencia. Se puede eliminar esta
	  advertencia e indicar que realmente se pretendía esto
	  utilizando un molde.
        </para>

        <!--
        Assigning from a void* is not allowed without a cast in C++
        (unlike C), as seen in (3). This is dangerous and requires that
        programmers know what they're doing. The static_cast, at least,
        is easier to locate than the old standard cast when you're
        hunting for bugs.
        -->

        <para>
          Tomar el valor de un <type>void*</type> no está permitido en
          C++ a menos que use un molde (al contrario de C), como se
          puede ver en (3). Esto es peligroso y requiere que los
          programadores sepan lo que están haciendo. El
          <kw>static_cast</kw>, al menos, es mas fácil de localizar que
          los moldes antiguos cuando se trata de cazar fallos.
        </para>

        <!--
        Section (4) of the program shows the kinds of implicit type
        conversions that are normally performed automatically by the
        compiler. These are automatic and require no casting, but again
        static_cast highlights the action in case you want to make it
        clear what's happening or hunt for it later.
        -->

        <para>
          La sección (FIXME:xref:4) del programa muestra las
          conversiones de tipo implícitas que normalmente se realizan
          de manera automática por el compilador. Son automáticas y no
          requieren molde, pero el utilizar <kw>static_cast</kw>
          acentúa dicha acción en caso de que se quiera reflejar
          claramente qué está ocurriendo, para poder localizarlo
          después.
        </para>
      </sect3>

      <sect3>
        <title><kw>const_cast</kw></title>

        <!--
        If you want to convert from a const to a nonconst or from a
        volatile to a nonvolatile, you use const_cast. This is the only
        conversion allowed with const_cast; if any other conversion is
        involved it must be done using a separate expression or you'll
        get a compile-time error.
        -->

        <para>
          Si quiere convertir de un <kw>const</kw> a un
          no-<kw>const</kw> o de un <kw>volatile</kw> a un
          no-<kw>volatile</kw>, se utiliza <kw>const_cast</kw>. Es la
          única conversión permitida con <kw>const_cast</kw>; si está
          involucrada alguna conversión adicional se debe hacer
          utilizando una expresión separada o se obtendrá un error en
          tiempo de compilación.
        </para>


//: V1C03:const_cast.cpp


        <!--
        If you take the address of a const object, you produce a pointer
        to a const, and this cannot be assigned to a nonconst pointer
        without a cast. The old-style cast will accomplish this, but the
        const_cast is the appropriate one to use. The same holds true
        for volatile.
        -->

        <para>
          Si toma la dirección de un objeto <kw>const</kw>, produce un
          puntero a <kw>const</kw>, éste no se puede asignar a un
          puntero que no sea <kw>const</kw> sin un molde. El molde al
          estilo antiguo lo puede hacer, pero el <kw>const_cast</kw> es
          el más apropiado en este caso. Lo mismo ocurre con
          <kw>volatile</kw>.
        </para>
      </sect3>

      <sect3>
        <title><kw>reinterpret_cast</kw></title>

        <!--
        This is the least safe of the casting mechanisms, and the one
        most likely to produce bugs. A reinterpret_cast pretends that an
        object is just a bit pattern that can be treated (for some dark
        purpose) as if it were an entirely different type of
        object. This is the low-level bit twiddling that C is notorious
        for. You'll virtually always need to reinterpret_cast back to
        the original type (or otherwise treat the variable as its
        original type) before doing anything else with it.
        -->

        <para>
          Este es el menos seguro de los mecanismos de molde, y el más
          susceptible de crear fallos. Un <kw>reinterpret_cast</kw>
          supone que un objeto es un patrón de bits que se puede
          tratar (para algún oscuro propósito) como si fuese de un
          tipo totalmente distinto. Ese es el jugueteo de bits a bajo
          nivel por el cual C es famoso. Prácticamente siempre
          necesitará hacer <kw>reinterpret_cast</kw> para volver al
          tipo original (o de lo contrario tratar a la variable como
          su tipo original) antes de hacer nada más con ella.
        </para>


//: V1C03:reinterpret_cast.cpp


        <!--
        In this simple example, struct X just contains an array of int,
        but when you create one on the stack as in X x, the values of
        each of the ints are garbage (this is shown using the print( )
        function to display the contents of the struct). To initialize
        them, the address of the X is taken and cast to an int pointer,
        which is then walked through the array to set each int to
        zero. Notice how the upper bound for i is calculated by "adding"
        sz to xp ; the compiler knows that you actually want sz pointer
        locations greater than xp and it does the correct pointer
        arithmetic for you.
        -->

        <para>
          En este ejemplo, <code>struct X</code> contiene un array de
          <type>int</type>, pero cuando se crea uno en la pila como en
          <code>X x</code>, los valores de cada uno de los
          <type>int</type>s tienen basura (esto se demuestra utilizando la
          función <function>print()</function> para mostrar los
          contenidos de <kw>struct</kw>). Para inicializarlas, la
          dirección del <type>X</type> se toma y se moldea a un puntero
          <type>int</type>, que es luego iterado a través del array para
          inicializar cada <type>int</type> a cero. Fíjese como el
          límite superior de <varname>i</varname> se calcula
          <quote>añadiendo</quote> <varname>sz</varname> a
          <varname>xp</varname>; el compilador sabe que lo que usted
          quiere realmente son las direcciones de sz mayores que
          <varname>xp</varname> y él realiza el cálculo aritmético por
          usted. FIXME(Comprobar lo que dice este párrafo de acuerdo con
          el código)

<!-- FIXME: dice javieralso:

Creo (a título personal) que podría quedar un poco mas claro algo
como:

"el compilador sabe que lo que usted quiere realmente son las
direcciones de los enteros contenidos en el array x.a, que comienzan
en la misma dirección que x (dirección almacenada en el puntero xp) y
cuya última dirección es la dirección [xp]+99 y él realiza el cálculo
aritmético por usted."

-->


        </para>

        <!--
        The idea of reinterpret_cast is that when you use it, what you
        get is so foreign that it cannot be used for the type's original
        purpose unless you cast it back. Here, we see the cast back to
        an X* in the call to print, but of course since you still have
        the original identifier you can also use that. But the xp is
        only useful as an int*, which is truly a "reinterpretation" of
        the original X.
        -->

        <para>
          La idea del uso de <kw>reinterpret_cast</kw> es que cuando se
          utiliza, lo que se obtiene es tan extraño que no se puede
          utilizar para los propósitos del tipo original, a menos que se
          vuelva a moldear.  Aquí, vemos el molde otra vez a
          <type>X*</type> en la llamada a <function>print()</function>,
          pero por supuesto, dado que tiene el identificador original
          también se puede utilizar. Pero <varname>xp</varname> sólo es
          útil como un <type>int*</type>, lo que es
          verdaderamente una <quote>reinterpretación</quote> del <type>X</type>
          original.
        </para>


        <!--
        A reinterpret_cast often indicates inadvisable and/or
        nonportable programming, but it's available when you decide you
        have to use it.
        -->

        <para>
          Un <kw>reinterpret_cast</kw> a menudo indica una programación
          desaconsejada y/o no portable, pero está disponible si decide
          que lo necesita.
        </para>
      </sect3>
    </sect2>



    <sect2>
      <!-- sizeof - an operator by itself  -->
      <title><oper>sizeof</oper> - un operador en si mismo</title>

      <!--
      The sizeof operator stands alone because it satisfies an unusual
      need. sizeof gives you information about the amount of memory
      allocated for data items. As described earlier in this chapter,
      sizeof tells you the number of bytes used by any particular
      variable. It can also give the size of a data type (with no
      variable name):
      -->

      <para>
        El operador <oper>sizeof</oper> es independiente porque
        satisface una necesidad inusual. <oper>sizeof</oper> proporciona
        información acerca de la cantidad de memoria ocupada por los
        elementos de datos. Como se ha indicado antes en este capítulo,
        <oper>sizeof</oper> indica el número de bytes utilizado por
        cualquier variable particular. También puede dar el tamaño de un
        tipo de datos (sin necesidad de un nombre de variable):
      </para>


//: V1C03:sizeof.cpp


      <!--
      By definition, the sizeof any type of char (signed, unsigned or
      plain) is always one, regardless of whether the underlying storage
      for a char is actually one byte. For all other types, the result
      is the size in bytes.
      -->

      <para>
        Por definición, el <oper>sizeof</oper> de cualquier tipo de
        <type>char</type> (<type>signed</type>, <type>unsigned</type> o
        simple) es siempre uno, sin tener en cuenta que el
        almacenamiento subyacente para un <type>char</type> es realmente
        un byte. Para todos los demás tipos, el resultado es el tamaño
        en bytes.
      </para>

      <!--
      Note that sizeof is an operator, not a function. If you apply it
      to a type, it must be used with the parenthesized form shown
      above, but if you apply it to a variable you can use it without
      parentheses:
      -->

      <para>
        Tenga en cuenta que <oper>sizeof</oper> es un operador, no una
        función. Si lo aplica a un tipo, se debe utilizar con la
        forma entre paréntesis mostrada anteriormente, pero si se aplica
        a una variable se puede utilizar sin paréntesis:
      </para>


//: V1C03:sizeofOperator.cpp


      <!--
      sizeof can also give you the sizes of user-defined data
      types. This is used later in the book.
        -->

      <para>
        <oper>sizeof</oper> también puede informar de los tamaños de
        tipos definidos por el usuario. Se utilizará más adelante en el
        libro.
      </para>
    </sect2>

    <sect2>
      <!-- The asm keyword -->
      <title>La palabra reservada <kw>asm</kw></title>

      <!--
      This is an escape mechanism that allows you to write assembly code
      for your hardware within a C++ program. Often you're able to
      reference C++ variables within the assembly code, which means you
      can easily communicate with your C++ code and limit the assembly
      code to that necessary for efficiency tuning or to use special
      processor instructions. The exact syntax that you must use when
      writing the assembly language is compiler-dependent and can be
      discovered in your compiler's documentation.
      -->

      <para>
        Este es un mecanismo de escape que permite escribir código
        ensamblador para el hardware dentro de un programa en C++. A
        menudo es capaz de referenciar variables C++ dentro del
        código ensamblador, lo que significa que se puede comunicar
        fácilmente con el código C++ y limitar el código ensamblador a
        lo necesario para ajustes eficientes o para utilizar
        instrucciones especiales del procesador. La sintaxis exacta que
        se debe usar cuando se escribe en lenguaje ensamblador es
        dependiente del compilador y se puede encontrar en la
        documentación del compilador.
      </para>
    </sect2>

    <sect2>
      <!-- Explicit operators -->
      <title>Operadores explícitos</title>

      <!--
      These are keywords for bitwise and logical operators
      . Non-U.S. programmers without keyboard characters like &, |, ^,
      and so on, were forced to use C's horrible trigraphs, which were
      not only annoying to type, but obscure when reading. This is
      repaired in C++ with additional keywords:
      -->

      <para>
        Son palabras reservadas para los operadores lógicos y
        binarios. Los programadores de fuera de los USA sin teclados con
        caracteres tales como &amp;, |, ^, y demás, estaban forzados a
        utilizar horribles <emphasis>trígrafos</emphasis>, que no sólo
        eran insoportable de escribir, además eran difíciles de
        leer. Esto se ha paliado en C++ con palabras reservadas
        adicionales:
      </para>


      <table>
        <!-- TABLA -->
        <title>Nuevas palabras reservadas para operadores booleanos</title>
        <tgroup cols="2">
          <thead>
            <row>
              <entry>Palabra reservada</entry>
              <entry>Significado</entry>
            </row>
          </thead>
          <tbody>
            <row>
              <entry><kw>and</kw></entry>
              <entry>&amp;&amp; ( <quote>y</quote> lógica)</entry>
            </row>
            <row>
              <entry><kw>or</kw></entry>
              <entry>|| (<quote>o</quote> lógica)</entry>
            </row>
            <row>
              <entry><kw>not</kw></entry>
              <entry>! (negación lógica)</entry>
            </row>
            <row>
              <entry><kw>not_eq</kw></entry>
              <entry>!= (no-equivalencia lógica)</entry>
            </row>
            <row>
              <entry><kw>bitand</kw></entry>
              <entry>&amp; (and para bits)</entry>
            </row>
            <row>
              <entry><kw>and_eq</kw></entry>
              <entry>&amp;= (asignación-and para bits)</entry>
            </row>
            <row>
              <entry><kw>bitor</kw></entry>
              <entry>| (or para bits)</entry>
            </row>
            <row>
              <entry><kw>or_eq</kw></entry>
              <entry>!= (asignación-or para bits)</entry>
            </row>
            <row>
              <entry><kw>xor</kw></entry>
              <entry>^ (<quote>o</quote> exclusiva para bits)</entry>
            </row>
            <row>
              <entry><kw>xor_equ</kw></entry>
              <entry>^= (asignación xor para bits)</entry>
            </row>
            <row>
              <entry><kw>compl</kw></entry>
              <entry>~ (complemento binario)</entry>
            </row>
          </tbody>
        </tgroup>
      </table>


      <!--
      If your compiler complies with Standard C++, it will support these
      keywords.
      -->

      <para>
        Si el compilador obedece al Estándar C++, soportará estas palabras
        reservadas.
      </para>
    </sect2>
  </sect1>


  <sect1>
    <!-- Composite type creation -->
    <title>Creación de tipos compuestos</title>

    <!--
    The fundamental data types and their variations are essential, but
    rather primitive. C and C++ provide tools that allow you to compose
    more sophisticated data types from the fundamental data types. As
    you'll see, the most important of these is struct, which is the
    foundation for class in C++. However, the simplest way to create
    more sophisticated types is simply to alias a name to another name
    via typedef.
    -->

    <para>
      Los tipos de datos fundamentales y sus variantes son esenciales,
      pero más bien primitivos. C y C++ incorporan herramientas que
      permiten construir tipos de datos más sofisticados a partir de los
      tipos de datos fundamentales. Como se verá, el más importante de
      estos es <kw>struct</kw>, que es el fundamento para las
      <kw>class</kw> en C++.  Sin embargo, la manera más simple de crear
      tipos más sofisticados es simplemente poniendo un alias a otro nombre
      mediante <kw>typedef</kw>.
    </para>

    <sect2>
      <!-- Aliasing names with typedef  -->
      <title>Creación de alias usando <kw>typedef</kw></title>

      <!--
      This keyword promises more than it delivers: typedef suggests
      "type definition" when "alias" would probably have been a more
      accurate description, since that's what it really does. The syntax
      is:
      -->

      <para>
        Esta palabra reservada promete más de lo que da:
        <kw>typedef</kw> sugiere <quote>definición de tipo</quote>
        cuando <quote>alias</quote> habría sido probablemente una
        descripción más acertada, ya que eso es lo que hace
        realmente. La sintaxis es:
      </para>

      <!--
      typedef existing-type-description alias-name
      -->

      <para>
	<kw>typede</kw>f descripción-de-tipo-existente nombre-alias
      </para>

      <!--
      People often use typedef when data types get slightly complicated,
      just to prevent extra keystrokes. Here is a commonly-used typedef:
      -->

      <para>
	La gente a menudo utiliza <kw>typedef</kw> cuando los tipos de
	datos se vuelven complicados, simplemente para evitar escribir
	más de lo necesario. A continuación, una forma común de utilizar
	typedef:
      </para>


<programlisting>
typedef unsigned long ulong;
</programlisting>


      <!--
      Now if you say ulong the compiler knows that you mean unsigned
      long. You might think that this could as easily be accomplished
      using preprocessor substitution, but there are key situations in
      which the compiler must be aware that you're treating a name as if
      it were a type, so typedef is essential.

      One place where typedef comes in handy is for pointer types. As
      previously mentioned, if you say:
      -->

      <para>
        Ahora si pone <type>ulong</type>, el compilador sabe que se está
        refiriendo a <type>unsigned long</type>. Puede pensar que esto
        se puede lograr fácilmente utilizando sustitución en el
        preprocesador, pero hay situaciones en las cuales el compilador
        debe estar advertido de que está tratando un nombre como si
        fuese un tipo, y por eso <kw>typedef</kw> es esencial.
      </para>


<programlisting>
int* x, y;
</programlisting>


      <!--
      This actually produces an int* which is x and an int (not an int*)
      which is y. That is, the '*' binds to the right, not the
      left. However, if you use a typedef:
      -->

      <para>
	Esto genera en realidad un <type>int*</type> que es
	<varname>x</varname>, y un <type>int</type> (no un
	<type>int*</type>) que es <varname>y</varname>. Esto significa
	que el <token>*</token> añade a la derecha, no a la
	izquierda. Pero, si utiliza un <kw>typedef</kw>:
      </para>


<programlisting>
typedef int* IntPtr;
IntPtr x, y;
</programlisting>


      <!--
      Then both x and y are of type int* .
      -->

      <para>
        Entonces ambos, <varname>x</varname> e <varname>y</varname> son
        del tipo <type>int*</type>.
      </para>

      <!--
      You can argue that it's more explicit and therefore more readable
      to avoid typedefs for primitive types, and indeed programs rapidly
      become difficult to read when many typedefs are used. However,
      typedefs become especially important in C when used with struct.
      -->

      <para>
        Se puede discutir sobre ello y decir que es más explícito y por
        consiguiente mas legible evitar <kw>typedef</kw>s para los tipos
        primitivos, y de hecho los programas se vuelven difíciles de
        leer cuando se utilizan demasiados <kw>typedef</kw>s. De todos
        modos, los <kw>typedef</kw>s se vuelven especialmente
        importantes en C cuando se utilizan con <kw>struct</kw>.
      </para>
    </sect2>


    <sect2>
      <!-- Combinar variables con struct -->
      <title>
        Usar <kw>struct</kw> para combinar variables
      </title>

      <!--
      A struct is a way to collect a group of variables into a
      structure. Once you create a struct, then you can make many
      instances of this "new" type of variable you've invented. For
      example:
      -->

      <para>
        Un <kw>struct</kw> es una manera de juntar un grupo de variables
        en una estructura. Cuando se crea un <kw>struct</kw>, se pueden
        crear varias instancias de este <quote>nuevo</quote> tipo de
        variable que ha inventado. Por ejemplo:
      </para>


//: V1C03:SimpleStruct.cpp


      <!--
      The struct declaration must end with a semicolon. In main( ), two
      instances of Structure1 are created: s1 and s2. Each of these has
      their own separate versions of c, i, f, and d. So s1 and s2
      represent clumps of completely independent variables. To select
      one of the elements within s1 or s2, you use a '.', syntax you've
      seen in the previous chapter when using C++ class objects - since
      classes evolved from structs, this is where that syntax arose
      from.
      -->

      <para>
        La declaración de <kw>struct</kw> debe acabar con una llave. En
        <function>main()</function>, se crean dos instancias de
        <type>Structure1</type>: <varname>s1</varname> y
        <varname>s2</varname>.  Cada una de ellas tiene su versión
        propia y separada de <varname>c</varname>, <varname>I</varname>,
        <varname>f</varname> y <varname>d</varname>. De modo que
        <varname>s1</varname> y <varname>s2</varname> representan
        bloques de variables completamente independientes. Para
        seleccionar uno de estos elementos dentro de
        <varname>s1</varname> o <varname>s2</varname>, se utiliza un
        <token>.</token>, sintaxis que se ha visto en el cápitulo
        previo cuando se utilizaban objetos <kw>class</kw> de C++ - ya
        que las clases surgían de <kw>struct</kw>s, de ahí proviene esta
        sintaxis.
      </para>

      <!--
      One thing you'll notice is the awkwardness of the use of
      Structure1 (as it turns out, this is only required by C, not
      C++). In C, you can't just say Structure1 when you're defining
      variables, you must say struct Structure1. This is where typedef
      becomes especially handy in C:
      -->

      <para>
        Una cosa a tener en cuenta es la torpeza de usar
        <type>Structure1</type> (como salta a la vista, eso sólo se
        requiere en C, y no en C++). En C, no se puede poner
        <type>Structure1</type> cuando se definen variables, se debe
        poner <type>struct Structure1</type>. Aquí es donde
        <kw>typedef</kw> se vuelve especialmente útil en C:
      </para>


//: V1C03:SimpleStruct2.cpp


      <!--
      By using typedef in this way, you can pretend (in C; try removing
      the typedef for C++) that Structure2 is a built-in type, like int
      or float, when you define s1 and s2 (but notice it only has data -
      characteristics - and does not include behavior, which is what we
      get with real objects in C++). You'll notice that the struct
      identifier has been left off at the beginning, because the goal is
      to create the typedef. However, there are times when you might
      need to refer to the struct during its definition. In those cases,
      you can actually repeat the name of the struct as the struct name
      and as the typedef:
      -->

      <para>
        Usando <kw>typedef</kw> de este modo, se puede simular (en C;
        intentar eliminar el <kw>typedef</kw> para C++) que
        <type>Structure2</type> es un tipo predefinido, como
        <type>int</type> o <type>float</type>, cuando define
        <varname>s1</varname> y <varname>s2</varname> (pero se ha de
        tener en cuenta de que sólo tiene información - características
        - y no incluye comportamiento, que es lo que se obtiene con
        objetos reales en C++). Observe que el <kw>struct</kw> se ha
        declarado al principio, porque el objetivo es crear el
        <kw>typedef</kw>. Sin embargo, hay veces en las que sería
        necesario referirse a <kw>struct</kw> durante su definición. En
        esos casos, se puede repetir el nombre del <kw>struct</kw> como
        tal y como <kw>typedef</kw>.
      </para>


//: V1C03:SelfReferential.cpp


      <!--
      If you look at this for awhile, you'll see that sr1 and sr2 point
      to each other, as well as each holding a piece of data.
      -->

      <para>
        Si lo observa detenidamente, puede ver que
        <varname>sr1</varname> y <varname>sr2</varname> apuntan el uno
        al otro, guardando cada uno una parte de la información.
     </para>

      <!--
      Actually, the struct name does not have to be the same as the
      typedef name, but it is usually done this way as it tends to keep
      things simpler.
      -->

      <para>
        En realidad, el nombre <kw>struct</kw> no tiene que ser lo mismo
        que el nombre <kw>typedef</kw>, pero normalmente se hace de esta
        manera ya que tiende a simplificar las cosas.
      </para>


      <sect3>
        <!-- Pointers and structs -->
        <title>Punteros y estructuras</title>

        <!--
        In the examples above, all the structs are manipulated as
        objects. However, like any piece of storage, you can take the
        address of a struct object (as seen in SelfReferential.cpp
        above). To select the elements of a particular struct object,
        you use a '.', as seen above. However, if you have a pointer to
        a struct object, you must select an element of that object using
        a different operator: the ' ->'. Here's an example:
        -->

        <para>
          En los ejemplos anteriores, todos los <kw>structs</kw> se
          manipulan como objetos. Sin embargo, como cualquier bloque de
          memoria, se puede obtener la dirección de un objeto
          <kw>struct</kw> (tal como se ha visto en
          <filename>SelfReferential.cpp</filename>). Para seleccionar
          los elementos de un objeto <kw>struct</kw> en particular, se
          utiliza un <token>.</token>, como se ha visto
          anteriormente. No obstante, si tiene un puntero a un objeto
          <kw>struct</kw>, debe seleccionar un elemento de dicho objeto
          utilizando un operador diferente: el <token>-></token>. A
          continuación, un ejemplo:
        </para>


//: V1C03:SimpleStruct3.cpp


        <!--
        In main( ), the struct pointer sp is initially pointing to s1,
        and the members of s1 are initialized by selecting them with the
        '->' (and you use this same operator in order to read those
        members). But then sp is pointed to s2, and those variables are
        initialized the same way. So you can see that another benefit of
        pointers is that they can be dynamically redirected to point to
        different objects; this provides more flexibility in your
        programming, as you will learn.
        -->

        <para>
          En <function>main()</function>, el puntero
          <varname>sp</varname> está apuntando inicialmente a
          <varname>s1</varname>, y los miembros de <varname>s1</varname>
          se inicializan seleccionándolos con el <token>-></token>
          (y se utiliza este mismo operador para leerlos). Pero luego
          <varname>sp</varname> apunta a <varname>s2</varname>, y esas
          variables se inicializan del mismo modo. Como puede ver, otro
          beneficio en el uso de punteros es que pueden ser redirigidos
          dinámicamente para apuntar a objetos diferentes, eso proporciona
          más flexibilidad a sus programas, tal como verá.
        </para>

        <!--
        For now, that's all you need to know about structs, but you'll
        become much more comfortable with them (and especially their
        more potent successors, classes) as the book progresses.
        -->

        <para>
          De momento, es todo lo que debe saber sobre <kw>struct</kw>,
          pero se sentirá mucho más cómodo con ellos (y especialmente
          con sus sucesores mas potentes, las clases) a medida que
          progrese en este libro.
        </para>
      </sect3>
    </sect2>

    <sect2>
      <!-- Clarifying programs with enum -->
      <title>Programas más claros gracias a <kw>enum</kw></title>

      <!--
      An enumerated data type is a way of attaching names to numbers,
      thereby giving more meaning to anyone reading the code. The enum
      keyword (from C) automatically enumerates any list of identifiers
      you give it by assigning them values of 0, 1, 2, etc. You can
      declare enum variables (which are always represented as integral
      values). The declaration of an enum looks similar to a struct
      declaration.
      -->

      <para>
        Un tipo de datos enumerado es una manera de asociar nombres a
        números, y por consiguiente de ofrecer más significado a alguien
        que lea el código. La palabra reservada <kw>enum</kw> (de C)
        enumera automáticamente cualquier lista de identificadores que
        se le pase, asignándoles valores de 0, 1, 2, etc. Se pueden
        declarar variables <kw>enum</kw> (que se representan siempre
        como valores enteros). La declaración de un <kw>enum</kw> se
        parece a la declaración de un <kw>struct</kw>.
     </para>

      <!--
      An enumerated data type is useful when you want to keep track of
      some sort of feature:
      -->

      <para>
        Un tipo de datos enumerado es útil cuando se quiere poder seguir
        la pista de alguna característica:
      </para>


//: V1C03:Enum.cpp


      <!--
      shape is a variable of the ShapeType enumerated data type, and its
      value is compared with the value in the enumeration. Since shape
      is really just an int, however, it can be any value an int can
      hold (including a negative number). You can also compare an int
      variable with a value in the enumeration.
      -->

      <para>
        <varname>shape</varname> es una variable del tipo de datos
        enumerado <type>ShapeType</type>, y su valor se compara con el
        valor en la enumeración. Ya que <varname>shape</varname> es
        realmente un <type>int</type>, puede albergar cualquier valor
        que corresponda a <type>int</type> (incluyendo un número
        negativo). También se puede comparar una variable
        <type>int</type> con un valor de una enumeración.
      </para>

      <!--
      You should be aware that the example above of switching on type
      turns out to be a problematic way to program. C++ has a much
      better way to code this sort of thing, the explanation of which
      must be delayed until much later in the book.
      -->

      <para>
        Se ha de tener en cuenta que el ejemplo anterior de intercambiar
        los tipos tiende a ser una manera problemática de programar. C++
        tiene un modo mucho mejor de codificar este tipo de cosas, cuya
        explicación se pospondrá para mucho mas adelante en este libro.
     </para>

      <!--
      If you don't like the way the compiler assigns values, you can do
      it yourself, like this:
      -->

      <para>
        Si el modo en que el compilador asigna los valores no es de su
        agrado, puede hacerlo manualmente, como sigue:
      </para>


<programlisting>
enum ShapeType {
  circle = 10, square = 20, rectangle = 50
};
</programlisting>


      <!--
      If you give values to some names and not to others, the compiler
      will use the next integral value. For example,
      -->

      <para>
	Si da valores a algunos nombres y a otros no, el compilador
	utilizará el siguiente valor entero. Por ejemplo,
      </para>


<programlisting>
enum snap { crackle = 25, pop };
</programlisting>


      <!--
      The compiler gives pop the value 26.
      -->

      <para>
        El compilador le da a <varname>pop</varname> el valor
        <literal>26</literal>.
     </para>

      <!--
      You can see how much more readable the code is when you use
      enumerated data types. However, to some degree this is still an
      attempt (in C) to accomplish the things that we can do with a
      class in C++, so you'll see enum used less in C++.
      -->

      <para>
        Es fácil comprobar que el código es más legible cuando se
        utilizan tipos de datos enumerados. No obstante, en cierto
        grado esto sigue siendo un intento (en C) de lograr las cosas
        que se pueden lograr con una <kw>class</kw> en C++, y por eso
        verá que <kw>enum</kw> se utiliza menos en C++.
      </para>

      <sect3>
        <!-- Type checking for enumerations -->
        <title>Comprobación de tipos para enumerados</title>

        <!--
        C's enumerations are fairly primitive, simply associating
        integral values with names, but they provide no type
        checking. In C++, as you may have come to expect by now, the
        concept of type is fundamental, and this is true with
        enumerations. When you create a named enumeration, you
        effectively create a new type just as you do with a class: The
        name of your enumeration becomes a reserved word for the
        duration of that translation unit.
        -->

        <para>
          Las enumeraciones en C son bastante primitivas, simplemente
          asocian valores enteros a nombres, pero no aportan
          comprobación de tipos. En C++, como era de esperar a estas
          alturas, el concepto de tipos es fundamental, y eso se cumple
          con las enumeraciones. Cuando crea una enumeración nombrada,
          crea efectivamente un nuevo tipo, tal como se hace con una
          clase: El nombre de la enumeración se convierte en una palabra
          reservada durante esa unidad de traducción.
        </para>


        <!--
        In addition, there's stricter type checking for enumerations in
        C++ than in C. You'll notice this in particular if you have an
        instance of an enumeration color called a. In C you can say a++,
        but in C++ you can't. This is because incrementing an
        enumeration is performing two type conversions, one of them
        legal in C++ and one of them illegal. First, the value of the
        enumeration is implicitly cast from a color to an int, then the
        value is incremented, then the int is cast back into a color. In
        C++ this isn't allowed, because color is a distinct type and not
        equivalent to an int. This makes sense, because how do you know
        the increment of blue will even be in the list of colors? If you
        want to increment a color, then it should be a class (with an
        increment operation) and not an enum, because the class can be
        made to be much safer. Any time you write code that assumes an
        implicit conversion to an enum type, the compiler will flag this
        inherently dangerous activity.
        -->

        <para>
          Además, hay una comprobación de tipos mas estricta para la
          enumeración en C++ que en C. En particular, resulta evidente
          si tiene una instancia de la enumeración <type>color</type>
          llamada <varname>a</varname>. En C puede decir
          <code>a++</code>, pero en C++ no es posible. Eso se debe a que
          el incrementar una enumeración se realizan dos conversiones de
          tipo, una de ellas es legal en C++ y la otra no. Primero, el
          valor de la enumeración se convierte del tipo
          <type>color</type> a <type>int</type>, luego el valor se
          incrementa, y finalmente el <type>int</type> se vuelve a
          convertir a tipo <type>color</type>. En C++ esto no está
          permitido, porque <type>color</type> es un tipo diferente de
          <type>int</type>. Eso tiene sentido, porque ¿cómo saber si el
          incremento de <literal>blue</literal> siquiera estará en la
          lista de colores?  Si quiere poder incrementar un
          <type>color</type>, debería ser una clase (con una operación
          de incremento) y no un <kw>enum,</kw> porque en la clase se
          puede hacer de modo que sea mucho más seguro. Siempre que
          escriba código que asuma una conversión implícita a un tipo
          <kw>enum</kw>, el compilador alertará de que se trata de una
          actividad inherentemente peligrosa.
        </para>

        <!--
        Unions (described next) have similar additional type checking in
        C++.
        -->

        <para>
          Las uniones (descriptas a continuación) tienen una comprobación
          adicional de tipo similar en C++.
        </para>
      </sect3>
    </sect2>


<!-- a partir de aquí con formato del libro -->

<!-- Revisando_y_formateando_DB_David_Villa -->


    <sect2>
      <!-- Saving memory with union -->
      <title>Cómo ahorrar memoria con <kw>union</kw></title>


      <!--
      Sometimes a program will handle different types of data using the
      same variable. In this situation, you have two choices: you can
      create a struct containing all the possible different types you
      might need to store, or you can use a union. A union piles all the
      data into a single space; it figures out the amount of space
      necessary for the largest item you've put in the union, and makes
      that the size of the union. Use a union to save memory.
      -->

      <para>
        A veces un programa manejará diferentes tipos de datos
        utilizando la misma variable. En esta situación, se tienen dos
        elecciones: se puede crear un <kw>struct</kw> que contenga todos
        los posibles tipos que se puedan necesitar almacenar, o se puede
        utilizar una <kw>union</kw>. Una <kw>union</kw> amontona toda la
        información en un único espacio; calcula la cantidad de espacio
        necesaria para el elemento más grande, y hace de ese sea el
        tamaño de la <kw>union</kw>. Utilice la <kw>union</kw> para
        ahorrar memoria.
      </para>


      <!--
      Anytime you place a value in a union, the value always starts in
      the same place at the beginning of the union, but only uses as
      much space as is necessary. Thus, you create a "super-variable"
      capable of holding any of the union variables. All the addresses
      of the union variables are the same (in a class or struct, the
      addresses are different).
      -->

      <para>
        Cuando se coloca un valor en una <kw>union</kw>, el valor
        siempre comienza en el mismo sitio al principio de la
        <kw>union</kw>, pero sólo utiliza el espacio necesario. Por eso,
        se crea una <quote>super-variable</quote> capaz de alojar
        cualquiera de las variables de la <kw>union</kw>. Las
        direcciones de todas las variables de la <kw>union</kw> son la
        misma (en una clase o <kw>struct</kw>, las direcciones son
        diferentes).
     </para>

      <!--
      Here's a simple use of a union. Try removing various elements and
      see what effect it has on the size o f the union. Notice that it
      makes no sense to declare more than one instance of a single data
      type in a union (unless you're just doing it to use a different
      name).
      -->

      <para>
        A continuación, un uso simple de una <kw>union</kw>. Intente
        eliminar varios elementos y observe qué efecto tiene en el
        tamaño de la <kw>union</kw>. Fíjese que no tiene sentido
        declarar más de una instancia de un sólo tipo de datos en una
        union (a menos que quiera darle un nombre distinto).
      </para>


//: V1C03:Union.cpp


      <!--
      The compiler performs the proper assignment according to the union
      member you select.
      -->

      <para>
        El compilador realiza la asignación apropiada para el miembro de
        la unión seleccionado.
     </para>

      <!--
      Once you perform an assignment, the compiler doesn't care what you
      do with the union. In the example above, you could assign a
      floating-point value to x:
      -->

      <para>
        Una vez que se realice una asignación, al compilador le da igual
        lo que se haga con la unión. En el ejemplo anterior, se puede
        asignar un valor en coma-flotante a <varname>x</varname>:
      </para>


<programlisting>
x.f = 2.222;
</programlisting>


      <!--
      and then send it to the output as if it were an int :
      -->

      <para>
	Y luego enviarlo a la salida como si fuese un <type>int</type>:
      </para>


<programlisting>
cout &lt;&lt; x.i;
</programlisting>


      <!--
      This would produce garbage.
      -->

      <para>
        Eso produciría basura.
      </para>
    </sect2>

    <sect2>
      <title>Arrays</title>

      <!--
      Arrays are a kind of composite type because they allow you to
      clump a lot of variables together, one right after the other,
      under a single identifier name. If you say:
      -->

      <para>
	Los vectores son un tipo compuesto porque permiten
	agrupar muchas variables, una a continuación de la otra,
	bajo un identificador único. Si dice:
      </para>


<programlisting>
int a[10];
</programlisting>


      <!--
      You create storage for 10 int variables stacked on top of each
      other, but without unique identifier names for each
      variable. Instead, they are all lumped under the name a.
      -->

      <para>
        Se crea espacio para 10 variables <type>int</type> colocadas una
        después de la otra, pero sin identificadores únicos para cada
        variable. En su lugar, todas están englobadas por el nombre
        <varname>a</varname>.
     </para>

      <!--
      To access one of these array elements, you use the same
      square-bracket syntax that you use to define an array:
      -->

      <para>
        Para acceder a cualquiera de los <emphasis>elementos del
        vector</emphasis>, se utiliza la misma sintaxis de corchetes que
        se utiliza para definir el vector:
      </para>


<programlisting>
a[5] = 47;
</programlisting>


      <!--
      However, you must remember that even though the size of a is 10,
      you select array elements starting at zero (this is sometimes
      called zero indexing), so you can select only the array elements
      0-9, like this:
      -->

      <para>
        Sin embargo, debe recordar que aunque el tamaño de
        <varname>a</varname> es <literal>10</literal>, se seleccionan
        los elementos del vector comenzando por cero (esto se llama a
        veces <emphasis>indexado a cero</emphasis><footnote>
        <para>(N. de T.) <emphasis>zero indexing</emphasis></para>
        </footnote>, de modo que sólo se pueden seleccionar los
        elementos del vector de 0 a 9, como sigue:
      </para>


//: V1C03:Arrays.cpp


      <!--
      Array access is extremely fast. However, if you index past the end
      of the array, there is no safety net - you'll step on other
      variables. The other drawback is that you must define the size of
      the array at compile time; if you want to change the size at
      runtime you can't do it with the syntax above (C does have a way
      to create an array dynamically, but it's significantly
      messier). The C++ vector, introduced in the previous chapter,
      provides an array-like object that automatically resizes itself,
      so it is usually a much better solution if your array size cannot
      be known at compile time.
      -->

      <para>
        Los accesos a vectores son extremadamente rápidos, Sin embargo,
        si se indexa más allá del final del vector, no hay ninguna red
        de seguridad - se entrará en otras variables. La otra desventaja
        es que se debe definir el tamaño del vector en tiempo de
        compilación; si se quiere cambiar el tamaño en tiempo de
        ejecución no se puede hacer con la sintaxis anterior (C tiene
        una manera de crear un vector dinámicamente, pero es
        significativamente más sucia). El <classname>vector</classname>
        de C++ presentado en el capítulo anterior, proporciona un objeto
        parecido al vector que se redimensiona automáticamente , de modo
        que es una solución mucho mejor si el tamaño del vector no puede
        conocer en tiempo de compilación.
     </para>

      <!--
      You can make an array of any type, even of structs:
      -->

      <para>
        Se puede hacer un vector de cualquier tipo, incluso de
        <kw>struct</kw>s:
      </para>


//: V1C03:StructArray.cpp


      <!--
      Notice how the struct identifier i is independent of the for
      loop's i.
      -->

      <para>
        Fíjese como el identificador de <kw>struct</kw>
        <varname>i</varname> es independiente del <varname>i</varname>
        del bucle <kw>for</kw>.
     </para>

      <!--
      To see that each element of an array is contiguous with the next,
      you can print out the addresses like this:
      -->

      <para>
        Para comprobar que cada elemento del vector es contiguo con el
        siguiente, puede imprimir la dirección de la siguiente manera:
      </para>


//: V1C03:ArrayAddresses.cpp


      <!--
      When you run this program, you'll see that each element is one int
      size away from the previous one. That is, they are stacked one on
      top of the other.
      -->

      <para>
	Cuando se ejecuta este programa, se ve que cada elemento está
	separado por el tamaño de un <type>int</type> del anterior. Esto
	significa, que están colocados uno a continuación del otro.
      </para>


      <sect3>
        <!-- Pointers and arrays -->
        <title>Punteros y arrays</title>

        <!--
        The identifier of an array is unlike the identifiers for
        ordinary variables. For one thing, an array identifier is not an
        lvalue; you cannot assign to it. It's really just a hook into
        the square-bracket syntax, and when you give the name of an
        array, without square brackets, what you get is the starting
        address of the array:
        -->

        <para>
	  El identificador de un vector es diferente de los
	  identificadores de las variables comunes. Un identificador de
	  un vector no es un <emphasis>lvalue</emphasis>; no se le puede
	  asignar nada. En realidad es FIXME:gancho dentro de la
	  sintaxis de corchetes, y cuando se usa el nombre de un vector,
	  sin los corchetes, lo que se obtiene es la dirección inicial
	  del vector:
        </para>


//: V1C03:ArrayIdentifier.cpp


        <!--
        When you run this program you'll see that the two addresses
        (which will be printed in hexadecimal, since there is no cast to
        long) are the same.
        -->

        <para>
          Cuando se ejecuta este programa, se ve que las dos direcciones
          (que se imprimen en hexadecimal, ya que no se moldea a
          <type>long</type>) son las misma.
        </para>

        <!--
        So one way to look at the array identifier is as a read-only
        pointer to the beginning of an array. And although we can't
        change the array identifier to point somewhere else, we can
        create another pointer and use that to move around in the
        array. In fact, the square-bracket syntax works with regular
        pointers as well:
        -->

        <para>
          De modo que una manera de ver el identificador de un vector es
          como un puntero de sólo lectura al principio de éste. Y aunque
          no se pueda hacer que el identificador del vector apunte a
          cualquier otro sitio, se puede crear otro puntero y utilizarlo
          para moverse dentro del vector. De hecho, la sintaxis de
          corchetes también funciona con punteros convencionales:
        </para>


//: V1C03:PointersAndBrackets.cpp


        <!--
        The fact that naming an array produces its starting address
        turns out to be quite important when you want to pass an array
        to a function. If you declare an array as a function argument,
        what you're really declaring is a pointer. So in the following
        example, func1( ) and func2( ) effectively have the same
        argument lists:
        -->

        <para>
          El hecho de que el nombre de un vector produzca su dirección
          de inicio resulta bastante importante cuando hay que pasar un
          vector a una función. Si declara un vector como un argumento
          de una función, lo que realmente está declarando es un
          puntero. De modo que en el siguiente ejemplo,
          <function>fun1()</function> y <function>func2()</function>
          tienen la misma lista de argumentos:
        </para>


//: V1C03:ArrayArguments.cpp


        <!--
        Even though func1( ) and func2( ) declare their arguments
        differently, the usage is the same inside the function. There
        are some other issues that this example reveals: arrays cannot
        be passed by value[32], that is, you never automatically get a
        local copy of the array that you pass into a function. Thus,
        when you modify an array, you're always modifying the outside
        object. This can be a bit confusing at first, if you're
        expecting the pass-by-value provided with ordinary arguments.
        -->

        <para>
          A pesar de que <function>func1()</function> y
          <function>func2()</function> declaran sus argumentos de
          distinta forma, el uso es el mismo dentro de la función. Hay
          otros hechos que revela este ejemplo: los vectores no se pueden
          pasados por valor<footnote>
	    <!--
	    Unless you take the very strict approach that "all argument
          passing in C/C++ is by value, and the 'value' of an array is
          what is produced by the array identifier: it's address."
          This can be seen as true from the assembly-language
          standpoint, but I don't think it helps when trying to work
          with higher-level concepts. The addition of references in C++
          makes the "all passing is by value" argument more confusing,
          to the point where I feel it's more helpful to think in terms
          of "passing by value" vs. "passing addresses."
	    -->
	    <para>
	      A menos que tome la siguiente aproximación estricta:
	      <quote>todos los argumentos pasado en C/C++ son por valor,
	      y el <quote>valor</quote> de un vector es el producido por
	      su identificador: su dirección</quote>. Eso puede parecer
	      correcto desde el punto de vista del lenguaje ensamblador,
	      pero yo no creo que ayude cuando se trabaja con conceptos
	      de alto nivel. La inclusión de referencias en C++ hace que
	      el argumento <quote>todo se pasa por valor</quote> sea más
	      confuso, hasta el punto de que siento que es más adecuado
	      pensar en términos de <quote>paso por valor</quote> vs
	      <quote>paso por dirección</quote>.
	    </para>
	  </footnote>, es decir, que nunca se puede obtener
          automáticamente una copia local del vector que se pasa a una
          función. Por eso, cuando se modifica un vector, siempre se
          está modificando el objeto externo. Eso puede resultar un poco
          confuso al principio, si lo que se espera es el paso-por-valor
          como en los argumentos ordinarios.
        </para>

        <!--
        You'll notice that print( ) uses the square-bracket syntax for
        array arguments. Even though the pointer syntax and the
        square-bracket syntax are effectively the same when passing
        arrays as arguments, the square-bracket syntax makes it clearer
        to the reader that you mean for this argument to be an array.
        -->

        <para>
          Fíjese que <function>print()</function> utiliza la sintaxis de
          corchetes para los argumentos de tipo vector. Aunque la
          sintaxis de puntero y la sintaxis de corchetes efectivamente
          es la mismo cuando se están pasando vectores como argumentos,
          la sintaxis de corchetes deja más clara al lector que se
          pretende enfatizar que dicho argumento es un vector.
        </para>

        <!--
        Also note that the size argument is passed in each case. Just
        passing the address of an array isn't enough information; you
        must always be able to know how big the array is inside your
        function, so you don't run off the end of that array.
        -->

        <para>
          Observe también que el argumento <varname>size</varname> se
          pasa en cada caso. La dirección no es suficiente información
          al pasar un vector; siempre se debe ser posible obtener el
          tamaño del vector dentro de la función, de manera que no se
          salga de los límites de dicho vector.
        </para>

        <!--
        Arrays can be of any type, including arrays of pointers. In
        fact, when you want to pass command-line arguments into your
        program, C and C++ have a special argument list for main( ),
        which looks like this:
        -->

        <para>
          Los vectores pueden ser de cualquier tipo, incluyendo vectores
          de punteros. De hecho, cuando se quieren pasar argumentos de
          tipo línea de comandos dentro del programa, C y C++ tienen una
          lista de argumentos especial para <function>main()</function>,
          que tiene el siguiente aspecto:
        </para>


<programlisting>
int main(int argc, char* argv[]) { // ...
</programlisting>


        <!--
        The first argument is the number of elements in the array, which
        is the second argument. The second argument is always an array
        of char*, because the arguments are passed from the command line
        as character arrays (and remember, an array can be passed only
        as a pointer). Each whitespace-delimited cluster of characters
        on the command line is turned into a separate array
        argument. The following program prints out all its command-line
        arguments by stepping through the array:
        -->

        <para>
          El primer argumento es el número de elementos en el vector,
          que es el segundo argumento. El segundo argumento es siempre
          un vector de <type>char*</type>, porque los argumentos se
          pasan desde la línea de comandos como vectores de caracteres
          (y recuerde, un vector sólo se puede pasar como un
          puntero). Cada bloque de caracteres delimitado por un espacio
          en blanco en la línea de comandos se aloja en un elemento
          separado en el vector. El siguiente programa imprime todos los
          argumentos de línea de comandos recorriendo el vector:
        </para>


//: V1C03:CommandLineArgs.cpp


        <!--
        You'll notice that argv[0] is the path and name of the program
        itself. This allows the program to discover information about
        itself. It also adds one more to the array of program arguments,
        so a common error when fetching command-line arguments is to
        grab argv[0] when you want argv[1].
        -->

        <para>
          Observe que <code>argv[0]</code> es la ruta y el nombre del
          programa en sí mismo. Eso permite al programa descubrir
          información de sí mismo. También añade un argumento más al
          vector de argumentos del programa, de modo que un error común
          al recoger argumentos de línea de comandos es tomar argv[0]
          como si fuera el primer argumento.
        </para>

        <!--
        You are not forced to use argc and argv as identifiers in main(
        ); those identifiers are only conventions (but it will confuse
        people if you don't use them). Also, there is an alternate way
        to declare argv:
        -->

        <para>
          No es obligatorio utilizar <varname>argc</varname> y
          <varname>argv</varname> como identificadores de los parámetros
          de <function>main()</function>; estos identificadores son sólo
          convenciones (pero puede confundir al lector si no se
          respeta). También, hay un modo alternativo de declarar argv:
        </para>


<programlisting>
int main(int argc, char** argv) { // ...
</programlisting>


        <!--
        Both forms are equivalent, but I find the version used in this
        book to be the most intuitive when reading the code, since it
        says, directly, "This is an array of character pointers."
        -->

        <para>
          Las dos formas son equivalentes, pero la versión utilizada en
          este libro es la más intuitiva al leer el código, ya que dice,
          directamente, <quote>Esto es un vector de punteros a
          carácter</quote>.
        </para>

        <!--
        All you get from the command-line is character arrays; if you
        want to treat an argument as some other type, you are
        responsible for converting it inside your program. To facilitate
        the conversion to numbers, there are some helper functions in
        the Standard C library, declared in &lt;cstdlib>. The simplest ones
        to use are atoi( ), atol( ), and atof( ) to convert an ASCII
        character array to an int, long, and double floating-point
        value, respectively. Here's an example using atoi( ) (the other
        two functions are called the same way):
        -->

        <para>
          Todo lo que se obtiene de la línea de comandos son vectores de
          caracteres; si quiere tratar un argumento como algún otro
          tipo, ha de convertirlos dentro del programa. Para facilitar
          la conversión a números, hay algunas funciones en la librería
          de C Estándar, declaradas en <filename
          role="header">&lt;cstdlib></filename>. Las más fáciles de
          utilizar son <function>atoi()</function>,
          <function>atol()</function>, y <function>atof()</function>
          para convertir un vector de caracteres ASCII a
          <type>int</type>, <type>long</type> y <type>double</type>,
          respectivamente. A continuación, un ejemplo utilizando
          <function>atoi()</function> (las otras dos funciones se
          invocan del mismo modo):
        </para>


//: V1C03:ArgsToInts.cpp


        <!--
        In this program, you can put any number of arguments on the
        command line. You'll notice that the for loop starts at the
        value 1 to skip over the program name at argv[0]. Also, if you
        put a floating-point number containing a decimal point on the
        command line, atoi( ) takes only the digits up to the decimal
        point. If you put non-numbers on the command line, these come
        back from atoi( ) as zero.
        -->

        <para>
          En este programa, se puede poner cualquier número de
          argumentos en la línea de comandos. Fíjese que el bucle
          <kw>for</kw> comienza en el valor <literal>1</literal> para
          saltar el nombre del programa en
          <code>argv[0]</code>. También, si se pone un número decimal
          que contenga un punto decimal en la línea de comandos,
          <function>atoi()</function> sólo toma los dígitos hasta el
          punto decimal. Si pone valores no numéricos en la línea de
          comandos, <function>atoi()</function> los devuelve como ceros.
        </para>
      </sect3>

      <sect3>
        <!-- Exploring floating-point format -->
        <title>El formato de punto flotante</title>

        <!--
        The printBinary( ) function introduced earlier in this chapter
        is handy for delving into the internal structure of various data
        types. The most interesting of these is the floating-point
        format that allows C and C++ to store numbers representing very
        large and very small values in a limited amount of
        space. Although the details can't be completely exposed here,
        the bits inside of floats and doubles are divided into three
        regions: the exponent, the mantissa, and the sign bit; thus it
        stores the values using scientific notation. The following
        program allows you to play around by printing out the binary
        patterns of various floating point numbers so you can deduce for
        yourself the scheme used in your compiler's floating-point
        format (usually this is the IEEE standard for floating point
        numbers, but your compiler may not follow that):
        -->

        <para>
          La función <function>printBinary()</function> presentada
          anteriormente en este capítulo es útil para indagar en la
          estructura interna de varios tipos de datos. El más
          interesante es el formato de punto-flotante que permite a C y
          C++ almacenar números que representan valores muy grandes y
          muy pequeños en un espacio limitado. Aunque los detalles no se
          pueden exponer completamente expuestos, los bits dentro de los
          <type>float</type>s y <type>double</type>s están divididos en
          tres regiones: el exponente, la mantisa, y el bit de signo;
          así almacena los valores utilizando notación científica. El
          siguiente programa permite jugar con ello imprimiendo los
          patrones binarios de varios números en punto-flotante de modo
          que usted mismo pueda deducir el esquema del formato de punto
          flotante de su compilador (normalmente es el estándar IEEE
          para números en punto-flotante, pero su compilador puede no
          seguirlo):
        </para>


//: V1C03:FloatingAsBinary.cpp


        <!--
        First, the program guarantees that you've given it an argument
        by checking the value of argc, which is two if there's a single
        argument (it's one if there are no arguments, since the program
        name is always the first element of argv). If this fails, a
        message is printed and the Standard C Library function exit( )
        is called to terminate the program.
        -->

        <para>
          Primero, el programa garantiza que se le haya pasado un
          argumento comprobando el valor de <varname>argc</varname>, que
          vale dos si hay un solo argumento (es uno si no hay
          argumentos, ya que el nombre del programa siempre es el primer
          elemento de <varname>argv</varname>). Si eso falla, imprime un
          mensaje e invoca la función <function>exit()</function> de la
          librería Estándar de C para finalizar el programa.
        </para>

        <!--
        The program grabs the argument from the command line and
        converts the characters to a double using atof( ). Then the
        double is treated as an array of bytes by taking the address and
        casting it to an unsigned char*. Each of these bytes is passed
        to printBinary( ) for display.
        -->

        <para>
          El programa toma el argumento de la línea de comandos y
          convierte los caracteres a <type>double</type> utilizando
          <function>atof()</function>. Luego el <type>double</type> se
          trata como un vector de bytes tomando la dirección y
          moldeándola a un <type>unsigned char*</type>. Para cada uno de
          estos bytes se llama a <function>printBinary()</function> para
          mostrarlos.
        </para>

        <!--
        This example has been set up to print the bytes in an order such
        that the sign bit appears first - on my machine. Yours may be
        different, so you might want to re-arrange the way things are
        printed. You should also be aware that floating-point formats
        are not trivial to understand; for example, the exponent and
        mantissa are not generally arranged on byte boundaries, but
        instead a number of bits is reserved for each one and they are
        packed into the memory as tightly as possible. To truly see
        what's going on, you'd need to find out the size of each part of
        the number (sign bits are always one bit, but exponents and
        mantissas are of differing sizes) and print out the bits in each
        part separately.
        -->

        <para>
          Este ejemplo se ha creado para imprimir los bytes en un orden
          tal que el bit de signo aparece al principio - en mi
          máquina. En otras máquinas puede ser diferente, por lo que
          puede querer re-organizar el modo en que se imprimen los
          bytes. También debería tener cuidado porque los formatos en
          punto-flotante no son tan triviales de entender; por ejemplo,
          el exponente y la mantisa no se alinean generalmente entre los
          límites de los bytes, en su lugar un número de bits se reserva
          para cada uno y se empaquetan en la memoria tan apretados como
          se pueda. Para ver lo que esta pasando, necesitaría averiguar
          el tamaño de cada parte del número (los bit de signo siempre
          son de un bit, pero los exponentes y las mantisas pueden ser
          de diferentes tamaños) e imprimir separados los bits de cada
          parte.
        </para>
      </sect3>

     <sect3>
        <title>Aritmética de punteros</title>

        <!--
        If all you could do with a pointer that points at an array is
        treat it as if it were an alias for that array, pointers into
        arrays wouldn't be very interesting. However, pointers are more
        flexible than this, since they can be modified to point
        somewhere else (but remember, the array identifier cannot be
        modified to point somewhere else).
        -->

        <para>
          Si todo lo que se pudiese hacer con un puntero que apunta a un
          vector fuese tratarlo como si fuera un alias para ese vector,
          los punteros a vectores no tendrían mucho interés. Sin
          embargo, los punteros son mucho más flexibles que eso, ya que
          se pueden modificar para apuntar a cualquier otro sitio (pero
          recuerde, el identificador del vector no se puede modificar
          para apuntar a cualquier otro sitio).
        </para>


        <!--
        Pointer arithmetic refers to the application of some of the
        arithmetic operators to pointers. The reason pointer arithmetic
        is a separate subject from ordinary arithmetic is that pointers
        must conform to special constraints in order to make them behave
        properly. For example, a common operator to use with pointers is
        ++, which "adds one to the pointer." What this actually means is
        that the pointer is changed to move to "the next value,"
        whatever that means. Here's an example:
        -->

        <para>
          La <emphasis>aritmética de punteros</emphasis> se refiere a la
          aplicación de alguno de los operadores aritméticos a los
          punteros. Las razón por la cual la aritmética de punteros es
          un tema separado de la aritmética ordinaria es que los
          punteros deben ajustarse a cláusulas especiales de modo que se
          comporten apropiadamente. Por ejemplo, un operador común para
          utilizar con punteros es ++, lo que "añade uno al puntero." Lo
          que de hecho significa esto es que el puntero se cambia para
          moverse al "siguiente valor," Lo que sea que ello
          signifique. A continuación, un ejemplo:
        </para>


//: V1C03:PointerIncrement.cpp


        <!--
        For one run on my machine, the output is:
        -->

        <para>
          Para una ejecución en mi máquina, la salida es:
        </para>


<programlisting>
ip = 6684124
ip = 6684128
dp = 6684044
dp = 6684052
</programlisting>


        <!--
        What's interesting here is that even though the operation ++
        appears to be the same operation for both the int* and the
        double*, you can see that the pointer has been changed only 4
        bytes for the int* but 8 bytes for the double*. Not
        coincidentally, these are the sizes of int and double on my
        machine. And that's the trick of pointer arithmetic: the
        compiler figures out the right amount to change the pointer so
        that it's pointing to the next element in the array (pointer
        arithmetic is only meaningful within arrays). This even works
        with arrays of structs:
        -->

        <para>
          Lo interesante aquí es que aunque la operación <oper>++</oper>
          parece la misma tanto para el <type>int*</type> como para el
          <type>double*</type>, se puede comprobar que el puntero de
          <type>int*</type> ha cambiado 4 bytes mientras que para el
          <type>double*</type> ha cambiado 8. No es coincidencia, que
          estos sean los tamaños de <type>int</type> y
          <type>double</type> en esta máquina. Y ese es el truco de la
          aritmética de punteros: el compilador calcula la cantidad
          apropiada para cambiar el puntero de modo que apunte al
          siguiente elemento en el vector (la aritmética de punteros
          sólo tiene sentido dentro de los vectores). Esto funciona incluso
          con vectores de <kw>struct</kw>s:
        </para>


//: V1C03:PointerIncrement2.cpp


        <!--
        The output for one run on my machine was:
        -->

        <para>
          La salida en esta máquina es:
        </para>


<programlisting>
sizeof(Primitives) = 40
pp = 6683764
pp = 6683804
</programlisting>


        <!--
        So you can see the compiler also does the right thing for
        pointers to structs (and classes and unions).
        -->

        <para>
          Como puede ver, el compilador también hace lo adecuado para
          punteros a <kw>struct</kw>s (y con <kw>class</kw> y
          <kw>union</kw>).
        </para>

        <!--
        Pointer arithmetic also works with the operators - -, +, and -,
        but the latter two operators are limited: you cannot add two
        pointers, and if you subtract pointers the result is the number
        of elements between the two pointers. However, you can add or
        subtract an integral value and a pointer. Here's an example
        demonstrating the use of pointer arithmetic:
        -->

        <para>
          La aritmética de punteros también funciona con los operadores
          <oper>--</oper>, <oper>+</oper> y <oper>-</oper>, pero los dos
          últimos están limitados: no se puede sumar dos punteros, y si
          se restan punteros el resultado es el número de elementos
          entre los dos punteros. Sin embargo, se puede sumar o restar
          un valor entero y un puntero. A continuación, un ejemplo
          demostrando el uso de la aritmética de punteros:
        </para>


//: V1C03:PointerArithmetic.cpp


        <!--
        It begins with another macro, but this one uses a preprocessor
        feature called stringizing (implemented with the '#' sign before
        an expression) that takes any expression and turns it into a
        character array. This is quite convenient, since it allows the
        expression to be printed, followed by a colon, followed by the
        value of the expression. In main( ) you can see the useful
        shorthand that is produced.
        -->

        <para>
          Comienza con otra macro, pero esta utiliza una característica
          del preprocesador llamada
          <foreignphrase>stringizing</foreignphrase> (implementada
          mediante el signo <token>#</token> antes de una expresión) que
          toma cualquier expresión y la convierte a un vector de
          caracteres. Esto es bastante conveniente, ya que permite
          imprimir la expresión seguida de dos puntos y del valor de la
          expresión. En <function>main()</function> puede ver lo útil
          que resulta este atajo.
        </para>

        <!--
        Although pre- and postfix versions of ++ and - - are valid with
        pointers, only the prefix versions are used in this example
        because they are applied before the pointers are dereferenced in
        the expressions above, so they allow us to see the effects of
        the operations. Note that only integral values are being added
        and subtracted; if two pointers were combined this way the
        compiler would not allow it.
        -->

        <para>
          Aunque tanto la versión prefijo como sufijo de <oper>++</oper>
          y <oper>--</oper> son válidas para los punteros, en este
          ejemplo sólo se utilizan las versiones prefijo porque se
          aplican antes de referenciar el puntero en las expresiones
          anteriores, de modo que permite ver los efectos en las
          operaciones. Observe que se han sumado y restado valores
          enteros; si se combinasen de este modo dos punteros, el
          compilador no lo permitiría.
        </para>

        <!--
        Here is the output of the program above:
        -->

        <para>
          Aquí se ve la salida del programa anterior:
        </para>


<programlisting>
*ip: 0
*++ip: 1
*(ip + 5): 6
*ip2: 6
*(ip2 - 4): 2
*--ip2: 5
</programlisting>


        <!--
        In all cases, the pointer arithmetic results in the pointer
        being adjusted to point to the "right place," based on the size
        of the elements being pointed to.
        -->

        <para>
          En todos los casos, el resultado de la aritmética de punteros
          es que el puntero se ajusta para apuntar al <quote>sitio
          correcto</quote>, basándose en el tamaño del tipo de los
          elementos a los que está apuntado.
        </para>

        <!--
        If pointer arithmetic seems a bit overwhelming at first, don't
        worry. Most of the time you'll only need to create arrays and
        index into them with [ ], and the most sophisticated pointer
        arithmetic you'll usually need is ++ and - -. Pointer arithmetic
        is generally reserved for more clever and complex programs, and
        many of the containers in the Standard C++ library hide most of
        these clever details so you don't have to worry about them.
        -->

        <para>
          Si la aritmética de punteros le sobrepasa un poco al
          principio, no tiene porqué preocuparse. La mayoría de las
          veces sólo la necesitará para crear vectores e indexarlos con
          <oper>[]</oper>, y normalmente la aritmética de punteros más
          sofisticada que necesitará es <oper>++</oper> y
          <oper>--</oper> . La aritmética de punteros generalmente está
          reservada para programas más complejos e ingeniosos, y
          muchos de los contenedores en la librería de Estándar C++
          esconden muchos de estos inteligentes detalles, por lo que no
          tiene que preocuparse de ellos.
        </para>
      </sect3>
    </sect2>
  </sect1>



  <sect1>
    <!--  Debugging hints -->
    <title>Consejos para depuración</title>

    <!--
    In an ideal environment, you have an excellent debugger available
    that easily makes the behavior of your program transparent so you
    can quickly discover errors. However, most debuggers have blind
    spots, and these will require you to embed code snippets in your
    program to help you understand what's going on. In addition, you
    may be developing in an environment (such as an embedded system,
    which is where I spent my formative years) that has no debugger
    available, and perhaps very limited feedback (i.e. a one-line LED
    display). In these cases you become creative in the ways you
    discover and display information about the execution of your
    program. This section suggests some techniques for doing this.
    -->

    <para>
      En un entorno ideal, habrá un depurador excelente disponible que
      hará que el comportamiento de su programa sea transparente y podrá
      descubrir cualquier error rápidamente. Sin embargo, muchos
      depuradores tienen puntos débiles, y eso puede requerir tenga que
      añadir trozos de código a su programa que le ayuden a entender que
      está pasando. Además, puede que para la plataforma para la que esté
      desarrollando (por ejemplo en sistemas empotrados, con lo que yo
      tuve que tratar durante mis años de formación) no haya ningún
      depurador disponible, y quizá tenga una realimentación muy
      limitada (por ejemplo, un display de LEDs de una línea). En esos
      casos debe ser creativo a la hora de descubrir y representar
      información acerca de la ejecución de su programa. Esta sección
      sugiere algunas técnicas para conseguirlo.
    </para>

    <sect2>
      <title>Banderas para depuración</title>

      <!--
      If you hard-wire debugging code into a program, you can run into
      problems. You start to get too much information, which makes the
      bugs difficult to isolate. When you think you've found the bug
      you start tearing out debugging code, only to find you need to put
      it back in again. You can solve these problems with two types of
      flags: preprocessor debugging flags and runtime debugging flags.
      -->
      <para>
        Si coloca el código de depuración mezclado con un programa,
        tendrá problemas. Empezará a tener demasiada información, que
        hará que los errores sean difíciles de aislar. Cuando cree que
        ha encontrado el error empieza a quitar el código de depuración,
        sólo para darse cuenta que necesita ponerlo de nuevo.  Puede
        resolver estos problemas con dos tipos de banderas: banderas de
        depuración del preprocesador y banderas de depuración en
        ejecución.
      </para>

      <sect3>
	<title>Banderas de depuración para el preprocesador</title>

	<!--
	By using the preprocessor to #define one or more debugging flags
	(preferably in a header file), you can test a flag using an
	#ifdef statement and conditionally include debugging code. When
	you think your debugging is finished, you can simply #undef the
	flag(s) and the code will automatically be removed (and you'll
	reduce the size and runtime overhead of your executable file).
	-->

	<para>
	  Usando el preprocesador para definir (con <kw>#define</kw>) una o más banderas
	  de depuración (preferiblemente en un fichero de cabecera), puede probar una
	  bandera usando una sentencia <kw>#ifdef</kw> e incluir condicionalmente código
	  de depuración. Cuando crea que la depuración ha terminado, simplemente utilice
	  <kw>#undef</kw> la bandera y el código quedará eliminado automáticamente (y
	  reducirá el tamaño y sobrecarga del fichero ejecutable).
	</para>

	<!--
	It is best to decide on names for debugging flags before you
	begin building your project so the names will be
	consistent. Preprocessor flags are traditionally distinguished
	from variables by writing them in all upper case. A common flag
	name is simply DEBUG (but be careful you don't use NDEBUG,
	which is reserved in C). The sequence of statements might be:
	-->

	<para>
	  Es mejor decidir los nombres de las banderas de depuración
	  antes de empezar a contruir el proyecto para que los nombres
	  sean consistentes. Las banderas del preprocesador
	  tradicionalmente se distinguen de las variables porque se
	  escriben todo en mayúsculas. Un nombre habitual es simplemente
	  <constant>DEBUG</constant> (pero tenga cuidado de no usar
	  <constant>NDEBUG</constant>, que está reservado en C). La
	  secuencia de sentencias podrías ser:
	</para>


<programlisting>
#define DEBUG // Probably in a header file
//...
#ifdef DEBUG // Check to see if flag is defined
/* debugging code here */
#endif // DEBUG
</programlisting>


	<!--
	Most C and C++ implementations will also let you #define and
	#undef flags from the compiler command line, so you can
	re-compile code and insert debugging information with a single
	command (preferably via the makefile, a tool that will be
	described shortly). Check your local documentation for details.
	-->

	<para>
	  La mayoría de las implementaciones de C y C++ también le
	  permitirán definir y eliminar banderas (con <kw>#define</kw> y
	  <kw>#undef</kw>) desde línea de comandos, y de ese modo puede
	  recompilar código e insertar información de depuración con un
	  único comando (preferiblemente con un
	  <filename>makefile</filename>, una herramienta que será
	  descrita en breve). Compruebe la documentación de su entorno si
	  necesita más detalles.
	</para>

      </sect3>

      <sect3>
	<title>Banderas para depuración en tiempo de ejecución</title>

	<!--
	In some situations it is more convenient to turn debugging flags
	on and off during program execution, especially by setting them
	when the program starts up using the command line. Large
	programs are tedious to recompile just to insert debugging code.
	-->

	<para>
	  En algunas situaciones es más conveniente activar y desactivar
	  las banderas de depuración durante la ejecución del programa,
	  especialmente cuando el programa se ejecuta usando la línea de
	  comandos. Con programas grandes resulta pesado recompilar sólo
	  para insertar código de depuración.
	</para>

	<!--
	To turn debugging code on and off dynamically, create bool
	flags:
	-->

	<para>
	  Para activar y desactivar código de depuración dinámicamente
	  cree banderas booleanas.
	</para>


//: V1C03:DynamicDebugFlags.cpp


	<!--
	This program continues to allow you to turn the debugging flag
	on and off until you type "quit" to tell it you want to
	exit. Notice it requires that full words are typed in, not just
	letters (you can shorten it to letter if you wish). Also, a
	command-line argument can optionally be used to turn debugging
	on at startup - this argument can appear anyplace in the command
	line, since the startup code in main( ) looks at all the
	arguments. The testing is quite simple because of the
	expression:
	-->

	<para>
	  Este programa sigue permitiéndole activar y desactivar la bandera de depuración
	  hasta que escriba <userinput>quit</userinput> para indicarle que quiere
	  salir. Fíjese que es necesario escribir palabras completas, no solo letras
	  (puede abreviarlo a letras si lo desea). Opcionalmente, también se puede usar un
	  argumento en línea de comandos para comenzar la depuración - este argumento
	  puede aparecer en cualquier parte de la línea de comando, ya que el código de
	  activación en <function>main()</function> busca en todos los argumentos. La
	  comprobación es bastante simple como se ve en la expresión:
	</para>


<programlisting>
string(argv[i])
</programlisting>


	<!--
	This takes the argv[i] character array and creates a string,
	which then can be easily compared to the right-hand side of the
	==. The program above searches for the entire string
	- -debug=on. You can also look for - -debug= and then see what's
	after that, to provide more options. Volume 2 (available from
	www.BruceEckel.com) devotes a chapter to the Standard C++ string
	class.
	-->

	<para>
	  Esto toma la cadena <varname>argv[i]</varname> y crea un
	  <classname>string</classname>, el cual se puede comparar
	  fácilmente con lo que haya a la derecha de <oper>==</oper>. El
	  programa anterior busca la cadena completa
	  <literal>--debug=on</literal>. También puede buscar
	  <literal>--debug=</literal> y entonces ver que hay después,
	  para proporcionar más opciones. El Volumen 2 (disponible en
	  <ulink
	  url="http://www.bruceeckel.com">www.BruceEckel.com</ulink>)
	  contiene un capítulo dedicado a la clase
	  <classname>string</classname> Estándar de C++.
	</para>

	<!--
	Although a debugging flag is one of the relatively few areas
	where it makes a lot of sense to use a global variable, there's
	nothing that says it must be that way. Notice that the variable
	is in lower case letters to remind the reader it isn't a
	preprocessor flag.
	-->

	<para>
	  Aunque una bandera de depuración es uno de los relativamente
	  pocos casos en los que tiene mucho sentido usar una variable
	  global, no hay nada que diga que debe ser así. Fíjese en que
	  la variable está escrita en minúsculas para recordar al lector
	  que no es una bandera del preprocesador.
	</para>


      </sect3>

    </sect2>

    <sect2>
      <!-- Turning variables and expressions into strings -->
      <title>Convertir variables y expresiones en cadenas</title>

      <!--
      When writing debugging code, it is tedious to write print
      expressions consisting of a character array containing the
      variable name, followed by the variable. Fortunately, Standard C
      includes the stringize operator '#', which was used earlier in
      this chapter. When you put a # before an argument in a
      preprocessor macro, the preprocessor turns that argument into a
      character array. This, combined with the fact that character
      arrays with no intervening punctuation are concatenated into a
      single character array, allows you to make a very convenient macro
      for printing the values of variables during debugging:
      -->

     <para>
	Cuando se escribe código de depuración, resulta pesado escribir
	expresiones print que consisten en una cadena que contiene el
	nombre de una variable, seguido de el valor de la
	variable. Afortunadamente, el C estándar incluye el operador de
	FIXME <emphasis>cadenización</emphasis> <token>#</token>, que ya
	se usó antes en este mismo capítulo. Cuando se coloca un # antes
	de una argumentos en una macro, el preprocesador convierte ese
	argumentos en una cadena. Esto, combinado con el hecho de que
	las cadenas no indexadas colocadas una a continuación de la otra
	se concatenan, permite crear macros muy adecuadas para imprimir
	los valores de las variables durante la depuración:
      </para>


<programlisting>
#define PR(x) cout &lt;&lt; #x " = " &lt;&lt; x &lt;&lt; "\n";
</programlisting>


      <!--
      If you print the variable a by calling the macro PR(a), it will
      have the same effect as the code:
      -->

      <para>
	Si se imprime la variable <varname>a</varname> invocando
	<code>PR(a)</code>, tendrá el mismo efecto que este código:
      </para>


<programlisting>
cout &lt;&lt; "a = " &lt;&lt; a &lt;&lt; "\n";
</programlisting>


      <!--
      This same process works with entire expressions. The following
      program uses a macro to create a shorthand that prints the
      stringized expression and then evaluates the expression and prints
      the result:
      -->

      <para>
	Este mismo proceso funciona con expresiones completas. El
	siguiente programa usa una macro para crear un atajo que imprime
	la expresión cadenizadas y después evalúa la expresión e imprime
	el resultado:
      </para>


//: V1C03:StringizingExpressions.cpp


      <!--
      You can see how a technique like this can quickly become
      indispensable, especially if you have no debugger (or must use
      multiple development environments). You can also insert an #ifdef
      to cause P(A) to be defined as "nothing" when you want to strip
      out debugging.
      -->

      <para>
	Puede comprobar cómo una técnica como esta se puede convertir
	rápidamente en algo indispensable, especialmente si no tiene
	depurador (o debe usar múltiples entornos de
	desarrollo). También puede insertar un <kw>#ifdef</kw> para
	conseguir que <code>P(A)</code> se defina como
	<quote>nada</quote> cuando quiera eliminar el código de
	depuración.
      </para>

    </sect2>

    <sect2>
      <title>La macro C assert()</title>

      <!--
      In the standard header file <cassert> you'll find assert( ),
      which is a convenient debugging macro. When you use assert( ), you
      give it an argument that is an expression you are "asserting to
      be true." The preprocessor generates code that will test the
      assertion. If the assertion isn't true, the program will stop
      after issuing an error message telling you what the assertion was
      and that it failed. Here's a trivial example:
      -->

      <para>
	En el fichero de cabecera estándar
	<filename>&lt;cassert></filename> aparece
	<function>assert()</function>, que es una macro de
	depuración. Cuando se utiliza <function>assert()</function>, se
	le debe dar un argumento que es una expresión que usted está
	<quote>aseverando</quote>. El preprocesador genera código que
	comprueba la aserción. Si la aserción no es cierta, el programa
	parará después de imprimir un mensaje de error informando que la
	aserción falló. Este es un ejemplo trivial:
      </para>


//: V1C03:Assert.cpp


      <!--
      The macro originated in Standard C, so it's also available in the
      header file assert.h.
      -->

      <para>
	La macro original es C Estándar, así que está disponible también
	en el fichero de cabecera <filename>assert.h</filename>.
      </para>


      <!--
      When you are finished debugging, you can remove the code generated
      by the macro by placing the line:
      -->

      <para>
	Cuando haya terminado la depuración, puede eliminar el código
	generado por la macro escribiendo la siguiente línea:
      </para>


<programlisting>
#define NDEBUG
</programlisting>


      <!--
      in the program before the inclusion of <cassert>, or by defining
      NDEBUG on the compiler command line. NDEBUG is a flag used in
      <cassert> to change the way code is generated by the macros.
      -->

      <para>
	en el programa, antes de la inclusión de
	<filename>&lt;cassert></filename>, o definiendo
	<constant>NDEBUG</constant> en la línea de comandos del
	compilador. <constant>NDEBUG</constant> es una bandera que se
	usa en <filename>&lt;cassert></filename> para cambiar el código
	generado por las macros.
      </para>

      <!--
      Later in this book, you'll see some more sophisticated
      alternatives to assert( )
      -->

      <para>
	Más adelante en este libro, verá algunas alternativas más
	sofisticadas a <function>assert()</function>.
      </para>

    </sect2>
  </sect1>



  <sect1 id="C03-punteros-a-funcion">

    <title>Direcciones de función</title>

    <!--
    Once a function is compiled and loaded into the computer to be
    executed, it occupies a chunk of memory. That memory, and thus the
    function, has an address.
    -->

    <para>
      Una vez que una función es compilada y cargada en la computadora
      para ser ejecutada, ocupa un trozo de memoria. Esta memoria, y por
      tanto esa función, tiene una dirección.
    </para>


    <!--
    C has never been a language to bar entry where others fear to
    tread. You can use function addresses with pointers just as you can
    use variable addresses. The declaration and use of function pointers
    looks a bit opaque at first, but it follows the format of the rest
    of the language.
    -->

    <para>
      C nunca ha sido un lenguaje [FIXME] donde otros temen pisar. Puede
      usar direcciones de función con punteros igual que puede usar
      direcciones variables. La declaración y uso de punteros a
      función parece un poco opaca al principio, pero sigue el formato
      del resto del lenguaje.
    </para>

    <sect2>
      <title>Definición de un puntero a función</title>

      <!--
      To define a pointer to a function that has no arguments and no
      return value, you say:
      -->

      <para>
	Para definir un puntero a una función que no tiene argumentos y
	no retorna nada, se dice:
      </para>


<programlisting>
void (*funcPtr)();
</programlisting>


      <!--
      When you are looking at a complex definition like this, the best
      way to attack it is to start in the middle and work your way
      out. "Starting in the middle" means starting at the variable
      name, which is funcPtr. "Working your way out" means looking to
      the right for the nearest item (nothing in this case; the right
      parenthesis stops you short), then looking to the left (a pointer
      denoted by the asterisk), then looking to the right (an empty
      argument list indicating a function that takes no arguments), then
      looking to the left (void, which indicates the function has no
      return value). This right-left-right motion works with most
      declarations.
      -->

      <para>
	Cuando se observa una definición compleja como esta, el mejor
	método para entenderla es empezar en el medio e ir hacia
	afuera. <quote>Empezar en el medio</quote> significa empezar con
	el nombre de la variable, que es
	<varname>funPtr</varname>. <quote>Ir hacia afuera</quote>
	significa mirar al elemento inmediatamente a la derecha (nada en
	este caso; el paréntesis derecho marca el fin de ese elemento),
	después mire a la izquierda (un puntero denotado por el
	asterisco), después mirar de nuevo a la derecha (una lista de
	argumentos vacía que indica que no función no toma argumentos),
	después a la izquierda (<type>void</type>, que indica que la función no
	retorna nada). Este movimiento derecha-izquierda-derecha
	funciona con la mayoría de las declaraciones.
	<footnote>
	  <para>
	    (N. del T.) Otra forma similar de entenderlo es dibujar
	    mentalmente una espiral que empieza en el medio (el
	    identificador) y se va abriendo.
	  </para>
	</footnote>
      </para>


      <!--
      To review, "start in the middle" ("funcPtr is a ..."), go to
      the right (nothing there - you're stopped by the right
      parenthesis), go to the left and find the '*' ("... pointer to
      a ..."), go to the right and find the empty argument list ("...
      function that takes no arguments ... "), go to the left and find
      the void ("funcPtr is a pointer to a function that takes no
      arguments and returns void").
      -->

      <para>
	Para repasar, <quote>empezar en el medio</quote>
	(<quote><varname>funcPtr</varname> es un ...</quote>, va a la
	derecha (nada aquí - pare en el paréntesis derecho), va a la
	izquierda y encuentra el <token>*</token> (<quote>... puntero a
	...</quote>), va a la derecha y encuentra la lista de argumentos
	vacía (<quote>... función que no tiene argumentos ...</quote>)
	va a la izquierda y encuentra el <type>void</type>
	(<quote><varname>funcPtr</varname> es un puntero a una función
	que no tiene argumentos y retorna <type>void</type></quote>).
      </para>


      <!--
      You may wonder why *funcPtr requires parentheses. If you didn't
      use them, the compiler would see:
      -->

      <para>
	Quizá se pregunte porqué <code>*funcPtr</code> necesita
	paréntesis. Si no los usara, el compilador podría ver:
      </para>


<programlisting>
void *funcPtr();
</programlisting>


      <!--
      You would be declaring a function (that returns a void*) rather
      than defining a variable. You can think of the compiler as going
      through the same process you do when it figures out what a
      declaration or definition is supposed to be. It needs those
      parentheses to "bump up against" so it goes back to the left and
      finds the '*', instead of continuing to the right and finding
      the empty argument list.
      -->

      <para>
	Lo que corresponde a la declaración de una función (que retorna
	un <type>void*</type>) en lugar de definir una variable. Se
	podría pensar que el compilador sería capaz distinguir una
	declaración de una definición por lo que se supone que es. El
	compilador necesita los paréntesis para <quote>tener contra qué
	chocar</quote> cuando vaya hacia la izquierda y encuentre el
	<token>*</token>, en lugar de continuar hacia la derecha y
	encontrar la lista de argumentos vacía.
      </para>
    </sect2>

    <sect2>
      <title>Declaraciones y definiciones complicadas</title>

      <!--
      As an aside, once you figure out how the C and C++ declaration
      syntax works you can create much more complicated items. For
      instance:
      -->

      <para>
	Al margen, una vez que entienda cómo funciona la sintáxis de
	declaración de C y C++ podrá crear elementos más
	complicados. Por ejemplo:
      </para>


<programlisting>
//: V1C03:ComplicatedDefinitions.cpp

/* 1. */     void * (*(*fp1)(int))[10];

/* 2. */     float (*(*fp2)(int,int,float))(int);

/* 3. */     typedef double (*(*(*fp3)())[10])();
             fp3 a;

/* 4. */     int (*(*f4())[10])();

int main() {}
</programlisting>


      <!--
      Walk through each one and use the right-left guideline to figure
      it out. Number 1 says "fp1 is a pointer to a function that takes
      an integer argument and returns a pointer to an array of 10 void
      pointers."
      -->

      <para>
	Estudie cada uno y use la regla derecha-izquierda para
	entenderlos. El número 1 dice <quote><varname>fp1</varname> es
	un puntero a una función que toma un entero como argumento y
	retorna un puntero a un array de 10 punteros
	<type>void</type></quote>.
      </para>


      <!--
      Number 2 says "fp2 is a pointer to a function that takes three
      arguments (int, int, and float) and returns a pointer to a
      function that takes an integer argument and returns a float."
      -->

      <para>
	El 2 dice <quote><varname>fp2</varname> es un puntero a función
	  que toma tres argumentos (<type>int</type>, <type>int</type> y
	  <type>float</type>) de retorna un puntero a una función que
	  toma un entero como argumento y retorna un
	  <type>float</type></quote>
      </para>


      <!--
      If you are creating a lot of complicated definitions, you might
      want to use a typedef. Number 3 shows how a typedef saves typing
      the complicated description every time. It says "An fp3 is a
      pointer to a function that takes no arguments and returns a
      pointer to an array of 10 pointers to functions that take no
      arguments and return doubles." Then it says "a is one of these
      fp3 types." typedef is generally useful for building complicated
      descriptions from simple ones.
      -->

      <para>
	Si necesita crear muchas definiciones complicadas, debería usar
	<kw>typedef</kw>. El número 3 muestra cómo un <kw>typedef</kw>
	ahorra tener que escribir una descripción complicada cada
	vez. Dice <quote>Un <type>fp3</type> es un puntero a una función
	que no tiene argumentos y que retorna un puntero a un array de
	10 punteros a funciones que no tienen argumentos y retornan
	<type>doubles</type></quote>. Después dice
	<quote><varname>a</varname> es una variable de ese tipo
	<type>fp3</type></quote>. <kw>typedef</kw> es útil para
	construir descripciones complicadas a partir de otras simples.
      </para>


      <!--
      Number 4 is a function declaration instead of a variable
      definition. It says "f4 is a function that returns a pointer to
      an array of 10 pointers to functions that return integers."
      -->

      <para>
	El 4 es una declaración de función en lugar de una definición de
	variable. Dice <quote><function>f4</function> es una función que
	retorna un puntero a un array de 10 punteros a funciones que
	retornan enteros</quote>.
      </para>


      <!--
      You will rarely if ever need such complicated declarations and
      definitions as these. However, if you go through the exercise of
      figuring them out you will not even be mildly disturbed with the
      slightly complicated ones you may encounter in real life.
      -->

      <para>
	Es poco habitual necesitar declaraciones y definiciones tan
	complicadas como éstas. Sin embargo, si se propone entenderlas,
	no le desconcertarán otras algo menos complicadas pero que si
	encontrará en la vida real.
      </para>
    </sect2>

    <sect2>
      <title>Uso de un puntero a función</title>

      <!--
      Once you define a pointer to a function, you must assign it to a
      function address before you can use it. Just as the address of an
      array arr[10] is produced by the array name without the brackets
      (arr), the address of a function func() is produced by the
      function name without the argument list (func). You can also use
      the more explicit syntax &func(). To call the function, you
      dereference the pointer in the same way that you declared it
      (remember that C and C++ always try to make definitions look the
      same as the way they are used). The following example shows how a
      pointer to a function is defined and used:
      -->

       <para>
	Una vez que se ha definido un puntero a función, debe asignarle
	la dirección de una función antes de poder usarlo. Del mismo
	modo que la dirección de un array <varname>arr[10]</varname> se
	obtiene con el nombre del array sin corchetes
	(<varname>arr</varname>), la dirección de una función
	<function>func()</function> se obtiene con el nombre de la
	función sin lista de argumentos
	(<function>func</function>). También puede usar una sintáxis más
	explícita: <code>&amp;func()</code>. Para invocar la función,
	debe dereferenciar el puntero de la misma forma que lo ha
	declarado (recuerde que C y C++ siempre intentan hacer que las
	definiciones se parezcan al modo en que se usan). El siguiente
	ejemplo muestra cómo se define y usa un puntero a función:
	</para>


//: V1C03:PointerToFunction.cpp


      <!--
      After the pointer to function fp is defined, it is assigned to the
      address of a function func() using fp = func (notice the argument
      list is missing on the function name). The second case shows
      simultaneous definition and initialization.
      -->

      <para>
	Una vez definido el puntero a función <varname>fp</varname>, se
	le asigna la dirección de una función
	<function>func()</function> usando <code>fp = func</code>
	(fíjese que la lista de argumentos no aparece junto al nombre de
	la función). El segundo caso muestra una definición e
	inicialización simultánea.
      </para>
    </sect2>

    <sect2>
      <title>Arrays de punteros a funciones</title>

      <!--
      One of the more interesting constructs you can create is an array
      of pointers to functions. To select a function, you just index
      into the array and dereference the pointer. This supports the
      concept of table-driven code; instead of using conditionals or
      case statements, you select functions to execute based on a state
      variable (or a combination of state variables). This kind of
      design can be useful if you often add or delete functions from the
      table (or if you want to create or change such a table
      dynamically).
      -->

      <para>
	Una de las construcciones más interesantes que puede crear es
	un array de punteros a funciones. Para elegir una función,
	sólo indexe el array y dereferencie el puntero. Esto permite
	implementar el concepto de <emphasis>código dirigido por
	tabla</emphasis>(<foreignphrase>table-driven
	code</foreignphrase>); en lugar de usar estructuras
	condicionales o sentencias case, se elige la función a
	ejecutar en base a una variable (o una combinación de
	variables). Este tipo de diseño puede ser útil si añade y
	elimina funciones de la tabla con frecuencia (o si quiere
	crear o cambiar una tabla dinámicamente).
      </para>


      <!--
      The following example creates some dummy functions using a
      preprocessor macro, then creates an array of pointers to those
      functions using automatic aggregate initialization. As you can
      see, it is easy to add or remove functions from the table (and
      thus, functionality from the program) by changing a small amount
      of code:
      -->

     <para>
	El siguiente ejemplo crea algunas funciones falsas usando una
	macro de preprocesador, después crea un array de punteros a esas
	funciones usando inicialización automática. Como puede ver, es
	fácil añadir y eliminar funciones de la table (y por tanto, la
	funcionalidad del programa) cambiando una pequeña porción de
	código.
      </para>


//: V1C03:FunctionTable.cpp


      <!--
      At this point, you might be able to imagine how this technique
      could be useful when creating some sort of interpreter or list
      processing program.
      -->

      <para>
	A partir de este punto, debería ser capaz de imaginar cómo esta
	técnica podría resultarle útil cuando tenga que crear algún tipo
	de intérprete o programa para procesar listas.
      </para>
    </sect2>
  </sect1>

  <sect1>
    <!-- Make: managing separate compilation -->
    <title>Make: cómo hacer compilación separada</title>

    <!--
    When using separate compilation (breaking code into a number of
    translation units), you need some way to automatically compile each
    file and to tell the linker to build all the pieces - along with the
    appropriate libraries and startup code - into an executable
    file. Most compilers allow you to do this with a single command-line
    statement. For the GNU C++ compiler, for example, you might say
    -->

    <para>
      Cuando se usa <emphasis>compilación separada</emphasis>
      (dividiendo el código en varias unidades de traducción), aparece
      la <emphasis>necesidad</emphasis> de un medio para compilar
      automáticamente cada fichero y decirle al enlazador como montar
      todas las piezas - con las librerías apropiadas y el código de
      inicio - en un fichero ejecutable. La mayoría de los compiladores
      le permiten hacerlo desde una sólo instrucción desde línea de
      comandos. Por ejemplo, para el compilador de C++ de <acronym
      >GNU</acronym> se puede hacer:
    </para>


<screen>
$ g++ SourceFile1.cpp SourceFile2.cpp
</screen>

    <!--
    The problem with this approach is that the compiler will first
    compile each individual file, regardless of whether that file needs
    to be rebuilt or not. With many files in a project, it can become
    prohibitive to recompile everything if you've changed only a single
    file.
    -->

    <para>
      En problema con este método es que el compilador compilará cada
      fichero individual tanto si el fichero
      <emphasis>necesita</emphasis> ser recompilado como sino. Cuando un
      proyecto tiene muchos ficheros, puede resultar prohibitivo
      recompilar todo cada vez que se cambia una línea en un fichero.
    </para>

    <!--
    The solution to this problem, developed on Unix but available
    everywhere in some form, is a program called make. The make utility
    manages all the individual files in a project by following the
    instructions in a text file called a makefile. When you edit some of
    the files in a project and type make, the make program follows the
    guidelines in the makefile to compare the dates on the source code
    files to the dates on the corresponding target files, and if a
    source code file date is more recent than its target file, make
    invokes the compiler on the source code file. make only recompiles
    the source code files that were changed, and any other source-code
    files that are affected by the modified files. By using make, you
    don't have to re-compile all the files in your project every time
    you make a change, nor do you have to check to see that everything
    was built properly. The makefile contains all the commands to put
    your project together. Learning to use make will save you a lot of
    time and frustration. You'll also discover that make is the typical
    way that you install new software on a Linux/Unix machine (although
    those makefiles tend to be far more complicated than the ones
    presented in this book, and you'll often automatically generate a
    makefile for your particular machine as part of the installation
    process).
    -->

    <para>
      La solución a este problema, desarrollada en Unix pero disponible
      de alún modo en todos los sistemas es un programa llamado
      <command>make</command>. La utilidad <command>make</command>
      maneja todos los ficheros individuales de un proyecto siguiendo
      las instrucciones escritas en un fichero de texto llamado
      <filename>makefile</filename>. Cuando edite alguno de los ficheros
      del proyecto y ejecute <command>make</command>, el programa
      <command>make</command> seguirá las directrices del
      <filename>makefile</filename> para comparar las fechas de los
      ficheros fuente con las de los ficheros resultantes
      correspondientes, y si una fichero fuente es más reciente que su
      fichero resultante, <command>make</command> recompila ese fichero
      fuente. <command>make</command> sólo recompila los ficheros fuente
      que han cambiado, y cualquier otro fichero que esté afectado por
      el fichero modificado. Usando <command>make</command> no tendrá
      que recompilar todos los ficheros de su proyecto cada vez que haga
      un cambio, ni tendrá que comprobar si todo se construye
      adecuadamente. El <filename>makefile</filename> contiene todas las
      instrucciones para montar el proyecto. Aprender a usar
      <command>make</command> le permitirá ahorrar mucho tiempo y
      frustraciones. También descubrirá que <command>make</command> es
      el método típico para instalar software nuevo en máquinas GNU o
      Unix<footnote>
	<para>
	  (N. de T.) El método del que habla el autor se refiere
	  normalmente a software instalado a partir de su código
	  fuente. La instalación de paquetes binarios es mucho más
	  simple y automatizada en la mayoría de las variantes actuales
	  del sistema operativo GNU.
	</para>
      </footnote>
      (aunque esos <filename>makefiles</filename> tienen a ser mucho más
      complicados que los que aparecen en este libro, y a menudo podrá
      generar automáticamente un <filename>makefile</filename> para su
      máquina particular como parte del proceso de instalación).
    </para>


    <!--
    Because make is available in some form for virtually all C++
    compilers (and even if it isn't, you can use freely-available makes
    with any compiler), it will be the tool used throughout this
    book. However, compiler vendors have also created their own project
    building tools. These tools ask you which files are in your project
    and determine all the relationships themselves. These tools use
    something similar to a makefile, generally called a project file,
    but the programming environment maintains this file so you don't
    have to worry about it. The configuration and use of project files
    varies from one development environment to another, so you must find
    the appropriate documentation on how to use them (although project
    file tools provided by compiler vendors are usually so simple to use
    that you can learn them by playing around - my favorite form of
    education).
    -->

    <para>
      Como <command>make</command> está disponible de algún modo para
      prácticamente todos los compiladores de C++ (incluso si no lo
      está, puede usar <command>makes</command> libres con cualquier
      compilador), será la herramienta usada en este libro. Sin embargo,
      los fabricantes de compiladores crean también sus propias
      herramientas para construir proyectos. Estás herramientas
      preguntan qué ficheros hay en el proyecto y determinan las
      relaciones entre ellos. Estas herramientas utilizan algo similar a
      un <filename>makefile</filename>, normalmente llamado
      <emphasis>fichero de proyecto</emphasis>, pero el entorno de
      programación mantiene este fichero para que el programador no
      tenga que preocuparse de él. La configuración y uso de los
      ficheros de proyecto varía de un entorno de desarrollo a otro, de
      modo que tendrá que buscar la documentación apropiada en cada caso
      (aunque esas herramientas proporcionadas por el fabricante
      normalmente son tan simples de usar que es fácil aprender a
      usarlas jugando un poco con ellas - mi método educativo favorito).
    </para>

    <!--
    The makefiles used within this book should work even if you are also
    using a specific vendor's project-building tool.
    -->

    <para>
      Los <filename>makefiles</filename> que acompañan a este libro
      deberían funcionar bien incluso si también usa una herramienta
      específica para construcción de proyectos.
    </para>

    <sect2>
      <title>Las actividades de Make</title>

      <!--
      When you type make (or whatever the name of your "make" program
      happens to be), the make program looks in the current directory
      for a file named makefile, which you've created if it's your
      project. This file lists dependencies between source code
      files. make looks at the dates on files. If a dependent file has
      an older date than a file it depends on, make executes the rule
      given after the dependency.
      -->

      <para>
	Cuando escribe <command>make</command> (o cualquiera que sea el
	nombre del su programa <command>make</command>),
	<command>make</command> busca un fichero llamado
	<filename>makefile</filename> o <filename>Makefile</filename> en
	el directorio actual, que usted habrá creado para su
	proyecto. Este fichero contiene una lista de dependencias entre
	ficheros fuente, <command>make</command> comprueba las fechas de
	los ficheros. Si un fichero tiene una fecha más antigua que el
	fichero del que depende, <command>make</command> ejecuta la
	<emphasis>regla</emphasis> indicada después de la dependencia.
      </para>

      <!--
      All comments in makefiles start with a # and continue to the end
      of the line.
      -->

      <para>
	Todos los comentarios de los <filename>makefiles</filename>
	empiezan con un <token>#</token> y continúan hasta el fina
	de la línea.
      </para>

      <!--
      As a simple example, the makefile for a program called "hello"
      might contain:
      -->

      <para>
	Como un ejemplo sencillo, el <filename>makefile</filename> para
	una programa llamado <quote>hello</quote> podría contener:
      </para>


<programlisting language="Make">
# A comment
hello.exe: hello.cpp
        mycompiler hello.cpp
</programlisting>


      <!--
      This says that hello.exe (the target) depends on hello.cpp. When
      hello.cpp has a newer date than hello.exe, make executes the
      "rule" mycompiler hello.cpp. There may be multiple dependencies
      and multiple rules. Many make programs require that all the rules
      begin with a tab. Other than that, whitespace is generally ignored
      so you can format for readability.
      -->

      <para>
	Esto dice que <filename>hello.exe</filename> (el objetivo)
	depende de <filename>hello.cpp</filename>. Cuando
	<filename>hello.cpp</filename> tiene una fecha más reciente que
	<filename>hello.exe</filename>, <command>make</command> ejecuta
	la <quote>regla</quote> <command>mycompiler
	hello.cpp</command>. Puede haber múltiples dependencias y
	múltiples reglas. Muchas implementaciones de
	<command>make</command> requieren que todas las reglas empiecen
	con un tabulador. Para lo demás, por norma general los espacios
	en blanco se ignoran de modo que se pueden usar a efectos de
	legibilidad.
      </para>

      <!--
      The rules are not restricted to being calls to the compiler; you
      can call any program you want from within make. By creating groups
      of interdependent dependency-rule sets, you can modify your source
      code files, type make and be certain that all the affected files
      will be rebuilt correctly.
      -->

      <para>
	Las reglas no están restringidas a llamadas al compilador; puede
	llamar a cualquier programa que quiera. Creando grupos de reglas
	de dependencia, puede modificar sus ficheros fuentes, escribir
	<filename>make</filename> y estar seguro de que todos los
	fichero afectados serán re-construidos correctamente.
      </para>


      <sect3>
	<title>Macros</title>
	<!--
	A makefile may contain macros (note that these are completely
	different from C/C++ preprocessor macros). Macros allow
	convenient string replacement. The makefiles in this book use a
	macro to invoke the C++ compiler. For example,
	-->

	<para>
	  Un <filename>makefile</filename> puede contener
	  <emphasis>macros</emphasis> (tenga en cuenta que estas macros
	  no tienen nada que ver con las del preprocesador de C/C++). La
	  macros permiten reemplazar cadenas de texto. Los
	  <filename>makefiles</filename> del libro usan una macro para
	  invocar el compilador de C++. Por ejemplo,
	</para>


<programlisting language="Make">
CPP = mycompiler
hello.exe: hello.cpp
        $(CPP) hello.cpp
</programlisting>


	<!--
	The = is used to identify CPP as a macro, and the $ and
	parentheses expand the macro. In this case, the expansion means
	that the macro call $(CPP) will be replaced with the string
	mycompiler. With the macro above, if you want to change to a
	different compiler called cpp, you just change the macro to:
	-->

	<para>
	  El <token>=</token> se usa para indicar que
	  <function>CPP</function> es una macro, y el
	  <token>$</token> y los paréntesis expanden la macro. En
	  este caso, la expansión significa que la llamada a la macro
	  <varname>$(CPP)</varname> será reemplazada con la cadena
	  <literal>mycompiler</literal>. Con esta macro, si quiere
	  utilizar un compilador diferente llamado
	  <command>cpp</command>, sólo tiene que cambiar la macro a:
	</para>


<programlisting>
CPP = cpp
</programlisting>


	<!--
	You can also add compiler flags, etc., to the macro, or use
	separate macros to add compiler flags.
	-->

	<para>
	  También puede añadir a la macro opciones del compilador, etc.,
	  o usar otras macros para añadir dichas opciones.
	</para>
      </sect3>


      <sect3>
	<!-- Suffix Rules -->
	<title>Reglas de sufijo</title>
	<!--
	It becomes tedious to tell make how to invoke the compiler for
	every single cpp file in your project, when you know it's the
	same basic process each time. Since make is designed to be a
	time-saver, it also has a way to abbreviate actions, as long as
	they depend on file name suffixes. These abbreviations are
	called suffix rules. A suffix rule is the way to teach make how
	to convert a file with one type of extension (.cpp, for example)
	into a file with another type of extension (.obj or .exe). Once
	you teach make the rules for producing one kind of file from
	another, all you have to do is tell make which files depend on
	which other files. When make finds a file with a date earlier
	than the file it depends on, it uses the rule to create a new
	file.
	-->

	<para>
	  Es algo tedioso tener que decir a <command>make</command> que
	  invoque al compilador para cada fichero
	  <filename>cpp</filename> del proyecto, cuando se sabe que
	  básicamente siempre es el mismo proceso. Como
	  <command>make</command> está diseñado para ahorrar tiempo,
	  también tiene un modo de abreviar acciones, siempre que
	  dependan del sufijo de los ficheros. Estas abreviaturas se
	  llaman <emphasis>reglas de sufijo</emphasis>. Una regla de
	  sufijo es la la forma de indicar a <command>make</command>
	  cómo convertir un fichero con cierta extensión
	  (<filename>.cpp</filename> por ejemplo) en un fichero con otra
	  extensión (<filename>.obj</filename> o
	  <filename>.exe</filename>). Una vez que le haya indicado a
	  <command>make</command> las reglas para producir un tipo de
	  fichero a partir de otro, lo único que tiene que hacer es
	  decirle a <command>make</command> cuales son las dependencias
	  respecto a otros ficheros. Cuando <command>make</command>
	  encuentra un fichero con una fecha previa a otro fichero del
	  que depende, usa la regla para crear la versión actualizada
	  del fichero objetivo.
	</para>

	<!--
	The suffix rule tells make that it doesn't need explicit rules
	to build everything, but instead it can figure out how to build
	things based on their file extension. In this case it says "To
	build a file that ends in exe from one that ends in cpp, invoke
	the following command." Here's what it looks like for the
	example above:
	-->

	<para>
	  La regla de sufijo le dice a <command>make</command> que no se
	  necesitan reglas explícitas para construir cada cosa, en su
	  lugar le explica cómo construir cosas en base a la extensión
	  del fichero. En este caso dice <quote>Para contruir un fichero
	  con extensión <filename>.exe</filename> a partir de uno con
	  extensión <filename>.cpp</filename>, invocar el siguiente
	  comando</quote>. Así sería para ese ejemplo:
	</para>


<programlisting language="Make">
CPP = mycompiler
.SUFFIXES: .exe .cpp
.cpp.exe:
        $(CPP) $&lt;
</programlisting>


	<!--
	The .SUFFIXES directive tells make that it should watch out for
	any of the following file-name extensions because they have
	special meaning for this particular makefile. Next you see the
	suffix rule .cpp.exe, which says "Here's how to convert any
	file with an extension of cpp to one with an extension of exe"
	(when the cpp file is more recent than the exe file). As before,
	the $(CPP) macro is used, but then you see something new:
	$<. Because this begins with a '$' it's a macro, but this is
	one of make's special built-in macros. The $< can be used only
	in suffix rules, and it means "whatever prerequisite triggered
	the rule" (sometimes called the dependent), which in this case
	translates to "the cpp file that needs to be compiled."
	-->

	<para>
	  La directiva <varname>.SUFFIXES</varname> le dice a
	  <command>make</command> que debe vigilar las extensiones que
	  se indican porque tiene un significado especial para este
	  <filename>makefile</filename> en particular. Lo siguiente que
	  aparece es la regla de sufijo <literal>.cpp.exe</literal>, que
	  dice <quote>cómo convertir cualquier fichero con extensión
	  <filename>.cpp</filename> a uno con extensión
	  <filename>.exe</filename></quote> (cuando el fichero
	  <filename>.cpp</filename> es más reciente que el fichero
	  .<filename>.exe</filename>). Como antes, se usa la macro
	  <varname>$(CPP)</varname>, pero aquí aparece algo nuevo:
	  <varname>$&lt;</varname>. Como empieza con un
	  <token>$</token> es que es una macro, pero esta es una
	  de las macros especiales predefinidas por
	  <command>make</command>. El <varname>$&lt;</varname> se puede
	  usar sólo en reglas de sufijo y significa <quote>cualquier
	  prerrequisito que dispare la regla</quote> (a veces llamado
	  <emphasis>dependencia</emphasis>), que en este caso se refiere
	  al <quote>fichero <filename>.cpp</filename> que necesita ser
	  compilado</quote>.
	</para>

	<!--
	Once the suffix rules have been set up, you can simply say, for
	example, "make Union.exe," and the suffix rule will kick in,
	even though there's no mention of "Union" anywhere in the
	makefile.
	-->

	<para>
	  Una ver que las reglas de sufijo se han fijado, puede indicar
	  por ejemplo algo tan simple como <command>make
	  Union.exe</command> y se aplicará la regla sufijo, incluso
	  aunque no se mencione <quote>Union</quote> en ninguna parte
	  del <filename>makefile</filename>.
	</para>

      </sect3>

      <sect3>
	<!-- Default targets -->
	<title>Objetivos predeterminados</title>
	<!--
	After the macros and suffix rules, make looks for the first
	"target" in a file, and builds that, unless you specify
	differently. So for the following makefile:
	-->

	<para>
	  Después de las macros y las reglas de sufijo,
	  <command>make</command> busca la primero <quote>regla</quote>
	  del fichero, y la ejecuta, a menos que se especifica una regla
	  diferente. Así que pare el siguiente
	  <filename>makefile</filename>:
	</para>


<programlisting language="Make">
CPP = mycompiler
.SUFFIXES: .exe .cpp
.cpp.exe:
        $(CPP) $&lt;
target1.exe:
target2.exe:
</programlisting>


	<!--
	If you just type 'make', then target1.exe will be built (using
	the default suffix rule) because that's the first target that
	make encounters. To build target2.exe you'd have to explicitly
	say 'make target2.exe'. This becomes tedious, so you normally
	create a default "dummy" target that depends on all the rest
	of the targets, like this:
	-->

	<para>
	  Si ejecuta simplemente <command>make</command>, se construirá
	  <filename>target1.exe</filename> (usando la regla de sufijo
	  predeterminada) porque ese es el primer objetivo que
	  <command>make</command> va a encontrar. Para construir
	  <filename>target2.exe</filename> se debe indicar
	  explícitamente diciendo <command>make
	  target2.exe</command>. Esto puede resultar tedioso de modo que
	  normalmente se crea un objetivo <quote>dummy</quote> por
	  defecto que depende del resto de objetivos, como éste:
	</para>


<programlisting language="Make">
CPP = mycompiler
.SUFFIXES: .exe .cpp
.cpp.exe:
        $(CPP) $&lt;
all: target1.exe target2.exe
</programlisting>


	<!--
	Here, 'all' does not exist and there's no file called 'all',
	so every time you type make, the program sees 'all' as the
	first target in the list (and thus the default target), then it
	sees that 'all' does not exist so it had better make it by
	checking all the dependencies. So it looks at target1.exe and
	(using the suffix rule) sees whether (1) target1.exe exists and
	(2) whether target1.cpp is more recent than target1.exe, and if
	so runs the suffix rule (if you provide an explicit rule for a
	particular target, that rule is used instead). Then it moves on
	to the next file in the default target list. Thus, by creating a
	default target list (typically called 'all' by convention, but
	you can call it anything) you can cause every executable in your
	project to be made simply by typing 'make'. In addition, you
	can have other non-default target lists that do other things -
	for example, you could set it up so that typing 'make debug'
	rebuilds all your files with debugging wired in.
	-->

	<para>
	  Aquí, <literal>all</literal> no existe y no hay ningún
	  fichero llamada <literal>all</literal>, así que cada vez que
	  ejecute <command>make</command>, el programa verá que
	  <literal>all</literal> es el primer objetivo de la lista (y
	  por tanto el objetivo por defecto), entonces comprobará que
	  <literal>all</literal> no existe y analizará sus
	  dependencias. Comprueba <filename>target1.exe</filename> y
	  (usando la regla de sufijo) comprobará (1) que
	  <filename>target1.exe</filename> existe y (2) que
	  <filename>target1.cpp</filename> es más reciente que
	  <filename>target1.exe</filename> , y si es así ejecutará la
	  regla (si proporciona una regla explícita para un objetivo
	  concreto, se usará esa regla en su lugar). Después pasa a
	  analizar el siguiente fichero de la lista de objetivos por
	  defecto. De este modo, breando una lista de objetivos por
	  defecto (típicamente llamada <literal>all</literal> por convenio,
	  aunque se puede tener cualquier nombre) puede conseguir que se
	  construyan todos los ejecutables de su proyecto simplemente
	  escribiendo <command>make</command>. Además, puede tener otras
	  listas de objetivos para hacer otras cosas - por ejemplo,
	  podría hacer que escribiendo <command>make debug</command> se
	  reconstruyeran todos los ficheros pero incluyendo información
	  de depuración.
	</para>

      </sect3>
    </sect2>

    <sect2>
      <title>Los Makefiles de este libro</title>

      <!--
      Using the program ExtractCode.cpp from Volume 2 of this book, all
      the code listings in this book are automatically extracted from
      the ASCII text version of this book and placed in subdirectories
      according to their chapters. In addition, ExtractCode.cpp creates
      several makefiles in each subdirectory (with different names) so
      you can simply move into that subdirectory and type make -f
      mycompiler.makefile (substituting the name of your compiler for
      'mycompiler', the '-f' flag says "use what follows as the
      makefile"). Finally, ExtractCode.cpp creates a "master"
      makefile in the root directory where the book's files have been
      expanded, and this makefile descends into each subdirectory and
      calls make with the appropriate makefile. This way you can compile
      all the code in the book by invoking a single make command, and
      the process will stop whenever your compiler is unable to handle a
      particular file (note that a Standard C++ conforming compiler
      should be able to compile all the files in this book). Because
      implementations of make vary from system to system, only the most
      basic, common features are used in the generated makefiles.
      -->

      <para>
	Usando el programa <filename>ExtractCode.cpp</filename> del
	Volumen 2 de este libro, se han extraido automáticamente todos
	los listado de código de este libro a partir de la versión en
	texto ASCII y se han colocado en subdirectorios de acuerdo a sus
	capítulos. Además, <filename>ExtractCode.cpp</filename> crea
	varios <filename>makefiles</filename> en cada subdirectorio (con
	nombres diferentes) para que pueda ir a cualquier subdirectorio
	y escribir <command>make -f mycompiler.makefile</command>
	(sustituyendo <quote>mycompiler</quote> por el nombre de su
	compilador, la opción <parameter>-f</parameter> dice
	<quote>utiliza lo siguiente como un
	<filename>makefile</filename></quote>). Finalmente,
	<filename>ExtractCode.cpp</filename> crea un
	<filename>makefile</filename> <quote>maestro</quote> en el
	directorio raíz donde se hayan extraido los fichero del libro, y
	este <filename>makefile</filename> descienda a cada
	subdirectorio y llama a <command>make</command> con el
	<filename>makefile</filename> apropiado. De este modo, se puede
	compilar todo el código de los listados del libro invocando un
	único comando <command>make</command>, y el proceso parará cada
	vez que su compilador no pueda manejar un fichero particular
	(tenga presente que un compilador conforme al Estándar C++
	debería ser compatible con todos los ficheros de este
	libro). Como algunas implementaciones de <command>make</command>
	varían de un sistema a otro, en los
	<filename>makefiles</filename> generados se usan sólo las
	características más básicas y comunes.
      </para>
    </sect2>

    <sect2>
      <title>Un ejemplo de Makefile</title>

      <!--
      As mentioned, the code-extraction tool ExtractCode.cpp
      automatically generates makefiles for each chapter. Because of
      this, the makefiles for each chapter will not be placed in the
      book (all the makefiles are packaged with the source code, which
      you can download from www.BruceEckel.com). However, it's useful
      to see an example of a makefile. What follows is a shortened
      version of the one that was automatically generated for this
      chapter by the book's extraction tool. You'll find more than one
      makefile in each subdirectory (they have different names; you
      invoke a specific one with 'make -f'). This one is for GNU C++:
      -->

      <para>
	Tal como se mencionaba, la herramienta de extracción de código
	<filename>ExtractCode.cpp</filename> genera automáticamente
	<filename>makefiles</filename> para cada capítulo. Por eso, los
	<filename>makefiles</filename> de cada capítulo no aparecen en
	el libro (todos los <filename>makefiles</filename> están
	empaquetados con el código fuente, que se puede descargar de
	<ulink
	url="http://www.bruceeckel.com">www.BruceEckel.com</ulink>).
	Sin embargo, es útil ver un ejemplo de un
	<filename>makefile</filename>. Lo siguiente es una versión
	recortada de uno de esos <filename>makefiles</filename>
	generados automáticamente para este capítulo. Encontrará más de
	un <filename>makefile</filename> en cada subdirectorio (tienen
	nombres diferentes; puede invocar uno concreto con <command>make
	-f</command>. Éste es para GNU C++:
      </para>


<programlisting language="Make">
CPP = g++
OFLAG = -o
.SUFFIXES : .o .cpp .c
.cpp.o :
  $(CPP) $(CPPFLAGS) -c $&lt;
.c.o :
  $(CPP) $(CPPFLAGS) -c $&lt;

all: \
  Return \
  Declare \
  Ifthen \
  Guess \
  Guess2
# Rest of the files for this chapter not shown

Return: Return.o
  $(CPP) $(OFLAG)Return Return.o

Declare: Declare.o
  $(CPP) $(OFLAG)Declare Declare.o

Ifthen: Ifthen.o
  $(CPP) $(OFLAG)Ifthen Ifthen.o

Guess: Guess.o
  $(CPP) $(OFLAG)Guess Guess.o

Guess2: Guess2.o
  $(CPP) $(OFLAG)Guess2 Guess2.o

Return.o: Return.cpp
Declare.o: Declare.cpp
Ifthen.o: Ifthen.cpp
Guess.o: Guess.cpp
Guess2.o: Guess2.cpp
</programlisting>


      <!--
      The macro CPP is set to the name of the compiler. To use a
      different compiler, you can either edit the makefile or change the
      value of the macro on the command line, like this:
      -->

      <para>
	La macro CPP contiene el nombre del compilador. Para usar un
	compilador diferente, puede editar el
	<filename>makefile</filename> o cambiar el valor de la macro
	desde línea de comandos, algo como:
      </para>


<screen>
$ make CPP=cpp
</screen>


      <!--
      Note, however, that ExtractCode.cpp has an automatic scheme to
      automatically build makefiles for additional compilers.
      -->

      <para>
	Tenga en cuenta, sin embargo, que
	<filename>ExtractCode.cpp</filename> tiene un esquema automático
	para construir <filename>makefiles</filename> para compiladores
	adicionales.
      </para>

      <!--
      The second macro OFLAG is the flag that's used to indicate the
      name of the output file. Although many compilers automatically
      assume the output file has the same base name as the input file,
      others don't (such as Linux/Unix compilers, which default to
      creating a file called a.out).
      -->

      <para>
	La segunda macro <varname>OFLAG</varname> es la opción que se
	usa para indicar el nombre del fichero de salida. Aunque muchos
	compiladores asumen automáticamente que el fichero de salida
	tiene el mismo nombre base que el fichero de entrada, otros no
	(como los compiladores GNU/Unix, que por defecto crean un
	fichero llamado <filename>a.out</filename>).
      </para>


      <!--
      You can see that there are two suffix rules here, one for cpp
      files and one for .c files (in case any C source code needs to be
      compiled). The default target is all, and each line for this
      target is "continued" by using the backslash, up until Guess2,
      which is the last one in the list and thus has no backslash. There
      are many more files in this chapter, but only these are shown here
      for the sake of brevity.
      -->

      <para>
	Como ve, hay dos reglas de sufijo, una para ficheros
	<filename>.cpp</filename> y otra para fichero
	<filename>.c</filename> (en caso de que se necesite compilar
	algún fuente C). El objetivo por defecto es
	<literal>all</literal>, y cada línea de este objetivo está
	<quote>continuada</quote> usando la contrabarra, hasta
	<filename>Guess2</filename>, que el el último de la lista y por
	eso no tiene contrabarra. Hay muchos más fichero en este
	capítulo, pero (por brevedad) sólo se muestran algunos.
      </para>


      <!--
      The suffix rules take care of creating object files (with a .o
      extension) from cpp files, but in general you need to explicitly
      state rules for creating the executable, because normally an
      executable is created by linking many different object files and
      make cannot guess what those are. Also, in this case (Linux/Unix)
      there is no standard extension for executables so a suffix rule
      won't work for these simple situations. Thus, you see all the
      rules for building the final executables explicitly stated.
      -->

      <para>
	Las reglas de sufijo se ocupan de crear fichero objeto (con
	extensión <filename>.o</filename>) a partir de los fichero
	<filename>.cpp</filename>, pero en general se necesita escribir
	reglas explícitamente para crear el ejecutable, porque
	normalmente el ejecutable se crea enlazando muchos fichero
	objeto diferente y <command>make</command> no puede adivinar
	cuales son. También, en este caso (GNU/Unix) no se usan
	extensiones estándar para los ejecutables de modo que una regla
	de sufijo no sirve para esas situaciones. Por eso, verá que
	todas las reglas para construir el ejecutable final se indican
	explícitamente.
      </para>

      <!--
      This makefile takes the absolute safest route of using as few make
      features as possible; it only uses the basic make concepts of
      targets and dependencies, as well as macros. This way it is
      virtually assured of working with as many make programs as
      possible. It tends to produce a larger makefile, but that's not
      so bad since it's automatically generated by ExtractCode.cpp.
      -->

      <para>
	Este <filename>makefile</filename> toma el camino más seguro
	usando el mínimo de prestaciones de <command>make</command>;
	sólo usa los conceptos básicos de objetivos y dependencias, y
	también macros. De este modo está prácticamente asegurado que
	funcionará con la mayoría de las implementaciones de
	<command>make</command>. Eso implica que se producen fichero
	<filename>makefile</filename> más grandes, pero no es algo
	negativo ya que se generan automáticamente por
	<filename>ExtractCode.cpp</filename>.

      </para>

      <!--
      There are lots of other make features that this book will not use,
      as well as newer and cleverer versions and variations of make with
      advanced shortcuts that can save a lot of time. Your local
      documentation may describe the further features of your particular
      make, and you can learn more about make from Managing Projects
      with Make by Oram and Talbott (O'Reilly, 1993). Also, if your
      compiler vendor does not supply a make or it uses a non-standard
      make, you can find GNU make for virtually any platform in
      existence by searching the Internet for GNU archives (of which
      there are many).
      -->

      <para>
	Hay muchísimas otras prestaciones de <command>make</command> que
	no se usan en este libro, incluyendo las versiones más nuevas e
	inteligentes y las variaciones de <command>make</command> con
	atajos avanzados que permiten ahorrar mucho tiempo. La
	documentación propia de cada <command>make</command> particular
	describe en más profundidad sus características; puede aprender
	más sobre <command>make</command> en <citetitle>Managing
	Projects with Make</citetitle> de Oram y Taiboot (O'Reilly,
	1993). También, si el fabricante de su compilador no proporciona
	un <command>make</command> o usa uno que no es estándar, puede
	encontrar GNU Make para prácticamente todas las plataformas que
	existen buscado en los archivos de GNU en internet (hay muchos).
      </para>

    </sect2>
  </sect1>

  <sect1>
    <title>Resumen</title>

    <!--
    This chapter was a fairly intense tour through all the fundamental
    features of C++ syntax, most of which are inherited from and in
    common with C (and result in C++'s vaunted backwards compatibility
    with C). Although some C++ features were introduced here, this tour
    is primarily intended for people who are conversant in programming,
    and simply need to be given an introduction to the syntax basics of
    C and C++. If you're already a C programmer, you may have even seen
    one or two things about C here that were unfamiliar, aside from the
    C++ features that were most likely new to you. However, if this
    chapter has still seemed a bit overwhelming, you should go through
    the CD ROM course Thinking in C: Foundations for C++ and Java (which
    contains lectures, exercises, and guided solutions), which is bound
    into this book, and also available at www.BruceEckel.com
    -->

    <para>
      Este capítulo ha sido un repaso bastante intenso a través de todas
      las características fundamentales de la sintaxis de C++, la
      mayoría heredada de C (y ello redunda la compatibilidad hacia
      atrás FIXME:vaunted de C++ con C). Aunque algunas características
      de C++ se han presentado aquí, este repaso está pensado
      principalmente para personas con experiencia en programación, y
      simplemente necesitan una introducción a la sintaxis básica de C y
      C++. Incluso si usted ya es un programador de C, puede que haya
      visto una o dos cosas de C que no conocía, aparte de todo lo
      referente a C++ que probablemente sean nuevas. Sin embargo, si
      este capítulo le ha sobrepasado un poco, debería leer el curso en
      CD ROM <citetitle>Thinking in C: Foundations for C++ and
      Java</citetitle> que contiene lecturas, ejercicios, y soluciones
      guiadas), que viene con este libro, y también está disponible en
      <ulink url="http://www.bruceeckel.com">www.BruceEckel.com</ulink>.
    </para>
  </sect1>

  <sect1>
    <title>Ejercicios</title>
    <xi:include parse="xml" href="./ejercicios.xml"/>

    <orderedlist>
      <listitem>
	<!--
	1. Create a header file (with an extension of '.h'). In this
	file, declare a group of functions by varying the argument lists
	and return values from among the following: void, char, int, and
	float. Now create a .cpp file that includes your header file and
	creates definitions for all of these functions. Each definition
	should simply print out the function name, argument list, and
	return type so you know it's been called. Create a second .cpp
	file that includes your header file and defines int main( ),
	containing calls to all of your functions. Compile and run your
	program.
	-->
	<para>
	  Cree un fichero de cabecera (con extensión
	  <quote>.h</quote>). En este fichero, declare un grupo de
	  funciones variando las listas de argumentos y valores de
	  retorno de entre los siguientes: <kw>void</kw>, <kw>char</kw>,
	  <kw>int</kw> y <kw>float</kw>. Ahora cree un fichero
	  <filename>.cpp</filename> que incluya su fichero de cabecera
	  y haga definiciones para todas esas funciones. Cada definición
	  simplemente debe imprimir en nombre de la función, la lista de
	  argumentos y el tipo de retorno para que se sepa que ha sido
	  llamada. Cree un segundo fichero <filename>.cpp</filename> que
	  incluya el fichero de cabecera y defina una <code>int
	  main()</code>, que contenga llamadas a todas sus
	  funciones. Compile y ejecute su programa.
	</para>
      </listitem>
      <listitem>
	<!--
	2. Write a program that uses two nested for loops and the
	modulus operator (%) to detect and print prime numbers (integral
	numbers that are not evenly divisible by any other numbers
	except for themselves and 1).
	-->
	<para>
	  Escriba un programa que use dos bucles <kw>for</kw> anidados y
	  el operador módulo (<oper>%</oper>) para detectar e imprimir
	  números enteros (números enteros sólo divisibles entre si mismos
	  y entre 1).
	</para>
      </listitem>
      <listitem>
	<!--
	3. Write a program that uses a while loop to read words from
	standard input (cin) into a string. This is an "infinite"
	while loop, which you break out of (and exit the program) using
	a break statement. For each word that is read, evaluate it by
	first using a sequence of if statements to "map" an integral
	value to the word, and then use a switch statement that uses
	that integral value as its selector (this sequence of events is
	not meant to be good programming style; it's just supposed to
	give you exercise with control flow). Inside each case, print
	something meaningful. You must decide what the "interesting"
	words are and what the meaning is. You must also decide what
	word will signal the end of the program. Test the program by
	redirecting a file into the program's standard input (if you
	want to save typing, this file can be your program's source
	file).
	-->
	<para>
	  Escriba un programa que utilice un bucle <kw>while</kw>
	  para leer palabras de la entrada estándar
	  (<varname>cin</varname>) y las guarde en un
	  <type>string</type>. Este es un bucle <kw>while</kw>
	  <quote>infinito</quote>, que debe romper (y salir del
	  programa) usando la sentencia <kw>break</kw>. Por cada palabra
	  que lea, evalúela primero usando una secuencia de sentencias
	  <kw>if</kw> para <quote>mapear</quote> un valor entero de la
	  palabra, y después use una sentencia <kw>switch</kw> que
	  utilice ese valor entero como selector (esta secuencia de
	  eventos no es un buen estilo de programación; solamente es un
	  supuesto para que practique con el control de flujo). Dentro
	  de cada <kw>case</kw>, imprima algo con sentido. Debe decidir
	  cuales son las palabras interesantes y qué significan. También
	  debe decidir qué palabra significa el fin del programa. Pruebe
	  el programa redireccionando un fichero como entrada (si quiere
	  ahorrarse tener que escribir, ese fichero puede ser el propio
	  código fuente del programa).
	</para>
      </listitem>
      <listitem>
	<!--
	4. Modify Menu.cpp to use switch statements instead of if
	statements.
	-->
	<para>
	  Modifique <filename>Menu.cpp</filename> para usar sentencias
	  <kw>switch</kw> en lugar de <kw>if</kw>.
	</para>
      </listitem>
      <listitem>
	<!--
	5. Write a program that evaluates the two expressions in the
	section labeled "precedence."
	-->
	<para>
	  Escriba un programa que evalúe las dos expresiones de la
	  sección llamada <quote>precedencia</quote>.
	</para>
      </listitem>
      <listitem>
	<!--
	6. Modify YourPets2.cpp so that it uses various different data
	types (char, int, float, double, and their variants). Run the
	program and create a map of the resulting memory layout. If you
	have access to more than one kind of machine, operating system,
	or compiler, try this experiment with as many variations as you
	can manage.
	-->
	<para>
	  Modifique <filename>YourPets2.cpp</filename> para que use
	  varios tipos de datos distintos (<type>char</type>,
	  <type>int</type>, <type>float</type>, <type>double</type>, y
	  sus variantes). Ejecute el programa y cree un mapa del esquema
	  de memoria resultante. Si tiene acceso a más de un tipo de
	  máquina, sistema operativo, o compilador, intente este
	  experimento con tantas variaciones como pueda manejar.
	</para>
      </listitem>
      <listitem>
	<!--
	7. Create two functions, one that takes a string* and one that
	takes a string&. Each of these functions should modify the
	outside string object in its own unique way. In main( ), create
	and initialize a string object, print it, then pass it to each
	of the two functions, printing the results.
	-->
	<para>
	  Cree dos funciones, una que tome un <type>string*</type> y una
	  que tome un <type>string&amp;</type>. Cada una de estas funciones
	  debería modificar el objeto <type>externo</type> a su
	  manera. En <function>main()</function>, cree e inicialice un
	  objeto <type>string</type>, imprímalo, después páselo a cada
	  una de las dos funciones, imprimiendo los resultados.
	</para>
      </listitem>
      <listitem>
	<!--
	8. Write a program that uses all the trigraphs to see if your
	compiler supports them.
	-->
	<para>
	  Escriba un programa que use todos los trígrafos para ver si su
	  compilador los soporta.
	</para>
      </listitem>
      <listitem>
	<!--
	9. Compile and run Static.cpp. Remove the static keyword from
	the code, compile and run it again, and explain what happens.
	-->
	<para>
	  Compile y ejecute <filename>Static.cpp</filename>. Elimine la
	  palabra reservada <kw>static</kw> del código, compile y
	  ejecútelo de nuevo, y explique lo que ocurre.
	</para>
      </listitem>
      <listitem>
	<!--
	10. Try to compile and link FileStatic.cpp with
	FileStatic2.cpp. What does the resulting error message mean?
	-->
	<para>
	  Intente compilar y enlazar <filename>FileStatic.cpp</filename>
	  con <filename>FileStatic2.cpp</filename>. ¿Qué significan los
	  mensajes de error que aparecen?
	</para>
      </listitem>
      <listitem>
	<!--
	11. Modify Boolean.cpp so that it works with double values
	instead of ints.
	-->
	<para>
	  Modifique <filename>Boolean.cpp</filename> para que funcione
	  con valores <type>double</type> en lugar de <type>int</type>.
	</para>
      </listitem>
      <listitem>
	<!--
	12. Modify Boolean.cpp and Bitwise.cpp so they use the explicit
	operators (if your compiler is conformant to the C++ Standard it
	will support these).
	-->
	<para>
	  Modifique <filename>Boolean.cpp</filename> y
	  <filename>Bitwise.cpp</filename> de modo que usen los
	  operadores explícitos (si su compilador es conforme al
	  Estándar C++ los soportará).
	</para>
      </listitem>
      <listitem>
	<!--
	13. Modify Bitwise.cpp to use the functions from
	Rotation.cpp. Make sure you display the results in such a way
	that it's clear what's happening during rotations.
	-->
	<para>
	  Modifique <filename>Bitwise.cpp</filename> para usar las
	  funciones de <filename>Rotation.cpp</filename>. Asegúrese de
	  que muestra los resultados que deje claro qué ocurre durante
	  las rotaciones.
	</para>
      </listitem>
      <listitem>
	<!--
	14. Modify Ifthen.cpp to use the ternary if-else operator (?:).
	-->
	<para>
	  Modifique <filename>Ifthen.cpp</filename> para usar el
	  operador <kw>if-else</kw> ternario(<oper>?:</oper>).
	</para>
      </listitem>
      <listitem>
	<!--
        15. Create a struct that holds two string objects and one
	int. Use a typedef for the struct name. Create an instance of
	the struct, initialize all three values in your instance, and
	print them out. Take the address of your instance and assign it
	to a pointer to your struct type. Change the three values in
	your instance and print them out, all using the pointer.
	-->
	<para>
	  Cree una <kw>struct</kw> que contenga dos objetos
	  <classname>string</classname> y uno <type>int</type>. Use un
	  <kw>typedef</kw> para el nombre de la <kw>struct</kw>. Cree
	  una instancia de la <kw>struct</kw>, inicialice los tres
	  valores de la instancia, y muestrelos en pantalla. Tome la
	  dirección de su instancia y asígnela a un puntero a tipo de la
	  <kw>struct</kw>. Usando el puntero, Cambie los tres valores de
	  la instancia y muestrelos.
	</para>
      </listitem>
      <listitem>
	<!--
	16. Create a program that uses an enumeration of colors. Create
	a variable of this enum type and print out all the numbers that
	correspond with the color names, using a for loop.
	-->
	<para>
	  Cree un programa que use un enumerado de colores. Cree una
	  variable de este tipo <kw>enum</kw> y, utilizando un bucle,
	  muestre todos los números que corresponden a los nombres de
	  los colores.
	</para>
      </listitem>
      <listitem>
	<!--
	17. Experiment with Union.cpp by removing various union elements
	to see the effects on the size of the resulting union. Try
	assigning to one element (thus one type) of the union and
	printing out a via a different element (thus a different type)
	to see what happens.
	-->
	<para>
	  Experimente con <filename>Union.cpp</filename> eliminando
	  varios elementos de la <kw>union</kw> para ver el efecto que
	  causa en el tamaño de la <kw>union</kw> resultante. Intente
	  asignar un elemento (por tanto un tipo) de la <kw>union</kw> y
	  muéstrelo por medio de un elemento diferente (por tanto, un
	  tipo diferente) para ver que ocurre.
	</para>
      </listitem>
      <listitem>
	<!--
	18. Create a program that defines two int arrays, one right
	after the other. Index off the end of the first array into the
	second, and make an assignment. Print out the second array to
	see the changes cause by this. Now try defining a char variable
	between the first array definition and the second, and repeat
	the experiment. You may want to create an array printing
	function to simplify your coding.
	-->
	<para>
	  Cree un programa que defina dos arrays de <type>int</type>,
	  uno a continuación del otro. Indexe el primer array más allá
	  de su tamaño para caer sobre el segundo, haga una
	  asignación. Muestre el segundo array para ver los cambios que
	  eso ha causado. Ahora intente definir una variable
	  <type>char</type> entre las definiciones de los arrays, y
	  repita el experimento. Quizá quiera crear una función para
	  imprimir arrays y así simplificar el código.
	</para>
      </listitem>
      <listitem>
	<!--
	19. Modify ArrayAddresses.cpp to work with the data types char,
	long int, float, and double.
	-->
	<para>
	  Modifique <filename>ArrayAddresses.cpp</filename> para que
	  funcione con los tipos de datos <type>char</type>, <type>long
	  int</type>, <type>float</type> y <type>double</type>.
	</para>
      </listitem>
      <listitem>
	<!--
	20. Apply the technique in ArrayAddresses.cpp to print out the
	size of the struct and the addresses of the array elements in
	StructArray.cpp.
	-->
	<para>
	  Aplique la técnica de <filename>ArrayAddresses.cpp</filename>
	  para mostrar el tamaño de la <kw>struct</kw> y las direcciones
	  de los elementos del array de
	  <filename>StructArray.cpp</filename>.
	</para>
      </listitem>
      <listitem>
	<!--
	21. Create an array of string objects and assign a string to
	each element. Print out the array using a for loop.
	-->
	<para>
	  Cree un array de objetos <type>string</type> y asigne una
	  cadena a cada elemento. Muestre el array usando un bucle
	  <kw>for</kw>.
	</para>
      </listitem>
      <listitem>
	<!--
	22. Create two new programs starting from ArgsToInts.cpp so they
	use atol( ) and atof( ), respectively.
	-->
	<para>
	  Cree dos nuevos programas a partir de
	  <filename>ArgsToInts.cpp</filename> que usen
	  <function>atol()</function> y <function>atof()</function>
	  respectivamente.
	</para>
      </listitem>
      <listitem>
	<!--
	23. Modify PointerIncrement2.cpp so it uses a union instead of a
	struct.
	-->
	<para>
	  Modifique <filename>PointerIncrement2.cpp</filename> de modo
	  que use una <kw>union</kw> en lugar de una <kw>struct</kw>.
	</para>
      </listitem>
      <listitem>
	<!--
	24. Modify PointerArithmetic.cpp to work with long and long
	double.
	-->
	<para>
	  Modifique <filename>PointerArithmetic.cpp</filename> para que
	  funcione con <type>long</type> y <type>long double</type>.
	</para>
      </listitem>
      <listitem>
	<!--
	25. Define a float variable. Take its address, cast that address
	to an unsigned char, and assign it to an unsigned char
	pointer. Using this pointer and [ ], index into the float
	variable and use the printBinary( ) function defined in this
	chapter to print out a map of the float (go from 0 to
	sizeof(float)). Change the value of the float and see if you can
	figure out what's going on (the float contains encoded data).
	-->
	<para>
	  Defina una variable <type>float</type>. Tome su dirección,
	  moldee esa dirección a un <type>unsigned char</type>, y
	  asígnela a un puntero <type>unsigned char</type>. Usando este
	  puntero y <oper>[]</oper>, indexe la variable
	  <type>float</type> y use la función
	  <function>printBinary()</function> definida en este capítulo
	  para mostrar un mapa de cada <type>float</type> (vaya desde 0
	  hasta <code>sizeof(float)</code>). Cambie el valor del
	  <type>float</type> y compruebe si puede averiguar que hay en el
	  float (el <type>float</type> contiene datos codificados).
	</para>
      </listitem>
      <listitem>
	<!--
	26. Define an array of int. Take the starting address of that
	array and use static_cast to convert it into an void*. Write a
	function that takes a void*, a number (indicating a number of
	bytes), and a value (indicating the value to which each byte
	should be set) as arguments. The function should set each byte
	in the specified range to the specified value. Try out the
	function on your array of int.
	-->
	<para>
	  Defina un array de <type>int</type>. Tome la dirección de
	  comienzo de ese array y utilice <oper>static_cast</oper> para
	  convertirlo a un <type>void*</type>. Escriba una función que
	  tome un <type>void*</type>, un número (que indica el número de
	  bytes), y un valor (indicando el valor que debería ser
	  asignado a cada byte) como argumentos. La función debería
	  asignar a cada byte en el rango especificado el valor dado
	  como argumento. Pruebe la función con su array de
	  <type>int</type>.
	</para>
      </listitem>
      <listitem>
	<!--
	27. Create a const array of double and a volatile array of
	double. Index through each array and use const_cast to cast each
	element to non-const and non-volatile, respectively, and assign
	a value to each element.
	-->
	<para>
	  Cree un array <kw>const</kw> de <type>double</type> y un array
	  <kw>volatile</kw> de <type>double</type>. Indexe cada array y
	  utilice <kw>const_cast</kw> para moldear cada elemento de
	  no-<kw>const</kw> y no-<kw>volatile</kw>, respectivamente, y
	  asigne un valor a cada elemento.
	</para>
      </listitem>
      <listitem>
	<!--
	28. Create a function that takes a pointer to an array of double
	and a value indicating the size of that array. The function
	should print each element in the array. Now create an array of
	double and initialize each element to zero, then use your
	function to print the array. Next use reinterpret_cast to cast
	the starting address of your array to an unsigned char*, and set
	each byte of the array to 1 (hint: you'll need to use sizeof to
	calculate the number of bytes in a double). Now use your
	array-printing function to print the results. Why do you think
	each element was not set to the value 1.0?
	-->
	<para>
	  Cree una función que tome un puntero a un array de
	  <type>double</type> y un valor indicando el tamaño de ese
	  array. La función debería mostrar cada valor del array. Ahora
	  cree un array de <type>double</type> y inicialice cada
	  elemento a cero, después utilice su función para mostrar el
	  array. Después use <kw>reinterpret_cast</kw> para moldear la
	  dirección de comienzo de su array a un <type>unsigned
	  char*</type>, y ponga a 1 cada byte del array (aviso:
	  necesitará usar <oper>sizeof</oper> para calcular el número de
	  bytes que tiene un <type>double</type>). Ahora use su función
	  de impresión de arrays para mostrar los resultados. ¿Por qué
	  cree los elementos no tienen el valor 1.0?
	</para>
      </listitem>
      <listitem>
	<!--
	29. (Challenging) Modify FloatingAsBinary.cpp so that it prints
	out each part of the double as a separate group of bits. You'll
	have to replace the calls to printBinary( ) with your own
	specialized code (which you can derive from printBinary( )) in
	order to do this, and you'll also have to look up and
	understand the floating-point format along with the byte
	ordering for your compiler (this is the challenging part).
	-->
	<para>
	  (Reto) Modifique <filename>FloatingAsBinary.cpp</filename>
	  para que muestra cada parte del <type>double</type> como un
	  grupo separado de bits. Tendrá que reemplazar las llamadas a
	  <function>printBinary()</function> con su propio código
	  específico (que puede derivar de
	  <function>printBinary()</function>) para hacerlo, y también
	  tendrá que buscar y comprender el formato de punto flotante
	  incluyendo el ordenamiento de bytes para su compilador (esta
	  parte es el reto).
	</para>
      </listitem>
      <listitem>
	<!--
	30. Create a makefile that not only compiles YourPets1.cpp and
	YourPets2.cpp (for your particular compiler) but also executes
	both programs as part of the default target behavior. Make sure
	you use suffix rules.
	-->
	<para>
	  Cree un <filename>makefile</filename> que no sólo compile
	  <filename>YourPets1.cpp</filename> y
	  <filename>YourPets2.cpp</filename> (para cada compilador
	  particular) sino que también ejecute ambos programas como
	  parte del comportamiento del objetivo
	  predeterminado. Asegúrese de usar las reglas de sufijo.
	</para>
      </listitem>
      <listitem>
	<!--
	31. Modify StringizingExpressions.cpp so that P(A) is
	conditionally #ifdefed to allow the debugging code to be
	automatically stripped out by setting a command-line flag. You
	will need to consult your compiler's documentation to see how
	to define and undefine preprocessor values on the compiler
	command line.
	-->
	<para>
	  Modifique <filename>StringizingExpressions.cpp</filename> para
	  que <code>P(A)</code> sea condicionalmente definida con
	  <kw>#ifdef</kw> para permitir que el código de depuración sea
	  eliminado automáticamente por medio de una bandera en línea de
	  comandos. Necesitará consultar la documentación de su
	  compilador para ver cómo definir y eliminar valores del
	  preprocesador en el compilador de línea de comandos.
	</para>
      </listitem>
      <listitem>
	<!--
	32. Define a function that takes a double argument and returns
	an int. Create and initialize a pointer to this function, and
	call the function through your pointer.
	-->
	<para>
	  Defina una función que tome un argumento <type>double</type> y
	  retorne un <type>int</type>. Cree e inicialice un puntero a
	  esta función, e invoque la función por medio del puntero.
	</para>
      </listitem>
      <listitem>
	<!--
	33. Declare a pointer to a function taking an int argument and
	returning a pointer to a function that takes a char argument and
	returns a float.
	-->
	<para>
	  Declare un puntero a un función que toma un argumento
	  <type>int</type> y retorna un puntero a una función que toma
	  un argumento <type>char</type> y retorna un
	  <type>float</type>.
	</para>
      </listitem>
      <listitem>
	<!--
	34. Modify FunctionTable.cpp so that each function returns a
	string (instead of printing out a message) and so that this
	value is printed inside of main( ).
	-->
	<para>
	  Modifique <filename>FunctionTable.cpp</filename> para que cada
	  función retorne un <type>string</type> (en lugar de mostrar un
	  mensaje) de modo que este valor se imprima en
	  <function>main()</function>.
	</para>
      </listitem>
      <listitem>
	<!--
	35. Create a makefile for one of the previous exercises (of your
	choice) that allows you to type make for a production build of
	the program, and make debug for a build of the program including
	debugging information.
	-->
	<para>
	  Cree un <filename>makefile</filename> para uno de los
	  ejercicios previos (a su elección) que le permita escribir
	  <command>make</command> para construir una versión en
	  producción del programa y <command>make debug</command> para
	  construir una versión del programa que incluye información de
	  depuración.
	</para>
      </listitem>
    </orderedlist>
  </sect1>
</chapter>


<!--
.. Local Variables:
..  coding: utf-8
..  mode: flyspell
..  ispell-local-dictionary: "castellano8"
..  fill-column: 90
.. End:
-->