Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Indi
e general
1. Compila
ion de un programa en C/C++
2. Prin
ipios de C
2.1.
2.2.
2.3.
2.4.
Orgenes del C . . . . . . . . . . . . .
Cara
tersti
as de C . . . . . . . . . .
Estru
tura de un programa en C . . .
Variables . . . . . . . . . . . . . . . .
2.4.1. Deni
ion de variables globales
2.4.2. Le
tura y es
ritura de variables
2.5. Constantes . . . . . . . . . . . . . . .
2.6. Operadores Aritmeti
os . . . . . . . .
2.7. Operadores de Compara
ion . . . . . .
2.8. Operadores logi
os . . . . . . . . . . .
2.9. Orden de pre
eden
ia . . . . . . . . .
2.10. Ejer
i
ios . . . . . . . . . . . . . . . .
La senten
ia if . .
El operador ? . . .
La senten
ia swit
h
Ejer
i
ios . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
1
1
2
2
2
3
3
3
3
4
5
5
6
7
7
8
10
10
10
11
12
13
14
15
15
16
16
16
18
19
19
20
21
23
INDICE GENERAL
ii
4. Itera
ion
4.1.
4.2.
4.3.
4.4.
4.5.
La senten
ia for . . . . .
La senten
ia while . . .
La senten
ia do-while .
Uso de break y
ontinue
Ejer
i
ios . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5. Arreglos y adenas
24
24
25
26
28
29
32
6. Fun
iones
6.1.
6.2.
6.3.
6.4.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8. Apuntadores
8.1.
8.2.
8.3.
8.4.
8.5.
8.6.
8.7.
8.8.
8.9.
Deni
ion de un apuntador . . . . . . . . . . . .
Apuntadores y Fun
iones . . . . . . . . . . . . .
Apuntadores y arreglos . . . . . . . . . . . . . . .
Arreglos de apuntadores . . . . . . . . . . . . . .
Arreglos multidimensionales y apuntadores . . .
Ini
ializa
ion estati
a de arreglos de apuntadores
Apuntadores y estru
turas . . . . . . . . . . . . .
Fallas
omunes
on apuntadores . . . . . . . . . .
Ejer
i
ios . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
free
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
36
37
37
38
39
40
40
41
42
43
44
44
45
46
46
49
49
51
51
53
53
54
55
56
56
57
58
58
61
63
INDICE GENERAL
iii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
69
69
70
71
72
73
73
73
74
74
75
76
76
77
78
14.Bibliote a <stdlib.h>
80
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
15.Bibliote a <math.h>
80
81
82
83
85
86
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
88
88
88
88
89
89
90
90
90
91
92
92
93
93
94
94
INDICE GENERAL
iv
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
98
. 98
. 99
. 101
. 101
. 102
103
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 103
. 104
. 106
. 106
. 106
. 108
. 108
. 108
109
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 109
. 110
. 110
. 110
. 111
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 112
. 112
. 113
. 114
. 114
. 117
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
112
118
. 118
. 120
. 120
. 121
. 121
. 122
. 123
. 123
. 124
. 125
. 126
INDICE GENERAL
22.Comuni a ion entre pro esos (IPC Interpro ess Communi ation), PIPES
127
Cap
tulo 1
Compila
i
on de un programa en C/C++
En esta
aptulo se dan las pro
esos basi
os que se requieren para
ompilar un programa de C. Se des
ribe tambien
el modelo de
ompila
ion de C y tambien
omo C soporta bibliote
as adi
ionales.
DE UN PROGRAMA EN C/C++
CAPITULO 1. COMPILACION
Cuando el
ompilador ha terminado
on exito, la version
ompilada, o el eje
utable, es dejado en un ar
hivo
llamado a.out, o si la op
ion -o es usada
on el
ompilador, el nombre despues de -o es el nombre del programa
ompilado.
Se re
omienda y es mas
onveniente usar la op
ion -o
on el nombre del ar
hivo eje
utable
omo se muestra a
ontinua
ion:
g
-o programa programa.
el
ual pone el programa
ompilado en el ar
hivo del programa se~nalado, en este
aso en programa, en vez del ar
hivo
a.out.
COMPILADOR
CODIGO EN
ENSAMBLADOR
ENSAMBLADOR
LIBRERIAS
CODIGO OBJETO
LIGADOR
CODIGO EJECUTABLE
DE UN PROGRAMA EN C/C++
CAPITULO 1. COMPILACION
1.4. Compilador de C
El
ompilador de C tradu
e el
odigo fuente en
odigo de ensamblador. El
odigo fuente es re
ibido del prepro
esador.
1.5. Ensamblador
El ensamblador
rea el
odigo fuentei o los ar
hivos objeto. En los sistemas
on UNIX se podran ver los ar
hivos
on el sujo .o.
1.6. Ligador
Si algun ar
hivo fuente ha
e referen
ia a fun
iones de una bibliote
a o de fun
iones que estan denidas en otros
ar
hivos fuentes, el ligador
ombina estas fun
iones (
on main()) para
rear un ar
hivo eje
utable. Las referen
ias a
variables externas en esta etapa son resueltas.
Suprime el pro
eso de ligado y produ
e un ar
hivo .o para
ada ar
hivo fuente listado. Despues los
ar
hivos objeto pueden ser ligados por el
omando g
, por ejemplo:
g
ar
h1.o ar
h2.o ... -o eje
utable
-lbibliote
a
DE UN PROGRAMA EN C/C++
CAPITULO 1. COMPILACION
Liga
on las bibliote
as objeto. Esta op
ion debera seguir los argumentos de los ar
hivos fuente. Las
bibliote
as objeto son guardadas y pueden estar estandarizadas, un ter
ero o usuario las
rea. Probablemente la bibliote
a mas
omunmente usada es la bibliote
a matemati
a (math.h). Esta bibliote
a
debera ligarse expl
itamente si se desea usar las fun
iones matemati
as (y por supuesto no olvidar el
ar
hivo
abe
era #in
lude <math.h>, en el programa que llama a las fun
iones), por ejemplo:
g
al
.
-o
al
-lm
Agrega dire
torios a la lista de dire
torios que
ontienen las rutinas de la bibliote
a de objetos. El
ligador siempre bus
a las bibliote
as estandares y del sistema en /lib y /usr/lib. Si se quieren ligar
bibliote
as personales o instaladas por usted, se tendra que espe
i
ar donde estan guardados los ar
hivos,
por ejemplo:
g
prog.
-L/home/minombr/mislibs milib.a
-Itraye
toria
Agrega una traye
toria o ruta a la lista de dire
torios en los
uales se bus
aran los ar
hivos
abe
era
#in
lude
on nombres relativos (es de
ir, los que no empiezan
on diagonal /).
El pro
esador por default, primero bus
a los ar
hivos #in
lude en el dire
torio que
ontiene el ar
hivo
fuente, y despues en los dire
torios nombrados
on la op
ion -I si hubiera, y nalmente, en /usr/in
lude.
Por lo tanto, si se quiere in
luir ar
hivos de
abe
era guardados en /home/minombr/mis
abe
eras se
tendra que ha
er:
g
prog.
-I/home/minombr/mis
abe
eras
Nota: Las
abe
eras de las bibliote
as del sistema son guardados en un lugar espe
ial (/usr/in
lude) y
no son afe
tadas por la op
ion -I. Los ar
hivos
abe
era del sistema y del usuario son in
ludos en una
manera un po
o diferente.
-g
Op
ion para llamar las op
iones de depura
ion (debug). Instruye al
ompilador para produ
ir informa
ion adi
ional en la tabla de smbolos que es usado por una variedad de utileras de depura
ion. Por
ejemplo, si se emplea el depurador de GNU, el programa debera
ompilarse de la siguiente forma para
generar extensiones de GDB:
g
-ggdb -o prog prog.
-D
Dene smbolos
omo identi
adores (-Didenti
ador) o
omo valores (-Dsmbolo=valor) en una forma
similar a la dire
tiva del prepro
esador #define).
-v
Muestra en la salida estandar de errores los omandos eje utados en las etapas de ompila ion.
DE UN PROGRAMA EN C/C++
CAPITULO 1. COMPILACION
1.9. Ejemplos
1.9.1. Crea
ion de una bibliote
a estati
a
Si se tiene un
onjunto de rutinas que se usen en forma fre
uente, se podra desear agruparlas en un
onjunto de
ar
hivos fuente,
ompilar
ada ar
hivo fuente en un ar
hivo objeto, y enton
es
rear una bibliote
a
on los ar
hivos
objeto. Con lo anterior se puede ahorrar tiempo al
ompilar en aquellos programas donde sean usadas.
Supongamos que se tiene un
onjunto de ar
hivos que
ontengan rutinas que son usadas fre
uentemente, por
ejemplo un ar
hivo
ubo.
:
float
ubo(float x)
{
return (x*x*x);
}
Para los ar
hivos de nuestras fun
iones tambien se debe tener un ar
hivo de
abezera, para que puedan ser usadas,
suponiendo que se tiene el siguiente ar
hivo libmm.h
on el siguiente
ontenido:
extern float
ubo(float);
extern int fa
torial(int);
DE UN PROGRAMA EN C/C++
CAPITULO 1. COMPILACION
{
printf("El
ubo de %d es %f\n",VALOR,
ubo(VALOR) );
printf("\t y su fa
torial es %d\n",fa
torial(VALOR) );
}
Para
rear la bibliote
a se deben
ompilar los ar
hivos fuente, que lo podemos ha
er de la siguiente forma:
$ g
-
ubo.
fa
torial.
Lo
ual nos dejara los ar
hivos
ubo.o y fa
torial.o. Despues se debe
rear la bibliote
a
on los ar
hivos fuentes,
suponiendo que nuestra bibliote
a se llame libmm.a, tendras que ha
erlo
on el
omando ar as:
$ ar r libmm.a
ubo.o fa
torial.o
Cuando se a
tualiza una bibliote
a, se ne
esita borrar el ar
hivo anterior (libmm.a). El ultimo paso es
rear un
ndi
e para la bibliote
a, lo que permite que el ligador pueda en
ontrar las rutinas. Lo anterior, lo ha
emos
on el
omando ranlib, por lo que te
learemos ahora:
$ ranlib libmm.a
Los ultimos dos pasos pudieron ser
ombinados en uno solo, enton
es hubieramos podido te
lear:
$ar rs libmm.a
ubo.o fa
torial.o
Ahora que ya tenemos la bibliote
a, es
onveniente que
oloquemos nuestra bibliote
a y el ar
hivo
abezera en
algun lugar apropiado. Supongamos que dejamos la bibliote
a en ~/lib y el
hero
abezera en ~/in
lude, debemos
ha
er lo siguiente:
$ mkdir ../in
lude
$ mkdir ../lib
$ mv libmm.h ../in
lude
$ mv libmm.a ../lib
DE UN PROGRAMA EN C/C++
CAPITULO 1. COMPILACION
No existe un paso para la indexa
ion
omo o
urre en las bibliote
as estati
as.
Despues habra que mover la bibliote
a dinami
a a su dire
torio
orrespondiente (../lib) y pro
eder a
ompilar
para que nuestro
odigo use la bibliote
a.
$ g
-I../in
lude -L../lib -o prueba prueba.
-lmm
Nos preguntamos que su
ede si hay una bibliote
a
ompartida (libmm.so) y una estati
a (libmm.a) disponibles.
En este
aso, el ligador siempre toma la
ompartida. Si se desea ha
er uso de la estati
a, se tendra que nombrar
expl
itamente en la lnea de
omandos:
$ g
-I../in
lude -L../lib -o prueba prueba.
libmm.a
Cuando se usan bibliote
as
ompartidas un
omando util es ldd, el
ual nos informa que bibliote
as
ompartidas
un programa eje
utable usa, a
ontinua
ion un ejemplo:
$ ldd prueba
libstuff.so => libstuff.so (0x40018000)
lib
.so.6 => /lib/i686/lib
.so.6 (0x4002f000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Como se ve en
ada lnea apare
e el nombre de la bibliote
a, el
amino
ompleto a la bibliote
a que es usada, y
donde en el espa
io de dire
iones virtuales la bibliote
a esta mapeada.
Si ldd muestra
omo salida not found para alguna bibliote
a, se van a tener problemas y el programa no podra
ser eje
utado. Una forma de arreglarlo es bus
ar la bibliote
a y
olo
arla en el lugar
orre
to para que el programa
loader la en
uentre, que siempre bus
a por default en lib y /usr/lib. Si se tienen bibliote
as en otro dire
torio,
rear una variable de ambiente LD_LIBRARY_PATH y poner los dire
torios separados por ;.
Si no sabe el nombre de la fun
ion, una lista
ompleta esta in
luida en la pagina introdu
toria de la se
ion 3 del
manual. Para leerlo, te
lee:
man 3 intro
Hay aproximadamente 700 fun
iones. El numero tiende a in
rementarse
on
ada a
tualiza
ion al sistema.
En
ualquier pagina del manual, la se
ion de SYNOPSIS in
luye informa
ion del uso de la fun
ion. Por ejemplo:
DE UN PROGRAMA EN C/C++
CAPITULO 1. COMPILACION
en el ar
hivo del programa que ha
e el llamado a
time. Y que la fun
ion
time toma un apuntador del tipo
time_t
omo un argumento, y regresa una
adena
har *.
En la se
ion DESCRIPTION se da una peque~na des
rip
ion de lo que ha
e la fun
ion.
2. El siguiente programa usa la bibliote
a matemati
a. Te
lealo,
ompilalo y eje
utalo. In
luye
on
omentarios
dentro del programa tu nombre y la forma
omo hi
istes lo anterior.
#in
lude <math.h>
main()
{
int i;
printf("\tAngulo \t\t Seno\n\n");
for( i=0; i<=360; i+=15)
printf("\t %d \t\t\t %f \n",i,sin((double) i*M_PI/180.0));
}
3. Bus
a en los dire
torios /lib y /usr/lib las bibliote
as que estan disponibles. Manda 3 nombres de estati
as
y 3 de
ompartidas.
Use el
omando man para obtener detalles de las fun
iones de la bibliote
a.
Sele
iona alguna bibliote
a y ve los
odigos objetos que
ontiene, puedes te
lear: ar tv bibliote
a
4. Ve en /usr/in
lude que ar
hivos de
abe
era estan disponibles.
DE UN PROGRAMA EN C/C++
CAPITULO 1. COMPILACION
Cap
tulo 2
Prin
ipios de C
En este
aptulo se ofre
e una breve historia del desarrollo del lenguaje C y se
onsideran tambien sus
ara
tersti
as.
En el resto del
aptulo se ven los aspe
tos basi
os de los programas de C, tales
omo su estru
tura, la de
lara
ion
de variables, tipos de datos y operadores.
CAPITULO 2. PRINCIPIOS DE C
11
Si la deni
ion del tipo es omitida, C asume que la fun
ion regresa un tipo entero. Nota: Lo anterior puede ser
una fuente de problemas en un programa.
A
ontinua
ion se muestra un primer programa:
CAPITULO 2. PRINCIPIOS DE C
Tipo
har
unsigned
har
short int
unsigned short int
(long) int
oat
double
12
Tama~no (bytes)
1
1
2
2
4
4
8
Lmite inferior
Lmite superior
|
0
32768
0
231
3;2 1038
1;7 10308
|
255
+32767
65536
+231 1
+3;2 1038
+1;7 10308
/* Programa ejemplo */
main()
{
printf( "Me gusta C\n" );
exit (0);
}
NOTAS:
C requiere un punto y
oma al nal de
ada senten
ia.
printf es una fun
ion estandar de C, la
ual es llamada en la fun
ion main().
\n signi
a salto de lnea. Salida formateada.
exit() es tambien una fun
ion estandar que ha
e que el programa termine. En el sentido estri
to no es ne
esario
ya que es la ultima lnea de main() y de
ualquier forma terminara el programa.
2.4. Variables
C tiene los siguientes tipos de datos simples:
Los tipos de datos basi
os tiene varios modi
adores que les pre
eden. Se usa un modi
ador para alterar el
signi
ado de un tipo base para que en
aje
on las diversas ne
esidades o situa
iones. Los modi
adores son: signed,
unsigned, long y short.
CAPITULO 2. PRINCIPIOS DE C
13
En los sistemas UNIX todos los tipos int son long int, a menos que se espe ique expl itamente short int.
Nota: no hay un tipo booleano en C | se debera usar har, int o aun mejor unsigned har.
signed, unsigned, long y short pueden ser usados
on los tipos
har e int. Aunque es permitido el uso de
signed en enteros, es redundante porque la de
lara
ion de entero por defe
to asume un n
umero
on signo.
tipo es un tipo valido de C y lista variables puede
onsistir en uno o mas indenti
adores separados por una
oma. Un identi
ador debe
omenzar
on una letra o un guion bajo.
Ejemplo:
int i, j, k;
float x,y,z;
har
h;
Es tambien posible preini
ializar variables globales usando el operador de asigna
ion =, por ejemplo:
float suma= 0.0;
int sumagr= 0;
har letra= 'A';
main()
{
...
}
CAPITULO 2. PRINCIPIOS DE C
14
main()
{
suma = 0.0;
sumagr= 0;
letra = 'A';
...
}
Dentro de C tambien se permite la asigna
ion multiple usando el operador =, por ejemplo:
a = b =
= d = 3;
=
=
=
=
3;
3;
3;
3;
La asigna
ion multiple se puede llevar a
abo, si todos los tipos de las variables son iguales.
Se pueden redenir los tipos de C usando typedef. Como un ejemplo de un simple uso se
onsidera
omo se
rean
dos nuevos tipos real y letra. Estos nuevos tipos pueden ser usados de igual forma
omo los tipos predenidos de C.
typedef float real;
typedef
har letra;
/* De
lara
ion de variables usando el nuevo tipo */
real suma=0.0;
letra sig_letra;
Por ejemplo:
printf("%
%d %f",
h,i,x);
La senten
ia de formato se en
ierra entre " ", y enseguida las variables. Asegurarse que el orden de formateo y
los tipos de datos de las variables
oin
idan.
s
anf() es la fun
ion para entrar valores a variables. Su formato es similar a printf. Por ejemplo:
CAPITULO 2. PRINCIPIOS DE C
15
Observar que se antepone & a los nombres de las varibles, ex
epto a la
adena de
ara
teres. En el
aptulo 8 que
trata sobre apuntadores se revisara mas a fondo el uso de este operador.
2.5. Constantes
ANSI C permite de
larar
onstantes. Cuando se de
lara una
onstante es un po
o pare
ido a de
larar una variable,
ex
epto que el valor no puede ser
ambiado.
La palabra
lave
onst se usa para de
larar una
onstante,
omo se muestra a
ontinua
ion:
onst a = 1;
int a = 2;
Notas:
Se puede usar
onst antes o despues del tipo.
Es usual ini
ializar una
onstante
on un valor, ya que no puede ser
ambiada de alguna otra forma.
La dire
tiva del prepro
esador #define es un metodo mas
exible para denir
onstantes en un programa.
Fre
uentemente se ve la de
lara
ion
onst en los parametros de la fun
ion. Lo anterior simplemente indi
a que
la fun
ion no
ambiara el valor del parametro. Por ejemplo, la siguiente fun
ion usa este
on
epto:
har *str
py(
har *dest,
onst
har *orig);
El segundo argumento orig es una
adena de C que no sera alterada,
uando se use la fun
ion de la bibliote
a
para
opiar
adenas.
Que es equivalente a:
CAPITULO 2. PRINCIPIOS DE C
16
int x,y,z;
main()
{
z++;
x = ( z-y ) % 100;
y--;
}
El operador % (modulo o residuo) solamente trabaja
on enteros, aunque existe una fun
ion para
otantes (15.1
fmod() ) de la bibliote
a matemati
a.
El operador division / es para division entera y
otantes. Por lo tanto hay que tener
uidado. El resultado de
x = 3 / 2; es uno, aun si x es de
larado
omo
oat. La regla es: si ambos argumentos en una division son enteros,
ento
es el resultado es entero. Si se desea obtener la division
on la fra
ion, enton
es es
ribirlo
omo: x = 3.0 / 2;
o x = 3 / 2.0 y aun mejor x = 3.0 / 2.0.
Por otra parte, existe una forma mas
orta para expresar
al
ulos en C. Por ejemplo, si se tienen expresiones
omo: i = i + 3; o x = x * (y + 2); , pueden ser rees
ritas
omo:
expr1 oper = expr2
Por lo que podemos rees ribir las expresiones anteriores omo: i += 3; y x *= y + 2; respe tivamente.
Es una senten
ia legal de C (sinta
ti
amente hablando aunque el
ompilador avisa
uando se emplea), la
ual
opia el valor de \j" en \i", lo
ual sera interpretado
omo VERDADERO, si j es diferente de
ero.
Diferente es !=, otros operadores son: < menor que, > mayor que, <= menor que o igual a y >= (mayor que o igual
a).
CAPITULO 2. PRINCIPIOS DE C
17
o
a + (b *
)
Todos los operadores tienen una prioridad, los operadores de mayor prioridad son evaluados antes que los que
tienen menor prioridad. Los operadores que tienen la misma prioridad son evaluados de izquierda a dere
ha, por lo
que:
a - b -
es evaluado
omo
(a - b) -
Prioridad
Operador(es)
Mas alta
( ) [ ->
! ~ ++ -- - (tipo) * & sizeof
*/%
+<< >>
< <= > >=
== !=
&
^
|
&&
||
?
= += -= *= /=
,
Mas baja
Es interpretada
omo:
(a < 10) && ( (2 * b) <
)
y
a =
b =
10 / 5
+ 2;
omo
a =
( b =
( 10 / 5 )
+ 2 );
CAPITULO 2. PRINCIPIOS DE C
18
4. Es
ribir un programa para imprimir varias ve
es el ejer
i
io 2. Puede usar varias instru
iones printf,
on
un
ara
ter de nueva lnea en
ada una, o una instru
ion
on varios
ara
teres nueva lnea en la
adena de
formateo.
5. Es
ribir un programa que lea el radio de un
r
ulo
omo un numero
otante y muestre el area y el permetro
del
r
ulo.
6. Dados
iertos
entmetros
omo entrada de tipo
otante, imprimir su equivalen
ia a pies (enteros) y pulgadas
(
otante, 1 de
imal), dando las pulgadas
on una pre
ision de un lugar de
imal Suponer 2.54
entmetros por
pulgada, y 12 pulgadas por pie.
Si la entrada es 333.3, el formato de la salida debera ser:
333.3
entmetros son 10 pies 11.2 pulgadas.
Cap
tulo 3
3.1. La senten
ia if
Las tres formas
omo se puede emplear la senten
ia if son:
if (
ondi
ion)
senten
ia;
...o
if (
ondi
ion)
senten
ia1 ;
else
senten
ia2 ;
...o
if ( ondi ion1 )
19
20
senten
ia1 ;
else if (
ondi
ion2 )
senten
ia2 ;
...
else
senten
ian ;
El
ujo logi
o de esta estru
tura es de arriba ha
ia abajo. La primera senten
ia se eje
utara y se saldra de la
estru
tura if si la primera
ondi
ion es verdadera. Si la primera
ondi
ion fue falsa, y existe otra
ondi
ion, se
evalua, y si la
ondi
ion es verdadera, enton
es se eje
uta la senten
ia aso
iada. Si existen mas
ondi
iones dentro
de la estru
tura if, se van evaluando estas, siempre y
uando las
ondi
iones que le pre
edan sean falsas.
La senten
ia que esta aso
iada a la palabra reservada else, se eje
uta si todas las
ondi
iones de la estru
tura
if fueron falsas.
Por ejemplo:
main()
{
int x, y, w;
........
if (x>0)
{
z=w;
.......
}
else
{
z=y;
.......
}
}
3.2. El operador ?
El operador ternario
ondi
ional ? es mas e
iente que la senten
ia if. El operador ? tiene el siguiente formato:
expresion1 ? expresion 2 : expresion3 ;
21
El uso del operador ? para reemplazar las senten
ias if ... else no se restringe solo a asigna
iones,
omo en
el ejemplo anterior. Se pueden eje
utar una o mas llamadas de fun
ion usando el operador ? poniendolas en las
expresiones que forman los operandos,
omo en el ejemplo siguiente:
f1(int n)
{
printf("%d ",n);
}
f2()
{
printf("introdu
ido\n");
}
main()
{
int t;
printf(": ");
s
anf("%d",&t);
/* imprime mensaje apropiado */
t ? f1(t) + f2() : printf("Cero introdu
ido\n");
}
swit h (variable)
ase
onstante1 :
se
uen
ia de senten
ias
break;
22
ase
onstante2 :
se
uen
ia de senten
ias
break;
ase
onstante3 :
se
uen
ia de senten
ias
break;
...
default:
g
donde la
omputadora eje
uta la senten
ia default si no
oin
ide ninguna
onstante
on la variable. Esta ultima
op
ion es op
ional. Cuando se en
uentra una
oin
iden
ia, la
omputadora eje
uta las senten
ias aso
iadas
on el
ase hasta en
ontrar un break, o hasta el nal de la senten
ia swit
h en
aso de que se emplee default o sea el
ultimo
ase.
Las limita
iones que tiene la senten
ia
ase respe
to a la estru
tura if son:
Con swit
h solo se puede
omprobar por igualdad, mientras que
on if puede ser
on
ualquier operador
rela
ional.
No se pueden tener dos
onstantes en un solo
ase.
La forma
omo se puede simular el ultimo punto, es teniendo una senten
ia nula in
luyendo solo un ; o permitiendo
que la senten
ia swit
h
aiga omitiendo las senten
ias
omo se muestra a
ontinua
ion.
swit
h (letra)
{
ase 'a':
ase 'e':
ase 'i':
ase 'o':
ase 'u':
numvo
ales++;
break;
ase ' ':
numesp++;
break;
default:
numotras++;
break;
}
23
Cap
tulo 4
Itera
i
on
En este
aptulo se revisan los me
anismos de C para repetir un
ojunto de instru
iones hasta que se
umple
ierta
ondi
ion.
for (
senten
ia;
o f bloque de senten
ias
En donde expresion1 se usa para realizar la ini
ializa
ion de variables, usando una o varias senten
ias, si se
usan varias senten
ias debera usarse el operador , para separarlas. Por lo general, estable
e el valor de la variable de
ontrol del
i
lo. expresion2 se usa para la
ondi
ion de termina
ion del
i
lo y expresion3 es el modi
ador a la
variable de
ontrol del
i
lo
ada vez que la
omputadora lo repite, pero tambien puede ser mas que un in
remento.
Por ejemplo:
int X;
main()
{
for( X=3; X>0; X--)
{
printf("X=%d\n",X);
}
}
Todos las siguientes senten
ias for son validas en C. Las apli
a
iones pra
ti
as de tales senten
ias no son importantes aqu, ya que tan solo se intenta ilustrar alguanas
ara
tersti
as que pueden ser de utilidad:
24
CAPITULO 4. ITERACION
25
En el segundo ejemplo se muestra la forma
omo multiples expresiones pueden apare
er, siempre y
uando esten
separadas por una
oma ,
En el ter
er ejemplo, el
i
lo
ontinuara iterando hasta que z se
onvierta en 0.
while (
donde senten
ia puede ser una senten
ia va
a, una senten
ia uni
a o un bloque de senten
ias que se repetiran.
Cuando el
ujo del programa llega a esta instru
ion, primero se revisa si la
ondi
ion es verdad para eje
utar la(s)
senten
ia(s), y despues el
i
lo while se repetira mientras la
ondi
ion sea verdadera. Cuando llega a ser falsa, el
ontrol del programa pasa a la lnea que sigue al
i
lo.
En el siguiente ejemplo se muetra una rutina de entrada desde el te
lado, la
ual se
i
la mientras no se pulse A:
main()
{
har
ara
;
ara
= '\0';
while(
ara
!= 'A')
ara
= get
har();
}
Antes de entrar al
i
lo se ini
ializa la variable
ara
a nulo. Despues pasa a la senten
ia while donde se
omprueba
si
ara
no es igual a 'A',
omo sea verdad enton
es se eje
uta la senten
ia del bu
le (
ara
= get
har();). La
fun
ion get
har() lee el siguiente
ara
ter del
ujo estandar (te
lado) y lo devuelve, que en nuestro ejemplo es el
ara
ter que haya sido te
leado. Una vez que se ha pulsado una te
la, se asigna a
ara
y se
omprueba la
ondi
ion
nuevamente. Despues de pulsar A, la
ondi
ion llega a ser falsa porque
ara
es igual a A,
on lo que el
i
lo termina.
De lo anterior, se tiene que tanto el
i
lo for,
omo el
i
lo while
omprueban la
ondi
ion en lo alto del
i
lo,
por lo que el
odigo dentro del
i
lo no se eje
uta siempre.
A
ontinua
ion mostramos otro ejemplo:
main()
{
int x=3;
while( x>0 )
{
printf("x = %d\n", x);
x--;
CAPITULO 4. ITERACION
26
}
}
Como se observa, dentro del
i
lo tenemos mas de una senten
ia, por lo que se requiere usar la llave abierta y la
llave
errada { ... } para que el grupo de senten
ias sean tratadas
omo una unidad.
Como el
i
lo while pueda a
eptar tambien expresiones, y no solamente
ondi
iones lo siguiente es valido:
while ( x-- );
while ( x = x + 1 );
while ( x += 5 );
Si se usan este tipo de expresiones, solamente
uando el resultado de x--, x=x+1 o x+=5 sea
ero, la
ondi
ion
fallara y se podra salir del
i
lo.
De a
uerdo a lo anterior, podemos realizar una opera
ion
ompleta dentro de la expresion. Por ejemplo:
main()
{
har
ara
;
ara
= '\0';
while ( (
ara
= get
har()) != 'A' )
put
har(
ara
);
}
En este ejemplo se usan las fun
iones de la bibliote
a estandar get
har() | lee un
ara
ter del te
lado y
put
har() es
ribe un
ara
ter dado en pantalla. El
i
lo while pro
edera a leer del te
lado y lo mostrara hasta que
do
f
senten
ia;
while (
ondi
i
on);
CAPITULO 4. ITERACION
27
Aunque no son ne
esarias las llaves
uando solo esta presente una senten
ia, se usan normalmente por legibilidad
y para evitar
onfusion (respe
to al le
tor, y no del
ompilador)
on la senten
ia while.
En el siguiente programa se usa un
i
lo do ... while para leer numeros desde el te
lado hasta que uno de ellos
es menor que o igual a 100:
main()
{
int num;
do
{
s
anf("%d", &num);
} while ( num>100 );
}
Otro uso
omun de la estru
tura do ... while es una rutina de sele
ion en un menu, ya que siempre se requiere
que se eje
ute al menos una vez.
main()
{
int op
;
printf("1. Derivadas\n");
printf("2. Limites\n");
printf("3. Integrales\n");
do
{
printf(" Te
lear una op
ion: ");
s
anf("%d", &op
);
swit
h(op
)
{
ase 1:
printf("\tOp
ion 1 sele
ionada\n\n");
break;
ase 2:
printf("\tOp
ion 2 sele
ionada\n\n");
break;
ase 3:
printf("\tOp
ion 3 sele
ionada\n\n");
break;
default:
printf("\tOp
ion no disponible\n\n");
break;
}
} while( op
!= 1 && op
!= 2 && op
!= 3);
}
CAPITULO 4. ITERACION
28
Se muestra un ejemplo donde se rees
ribe usando do ... while uno de los ejemplos ya mostrados.
main()
{
int x=3;
do
{
printf("x = %d\n", x--);
}
while( x>0 ) ;
}
Este programa muestra en pantalla los numeros del 0 al 10,
uando al
anza el valor 10 se
umple la
ondi
ion de
la senten
ia if, se eje
uta la senten
ia break y sale del
i
lo.
La senten
ia
ontinue fun
iona de manera similar a la senten
ia break. Sin embargo, en vez de forzar la salida,
ontinue fuerza la siguiente itera
ion, por lo que salta el
odigo que falta para llegar a probar la
ondi
ion. Por
ejemplo, el siguiente programa visualizara solo los numeros pares:
main()
{
int x;
for( x=0; x<100; x++)
{
if (x%2)
ontinue;
printf("%d ",x);
}
}
Finalmente se
onsidera el siguiente ejemplo donde se leen valores enteros y se pro
esan de a
uerdo a las siguientes
ondi
iones. Si el valor que sea ledo es negativo, se desea imprimir un mensaje de error y se abandona el
i
lo. Si el
valor es mayor que 100, se ignora y se
ontinua leyendo, y si el valor es
ero, se desea terminar el
i
lo.
CAPITULO 4. ITERACION
29
main()
{
int valor;
while( s
anf("%d", &valor) == 1 && valor != 0)
{
if ( valor<0 )
{
printf("Valor no valido\n");
break;
/* Salir del
i
lo */
}
if ( valor>100)
{
printf("Valor no valido\n");
ontinue;
/* Pasar al prin
ipio del
i
lo nuevamente */
}
printf("Se garantiza que el valor leido esta entre 1 y 100");
}
}
Salida
=========
1234
63
15
4. Es
ribir un programa que lea un numero en base 10 y lo
onvierta a base 2, base 8 y base hexade
imal.
5. Leer tres valores representando lo siguiente:
El
apital (numero entero de pesos)
CAPITULO 4. ITERACION
30
Imprimir los valores de moneda
on una pre
ision de dos de
imales. Imprimir los valores del interes
ompuesto
para
ada a~no al nal del perodo. La salida puede ser
omo la siguiente:
Capital ini
ial 35000.00
on tasa del 12.50 en 10 a~
nos
A~no
Interes
Suma
-----+-----------+--------1 4375.00
39375.00
2 4921.88
44296.88
3 5537.11
49833.98
4 6229.25
56063.23
5 7007.90
63071.14
6 7883.89
70955.03
7 8869.38
79824.41
8 9978.05
89802.45
9 11225.31 101027.76
10 12628.47 113656.23
6. Leer un valor positivo, y ha
er la siguiente se
uen
ia: si el numero es par, dividirlo entre 2; si es non, multipli
arlo por 3 y sumarle 1. Repetir lo anterior hasta que el valor sea 1, imprimiendo
ada valor, tambien se
debera imprimir
uantas opera
iones de estas son he
has.
Una salida podra ser la siguiente:
El valor ini
ial es 9
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
El siguiente valor es
Valor fina1 1, numero
28
14
7
22
11
34
17
52
26
13
40
20
10
5
16
8
4
2
de pasos 19.
CAPITULO 4. ITERACION
31
y haga
exit(0)
Cap
tulo 5
Arreglos y
adenas
En el siguiente
aptulo se presentan los arreglos y las
adenas. Las
adenas se
onsideran
omo un arreglo de
tipo
har.
tama~no
Por ejemplo, para de
larar un arreglo de enteros llamado listanum
on diez elementos se ha
e de la siguiente
forma:
int listanum[10;
En C, todos los arreglos usan
ero
omo ndi
e para el primer elemento. Por tanto, el ejemplo anterior de
lara un
arreglo de enteros
on diez elementos desde listanum[0 hasta listanum[9.
La forma
omo pueden ser a
esados los elementos de un arreglo, es de la siguiente forma:
listanum[2 = 15; /* Asigna 15 al 3er elemento del arreglo listanum*/
num = listanum[2; /* Asigna el
ontenido del 3er elemento a la variable num */
El lenguaje C no realiza
omproba
ion de
ontornos en los arreglos. En el
aso de que sobrepase el nal durante
una opera
ion de asigna
ion, enton
es se asignaran valores a otra variable o a un trozo del
odigo, esto es, si se
dimensiona un arreglo de tama~no N, se puede referen
iar el arreglo por en
ima de N sin provo
ar ningun mensaje de
error en tiempo de
ompila
ion o eje
u
ion, in
luso aunque probablemente se provoque el fallo del programa. Como
programador se es responsable de asegurar que todos los arreglos sean lo su
ientemente grandes para guardar lo
que pondra en ellos el programa.
C permite arreglos
on mas de una dimension , el formato general es:
tipo nombre arr [
32
33
Observar que para de
larar
ada dimension lleva sus propios parentesis
uadrados.
Para a
eder los elementos se pro
ede de forma similar al ejemplo del arreglo unidimensional, esto es,
tabladenums[2[3 = 15; /* Asigna 15 al elemento de la 3a fila y la 4a
olumna*/
num = tabladenums[25[16;
A
ontinua
ion se muestra un ejemplo que asigna al primer elemento de un arreglo bidimensional
ero, al siguiente
1, y as su
esivamente.
main()
{
int t,i,num[3[4;
for(t=0; t<3; ++t)
for(i=0; i<4; ++i)
num[t[i=(t*4)+i*1;
for(t=0; t<3; ++t)
{
for(i=0; i<4; ++i)
printf("num[%d[%d=%d ", t,i,num[t[i);
printf("\n");
}
}
Por ejemplo:
int i[10 = {1,2,3,4,5,6,7,8,9,10};
int num[3[4={0,1,2,3,4,5,6,7,8,9,10,11};
5.2. Cadenas
A diferen
ia de otros lenguajes de programa
ion que emplean un tipo denominado
adena string para manipular
un
onjunto de simbolos, en C, se debe simular mediante un arreglo de
ara
teres, en donde la termina
ion de la
adena se debe indi
ar
on nulo. Un nulo se espe
i
a
omo '\0'. Por lo anterior,
uando se de
lare un arreglo de
ara
teres se debe
onsiderar un
ara
ter adi
ional a la
adena mas larga que se vaya a guardar. Por ejemplo, si se
quiere de
larar un arreglo
adena que guarde una
adena de diez
ara
teres, se hara
omo:
har
adena[11;
Se pueden ha
er tambien ini
ializa
iones de arreglos de
ara
teres en donde automati
amente C asigna el
ara
ter
nulo al nal de la
adena, de la siguiente forma:
har nombre arr[ tam =
adena";
34
Para asignar la entrada estandar a una
adena se puede usar la fun
ion s
anf
on la op
ion %s (observar que no
se requiere usar el operador &), de igual forma para mostrarlo en la salida estandar.
Por ejemplo:
main()
{
har nombre[15, apellidos[30;
printf("Introdu
e tu nombre: ");
s
anf("%s",nombre);
printf("Introdu
e tus apellidos: ");
s
anf("%s",apellidos);
printf("Usted es %s %s\n",nombre,apellidos);
}
El lenguaje C no maneja
adenas de
ara
teres,
omo se ha
e
on enteros o
otantes, por lo que lo siguiente no
es valido:
main()
{
har nombre[40, apellidos[40,
ompleto[80;
nombre="Jose Mara";
/* Ilegal */
apellidos="Morelos y Pav
on";
/* Ilegal */
ompleto="Gral."+nombre+appellidos; /* Ilegal */
}
o
har
h;
while( s
anf( "%
", &
h ) == 1 ) /* se lee un
ara
ter */
35
3. Es
ribir un programa para leer un texto hasta el n-de-datos, y mostrar una estadsti
a de las longitudes de
las palabras, esto es, el numero total de palabras de longitud 1 que hayan o
urrido, el total de longitud 2 y
as su
esivamente.
Dene una palabra
omo una se
uen
ia de
ara
teres alfabeti
os. Se deberan permitir palabras hasta de una
longitud de 25 letras.
Una salida tpi
a podra ser
omo esta:
longitud
longitud
longitud
longitud
longitud
1 : 16 o
urren
ias
2 : 20 o
urren
ias
3 : 5 o
urren
ias
4 : 2 o
urren
ias
5 : 0 o
urren
ias
........
Cap
tulo 6
Fun
iones
Una fun
ion es un
onjunto de de
lara
iones, deni
iones, expresiones y senten
ias que realizan una tarea espe
a.
El formato general de una fun
ion en C es
de parametros )
variables lo
ales
odigo de la fun
ion
g
El espe
i
ador de tipo indi
a el tipo del valor que la fun
ion devolvera mediante el uso de return. El valor puede
ser de
ualquier tipo valido. Si no se espe
a un valor, enton
es la
omputadora asume por defe
to que la fun
ion
devolvera un resultado entero. No se tienen siempre que in
luir parametros en una fun
ion. la lista de parametros
puede estar va
a.
Las fun
iones terminan y regresan automati
amente al pro
edimiento que las llamo
uando se en
uentra la ultima
llave }, o bien, se puede forzar el regreso antes usando la senten
ia return. Ademas del uso se~nalado la fun
ion return
se usa para devolver un valor.
Se examina a
ontinua
ion un ejemplo que en
uentra el promedio de dos enteros:
float en
ontprom(int num1, int num2)
{
float promedio;
promedio = (num1 + num2) / 2.0;
return(promedio);
}
main()
{
int a=7, b=10;
float resultado;
resultado = en
ontprom(a, b);
36
CAPITULO 6. FUNCIONES
37
printf("Promedio=%f\n",resultado);
}
En la fun
ion
uadrados no esta denido ningun parametro, y por otra parte tampo
o se emplea la senten
ia
return para regresar de la fun
ion.
CAPITULO 6. FUNCIONES
38
Observar que en la fun
ion imp_rev se usa la fun
ion strlen para
al
ular la longitud de la
adena sin in
luir el
terminador nulo. Por otra parte, la fun
ion imp_rev no usa la senten
ia return ni para terminar de usar la fun
ion,
ni para regresar algun valor.
Se muestra otro ejemplo,
float en
onprom(int tam, float lista[)
{
int i;
float suma = 0.0;
for ( i=0; i<tam; i++)
suma += lista[i;
return(suma/tam);
}
main()
{
float numeros[={2.3, 8.0, 15.0, 20.2, 44.01, -3.0, -2.9};
printf("El promedio de la lista es %f\n", en
onprom(7,numeros) );
}
Para el
aso de que se tenga que pasar un arreglo
on mas de una dimension, no se indi
a la primera dimension
pero, el resto de las dimensiones deben se~nalarse. Se muestra a
ontinua
ion un ejemplo:
void imprtabla(int tamx,int tamy, float tabla[[5)
{
int x,y;
for ( x=0; x<tamx; x++ )
{
for ( y=0; y<tamy; y++ )
printf("t[%d[%d=%f",x,y,tabla[x[y);
printf("\n");
}
}
CAPITULO 6. FUNCIONES
39
Si no es as, enton
es la fun
ion se debe de
larar. La de
lara
ion simplemente maneja el tipo de dato que la
fun
ion regresa y el tipo de paro ametros usados por la fun
ion.
Es una pra
ti
a usual y
onveniente es
ribir el prototipo de todas las fun
iones al prin
ipio del programa, sin
embargo esto no es estri
tamente ne
esario.
Para de
larar un prototipo de una fun
ion se indi
ara el tipo de dato que regresara la fun
ion, el nombre de la
fun
ion y entre parentesis la lista del tipo de los parametros de a
uerdo al orden que apare
en en la deni
ion de la
fun
ion. Por ejemplo:
int long
ad(
har [);
Lo anterior de lara una fun ion llamada long ad que regresa un valor entero y a epta una adena omo parametro.
debera devolver:
adena
onvertida "El_gato_negro"
n = 2
2. Es
ribir un programa que lea una lnea de texto en un buer (una
adena de
ara
teres) usando la fun
ion
gets y
al
ule la longitud de la lnea (NO usar la fun
ion strlen).
3. Modi
ar el programa anterior para que lea un ar
hivo de texto. El ar
hivo debera redire
ionarse al programa,
debiendo mostrar el
ontenido del mismo. En
aso de que se lea una lnea
on longitud 0 debera terminar el
programa.
Cap
tulo 7
Con el trozo de
odigo anterior no ha sido de
larada ninguna variable, tan solo se ha denido el formato.
Para de
larar una variable, se hara
omo sigue:
stru
t dire
info_dire
;
Se pueden de
larar una o mas variables
uando se dene una estru
tura entre ) y ;. Por ejemplo:
stru
t dire
{
har nombre[30;
har
alle[40;
har
iudad[20;
har estado[3;
unsigned int
odigo;
40
TIPOS DE DATOS
CAPITULO 7. MAS
41
observar que dire
es una etiqueta para la estru
tura que sirve
omo una forma breve para futuras
de
lara
iones. Como en este ultima de
lara
ion se indi
an las variables
on esta estru
tura, se puede
omitir el nombre de la estru
tura tipo.
Las estru
turas pueden ser tambien preini
ializadas en la de
lara
ion:
stru
t dire
info_dire
={"Vi
ente Fernandez","Fantasia 2000","Dorado","MMX",12345};
Para referen
iar o a
esar un miembro (o
ampo) de una estru
tura, C propor
iona el operador punto ., por
ejemplo, para asignar a info_dire
otro
odigo, lo ha
emos
omo:
info_dire
.
odigo=54321;
typedef <tipo><nombre>;
Se puede usar typedef para
rear nombres para tipos mas
omplejos,
omo una estru
tura, por ejemplo:
typedef stru
t dire
{
har nombre[30;
har
alle[40;
har
iudad[20;
har estado[3;
unsigned int
odigo;
} sdire
;
sdire
info_dire
={"Vi
ente Fernandez","Fantasia 2000","Dorado","MMX",12345};
en este
aso dire
sirve
omo una etiqueta a la estru
tura y es op
ional, ya que ha sido denido un nuevo
tipo de dato, por lo que la etiqueta no tiene mu
ho uso, en donde sdire
es el nuevo tipo de datos e
info_dire
es una variable del tipo sdire
, la
ual es una estru
tura.
Con C tambien se pueden tener arreglos de estru
turas:
typedef stru
t dire
{
har nombre[30;
har
alle[40;
har
iudad[20;
har estado[3;
unsigned int
odigo;
} info_dire
;
info_dire
artistas[1000;
por lo anterior, artistas tiene 1000 elementos del tipo info_dire
. Lo anterior podra ser a
esado de
la siguiente forma:
TIPOS DE DATOS
CAPITULO 7. MAS
42
artistas[50. odigo=22222;
7.2. Uniones
Una union es una variable la
ual podra guardar (en momentos diferentes) objetos de diferentes tama~nos y tipos.
C emplea la senten
ia union para
rear uniones por ejemplo:
union numero
{
short shortnumero;
long longnumero;
double floatnumero;
} unumero;
on lo anterior se dene una union llamada numero y una instan
ia de esta llamada unumero. numero es
la etiqueta de la union y tiene el mismo
omportamiento que la etiqueta en la estru
tura.
Los miembros pueden ser a
esados de la siguiente forma:
printf("%ld\n",unumero.longnumero);
TIPOS DE DATOS
CAPITULO 7. MAS
43
typedef stru
t
{
int tipo;
int velo
idad;
transporteaereo des
rip
ion;
} un_transporteaereo
en el ejemplo se dene una union base de transporte aereo el
ual puede ser un jet, un heli
optero o un
avion de
arga.
En la estru
tura un_transporeaereo hay un miembro para el tipo, que indi
a
ual es la estru
tura manejada en
ese momento.
asigna 10.0 a numeroflotante. Como se observa C
onvierte el valor del lado dere
ho de la asigna
ion
al tipo del lado izquierdo.
La
onversion de tipos puede ser tambien usada
on
ualquier tipo simple de datos in
luyendo
har, por lo tanto:
int numeroentero;
har letra = 'A';
numeroentero = (int) letra;
a numeroentero.
asigna 65 (que es el
odigo ASCII de A')
Algunas
onversiones de tipos son he
has automati
amente { esto es prin
ipalmente por la
ara
tersti
a de
ompatibilidad de tipos.
Una buena regla es la siguiente: En
aso de duda,
onversion de tipos.
Otro uso es asegurarse que la division de numeros se
omporta
omo se requiere, ya que si se tienen dos enteros
la forma de forzar el resultado a un numero
otante es:
numeroflotante = (float) numerent / (float) denoment;
TIPOS DE DATOS
CAPITULO 7. MAS
44
Es op
ional nombre enum y lista de variables. La primera se usa para de
larar las variables de su tipo. El
siguiente fragmento dene una enumera
ion llamada dis
o que de
lara alma
enamiento para ser de ese tipo.
enum alma
enamiento { diskette, dd,
d, dvd,
inta };
enum alma
enamiento dis
o;
Con la siguiente deni
ion y de
lara
ion son validas las siguientes senten
ias:
dis
o =
d;
if ( dis
o == diskette )
printf("Es de 1440 Kb\n");
Se ini
ializa el primer smbolo de enumera
ion a
ero, el valor del segundo smbolo a 1 y as su
esivamente, a
menos que se ini
iali
e de otra manera. Por tanto,
printf("%d %d\n", dd,
inta)
muestra 1 4 en la pantalla.
Se puede espe
i
ar el valor de uno o mas smbolos usando un ini
ializador. Para ha
erlo, poner un signo igual y
un valor entero despues del smbolo.
Por ejemplo, lo siguiente asigna el valor 250 a
d
enum dis
o { diskette, duro,
d=250, dvd,
inta };
diskette
duro
d
dvd
inta
0
1
250
251
252
auto
extern
stati
register
Estos espe
if
adores le di
en al
ompilador
omo alma
enar la variable que sigue. El espe
i
ador de alma
enamiento pre
ede a la de
lara
ion de variable que tiene el formato general:
TIPOS DE DATOS
CAPITULO 7. MAS
45
stati
void stat();
main()
{
int i;
for (i=0; i<5; ++i)
stat();
}
void stat()
{
auto int a_var = 0;
stati
int s_var = 0;
printf("auto = %d, stati
= %d \n", a_var, s_var);
++a_var;
++s_var;
}
=
=
=
=
=
0,
0,
0,
0,
0,
stati
stati
stati
stati
stati
=
=
=
=
=
0
1
2
3
4
Como se puede observar la variable a_var es
reada
ada vez que se llama a la fun
ion. La variable s_var es
reada en la primera llamada y despues re
uerda su valor, es de
ir, no se destruye
uando termina la fun
ion.
Cap
tulo 8
Apuntadores
Los apuntadores son una parte fundamental de C. Si usted no puede usar los apuntadores apropiadamente enton
es
esta perdiendo la poten
ia y la
exibilidad que C ofre
e basi
amente. El se
reto para C esta en el uso de apuntadores.
C usa los apuntadores en forma extensiva. >Porque?
Es la uni
a forma de expresar algunos
al
ulos.
Se genera
odigo
ompa
to y e
iente.
Es una herramienta muy poderosa.
C usa apuntadores expl
itamente
on:
Es la uni
a forma de expresar algunos
al
ulos.
Se genera
odigo
ompa
to y e
iente.
Es una herramienta muy poderosa.
C usa apuntadores expl
itamente
on:
Arreglos,
Estru
turas y
Fun
iones
Se debe aso
iar a
ada apuntador un tipo parti
ular. Por ejemplo, no se puede asignar la dire
ion de un short int
a un long int.
Para tener una mejor idea,
onsiderar el siguiente
odigo:
46
CAPITULO 8. APUNTADORES
47
main()
{
int x = 1, y = 2;
int *ap;
ap = &x;
y = *ap;
x = ap;
*ap = 3;
}
Con el objetivo de entender el
omportamiento del
odigo supongamos que la variable x esta en la lo
alidad de
la memoria 100, y en 200 y ap en 1000. Nota: un apuntador es una variable, por lo tanto, sus valores ne
esitan ser
guardados en algun lado.
int x = 1, y = 2;
int *ap;
ap = &x;
100
1
200
2
ap
1000
100
Las variables x e y son de
laradas e ini
ializadas
on 1 y 2 respe
tivamente, ap es de
larado
omo un apuntador
a entero y se le asigna la dire
ion de x (&x). Por lo que ap se
arga
on el valor 100.
y = *ap;
100
x 1
200
y 1
1000
ap 100
Despues y obtiene el
ontenido de ap. En el ejemplo ap apunta a la lo
alidad de memoria 100 | la lo
alidad de
x. Por lo tanto, y obtiene el valor de x | el
ual es 1.
x = ap;
100
x 100
200
y 1
1000
ap 100
Como se ha visto C no es muy estri
to en la asigna
ion de valores de diferente tipo (apuntador a entero). As que
es perfe
tamente legal (aunque el
ompilador genera un aviso de
uidado) asigna el valor a
tual de ap a la variable
x. El valor de ap en ese momento es 100.
CAPITULO 8. APUNTADORES
48
*ap = 3;
100
3
200
1
ap
1000
100
Importante: Cuando un apuntador es de larado apunta a algun lado. Se debe ini ializar el apuntador antes de
main()
{
int *ap;
*ap = 100;
}
Con los apuntadores se puede realizar tambien aritmeti
a entera, por ejemplo:
main()
{
float *flp, *flq;
*flp = *flp + 10;
++*flp;
(*flp)++;
flq = flp;
}
NOTA: Un apuntador a
ualquier tipo de variables es una dire
ion en memoria | la
ual es una dire
ion entera,
pero un apuntador NO es un entero.
La razon por la
ual se aso
ia un apuntador a un tipo de dato, es por que se debe
ono
er en
uantos bytes esta
guardado el dato. De tal forma, que
uando se in
rementa un apuntador, se in
rementa el apuntador por un \bloque"
de memoria, en donde el bloque esta en fun
ion del tama~no del dato.
Por lo tanto para un apuntador a un
har, se agrega un byte a la dire
ion y para un apuntador a entero o a
otante se agregan 4 bytes. De esta forma si a un apuntador a
otante se le suman 2, el apuntador enton
es se mueve
dos posi
iones
oat que equivalen a 8 bytes.
CAPITULO 8. APUNTADORES
49
x = *ap;
*(ap + 1) = 100; /* Se asigna al segundo elemento de 'a' el valor 100 usando ap*/
Como se puede observar en el ejemplo la senten
ia a[t es identi
a a ap+t. Se debe tener
uidado ya que C no
ha
e una revision de los lmites del arreglo, por lo que se puede ir fa
ilmente mas alla del arreglo en memoria y
sobrees
ribir otras
osas.
CAPITULO 8. APUNTADORES
50
C sin embargo es mu
ho mas sutil en su rela
ion entre arreglos y apuntadores. Por ejemplo se puede te
lear
solamente:
ap = a; en vez de ap = &a[0; y tambien *(a + i) en vez de a[i, esto es, &a[i es equivalente
on
a+i.
Se muestra enseguida una fun
ion para
opiar una
adena en otra. Al igual que en el ejer
i
io anterior existe en
la bibliote
a estandar una fun
ion que ha
e lo mismo.
void str
py(
har *s,
har *t)
{
while ( (*s++ = *t++) != '\0' );
}
En los dos ultimos ejemplos se emplean apuntadores y asigna
ion por valor. Nota: Se emplea el uso del
ara
ter
nulo
on la senten
ia while para en
ontrar el n de la
adena.
CAPITULO 8. APUNTADORES
51
p[1]
p[2]
ABC
ABC
DEF
DEF
CAT
CAT
nos indi
a que los elementos del arreglo estan guardados renglon por renglon.
Cuando se pasa una arreglo bidimensional a una fun
ion se debe espe
i
ar el numero de
olumnas | el numero
de renglones es irrelevante.
La razon de lo anterior, es nuevamente los apuntadores. C requiere
ono
er
uantas son las
olumnas para que
pueda brin
ar de renglon en renglon en la memoria.
Considerando que una fun
ion deba re
ibir int a[5[35, se puede de
larar el argumento de la fun
ion
omo:
CAPITULO 8. APUNTADORES
52
o aun
f( int (*a)[35 ) { ..... }
En el ultimo ejemplo se requieren los parenteis (*a) ya que [ tiene una pre
eden
ia mas alta que *.
Por lo tanto:
int (*a)[35; de
lara un apuntador a un arreglo de 35 enteros, y por ejemplo si ha
emos la siguiente
referen
ia a+2, nos estaremos reriendo a la dire
ion del primer elemento que se en
uentran en el ter
er
renglon de la matriz supuesta, mientras que
int *a[35; de
lara un arreglo de 35 apuntadores a enteros.
Ahora veamos la diferen
ia (sutil) entre apuntadores y arreglos. El manejo de
adenas es una apli
a
ion
omun
de esto.
Considera:
har *nomb[10;
har anomb[10[20;
NOTA: si
ada apuntador en nomb indi
a un arreglo de 20 elementos enton
es y solamente enton
es 200
hars
estaran disponibles (10 elementos).
Con el primer tipo de de
lara
ion se tiene la ventaja de que
ada apuntador puede apuntar a arreglos de diferente
longitud.
Considerar:
har *nomb[ = { "No mes", "Ene", "Feb", "Mar", .... };
har anomb[[15 = { "No mes", "Ene", "Feb", "Mar", ... };
Lo
ual gra
amente se muestra en la gura 8.2. Se puede indi
ar que se ha
e un manejo mas e
iente del espa
io
ha
iendo uso de un arreglo de apuntadores y usando un arreglo bidimensional.
CAPITULO 8. APUNTADORES
53
anomb
15 elementos
No mes\0
Ene\0
Feb\0
Mar\0
13
nomb
0
No mes\0
Ene\0
Feb\0
Re
ordando que
on el espe
i
ador de alma
enamiento de
lase stati
se reserva en forma permanente memoria
el arreglo, mientras el
odigo se esta eje
utando.
CAPITULO 8. APUNTADORES
54
*sig
n1
valor
*sig
n2
Nota: Solamente se puede de larar sig omo un apuntador tipo ELEMENTO. No se puede tener un elemento del
tipo variable ya que esto generara una deni
ion re
ursiva la
ual no esta permitida. Se permite poner una referen
ia
a un apuntador ya que los los bytes se dejan de lado para
ualquier apuntador.
lo ade
uado sera, tener primeramente una lo
alidad fsi
a de memoria, digamos int y;
int *x, y;
x = &y;
*x = 100;
CAPITULO 8. APUNTADORES
55
/* pide 100 bytes de la memoria */
*p = 'y';
Ahora si mallo
no puede regresar un bloque de memoria, enton
es p es nulo, y por lo tanto no se podra ha
er:
*p = 'y';
Un buen programa en C debe revisar lo anterior, por lo que el
odigo anterior puede ser rees
rito
omo:
p = (
har *) mallo
(100):
if ( p == NULL )
{
printf("Error: fuera de memoria\n");
exit(1);
}
*p = 'y';
Cap
tulo 9
Asigna
i
on dinami
a de memoria y
Estru
turas dinami
as
La asigna
ion dinami
a de memoria es una
ara
tersti
a de C. Le permite al usuario
rear tipos de datos y
estru
turas de
ualquier tama~no de a
uerdo a las ne
esidades que se tengan en el programa.
Se revisaran dos de las apli
a
iones mas
omunes:
Arreglos dinami
os
Estru
turas dinami
as de datos.
Lo anterior indi
a que regresara un apuntador del tipo void *, el
ual es el ini
io en memoria de la por
ion
reservada de tama~no size. Si no puede reservar esa
antidad de memoria la fun
ion regresa un apuntador nulo o
NULL
Dado que void * es regresado, C asume que el apuntador puede ser
onvertido a
ualquier tipo. El tipo de
argumento size_t esta denido en la
abe
era stddef.h y es un tipo entero sin signo.
Por lo tanto:
har *
p;
p = (
har *) mallo
(100);
El ompilador de C requiere ha er una onversion del tipo. La forma de lograr la oer ion ( ast) es usando
( har *) y (int *), que permite onvertir un apuntador void a un apuntador tipo har e int respe tivamente.
56
DINAMICA
CAPITULO 9. ASIGNACION
DE MEMORIA Y ESTRUCTURAS DINAMICAS
57
Ha
er la
onversion al tipo de apuntador
orre
to asegura que la aritmeti
a
on el apuntador fun
ionara de forma
orre
ta.
Es una buena pra
ti
a usar sizeof() aun si se
ono
e el tama~no a
tual del dato que se requiere, | ya que de
esta forma el
odigo se ha
e independiente del dispositivo (portabilidad).
La fun
ion sizeof() puede ser usada para en
ontrar el tama~no de
ualquier tipo de dato, variable o estru
tura.
Simplemente se debe propor
ionar uno de los anteriores
omo argumento a la fun
ion.
Por lo tanto:
int i;
stru
t COORD {float x,y,z};
stru
t COORD *pt;
sizeof(int), sizeof(i), sizeof(stru
t COORD) y
sizeof(PT) son tambien senten
ias
orre
tas.
En el siguiente ejemplo se reserva memoria para la variable ip, en donde se emplea la rela
ion que existe entre
apuntadores y arreglos, para manejar la memoria reservada
omo un arreglo. Por ejemplo, se pueden ha
er
osas
omo:
main()
{
int *ip, i;
ip = (int *) mallo
(100 * sizeof(int) );
ip[0 = 1000;
for (i=0; i<100; ++i)
s
anf("%d",ip++);
}
Cuando se ha terminado de usar una por
ion de memoria siempre se debera liberar usando la fun
ion free().
Esta fun
ion permite que la memoria liberada este disponible nuevemente quizas para otra llamada de la fun
ion
mallo
()
La fun
ion free() toma un apuntador
omo un argumento y libera la memoria a la
ual el apuntador ha
e
referen
ia.
Cuando se usa la fun
ion mallo
() la memoria no es ini
ializada (a
ero ) o borrada. Si se quiere ini
ializar la
memoria enton
es se puede usar la fun
ion
allo
. La fun
ion
allo
es
omputa
ionalmente un po
o mas
ara
pero, o
asionalmente, mas
onveniente que mallo
. Se debe observar tambien la diferen
ia de sintaxis entre
allo
DINAMICA
CAPITULO 9. ASIGNACION
DE MEMORIA Y ESTRUCTURAS DINAMICAS
58
y mallo
, ya que
allo
toma el numero de elementos deseados (nmemb) y el tama~no del elemento (size),
omo dos
argumentos individuales.
Por lo tanto para asignar a 100 elementos enteros que esten ini
ializados a
ero se puede ha
er:
int *ip;
ip = (int *)
allo
(100, sizeof(int) );
La fun
ion reallo
intenta
ambiar el tama~no de un bloque de memoria previamente asignado. El nuevo tama~no
puede ser mas grande o mas peque~no. Si el bloque se ha
e mas grande, enton
es el
ontenido anterior permane
e
sin
ambios y la memoria es agregada al nal del bloque. Si el tama~no se ha
e mas peque~no enton
es el
ontenido
sobrante permane
e sin
ambios.
Si el tama~no del bloque original no puede ser redimensionado, enton
es reallo
intentara asignar un nuevo
bloque de memoria y
opiara el
ontenido anterior. Por lo tanto, la fun
ion devolvera un nuevo apuntador (o de
valor diferente al anterior), este nuevo valor sera el que debera usarse. Si no puede ser reasignada nueva memoria la
fun
ion reallo
devuelve NULL.
Si para el ejemplo anterior, se quiere reasignar la memoria a 50 enteros en vez de 100 apuntados por ip, se hara;
ip = (int *) reallo
( ip, 50*sizeof(int) );
*/
*/
DINAMICA
CAPITULO 9. ASIGNACION
DE MEMORIA Y ESTRUCTURAS DINAMICAS
/* fin de main */
59
DINAMICA
CAPITULO 9. ASIGNACION
DE MEMORIA Y ESTRUCTURAS DINAMICAS
60
lo al;
printf("\nEntre\t1 para agregar un dato,\n\t2 para borrar un dato,\n\t3 para mostrar el
ont
do {
lo
al = get
har ();
if ((isdigit (lo
al) == FALSO) && (lo
al != '\n'))
{
printf ("\nSe debe ingresar un entero.\n");
printf ("Te
lee 1 para agregar, 2 para borrar, 3 para imprimir, 4 para salir\n");
}
} while (isdigit ((unsigned
har) lo
al) == FALSO);
*op
ion = (int) lo
al - '0';
}
DINAMICA
CAPITULO 9. ASIGNACION
DE MEMORIA Y ESTRUCTURAS DINAMICAS
61
return tempp;
}
DINAMICA
CAPITULO 9. ASIGNACION
DE MEMORIA Y ESTRUCTURAS DINAMICAS
14
4
15
18
14
16
17
20
62
Cap
tulo 10
/* muestra el valor de h */
63
CAPITULO 10. TOPICOS
AVANZADOS CON APUNTADORES
64
Lo anterior se puede visualizar
omo se muestra en la gura 10.1, en donde se observa que **pp
h se reere
a la dire
ion de memoria de *p
h, la
ual a su vez se reere a la dire
ion de memoria de la variable
h. Pero
>que signi
a lo anterior en la pra
ti
a?
ppch
pch
ch
pch
String 1
String 3
String 4
String 5
String 6
pch
CAPITULO 10. TOPICOS
AVANZADOS CON APUNTADORES
65
o
main(int arg
,
har *argv[)
Con lo que la fun
ion prin
ipal tiene ahora sus propios argumentos. Estos son solamente los uni
os argumentos
que la fun
ion main a
epta.
* arg
es el numero de argumentos dados | in
luyendo el nombre del programa.
* argv es un arreglo de
adenas que tiene a
ada uno de los argumentos de la lnea de
omandos | in
luyendo
el nombre del programa en el primer elemento del arreglo.
Se muestra a
ontinua
ion un programa de ejemplo:
main (int arg
,
har **argv)
{
/* Este programa muestra los argumentos de la linea de
omandos */
int i;
printf("arg
= %d\n\n",arg
);
for (i=0; i<arg
; ++i)
printf("\t\targv[%d: %s\n", i, argv[i);
}
La salida sera:
arg
= 6
argv[0:
argv[1:
argv[2:
argv[3:
argv[4:
argv[5:
args
f1
f2 y f3
f4
5
FIN
Observar lo siguiente:
- argv[0
ontiene el nombre del programa.
- arg
uenta el numero de argumentos in
luyendo el nombre del programa.
- Los espa
ios en blan
o delimitan el n de los argumentos.
- Las
omillas dobles " " son ignoradas y son usadas para in
luir espa
ios dentro de un argumento.
CAPITULO 10. TOPICOS
AVANZADOS CON APUNTADORES
66
Lo
ual de
lara un apuntador pf a una fun
ion que regresa un tipo de dato int. Todava no se ha indi
ado a que
fun
ion apunta.
Suponiendo que se tiene una fun
ion int f(), enton
es simplemente se debe es
ribir:
pf = &f;
El argumento base apunta al
omienzo del ve
tor que sera ordenado, nmiemb indi
a el tama~no del arreglo, tam
es el tama~no en bytes de
ada elemento del arreglo y el argumento nal
ompar es un apuntador a una fun
ion.
La fun
ion qsort llama a la fun
ion
ompar la
ual es denida por el usuario para
omparar los datos
uando
se ordenen. Observar que qsort
onserva su independen
ia respe
to al tipo de dato al dejarle la responsabilidad al
usuario. La fun
ion
ompar debe regresar un determinado valor entero de a
uerdo al resultado de
ompara
ion, que
debe ser:
CAPITULO 10. TOPICOS
AVANZADOS CON APUNTADORES
67
A
ontinua
ion se muestra un ejemplo que ordena un arreglo de
ara
teres, observar que en la fun
ion
omp, se
ha
e un
ast para forzar el tipo void * al tipo
har *.
#in
lude <stdlib.h>
int
omp(
onst void *i,
onst void *j);
main()
{
int i;
har
ad[ = "fa
ultad de
ien
ias fisi
o-matemati
as";
printf("\n\nArreglo original: \n");
for (i=0; i<strlen(
ad); i++)
printf("%
",
ad[i);
qsort(
ad, strlen(
ad), sizeof(
har),
omp );
printf("\n\nArreglo ordenado: \n");
for (i=0; i<strlen(
ad); i++)
printf("%
",
ad[i);
printf("\n");
}
int
omp(
onst void *i,
onst void *j)
{
har *a, *b;
a = (
har *) i; /* Para forzar void * al tipo
har *, se ha
e
ast */
b = (
har *) j; /*
empleando (
har *)
*/
return *a - *b;
}
muestra las ultimas n lneas, donde n es un entero. El programa debera ha
er el mejor uso del espa
io de
alma
enamiento. (El texto de entrada podra ser ledo de un ar
hivo dado desde la lnea de
omandos o leyendo
un ar
hivo de la entrada estandar.)
2. Es
ribir un programa que ordene una lista de enteros en forma as
endente. Sin embargo, si una op
ion r esta
presente en la lnea de
omandos el programa debera ordenar la lista en forma des
endente.
3. Es
ribir un programa que lea la siguiente estru
tura y ordene los datos por la llave usando qsort
CAPITULO 10. TOPICOS
AVANZADOS CON APUNTADORES
typedef stru
t {
har llave[10;
int algo_mas;
} Re
ord;
68
Cap
tulo 11
A
ion
Y
O
O ex
lusiva (XOR)
Complemento a uno
Nega
ion
Desplazamiento a la izquierda
Desplazamiento a la dere
ha
No se debe
onfundir el operador &
on el operador &&: & es el operador Y sobre bits, && es el operador logi
o Y.
Similarmente los operadores | y ||.
El operador unario ~ solo requiere un argumento a la dere
ha del operador.
Los operadores de desplazamiento, >> y <<, mueven todos los bits en una posi
ion ha
ia la dere
ha o la izquierda
un determinado numero de posi
iones. El formato general de la senten
ia de desplazamiento a la dere
ha es:
variable >> num_pos_de_bit
Como los operadores desplazan bits en un sentido, la
omputadora trae
eros en el otro extremo. Se debe re
ordar
que un desplazamiento no es una rota
ion: los bits desplazados en un extremo no vuelven al otro. Se pierden y los
eros trados los reemplazan.
Una apli
a
ion que tienen los operadores de desplazamiento de bits es para realizar multipli
a
iones y divisiones
rapidas
on enteros. Como se ve en la siguiente tabla, donde un desplazamiento a la izquierda es multipli
ar por 2 y
uno a la dere
ha dividir por 2.
69
har x
x
x
x
x
x
x
= 7;
<< 1;
<< 3;
<< 2;
>> 1;
>> 2;
Eje
u
ion
0
0
0
1
0
0
0
0
1
1
1
0
0
0
1
0
1
0
0
0
1
0
0
1
0
1
0
0
0
1
1
1
0
0
0
0
1
1
0
0
0
0
1
0
0
0
0
0
70
Valor de x
7
14
112
192
96
24
Los desplazamientos son mu
ho mas rapidos que la multipli
a
ion a
tual (*) o la division (/) por dos. Por lo
tanto, si se quieren multipli
a
iones o divisiones rapidas por 2 use desplazamientos.
Con la nalidad de ilustrar algunos puntos de los operadores sobre bits, se muestra la siguiente fun
ion
ontbit,
la
ual
uenta los bits puestos a 1 en un numero de 8 bits (unsigned
har) pasado
omo un argumento a la fun
ion.
int
ontbit(unsigned
har x)
{
int
ount;
for (
ount=0; x!=0; x>>=1)
if ( x & 1)
ount++;
return
ount;
}
71
g
Se debe de
larar un
ampo de bit
omo int, unsigned o signed. Se debe de
larar los
ampos de bits de longitud
1
omo unsigned, ya que un bit uni
o no puede tener signo.
Por ejemplo,
onsiderar esta deni
ion de estru
tura:
stru
t empaquetado {
unsigned int b1:1;
unsigned int b2:1;
unsigned int b3:1;
unsigned int b4:1;
unsigned int tipo:4;
unsigned int ent_raro:9;
} paquete;
La estru
tura empaquetado
ontiene 6 miembros: 4 banderas de 1 bit (b1, b2, b3 y b4), uno de 4 bits (tipo) y
otro de 9 bits (ent raro).
C automati
amente empa
a los
ampos de bit anteriores tan
ompa
tamente
omo sea posible, donde la longitud
maxima del
ampo es menor que o igual a la longitud de la palabra entera de la
omputadora. Si no fuera el
aso,
enton
es algunos
ompiladores podran permitir traslape en memoria para los
ampos, mientras otros podran guardar
el siguiente
ampo en la siguiente palabra.
La forma de a
esar los miembros es en la forma usual:
paquete.tipo = 7;
11.2.1. Portabilidad
Los
ampos de bit son una forma
onveniente de expresar mu
has opera
iones di
iles. Sin embargo, los
ampos
de bit
are
en de portabilidad entre plataformas, por alguna de las siguientes razones:
Los enteros podran ser
on o sin signo.
Mu
hos
ompiladores limitan el numero maximo de bits en el
ampo de bit al tama~no de un integer,
el
ual podra ser de 16 bits o de 32 bits.
Algunos miembros
ampos de bit son guardados de izquierda a dere
ha, otros son guardados de
dere
ha a izquierda en memoria.
Si los
ampos de bits son muy largos, el siguiente
ampo de bit podra ser guardado
onse
utivamente
en memoria (traslapando los lmites entre las lo
alidades de memoria) o en la siguiente palabra de
memoria.
72
3. Es
ribir una fun
ion que invierta los bits de x (unsigned
har) y guarde la respuesta en y.
La respuesta debera mostrarse en forma binaria (ver primer ejer
i
io), sin embargo la entrada puede estar en
forma de
imal.
La salida podra ser
omo la siguiente:
x = 10101010 (binario)
x invertida = 01010101 (binario)
4. Es
ribir una fun
ion que rote (no desplaze) a la dere
ha n posi
iones de bits de x del tipo unsigned
har. La
respuesta debera mostrarse en forma binaria (ver primer ejer
i
io) y la entrada puede ser en forma de
imal.
La salida podra ser
omo la siguiente:
x = 10100111 (binario)
x rotada por 3 = 11110100 (binario)
Cap
tulo 12
El prepro
esador de C
12.1. Dire
tivas del prepro
esador
Como se
omento en el primer
aptulo el prepro
esamiento es el primer paso en la etapa de
ompila
ion de un
programa {esta propiedad es uni
a del
ompilador de C.
El prepro
esador tiene mas o menos su propio lenguaje el
ual puede ser una herrramienta muy poderosa para el
programador. Todas las dire
tivas de prepro
esador o
omandos ini
ian
on un #.
Las ventajas que tiene usar el prepro
esador son:
- los programas son mas fa
iles de desarrollar,
- son mas fa
iles de leer,
- son mas fa
iles de modi
ar
- y el
odigo de C es mas transportable entre diferentes arquite
turas de maquinas.
12.1.1.
#define
El prepro
esador tambien permite
ongurar el lenguaje. Por ejemplo, para
ambiar a las senten
ias de bloque
de
odigo { ... } delimitadores que haya inventado el programador
omo ini
io ... fin se puede ha
er:
#define ini
io {
#define fin }
Durante la
ompila
ion todas las o
urren
ias de ini
io y fin seran reemplazadas por su
orrespondiente { o }
delimitador y las siguientes etapas de
ompila
ion de C no en
ontraran ninguna diferen
ia.
La dire
tiva #define se usa para denir
onstantes o
ualquier sustitu
ion de ma
ro. Su formato es el siguiente:
Por ejemplo:
#define FALSO 0
#define VERDADERO !FALSO
La dire
tiva #define tiene otra poderosa
ara
tersti
a: el nombre de ma
ro puede tener argumentos. Cada vez
que el
ompilador en
uentra el nombre de ma
ro, los argumentos reales en
ontrados en el programa reemplazan los
argumentos aso
iados
on el nombre de la ma
ro. Por ejemplo:
73
74
Cuando se
ompila este programa, el
ompilador sustiuira la expresion denida por MIN(x,y), ex
epto que x e y
seran usados
omo los operandos. As despues de que el
ompilador ha
e la sustitu
ion, la senten
ia printf sera esta:
printf("El minimo es %d\n", (x < y) ? x : y);
Como se puede observar donde se
oloque MIN, el texto sera reemplazado por la deni
ion apropiada. Por lo tanto,
si en el
odigo se hubiera puesto algo
omo:
x = MIN(q+r,s+t);
La ultima ma ro IZQ DESP 8 es solamente valida en tanto el reemplazo del ontexto es valido, por ejemplo: x =
y IZQ DESP 8.
El uso de la sustitu
ion de ma
ros en el lugar de las fun
iones reales tiene un bene
io importante: in
rementa
la velo
idad del
odigo porque no se penaliza
on una llamada de fun
ion. Sin embargo, se paga este in
remento de
velo
idad
on un in
remento en el tama~no del programa porque se dupli
a el
odigo.
12.1.2. #undef
Se usa #undef para quitar una deni
ion de nombre de ma
ro que se haya denido previamente. El formato
general es:
El uso prin
ipal de #undef es permitir lo
alizar los nombres de ma
ros solo en las se
iones de
odigo que los
ne
esiten.
75
Cuando se indi
a <ar
hivo> se le di
e al
ompilador que busque donde estan los ar
hivos in
luidos o \in
lude"
del sistema. Usualmente los sistemas
on UNIX guardan los ar
hivos en el dire
torio /usr/in
lude.
Si se usa la forma "ar
hivo" es bus
ado en el dire
torio a
tual, es de
ir, donde el programa esta siendo eje
utado.
Los ar
hivos in
luidos usualmente
ontienen los prototipos de las fun
iones y las de
lara
iones de los ar
hivos
abe
era (header les) y no tienen
odigo de C (algoritmos).
Otro metodo de
ompila
ion
ondi
ional usa las dire
tivas #ifdef (si denido) y #ifndef (si no denido).
El formato general de #ifdef es:
#endif
Si el nombre de ma
ro ha sido denido en una senten
ia #dene, se
ompilara la se
uen
ia de sente
ias entre
el #ifdef y #endif.
El formato general de #ifdef es:
#endif
Las dire
tivas anteriores son utiles para revisar si las ma
ros estan denidas | tal vez por modulos diferentes o
ar
hivos de
abe
era.
Por ejemplo, para poner el tama~no de un entero para un programa portable entre TurboC de DOS y un sistema
operativo
on UNIX, sabiendo que TurboC usa enteros de 16 bits y UNIX enteros de 32 bits, enton
es si se quiere
ompilar para TurboC se puede denir una ma
ro TURBOC, la
ual sera usada de la siguiente forma:
76
#ifdef TURBOC
#define INT_SIZE 16
#else
#define INT_SIZE 32
#endif
en
aso de que hubiera dentro del programa (prog.
) algun #define o #undef pasara por en
ima de la entrada
de la lnea de
omandos, y el
ompilador podra mandar un \warning" sobre esta situa
ion.
Tambien se puede poner un smbolo sin valor, por ejemplo:
g
-DDEBUG prog.
-o prog
Como los
omandos del prepro
esador pueden estar en
ualquier parte de un programa, se pueden ltrar variables
para mostrar su valor,
uando se esta depurando, ver el siguiente ejemplo:
x = y * 3;
#ifdef DEBUG
printf("Depurando: variables x e y iguales a \n",x,y);
#endif
La op
ion -E ha
e que la
ompila
ion se detenga despues de la etapa de prepro
esamiento, por lo anterior no se
esta propiamente
ompilando el programa. La salida del prepro
esamiento es enviada a la entrada estandar. GCC
ignora los ar
hivos de entrada que no requieran prepro
esamiento.
77
#ifdef OS_MSDOS
#in
lude <msdos.h>
#elifdef OS_UNIX
#in
lude "default.h"
#else
#error Sistema Operativo in
orre
to
#endif
La dire
tiva #line numero \
adena" informa al prepro
esador
ual es el numero siguiente de la lnea de entrada.
Cadena es op
ional y nombra la siguiente lnea de entrada. Esto es usado fre
uentemente
uando son tradu
idos otros
lenguajes a C. Por ejemplo, los mensajes de error produ
idos por el
ompilador de C pueden referen
iar el nombre
del ar
hivo y la lnea de la fuente original en vez de los ar
hivos intermedios de C.
Por ejemplo, lo siguiente espe
i
a que el
ontador de lnea empezara
on 100.
#line 100 "test.
"
/* ini
ializa el
ontador de linea y nombre de ar
hivo */
main()
/* linea 100 */
{
printf("%d\n",__LINE__); /* ma
ro predefinida, linea 102 */
printf("%s\n",__FILE__); /* ma
ro predefinida para el nombre */
}
Cap
tulo 13
on UNIX y C estandares deben orrer en ualquier maquina pra ti amente sin ningun problema.
Multiusuario/Multitarea Mu
hos programas pueden
ompartir la
apa
idad de pro
esamiento de las maquinas.
Manejo de ar
hivos El sistema jerarqui
o de ar
hivos emplea mu
has rutinas de manejo de ar
hivos.
Programa
ion del Shell UNIX suministra un interprete de
omandos poderoso que entiende mas de 200
omandos
Entubamiento o Pipe Permite la onexion entre programas, en donde la salida de un programa puede ser la
Utileras de UNIX Hay er a de 200 utileras que permiten eje utar mu has rutinas sin es ribir nuevos programas.
Llamadas al sistema UNIX tiene aproximadamente 60 llamadas al sistema, que son el
orazon del sistema
operativo o del kernel de UNIX. Las llamadas estan a
tualmente es
ritas en C. Todas ellas pueden ser a
esadas
desde programas de C. Ejemplos de estas son el sistema basi
o de E/S, a
eso al reloj del sistema. La fun
ion
open() es un ejemplo de una llamada al sistema.
78
CAPITULO 13. C, UNIX Y LAS BIBLIOTECAS ESTANDAR
79
Operadores aritmeti
os, generadores de numeros aleatorios | random(), srandom(), lrand48(), drand48(), et
.
y fun
iones para
onversion de
adenas a los tipos basi
os de C (atoi(), atof(), et
.) son miembros de la bibliote
a
estandar stdlib.h.
Todas las fun
iones matemati
as
omo sin(),
os(), sqrt() son fun
iones de la bibliote
a estandar de matemati
as
(math.h).
Para mu
has llamadas del sistema y fun
iones de las bibliote
as se tiene que in
luir el ar
hivo
abe
era apropiado,
por ejemplo: stdio.h, math.h.
Para usar una fun
ion se debe asegurar de haber puesto los
orrespondientes #in
lude en el ar
hivo de C. De
esta forma la fun
ion puede ser llamada
orre
tamente.
Es importante asegurarse que los argumentos tengan los tipos esperados, de otra forma la fun
ion probablemente
produ
ira resultados extra~nos.
Algunas bibliote
as requieren op
iones extras antes de que el
ompilador pueda soportar su uso. Por ejemplo, para
ompilar un programa que in
luya fun
iones de la bibliote
a math.h el
omando podra ser de la siguiente forma:
g
matprog.
-o matprog.
-lm
La op
ion nal -lm es una instru
ion para ligar la bibliote
a matemati
a
on el programa. La pagina de man
para
ada fun
ion usualmente informa si se requiere alguna bandera de
ompila
ion espe
ial.
Informa
ion de
asi todas las llamadas al sistema y fun
iones de bibliote
a estan disponibles en las paginas del
man. Se en
uentran disponibles en lnea
on tan solo te
lear man y el nombre de la fun
ion. Por ejemplo:
man drand48
Cap
tulo 14
Bibliote
a <stdlib.h>
Para usar todas las fun
iones de esta bibliote
a se debe tener la siguiente dire
tiva
#in
lude <stdlib.h>
Las fun
iones de la bibliote
a pueden ser agrupadas en tres
ategoras basi
as:
Aritmeti
as;
Numeros aleatorios; y
Conversion de
adenas.
El uso de todas las fun
iones es sen
illo. Se
onsideran dentro del
aptulo en forma breve.
Fundamentalmente hay dos fun
iones para enteros y para
ompatibilidad
on enteros largos.
abs() La fun
ion regresa el valor absoluto del argumento entero j.
div() Cal
ula el valor numer entre denom y devuelve el
o
iente y el resto en una estru
tura llamada div t que
ontiene dos miembros llamados quot y rem.
81
1 (RAND MAX).
srand() Estable e su argumento omo la semilla de una nueva serie de enteros pseudo-aleatorios.
Un ejemplo sen
illo del uso del tiempo de la fe
ha es ini
ializando la semilla a traves de una llamada:
srand( (unsigned int) time( NULL ) );
El siguiente programa tarjeta.
muestra el uso de estas fun
iones para simular un paquete de tarjetas que esta
siendo revueltas.
/*
** Se usan numeros aleatorios para revolver las "tarjetas" de la baraja.
** El segundo argumento de la fun
ion indi
a el numero de tarjetas.
double atof(
onst
har *
adena) Convierte una
adena a un valor
otante.
int atoi(
onst
har *
adena) Convierte una
adena a un valor entero.
int atol(
onst
har *
adena) Convierte una
adena a un valor entero largo.
double strtod(
onst
har *
adena,
har **nap) Convierte una
adena a un valor de punto
otante.
82
83
double strtol(
onst
har *
adena,
har *nap, int base) Convierte una
adena a un entero largo de
a
uerdo a una base dada, la
ual debera estar entre 2 y 36 in
lusive.
unsigned long strtoul(
onst
har *
adena,
har *nap, int base) Convierte una
adena a un entero
largo sin signo.
Varias de las fun
iones se pueden usar en forma dire
ta, por ejemplo:
har
har
har
har
har
har
har
*
ad1 =
*
ad2 =
*
ad3 =
*
ad4 =
*
ad5 =
*
ad6 =
*
ad7;
"100";
"55.444";
"
1234";
"123
uatro";
"invalido123";
"123E23Hola";
int i;
float f:
i
f
i
i
i
f
=
=
=
=
=
=
atoi(
ad1);
/* i =
atof(
ad2);
/* f =
atoi(
ad3);
/* i =
atoi(
ad4);
/* i =
atoi(
ad5);
/* i =
strtod(
ad6, &
ad7);
100 */
55.44 */
1234 */
123 */
0 */
/* f=1.230000E+25 y
ad7=hola*/
Nota:
Los
ara
teres en blan
o son saltados.
Cara
teres ilegales son ignorados.
Si la
onversion no puede ser he
ha se regresa
ero y errno es puesta
on el valor ERANGE.
Similarmente, hay una fun
ion para busqueda binaria, bsear
h() la
ual tiene el siguiente prototipo en stdlib.h
omo:
void *bsear
h(
onst void *key,
onst void *base, size_t nmemb,
size_t size, int (*
ompar)(
onst void *,
onst void *));
A ontinua ion se muestra un ejemplo que ha e uso de la fun ion bsear h():
84
#define TAM 10
#in
lude <stdio.h>
#in
lude <stdlib.h>
typedef stru
t {
int llave;
har informa
ion[30;
} Registro;
int
ompara_registro(void
onst *i, void
onst *j)
{
int a, b;
a = ((Registro *) i)->llave;
b = ((Registro *) j)->llave;
return a - b;
}
main()
{
Registro llave;
Registro *resp;
Registro arreglo[TAM;
int long_arreglo = TAM;
arreglo[0.llave
arreglo[3.llave
arreglo[6.llave
arreglo[9.llave
=
=
=
=
La fun
ion bsear
h() regresa un apuntador al registro que
oin
ide
on la llave dada, o bien, el valor NULL si no
en
uentra el registro.
Observar que el tipo del argumento de la llave debe ser del mismo tipo que la del arreglo de los elementos (en
nuestro
aso Registro).
85
Cap
tulo 15
Bibliote
a <math.h>
La bibliote
a de matemati
as es relativamente fa
il de usar, al igual que las vistas previamente. Se debe in
luir
la dire
tiva de prepro
esamiento #in
lude <math.h>, ademas de re
ordar de ligar la bibliote
a de matemati
as al
ompilar:
g
progmat.
-o progmat -lm
el ar
o tangente de y / x, ex
epto en que los signos de ambos argumentos son usados para determinar el
uadrante del resultado.
double
eil(double x) Redondea x ha
ia arriba al entero mas
er
ano.
double
os(double x) devuelve el
oseno de x, donde x esta dado en radianes.
double
osh(double x) Devuelve el
oseno hiperboli
o de x.
double exp(double x) Devuelve el valor de e (la base de los logaritmos naturales) elevado a la poten
ia x.
double fabs(double x) Devuelve el valor absoluto del n
umero en punto
otante x.
double floor(double x) Redondea x ha
ia abajo al entero mas
er
ano.
double fmod(double x, double y) Cal
ula el resto de la division de x entre y. El valor devuelto es x - n * y,
donde n es el o iente de x / y.
86
87
long int labs(long int j) Cal
ula el valor absoluto de un entero largo.
double ldexp(double x, int exp) Devuelve el resultado de multipli
ar el n
umero x por 2 elevado a exp
(inversa de frexp).
double log(double x); Devuelve el logaritmo neperiano de x.
double log10(double x) Devuelve el logaritmo de
imal de x.
double modf(double x, double *iptr) Divide el argumento x en una parte entera y una parte fra
ional.
M_2_SQRTPI 2=
M_SQRT2 La raz
uadrada positiva de 2
M_SQRT1_2 La raz
uadrada positiva de 1/2
Cap
tulo 16
16.1.1. perror()
El prototipo de la fun
ion perror es:
void perror(
onst
har *s);
La fun
ion perror() produ
e un mensaje que va a la salida estandar de errores, des
ribiendo el ultimo error
en
ontrado durante una llamada al sistema o a
iertas fun
iones de bibliote
a. La
adena de
ara
teres s que se pasa
omo argumento, se muestra primero, luego un signo de dos puntos y un espa
io en blan
o; por ultimo, el mensaje y
un salto de lnea. Para ser de mas utilidad, la
adena de
ara
teres pasada
omo argumento debera in
luir el nombre
de la fun
ion que in
urrio en el error. El
odigo del error se toma de la variable externa errno, que toma un valor
uando o
urre un error, pero no es puesta a
ero en una llamada no erronea.
16.1.2. errno
A la variable espe
ial del sistema errno algunas llamadas al sistema (y algunas fun
iones de bibliote
a) le dan un
valor entero, para indi
ar que ha habido un error. Esta variable esta denida en la
abe
era #in
lude <errno.h> y
para ser usada dentro de un programa debe ser de
larada de la siguiente forma:
extern int errno;
El valor solo es signi
ativo
uando la llamada devolvio un error (usualmente -1), algunas ve
es una fun
ion
tambien puede devolver -1
omo valor valido, por lo que se debe poner errno a
ero antes de la llamada, para poder
dete
tar posibles errores.
88
89
16.1.3. exit
La fun
ion exit tiene el siguiente prototipo de a
uerdo a la
abe
era #in
lude <stdlib.h>:
void exit(int status);
La fun
ion produ
e la termina
on normal del programa y la devolu
ion de status al pro
eso padre o al sistema
operativo. El valor de status es usado para indi
ar
omo ha terminado el programa:
o sale
on un valor EXIT_SUCCESS en una termina
ion
o sale
on un valor EXIT_FAILURE en una termina
ion
Por lo tanto
uando se en
uentre un error se llamara a la fun
ion
omo exit(EXIT_FAILURE) para terminar un
programa
on errores.
16.2. Flujos
Los (
ujos) son una forma
exible y e
iente para leer y es
ribir datos.
Existe una estru
tura interna de C, FILE, la
ual representa a todas los
ujos y esta denida en stdio.h. Por lo
tanto simplemente se ne
esita referirse a la estru
tura para realizar entrada y salida de datos.
Para usar los
ujos enton
es se debe de
larar una variable o apuntador de este tipo en el programa. No se requiere
ono
er mas detalles a
er
a de la deni
ion. Se debe abrir un
ujo antes de realizar
ualquier E/S, despues se puede
a
esar y enton
es se
ierra.
El
ujo de E/S usa un BUFFER, es de
ir, un pedazo jo de area temporal de la memoria (el buer) es ledo o
es
rito a un ar
hivo. Lo siguiente se muestra en la gura 17.1. Observar que el apuntador del ar
hivo a
tualmente
apunta a este buer.
Dispositivo de Almacenamiento
Archivo o disco
Sistema Operativo
01
1010
10
10
1010
10
1010
1010
1010
1010
10
1010
1010
1010
1010
1010
1010
10
Buffer
90
Redire
ionamiento
Lo siguiente no es parte de C, pero depende del sistema operativo. Se ha
e redire
ionamiento desde la lnea de
omandos
on:
> que redire
iona stdout a un ar
hivo.
Por lo tanto, si se tiene un programa llamado salida, que usualmente muestra en pantalla algo, enton
es:
salida > ar
hivo_sal
Por ejemplo, mandar la salida (usualmente a
onsola) de un programa dire
tamente a la impresora
out | lpr
91
16.4.1. printf
El prototipo de la fun
ion esta denido
omo:
int printf(
onst
har *formato, lista arg ...);
que muestra en stdout la lista de argumentos de a
uerdo al formato espe
i
ado. La fun
ion devuelve el numero
de
ara
teres impresos.
La
adena de formateo tiene dos tipos de objetos:
ara
teres ordinarios | estos son
opiados a la salida.
espe
i
adores de
onversion | pre
edidos por % y listados en la tabla 16.1.
Espe
i
ador ( %)
Tipo
Resultado
i,d
o
x,X
har
int
int
int
u
s
int
har *
f
e,E
double/
oat
"
g,G
"
y
printf("VAT=17.5%%\n");
92
16.4.2. s
anf
La fun
ion esta denida
omo sigue:
int s
anf(
onst
har *formato, lista arg ...);
Lee de la entrada estandar (stdin) y
olo
a la entrada en la dire
ion de las variables indi
adas en lista args.
Regresa el numero de
ara
teres ledos.
La
adena de
ontrol de formateo es similar a la de printf.
Importante: se requiere la dire
ion de la variable o un apuntador
on s
anf.
Por ejemplo:
s
anf("%d", &i);
Para el
aso de un arreglo o
adena solo se requiere el nombre del mismo para poder usar s
anf ya que
orresponde
al ini
io de la dire
ion de la
adena.
har
adena[80;
s
anf("%s",
adena);
16.5. Ar
hivos
Los ar
hivos son la forma mas
omun de los
ujos.
Lo primero que se debe ha
er es abrir el ar
hivo. La fun
ion fopen() ha
e lo siguiente:
FILE *fopen(
onst
har *nomb,
onst
har *modo);
fopen regresa un apuntador a un FILE. En la
adena nomb se pone el nombre y la traye
toria del ar
hivo que se
desea a
esar. La
adena modo
ontrola el tipo de a
eso. Si un ar
hivo no puede ser a
esado por alguna razon un
apuntador NULL es devuelto.
\r " le
tura;
\w " es
ritura; y
\a "
Para abrir un ar
hivo se debe tener un
ujo (apuntador tipo ar
hivo) que apunte a la estru
tura FILE.
Por lo tanto, para abrir un ar
hivo denominado miar
h.dat para le
tura haremos algo
omo lo siguiente;
FILE *flujo; /* Se de
lara un flujo */
flujo = fopen("miar
h.dat","r");
93
Las fun
iones son similares a printf y s
anf ex
epto que los datos son ledos desde el
ujo, el
ual debera ser
abierto
on fopen().
El apuntador al
ujo es automati
amente in
rementado
on todas las fun
iones de le
tura y es
ritura. Por lo
tanto, no se debe preo
upar en ha
er lo anterior.
har *
adena[80;
FILE *flujo;
if ( (flujo = fopen( ... )) != NULL)
fs
anf(flujo,"%s",
adena);
Tambien se puede tener a
eso a los
ujos predeterminados
on fprintf, et
. Por ejemplo:
fprintf(stderr,"<<No se puede
al
ular!!\n");
fs
anf(stdin,"%s",string);
Por ejemplo:
float tanque_lleno = 47.0; /* litros */
float kilometros = 400;
har km_por_litro[80;
sprintf( km_por_litro, "Kilometros por litro = %2.3f", kilometros/tanque_lleno);
94
feof() devuelve verdadero si el
ujo indi
ado esta en el n del ar
hivo. Por lo tanto para leer un
ujo,
fp, lnea a lnea se podra ha
er algo
omo:
while ( !feof(fp) )
fs
anf(fp,"%s",linea);
ferror() inspe iona el indi ador de error para el ujo indi ado, regresando verdadero si un error ha
o urrido.
learerr() limpia los indi
adores de n-de-
hero y error para el
ujo indi
ado.
leno() examina el argumento
ujo y devuelve su des
riptor de
hero,
omo un entero.
flag ontrola el a eso al ar hivo y tiene los siguientes ma ros denidas en f ntl.h:
95
que pueden ser usadas para
errar un ar
hivo y leer/es
ribir un determinado numero de bytes de la memoria/ha
ia
un ar
hivo en la lo
alidad de memoria indi
ada por buffer.
La fun
ion sizeof() es
omunmente usada para indi
ar la longitud.
Las fun
iones read y write regresan el numero de bytes ledos/es
ritos o -1 si fallan.
Se tiene a
ontinua
ion dos apli
a
iones que usan algunas de las fun
iones indi
adas:
#in
lude
#in
lude
#in
lude
#in
lude
<stdio.h>
<sys/types.h>
<sys/stat.h>
<f
ntl.h>
96
*/
*/
*/
*/
97
2. Es
ribir un programa ultimas"que muestre las ultimas n lneas de un ar
hivo de texto. n y el nombre del
ar
hivo deberan espe
i
arse desde la lnea de
omandos. Por defe
to n debera ser 5. El programa debera ha
er
el mejor uso del espa
io de alma
enamiento.
3. Es
ribir un programa que
ompare dos ar
hivos y muestre las lneas que dieran. Tip: bus
ar rutinas apropiadas
para manejo de
adenas y manejo de ar
hivos. El programa no debera ser muy grande.
Cap
tulo 17
A C U
D .........
\0
49
Las fun
iones mas
omunes son des
ritas a
ontinua
ion:
har *str
py(
onst
har *dest,
onst
har *orig) | Copia la
adena de
ara
teres apuntada por orig
(in
luyendo el
ara
ter terminador '\0') al ve
tor apuntado por dest. Las
adenas no deben sola-
parse, y la de destino, debe ser su ientemente grande omo para alojar la opia.
int str
mp(
onst
har *s1,
onst
har *s2) | Compara las dos
adenas de
ara
teres s1 y s2. Devuelve
un entero menor, igual o mayor que
ero si se en
uentra que s1 es, respe
tivamente, menor que, igual
a, o mayor que s2.
har *strerror(int errnum) | Devuelve un mensaje de error que
orresponde a un numero de error.
int strlen(
onst
har *s) | Cal
ula la longitud de la
adena de
ara
teres.
har *strn
at(
har *s1,
onst
har *s2, size t n) | Agrega n
ara
teres de s2 a s1.
int strn
mp(
onst
har *s1,
har *s2, size t n) | Compara los primeros n
ara
teres de dos
adenas.
98
99
har *strn
py(
onst
har *s1,
onst
har *s2, size t n) | Copia los primeros n
ara
teres de s2 a s1.
str
ase
mp(
onst
har *s1,
onst
har *s2) | version que ignora si son mayus
ulas o minus
ulas de
str
mp().
strn
ase
mp(
onst
har *s1,
onst
har *s2, size t n) | version insensible a mayus
ulas o minus
ulas
de strn
mp() que
ompara los primeros n
ara
teres de s1.
Observar que tanto str
at() y str
opy() regresan una
opia de su primer argumento, el
ual es el arreglo
destino. Observar tambien que orden de los argumentos es arreglo destino seguido por arreglo fuente lo
ual a ve
es
es una situa
ion para ha
erlo in
orre
tamente.
La fun
ion str
mp()
ompara lexi
ogra
amente las dos
adenas y regresa:
Menor que
ero | si s1 es lexi
amente menor que s2;
Cero | si s1 y s2 son lexi
amente iguales;
Mayor que
ero | si s1 es lexi
amente mayor que s2;
Las fun
iones de
opiado strn
at(), strn
mp() y strn
py() son versiones mas restringidas que sus
ontrapartes
mas generales. Realizan una tarea similar, pero solamente para los primeros n
ara
teres. Observar que el
ara
ter
de termina
ion NULL podra ser violado
uando se usa estas fun
iones, por ejemplo:
har *s1 = "Hola";
har *s2 = 2;
int longitud = 2;
(void) strn
py(s2, s1, longitud); /* s2 = "Ho" */
adena s1.
har *strpbrk( onst har *s1, onst har *s2) | Regresa un apuntador a la primera o urren ia en la
adena s1 de
ualquier
ara
ter de la
adena s2, o un apuntador nulo si no hay un
ara
ter de s2
que exista en s1.
100
size t strspn( onst har *s1, onst har *s2) | Cal ula la longitud del segmento ini ial de s1 que
size t str spn( onst har *s1, onst har *s2) | Regresa el numero de ara teres al prin ipio de s1
har *strtok(
har *s1,
onst
har *s2) | Divide la
adena apuntada a s1 en una se
uen
ia de \tokens",
ada uno de ellos esta delimitado por uno o mas
ara
teres de la
adena apuntada por s2.
Las fun
iones str
hr() y strr
hr() son las mas simples de usar, por ejemplo:
har *s1 = "Hola";
har *resp;
resp = str
hr(s1,'l');
101
El uso de estas fun
iones es dire
to y pare
ido a las opera
iones de
ompara
ion de
ara
teres (ex
epto que la
longitud exa
ta (n) de todas las opera
iones debera ser indi
ada ya que no hay una forma propia de termina
ion).
Observar que en todos los
asos bytes de memoria son
opiados, por lo que la fun
ion sizeof() ayuda en estos
asos, por ejemplo:
har fuente[TAM, dest[TAM;
int ifuente[TAM,idest[TAM;
mem
py(dest, fuente, TAM); /* Copia
hars (bytes) OK */
mem
py(idest,ifuente,TAM*sizeof(int)); /* Copia arreglo de enteros */
102
La fun
ion memmove() se
omporta de la misma forma que mem
py() ex
epto que las lo
alidades de la fuente y
el destino podran traslaparse.
La fun
ion mem
mp() es similar a str
mp() ex
epto que unsigned bytes son
omparados y se devuelve
ero si s1
es menor que s2, et
.
Cap
tulo 18
103
104
printf("Error en %s.\n",argv[0);
exit(1);
}
get
wd(
adena,TAM);
printf("El dire
torio a
tual es %s\n",
adena);
Esta fun
ion rastrea el dire
torio dir, llamando sele
t() en
ada entrada de dire
torio. Las entradas para las que
sele
t() devuelve un valor distinto de
ero se alma
enan en
adenas que se asignan de la memoria
on mallo
(),
ordenadas usando qsort()
on la fun
ion de
ompara
ion
ompar(), y puestas en la matriz listanomb. Si sele
t
es NULL, se sele
ionan todas las entradas.
int alphasort(
onst stru
t dirent **a,
onst stru
t dirent **b);
Puede ser usada
omo fun
ion de
ompara
ion para que la fun
ion s
andir() ponga las entradas de dire
torio
en orden alfabeti
o.
A
ontinua
ion se tiene una version simple del
omando de UNIX ls
#in
lude
#in
lude
#in
lude
#in
lude
<dirent.h>
<unistd.h>
<sys/param.h>
<stdio.h>
#define FALSO 0
#define VERDADERO !FALSO
extern int alphasort();
har traye
toria[MAXPATHLEN;
main()
{
int
ontar,i;
stru
t dirent **ar
hivos;
int sele
_ar
h();
if ( getwd(traye
toria) == NULL )
105
{
printf("Error obteniendo la traye
toria a
tual\n");
exit(0);
}
printf("Dire
torio de trabajo a
tual: %s\n",traye
toria);
ontar = s
andir(traye
toria, &ar
hivos, sele
_ar
h, alphasort);
/* Si no se en
ontraron ar
hivos */
if (
ontar <= 0)
{
printf("No hay ar
hivos en este direntorio\n");
exit(0);
}
printf("Hay %d ar
hivos.\n",
ontar);
for (i=1;i<
ontar+1;++i)
printf("%s ",ar
hivos[i-1->d_name);
printf("\n"); /* flush buffer */
}
int sele
_ar
h(stru
t dirent *entry)
{
if ((str
mp(entry->d_name, ".") == 0) ||
(str
mp(entry->d_name, "..") == 0))
return (FALSO);
else
return (VERDADERO);
}
s
andir regresa los pseudodire
torios (.), (..) y tambien todos los ar
hivos. En este ejemplo se ltran los
pseudodire
torios para que no se muestren ha
iendo que la fun
ion regrese FALSO.
Los prototipos de las fun
iones s
andir y alphasort tienen deni
iones en la
abe
era dirent.h
MAXPATHLEN esta denida en sys/param.h y la fun
ion getwd() en unistd.h.
Se puede ir mas lejos que lo anterior y bus
ar por ar
hivos parti
ulares.
Rees
ribiendo la fun
ion sele
_ar
h para que solo muestre los ar
hivos
on los sujos .
, .h y .o.
int sele
_ar
h(stru
t dirent *entry)
{
har *ptr;
if ((str
mp(entry->d_name, ".")== 0) ||
(str
mp(entry->d_name, "..") == 0))
return (FALSO);
/* Revisar las extensiones de los ar
hivos */
ptr = rindex(entry->d_name, '.'); /* Probar que tenga un punto */
if ( (ptr != NULL ) &&
( (str
mp(ptr, ".
") == 0)
106
La fun
ion rindex() es una fun
ion para manejo de
adenas que regresa un apuntador a la ultima o
urren
ia del
ara
ter
en la
adena s, o un apuntador NULL si
no o
urre en la
adena. (index() es una fun
ion similar pero
asigna un apuntador a la primera o
urren
ia.)
La fun
ion a
ess() regresa: 0 si ha habido exito, o -1 en
aso de falla y a errno se le asigna un valor ade
uado.
Ver las paginas del man para ver la lista de errores.
errno
Algunas llamadas al sistema (y algunas fun
iones de bibliote
a) dan un valor al entero errno para indi
ar que
ha habido un error. Esta es una variable espe
ial del sistema.
Para usar errno en un programa de C, debe ser de
larado de la siguiente forma:
extern int errno;
Esta puede ser manualmente puesto dentro de un programa en C, de otra forma simplemente retiene el ultimo
valor.
La fun
ion int
hmod(
onst
har *traye
toria, mode_t modo);
ambia el modo del ar
hivo dado mediante
traye
toria para un modo dado.
hmod() devuelve 0 en
aso de exito y -1 en
aso de error ademas se asigna a la variable errno un valor ade
uado
(revisar las paginas de man para ver los tipos de errores)
107
int stat(
onst
har *nomb ar
h, stru
t stat *buf) | obtiene informa
ion a
er
a del ar
hivo apuntado
por nomb_ar
h. No se requieren permisos de le
tura, es
ritura o eje
u
ion, pero todos los dire
torios
listados en nomb_ar
h deberan estar disponibles.
int fstat(int desar
h, stru
t stat *buf) | obtiene la misma informa
ion que el anterior, pero solo el
ar
hivo abierto apuntado por desar
h (tal y
omo lo devuelve open()) es examinado en lugar de
nomb_ar
h.
Las fun
iones stat() y fstat() regresan 0 en
aso exito, -1 si hubo error y errno es a
tualizado apropiadamente.
buf es un apuntador a la estru
tura stat en la
ual la informa
ion es
olo
ada. La estru
tura stat esta denida
en in
lude <sys/stat.h>,
omo sigue:
stru
t stat
{
dev_t
ino_t
mode_t
nlink_t
uid_t
gid_t
dev_t
st_dev;
st_ino;
st_mode;
st_nlink;
st_uid;
st_gid;
st_rdev;
/*
/*
/*
/*
/*
/*
/*
off_t
st_size;
/*
unsigned long st_blksize; /*
unsigned long st_blo
ks;
time_t
st_atime;
time_t
st_mtime;
time_t
st_
time;
/*
/*
/*
/*
dispositivo */
inodo */
prote
ion */
numero de enla
es fisi
os */
ID del usuario propietario */
ID del grupo propietario */
tipo dispositivo (si es
dispositivo inodo) */
tama~no total, en bytes */
tama~no de bloque para el
sistema de fi
heros de E/S */
numero de bloques asignados */
hora ultimo a
eso */
hora ultima modifi
a
ion */
hora ultimo
ambio */
};
108
{
printf("Tama~no del ar
hivo %s %d bytes.\n",argv[0,buf.st_size);
}
}
Dos llamadas al sistema (denidas en unistd.h) las
uales son a
tualmente usadas por las fun
iones remove()
y rename() tambien existen, pero son probablemente mas d
iles de re
ordar, al menos que se este su
ientemente
familiarizado
on UNIX.
int unlink(
onst
har *pathname); | borra un nombre del sistema de ar
hivos. Si di
ho nombre era
el ultimo enla
e a un ar
hivo, y ningun pro
eso tiene el ar
hivo abierto, el
hero es borrado y el
espa
io que o
upaba vuelve a estar disponible. Regresa 0 en
aso de exito, -1 en
aso de error y pone
un valor en errno para indi
arlo.
int link( onst har *oldpath, onst har *newpath); | rea un nuevo enla e (tambien ono ido omo
Las fun
iones stat() y fstat() regresan 0 en
aso exito, -1 si hubo error y pone la variable errno
on algun
valor indi
ando el tipo de error.
Cap
tulo 19
horas, 0 minutos, 0 segundos, tiempo universal
oordinado (GMT) del 1o de enero de 1970. Esta
medida se llama el \tiempo de
alendario". Si t no es nulo, el valor devuelto tambien se guarda en
la zona de memoria a la que apunta t. En
aso de error, se devuelve ((time_t)-1) y se asigna a la
variable errno un valor apropiado.
ftime(stru t timeb *pt) | devuelve la hora y la fe ha a tuales en pt, que esta de larada en <sys/timeb.h>
omo sigue:
stru
t timeb
{
time_t time;
unsigned short int millitm;
short int timezone;
short int dstflag;
};
/*
/*
/*
/*
En
aso de exito, se devuelve el tiempo trans
urrido en segundos desde la epo
a. En
aso de error,
se devuelve ((time_t)-1) y se asigna a la variable errno un valor apropiado.
har *
time(time t *timep) | toma un argumento de tipo time_t (long integer) que representa el
tiempo de
alendadrio y lo
onvierte a una
adena de 26
ara
teres de la forma produ
ida por
la fun
ion as
time(). En primer lugar des
ompone los segundos a una estru
tura tm llamando a
lo
altime(), y enton
es llama a as
time() para
onvertir la estru
tura tm a una
adena.
109
110
har *as
time(
onst stru
t tm *timeptr) |
onvierte un valor de tiempo
ontenido en una estru
tura
tm a una
adena de 26
ara
teres de la forma:
111
time_t t1;
(void) time(&t1);
srand48((long) t1);
/* usar time en segundos para poner la semilla */
printf("5 numeros aleatorios (semilla = %d):\n",(int) t1);
for (i=0;i<5;++i)
printf("%d ", lrand48());
printf("\n\n");
}
La fun
ion lrand48() devuelve enteros largos no negativos distribuidos uniformememnte entre 0 y 231 .
Una fun
ion similar es la fun
ion drand48 que regresa numeros de doble pre
ision en el rango [0;0; 1;0).
srand48() pone el valor de la semilla para estos generadores de n
umeros aleatorios. Es importante tener diferentes
semillas
uando se llame a las fun
iones de otra forma el mismo
onjunto numeros pseudo-aleatorios sera generados.
La fun
ion time() siempre da una semilla uni
a (siempre y
uando haya trans
urrido por lo menos 1 segundo).
Cap
tulo 20
La fun
ion system es una llamada que esta
onstruida de otras 3 llamadas del sistema: exe
l(), wait() y fork()
(las
uales tienen su prototipo en <unistd.h>).
113
exe l ( onst har * amino, onst har *arg0, ..., har *argn, 0);
El ultimo parametro debera ser siempre 0. Este es un terminador Nulo. Como la lista de argumentos sea variable
se debe indi
ar de alguna forma a C
uando se termine la lista. El terminador nulo ha
e lo anterior.
El apuntador
amino indi
a el nombre de un ar
hivo que
ontiene el
omando que sera eje
utado, arg0 apunta
a una
adena que es el mismo nombre (o al menos su ultimo
omponente).
arg1, ... , argn son apuntadores a los argumentos para el
omando y el 0 solamente indi
a el n de la lista
de argumentos variables.
Por lo tanto nuestro ejemplo queda de la siguiente forma:
#in
lude <unistd.h>
main()
{
printf("Los ar
hivos en el dire
torio son:\n");
exe
l("/bin/ls","ls","-l",0);
printf("<<< Esto no se eje
uta !!!\n");
}
20.3. fork()
La fun
ion int fork()
ambia un pro
eso uni
o en 2 pro
esos identi
os,
ono
idos
omo el padre (parent) y el
hijo (
hild). En
aso de exito, fork() regresa 0 al pro
eso hijo y regresa el identi
ador del pro
eso hijo al pro
eso
padre. En
aso de falla, fork() regresa 1 al pro
eso padre, pone un valor a errno, y no se
rea un pro
eso hijo.
El pro
eso hijo tendra su propio identi
ador uni
o (PID).
El siguiente programa ilustra un ejemplo sen
illo del uso de fork, donde dos
opias son he
has y se eje
utan
juntas (multitarea).
main()
{
int valor_regr=0;
printf("Bifur
ando el pro
eso\n");
valor_regr=fork();
printf("El id del pro
eso es %d y el valor regresado es %d\n",
getpid(), valor_regr);
exe
l("/bin/ls","ls","-l",0);
printf("Esta linea no es impresa\n");
}
Los pro esos tienen un uni o identi ador, el ual sera diferente en ada eje u ion.
114
Es imposible indi
ar
on antela
ion
ual pro
eso obtendra el CPU. Cuando un pro
eso es dupli
ado en 2 pro
esos
se puede dete
tar fa
ilmente (en
ada pro
eso) si el pro
eso es el hijo o el padre ya que fork() regresa 0 para el hijo.
Se pueden atrapar
ualquier error, ya que fork() regresa un 1, por ejemplo:
int pid; /* identifi
ador del pro
eso */
pid = fork();
if ( pid < 0 )
{
printf("<< No se pudo dupli
ar !!\n");
exit(1);
}
if ( pid == 0 )
{
/* Pro
eso hijo */
......
}
else
{
/* Pro
eso padre */
......
}
20.4. wait()
La fun
ion int wait() (int *status) forzara a un pro
eso padre para que espere a un pro
eso hijo que se
detenga o termine. La fun
ion regresa el PID del hijo o 1 en
aso de errror. El estado de la salida del hijo es
regresado en status.
20.5. exit()
La fun
ion void exit(int status) termina el pro
eso que llama a esta fun
ion y regresa en la salida el valor
de status. Tanto UNIX y los programas bifur
ados de C pueden leer el valor de status.
Por
onven
ion, un estado de 0 signi
a termina
ion normal y
ualquier otro indi
a un error o un evento no
usual. Mu
has llamadas de la bibliote
a estandar tienen errores denidos en la
abe
era de ar
hivo sys/stat.h. Se
puede fa
ilmente derivar su propia
onven
ion.
Un ejemplo
ompleto de un programa de bifur
a
ion se muestra a
ontinua
ion:
/*
fork.
- ejemplo de un programa de bifur
a
ion
El programa pide el ingreso de
omandos de UNIX que son dejados en una
adena. La
adena es enton
es "analizada" en
ontrando blan
os, et
Cada
omando y sus
orrespondientes argumentos son puestos en
un arreglo de argumentos, exe
vp es llamada para eje
utar estos
omandos
en un pro
eso hijo generado por fork()
*/
#in
lude <stdio.h>
#in
lude <sys/types.h>
#in
lude <unistd.h>
main()
{
har buf[1024;
har *args[64;
for (;;)
{
/*
* Pide y lee un
omando.
*/
printf("Comando: ");
if (gets(buf) == NULL)
{
printf("\n");
exit(0);
}
/*
* Dividir la
adena en argumentos.
*/
parse(buf, args);
/*
* Eje
utar el
omando.
*/
eje
utar(args);
}
}
/*
* parse--divide el
omando que esta en buf
*
en argumentos.
*/
parse(
har *buf,
har **args)
{
while (*buf != (
har) NULL)
{
/*
* Quitar blan
os. Usar nulos, para que
* el argumento previo sea terminado
115
* automati
amente.
*/
while ( (*buf == ' ') || (*buf == '\t') )
*buf++ = (
har) NULL;
/*
* Guardar los argumentos
*/
*args++ = buf;
/*
* Brin
ar sobre los argumentos.
*/
while ((*buf != (
har) NULL) && (*buf != ' ') && (*buf != '\t'))
buf++;
}
*args = (
har) NULL;
}
/*
* eje
utar--genera un pro
eso hijo y eje
uta
*
el programa.
*/
eje
utar(
har **args)
{
int pid, status;
/*
* Obtener un pro
eso hijo.
*/
if ( (pid = fork()) < 0 )
{
perror("fork");
exit(1);
/* NOTA: perror() genera un mensaje de error breve en la
* salida de errores des
ribiendo el ultimo error en
ontrado
* durante una llamada al sistema o fun
ion de la bibliote
a.
*/
}
/*
* El pro
eso hijo eje
uta el
odigo dentro del if.
*/
if (pid == 0)
116
117
{
exe
vp(*args, args);
perror(*args);
exit(1);
/* NOTA: las versiones exe
v() y exe
vp() de exe
l() son utiles
uando
el numero de argumentos es des
ono
ido previamente.
Los argumentos para exe
v() y exe
vp() son el nombre del ar
hivo que
sera eje
utado y un ve
tor de
adenas que
ontienen los argumentos.
El ultimo argumento de
adema debera ser un apuntador a 0 (NULL)
exe
lp() y exe
vp() son llamados
on los mismos argumentos que
exe
l() y exe
v(), pero dupli
an las a
iones del shell en
la busqueda de un ar
hivo eje
utable en un lista de dire
torios.
La lista de dire
torios es obtenida del ambiente.
*/
}
/*
* El padre eje
uta el wait.
*/
while (wait(&status) != pid)
/* va
io */ ;
}
Cap
tulo 21
Compila
i
on de Programas
on Ar
hivos
M
ultiples
En este
aptulo se revisa los aspe
tos teori
os y pra
ti
os que ne
esitan ser
onsiderados
uando son es
ritos
programas grandes.
Cuando se es
riben programas grandes se debera programar en modulos. Estos seran ar
hivos fuentes separados.
La fun
ion main() debera estar en un ar
hivo, por ejemplo en main.
, y los otros ar
hivos tendran otras fun
iones.
Se puede
rear una bibliote
a propia de fun
iones es
ribiendo una suite de subrutinas en uno o mas modulos. De
he
ho los modulos pueden ser
ompartidos entre mu
hos programas simplemente in
luyendo los modulos al
ompilar
omo se vera a
ontinua
ion.
Se tiene varias ventajas si los programas son es
ritos de esta forma:
los modulos de forma natural se dividiran en grupos
omunes de fun
iones.
se puede
ompilar
ada modulos separadamente y ligarlo
on los modulos ya
ompilados.
las utileras tales
omo make nos ayudan a mantener sistemas grandes.
Se pueden denir los propios ar
hivos
abe
era y se pueden in
luir en el programa
omo se muestra enseguida:
#in
lude "mi_
abe
era.h"
Los ar
hivos
abe
era por lo general solo
ontienen deni
iones de tipos de datos, prototipos de fun
iones y
omandos del prepro
esador de C.
Considerar el siguiente programa de ejemplo:
main.
118
/*
*
main.
*/
#in
lude "
abe
era.h"
#in
lude <stdio.h>
har
main()
{
printf("Eje
utando...\n");
/*
*
Llamar a Es
ribirMiCadena() - definida en otro ar
hivo
*/
Es
ribirMiCadena(MI_CADENA);
printf("Terminado.\n");
}
Es
ribirMiCadena.
/*
*
Es
ribirMiCadena.
*/
extern
har
*Otra_
adena;
void Es
ribirMiCadena(EstaCadena)
har
*EstaCadena;
{
printf("%s\n", EstaCadena);
printf("Variable Global = %s\n", Otra_
adena);
}
abe
era.h
/*
*
abe
era.h
*/
#define MI_CADENA "Hola Mundo"
void Es
ribirMiCadena();
119
120
Algunos modulos tienen la dire
tiva de prepro
esamiento #in
lude "
abe
era.h" ya que
omparten deni
iones
omunes. Algunos
omo main.
tambien in
luyen ar
hivos
abe
era estandar. La fun
ion main.
llama a la fun
ion
Es
ribirMiCadena() la
ual esta en el modulo (ar
hivo) Es
ribirMiCadena.
El prototipo void de la fun
ion Es
ribirMiCadena esta denida en
abe
era.h.
Observar que en general se debe de
idir entre tener un modulo .
que tenga a
eso solamente a la informa
ion que
ne
esita para su trabajo,
on la
onse
uen
ia de mantener mu
hos ar
hivos
abe
era y tener programas de tama~no
moderado
on uno o dos ar
hivos
abe
era (probablemente lo mejor) que
ompartan mas deni
iones de modulos.
Un problema que se tiene al emplear modulos son el
ompartir variables. Si se tienen variables globales de
laradas
y son instan
iadas en un modulo, >
omo pueden ser pasadas a otros modulos para que sean
ono
idas?
Se podran pasar los valores
omo parametros a las fun
iones, pero:
puede ser esto laborioso si se pasan los mismos parametros a mu
has fun
iones o si la lista de argumentos es
muy larga.
arreglos y estru
turas muy grandes son dif
iles de guardar lo
almente | problemas de memoria
on el sta
k.
La fun
ion main() no puede ver a las variables que_al
an
e o fin_de_al
an
e, pero las fun
iones que_global()
y fn() si pueden. Solamente la fun
ion fn() puede ver a solitaria.
Esta es tambien una de las razones por las que se deben poner los prototipos de las fun
iones antes del
uerpo
del
odigo.
121
Por lo que en el ejemplo la fun
ion main no
ono
era nada a
er
a de las fun
iones que_global() y fn(). La
fun
ion que_global() no sabe nada a
er
a de la fun
ion fn(), pero fn() si sabe a
er
a de la fun
ion que_global(),
ya que esta apare
e de
larada previamente.
La otra razon por la
ual se usan los prototipos de las fun
iones es para revisar los parametros que seran pasados
a las fun
iones.
Si se requiere ha
er referen
ia a una variable externa antes de que sea de
larada o que esta denida en otro
modulo, la variable debe ser de
larada
omo una variable externa, por ejemplo:
extern int que_global;
Regresando al ejemplo de programa
ion modular, se tiene una arreglo de
ara
teres tipo global Otra_
adena
de
larado en main.
y que esta
ompartido
on Es
ribirMiCadena donde esta de
larada
omo externa.
Se debe tener
uidado
on el espe
i
ador de alma
enamiento de
lase ya que el prejo es una de
lara
ion, NO
una deni
ion, esto es, no se da alma
enamiento en la memoria para una variable externa | solamente le di
e al
ompilador la propiedad de la variable. La variable a
tual solo debera estar denida una vez en todo el programa |
se pueden tener tantas de
lara
iones externas
omo se requieran.
Los tama~nos de los arreglos deberan ser dados dentro de la de
lara
ion, pero no son ne
esarios en las de
lara
iones
externas, por ejemplo:
main.
int arr[100;
ar h.
122
Los programadores usualmente ini
ian dise~nando un programa dividiendo el problema en se
iones mas fa
ilmente
manejables. Cada una de estas se
iones podran ser implementaddas
omo una o mas fun
iones. Todas las fun
iones
de
ada se
ion por lo general estaran en un solo ar
hivo.
Cuando se ha
e una implementa
ion tipo objeto de las estru
turas de datos, es usual tener todas las fun
iones
que a
esan ese objeto en el mismo ar
hivo. Las ventajas de lo anterior son:
El objeto puede ser fa
ilmente reusado en otros programas.
Todas las fun
iones rela
ionadas estan guardadas juntas.
Los ultimos
ambios al objeto requieren solamente la modi
a
ion de un ar
hivo.
El ar
hivo
ontiene la deni
ion de un objeto, o fun
iones que regresasan valores, hay una restri
ion en la llamada
de estas fun
iones desde otro ar
hivo, al menos que la deni
ion de las fun
iones esten en el ar
hivo, no sera posible
ompilar
orre
tamente.
La mejor solu
ion a este problema es es
ribir un ar
hivo
abe
era para
ada ar
hivo de C, estos tendran el mismo
nombre que el ar
hivo de C, pero terminaran en .h. El ar
hivo
abe
era
ontiene las deni
iones de todas las fun
iones
usadas en el ar
hivo de C.
Cuando una fun
ion en otro ar
hivo llame una fun
ion de nuestro ar
hivo de C, se puede denir la fun
ion usando
la dire
tiva #in
lude
on el ar
hivo apropiado .h
El prototipo puede apare
er entre las variables globales en el ini
io del ar
hivo fuente. Alternativamente puede
ser de
larado en el ar
hivo
abe
era el
ual es ledo usando la dire
tiva #in
lude.
Es importante re
ordar que todos los objetos en C deberan estar de
larados antes de ser usados.
123
Sin embargo si se sabe que algunos ar
hivos han sido
ompilados previamente y sus ar
hivos fuente no han sido
ambiados desde enton
es, enton
es se puede ahorrar tiempo de
ompila
ion ligando los
odigos objetos de estos
ar
hivos, es de
ir:
g
-o main main.
f1.
... fi.o ... fj.o ... fn.
Se puede usar la op
ion -
del
ompilador de C para
rear un
odigo objeto (.o) para un modulo dado. Por
ejemplo:
g
-
main.
que
reara un ar
hivo main.o. No se requiere propor
ionar ninguna liga de alguna bibliote
a ya que sera resuelta
en la etapa de ligamiento.
Se tiene el problema en la
ompila
ion del programa de ser muy larga, sin embargo:
Se
onsume tiempo al
ompilar un modulo .
| si el modulo ha sido
ompilado antes y no ha sido modi
ado
el ar
hivo fuente, por lo tanto no hay ne
esidad de re
ompilarlo. Se puede solamente ligar los ar
hivos objeto.
Sin embargo, no sera fa
il re
ordar
uales ar
hivos han sido a
tualizados, por lo que si ligamos un ar
hivo
objeto no a
tualizado, el programa eje
utable nal estara in
orre
to.
Cuando se te
lea una se
uen
ia larga de
ompila
ion en la lnea de
omandos se
ometen errores de te
leo, o
bien, se te
lea en forma in
ompleta. Existiran varios de nuestros ar
hivos que seran ligados al igual que ar
hivos
de bibliote
as del sistema. Puede ser dif
il re
ordar la se
uen
ia
orre
ta.
Si se usa la utilera make todo este
ontrol es he
ho
on
uidado. En general solo los modulos que sean mas viejos
que los ar
hivos fuente seran re
ompilados.
124
El lado izquierdo da el nombre del destino (los nombres del programa o ar
hivos del sistema) que sera
onstrudo
(target ), mientras el lado dere
ho da los nombres de los ar
hivos de los
uales depende el destino (por ejemplo,
ar
hivos fuente, ar
hivos
abe
era, ar
hivos de datos).
Si el destino esta fuera de fe
ha
on respe
to a las partes que le
onstituyen, las reglas de
onstru
ion siguiendo
las reglas de dependen
ia son usadas.
Por lo tanto para un programa tpi
o de C
uando un ar
hivo make es eje
utado las siguientes tareas son he
has:
1. El ar
hivo make es ledo. El Makefile indi
a
uales objetos y ar
hivos de bibliote
a se requieren para ser ligados
y
uales ar
hivos
abe
era y fuente ne
esitan ser
ompilados para
rear
ada ar
hivo objeto.
2. La hora y la fe
ha de
ada ar
hivo objeto son revisados
ontra el
odigo fuente y los ar
hivos
abe
era de los
uales dependen. Si
ualquier fuente o ar
hivo
abe
era son mas re
ientes que el ar
hivo objeto, enton
es los
ar
hivos han sido modi
ados desde la ultima modi
a
ion y por lo tanto los ar
hivos objeto ne
esitan ser
re
ompilados.
3. Una vez que todos los ar
hivos objetos han sido revisados, el tiempo y la fe
ha de todos los ar
hivos objeto son
revisados
ontra los ar
hivos eje
utables. Si existe ar
hivos eje
utables viejos seran re
ompilados.
Observar que los ar
hivos make pueden obede
er
ualquier
omando que sea te
leado en la lnea de
omandos,
por
onsiguiente se pueden usar los ar
hivos make para no solamente
ompilar ar
hivos, sino tambien para ha
er
respaldos, eje
utar programas si los ar
hivos de datos han sido
ambiados o limpieza de dire
torios.
125
f1.o: f1.
g
-
f1.
f2.o: f2.
g
-
f2.
se puede generalizar a:
.
.o: g
-
$<
Lo
ual se lee
omo .ext_fuente.ext_destino:
omando donde $< es una forma breve para indi
ar los ar
hivos
que tienen la extension .
Se pueden insertar
omentarios en un Makefile usando el smbolo #, en donde todos los
ara
teres que siguen a
# son ignorados.
=
=
=
=
=
126
INCLUDES=
CFLAGS=
SLIBS=
PROGRAMA=main
OBJETOS=$(FUENTES.
:.
=.o)
# Destino (target) espe
ial (ini
ia
on .)
.KEEP_STATE:
debug := CFLAGS=-ggdb
all debug: $(PROGRAMA)
$(PROGRAMA): $(INCLUDES) $(OBJETOS)
$(LINK.
) -o $ $(OBJETOS) $(SLIBS)
lean:
rm -f $(PROGRAMA) $(OBJETOS)
Para ver mas informa ion de esta utilera dentro de Linux usar info make
Cap
tulo 22
Comuni
a
i
on entre pro
esos (IPC
Interpro
ess Communi
ation), PIPES
A
ontinua
ion se ini
iara la revision de
omo multiples pro
esos pueden estar siendo eje
utados en una maquina
y quizas siendo
ontrolados (generados por la fun
ion fork()) por uno de nuestros programas.
En numerosas apli
a
iones hay una ne
esidad
lara para que estos pro
esos se
omuniquen para el inter
ambio de
datos o informa
ion de
ontrol. Hay unos
uantos metodos para ha
er lo anterior. Se pueden
onsiderar los siguientes:
Tubera (Pipes)
Se~nales (Signals)
Colas de Mensajes
Semaforos
Memoria Compartida
So
kets
En este
aptulo se estudia el entubamiento de dos pro
esos, en los siguientes
aptulos se revisan los otros
metodos.
127
El modelo de programa
ion estandar es que una vez que la tubera ha sido puesta, dos (o mas) pro
esos
ooperativos seran
reados por division y los datos seran pasados empleando read() y write().
Las tuberas abiertas
on pipe() deberan ser
erradas
on
lose(int fd). A
ontinua
ion se muestra un ejemplo
de entubamiento que se utiliza para estar enviando datos al programa gnuplot, empleado para gra
ar. La des
rip
ion
de las fun
iones de los modulos es la siguiente:
El programa tiene dos modulos, grafi
a.
que
ontiene la fun
ion main() y grafi
ador.
que
ontiene las rutinas para enviar los datos al programa gnuplot.
El programa supone que se tiene instalado el programa de gra
a
ion gnuplot en el dire
torio
/usr/bin.
El programa grafi
a.
llama al programa gnuplot.
Dos
ujos son generados usando el programa grafi
a.
, en uno de ellos se gra
a la fun
ion
y=0.5 e y=aleat(0-1.0) y en el otro las fun
iones y=sen(x) e y=sen(1/x).
Dos tuberas son
readas
ada una
on un
ujo de datos.
Gnuplot genera en \vivo" la salida de las gra
as.
f
lose(fp4);
printf("Borrando los ar
hivos de datos\n");
BorrarDat();
}
stati
har *ini
iargraf1 = "plot [ [0:1.1 'plot11.dat' with lines, 'plot12.dat' with lines\n"
stati
har *ini
iargraf2 = "plot 'plot21.dat' with lines, 'plot22.dat' with lines\n";
stati
stati
stati
stati
har
har
har
har
Con la nalidad de tener un mejor
ontrol en la
ompila
ion del programa se luede usar el siguiente ar
hivo
Makefile:
FUENTES.
= grafi
a.
grafi
ador.
INCLUDES=
CFLAGS=
SLIBS= -lm
PROGRAMA= grafi
a
OBJETOS= $(FUENTES.
:.
=.o)
$(PROGRAMA): $(INCLUDES) $(OBJETOS)
g
-o $(PROGRAMA) $(OBJETOS) $(SLIBS)
grafi
a.o: externals.h grafi
a.
g
-
grafi
a.
grafi
ador.o: externals.h grafi
ador.
g
-
grafi
ador.
lean:
rm -f $(PROGRAMA) $(OBJETOS)