in
a
el
im
Pr
Lsaro Camargos
Ve
r
s
o
12 de maro de 2013
s
o
Ve
r
in
a
el
im
Pr
Bsico
11
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Compilao e Execuo
2.1 O processo de compilao
2.2 A IDE Code::Blocks . . .
2.2.1 Criando um Projeto
2.2.2 Depurao . . . .
2.3 O Arquivo Executvel . . .
2.4 Exerccios . . . . . . . . .
2.4.1
. . . . . . . . . .
2.4.2
. . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
13
13
13
14
14
15
16
16
17
18
18
18
18
Pr
el
im
in
a
Sumrio
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
19
19
20
20
21
22
23
23
23
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
25
25
26
28
28
28
29
30
30
s
o
.
.
.
.
.
.
.
.
Ve
r
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
SUMRIO
.
.
.
.
.
.
.
.
.
.
.
.
Seleo Simples
5.1 Operadores Relacionais .
5.2 if-else . . . . . . . .
5.3 Funes e Procedimentos
5.4 O Tipo Primitivo bool .
5.5 Exerccios . . . . . . . .
5.5.1
. . . . . . . . .
5.5.2
. . . . . . . . .
5.5.3
. . . . . . . . .
5.5.4
. . . . . . . . .
5.5.5
. . . . . . . . .
5.6 Laboratrio . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
31
31
31
31
32
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
33
33
36
36
36
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
37
39
40
43
44
44
44
45
46
46
46
46
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
47
47
49
50
50
50
51
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
53
53
56
57
57
59
59
59
Repetio (I)
8.1 Motivao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.2 O comando while . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.3 O comando do-while . . . . . . . . . . . . . . . . . . . . . . . . . .
61
61
62
63
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Switch
7.1 switch-case-default
7.2 break . . . . . . . .
7.3 Exerccios . . . . . . .
7.3.1
. . . . . . . .
7.3.2
. . . . . . . .
7.3.3
. . . . . . . .
7.4 Laboratrio . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
s
o
Pr
el
im
Variveis (II)
4.1 Escopo de Variveis
4.2 Faixas de Valores .
4.3 Exerccios . . . . .
4.4 Laboratrio . . . .
.
.
.
.
.
Ve
r
in
a
3.4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
SUMRIO
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Repetio (II)
9.1 for . . . . . . . . . . . . . . . . . . . . . . . .
9.2 Mais Exemplos . . . . . . . . . . . . . . . . .
9.3 Declaraes especiais . . . . . . . . . . . . . .
9.4 Alterando a repetio com o break e continue
9.5 Exerccios . . . . . . . . . . . . . . . . . . . .
9.6 Laboratrio . . . . . . . . . . . . . . . . . . .
9.6.1
. . . . . . . . . . . . . . . . . . . . .
9.6.2
. . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Ve
r
s
o
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
64
66
66
66
66
66
67
67
67
67
67
67
68
68
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
69
69
71
71
72
73
73
73
73
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
75
75
75
76
76
77
77
79
80
80
81
81
81
82
82
82
82
83
84
84
84
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Pr
.
.
.
.
.
.
.
.
.
.
.
.
.
.
in
a
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8.6
Mais exemplos
Exerccios . . .
8.5.1
. . . .
8.5.2
. . . .
8.5.3
. . . .
8.5.4
. . . .
Laboratrio . .
8.6.1
. . . .
8.6.2
. . . .
8.6.3
. . . .
8.6.4
. . . .
8.6.5
. . . .
8.6.6
. . . .
8.6.7
. . . .
el
im
8.4
8.5
SUMRIO
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
84
84
85
85
11 Arranjos Unidimensionais
11.1 Vetores . . . . . . . . . . . . . . . . . . .
11.2 Vetores de Caracteres . . . . . . . . . . . .
11.2.1 Vetores de Caracteres como Strings
11.3 Exerccios . . . . . . . . . . . . . . . . . .
11.4 Laboratrio . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
87
87
88
90
91
91
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
13 Funes teis I
13.1 Funes Matemticas
13.2 Exerccios . . . . . .
13.2.1 . . . . . . .
13.2.2 . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
93
93
94
96
96
96
96
96
96
96
96
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
97
97
99
99
99
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
101
101
102
102
103
103
104
104
104
105
.
.
.
.
.
.
.
.
.
.
.
.
107
. 107
. 107
. 108
. 110
Ve
r
s
o
Pr
el
im
12 Strings e Funes
12.1 Funes para manipulao Strings . .
12.2 Funes com vetores como parmetros
12.3 Exerccios . . . . . . . . . . . . . . .
12.3.1 . . . . . . . . . . . . . . . .
12.3.2 . . . . . . . . . . . . . . . .
12.3.3 . . . . . . . . . . . . . . . .
12.3.4 . . . . . . . . . . . . . . . .
12.3.5 . . . . . . . . . . . . . . . .
12.3.6 . . . . . . . . . . . . . . . .
12.3.7 . . . . . . . . . . . . . . . .
.
.
.
.
in
a
10.8.1
10.8.2
10.8.3
10.8.4
.
.
.
.
.
.
.
.
.
.
.
.
7
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
II
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
el
im
16 Ordenao de Arranjos
16.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . .
16.2 Algoritmos de Ordenao . . . . . . . . . . . . . . . . .
16.2.1 Algoritmo de Insero (Insertion Sort) . . . . . .
16.2.2 Algoritmo de Seleo (Selection Sort) . . . . . .
16.2.3 Algoritmo de Ordenao por Troca (Bubble Sort)
16.3 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . .
16.3.1 . . . . . . . . . . . . . . . . . . . . . . . . . .
16.3.2 . . . . . . . . . . . . . . . . . . . . . . . . . .
16.3.3 . . . . . . . . . . . . . . . . . . . . . . . . . .
Intermedirio
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
111
111
111
111
112
113
114
114
114
114
115
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
117
117
117
118
119
119
120
120
120
120
18 Referncias
18.1 A memria um grande vetor . . . . . . .
18.2 Variveis do Tipo Referncia . . . . . . . .
18.3 Passagem de Referncias como Parmetros
18.4 Laboratrio . . . . . . . . . . . . . . . . .
18.4.1 . . . . . . . . . . . . . . . . . . .
18.4.2 . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
121
121
121
123
124
124
124
19 Referncias II
19.1 Ponteiros para Structs . . . . . . . . . . . .
19.2 Arranjos e Ponteiros . . . . . . . . . . . .
19.2.1 Percorrendo vetores com ponteiros .
19.3 Laboratrio . . . . . . . . . . . . . . . . .
19.3.1 . . . . . . . . . . . . . . . . . . .
19.3.2 . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
125
125
126
127
128
128
129
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Ve
r
s
o
Pr
17 Estruturas No-Homogneas
17.1 Introduo . . . . . . . . . . . . . . .
17.2 Declarao . . . . . . . . . . . . . .
17.2.1 typedef . . . . . . . . . . . .
17.3 Acesso aos Campos de Uma Estrutura
17.4 Exemplo . . . . . . . . . . . . . . . .
17.5 Exerccios . . . . . . . . . . . . . . .
17.5.1 . . . . . . . . . . . . . . . .
17.5.2 . . . . . . . . . . . . . . . .
17.6 Laboratrio . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
110
110
in
a
15.4.1
15.4.2
SUMRIO
SUMRIO
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
21 Arquivos
21.1 Arquivos de texto . . . . . . . . . . . . . . . .
21.1.1 Abertura e Fechamendo de Arquivos . .
21.1.2 Criao de Arquivos . . . . . . . . . .
21.1.3 Cuidados com a Formatao dos Dados
21.2 Laboratrio . . . . . . . . . . . . . . . . . . .
21.2.1 . . . . . . . . . . . . . . . . . . . . .
21.2.2 . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
131
131
132
133
133
134
134
134
134
134
134
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
135
135
135
137
138
139
139
139
in
a
.
.
.
.
.
.
.
.
.
.
el
im
.
.
.
.
.
.
.
.
.
.
20 Alocao Dinmica
20.1 Alocao Dinmica de Tipos Simples
20.2 Alocao Dinmica de Vetores . . . .
20.3 Liberao de memria . . . . . . . .
20.4 Alocao Dinmica de Estruturas . . .
20.5 Exerccios . . . . . . . . . . . . . . .
20.5.1 . . . . . . . . . . . . . . . .
20.5.2 . . . . . . . . . . . . . . . .
20.6 Laboratrio . . . . . . . . . . . . . .
20.6.1 . . . . . . . . . . . . . . . .
20.6.2 . . . . . . . . . . . . . . . .
Ve
r
s
o
Pr
in
a
Introduo
Ve
r
s
o
Pr
el
im
s
o
Ve
r
in
a
el
im
Pr
10
SUMRIO
s
o
Ve
r
Bsico
11
in
a
el
im
Pr
Parte I
s
o
Ve
r
in
a
el
im
Pr
el
im
in
a
Captulo 1
1.1
Algoritmo
Pr
s
o
Um algoritmo nada mais que um conjunto de instrues para se resolver um problema. Por exemplo, para se destrancar uma porta temos o seguinte algoritmo:
Coloque a chave na fechadura
Gire a chave
Ve
r
claro que este algoritmo est em um nvel de abstrao muito alto e que poderia
ser muito mais detalhado. Por exemplo, no h por qu destrancar a porta se ela j estiver destrancada e no h como destranc-la se no estiver de posse da chave. Quanto
mais detalhada sua sequncia de passos, mais prximo de algo inteligvel ao computador ela ser. Para isto ocorra, isto , para que o computador entenda suas intrues,
alm de detalhadas, eles precisam ser escritas em uma linguagem de programao.
1.2
Linguagem de Programao
14
1.3
A linguagem C(++)
in
a
s
o
Pr
el
im
1.3.1
Ve
r
15
in
a
int main()
{
cout << "Ola Mundo!" << endl;
return 0;
}
1.3.2
rea de um Retngulo
el
im
A linha 1 do cdigo define a funo f como uma funo que aceita dois parmetros
e b. Alm disso, esta funo tambm define que cada um destes parmetros um
nmero inteiro ao preceder cada parmetro pela palavra int. Finalmente, esta linha
tambm define que o resultado da funo ser um nmero inteiro ao preceder o nome
da funo (f) pela palavra int. Isto quer dizer que se voc no pode usar esta funo
para calcular a rea de retngulos cujos lados no sejam inteiros. Mas no se preocupe,
corrigiremos esta deficincia daqui a pouco.
As linhas 2 e 4 definem o corpo da funo, isto , quais outras linhas so partes da
funo f. Toda funo na linguagem C precisa ter definido seu comeo e fim usando {
e }, respectivamente.
A linha 3 do cdigo onde o clculo da rea efetivamente executado: a*b. Alm
disso, esta linha define tambm qual o resultado da funo ao preceder o resultado da
multiplicao por return.
Ve
r
s
o
Pr
A rea de um retngulo pode ser facilmente calculada caso voc saiba o comprimento
de sua base e de sua altura. Matematicamente, seja b o comprimento da base e a a
altura. A funo f equivalente rea do retngulo pode ser definda como: f (a, b) =
a b. Isto , a funo f tem dois parmetros (a altura a e base b do retngulo) e calcula
a rea como sendo a multiplicao de a e b. Em linguagem C(++) pode-se escrever esta
funo como mostrado no prximo segmento de cdigo, que analisaremos em seguida.
16
1.3.3
in
a
1.3.4
el
im
Pronto, a funo agora recebe dois parmetros do tipo float e retorna um resultado tambm deste tipo. Juntamente com outros tipos que sero vistos adiante no curso,
int e float so chamados de tipos de dados primitivos da linguagem. Isto sugere,
obviamente, que h tambm tipos no primitivos, e nada poderia ser mais verdade.
Estes tipos, contudo, no sero estudados por enquanto.
Organizao do Cdigo
Pr
s
o
Ve
r
Esta organizao do cdigo serve para facilitar a leitura do cdigo, uma vez que torna
extremamente bvio onde a funo comea e termina.
Algo que faltou nestes exemplos e que tambm serve ao propsito de facilitar o
entendimento do cdigo so os chamados comentrios. O exemplo a seguir mostra
como a funo f poderia ser comentada.
10
/*
* A funcao a seguir calcula a area de um retangulo de base
* b e altura b. Os parametros e resultado da funcao sao do
* tipo float.
*/
float f(float a, float b)
{
//Calcula e retorna a area do retangulo.
return a * b;
}
17
10
in
a
/*
* A funcao a seguir calcula a area de um retangulo de base
* base e altura altura. Os parametros e resultado da funcao
* sao do tipo float.
*/
float area_retangulo(float altura, float base)
{
//Calcula e retorna a area do retangulo.
return altura * base;
}
1.4
el
im
A Funo main
#include <iostream>
Pr
Que o computador uma mquina burra e executa somente o que voc manda voc j
deve ter entendido, mas como mand-lo executar algo? Em linguagem C, o computador
sempre comea a execuo de um programa pela funo main. Sendo assim, se voc
quer dizer ao computador que calcule a rea de um retngulo, ento esta ordem dever
partir, de alguma forma, da funo main. Por exemplo, veja o cdigo abaixo.
s
o
Ve
r
/*
* A funcao a seguir calcula a area de um retangulo de base
* base e altura altura. Os parametros e resultado da funcao
* sao do tipo float.
*/
float area_retangulo(float altura, float base)
{
//Calcula e retorna a area do retangulo.
return altura * base;
}
10
12
14
16
18
20
22
int main()
{
//Calculemos a area de alguns retangulos.
cout << area_retangulo(3.3, 2.0) << endl;
cout << area_retangulo(2.0, 2.0) << endl;
//Lembre-se, todo numero inteiro tambem e um numero real.
cout << area_retangulo(4, 2) << endl;
24
return 0;
18
26
in
a
2. Funo main como um highlander: s pode haver uma! Isto , cada programa
s pode conter a definio de uma funo com este nome.
3. Finalmente, a funo area_retangulo aparece antes da fuo main no programa. Isto deve ser verdade para todas as funes do seu programa. Isto ocorre
por qu, antes de executar a funo main, o computador precisa aprender sobre
a existncia das outras funes.
Concluso
Pr
1.5
el
im
O cdigo como est, includindo as duas linhas iniciais que ainda no sabem para
que serverm, est pronto para ser executado no seu computador. Por que voce no
experimenta faz-lo? Para tal, crie um projeto do tipo Console Application, usando a
linguagem C++.
s
o
Ve
r
1.6
Exerccios
1.6.1
1.6.2
Escreva um funo que calcule a rea de um crculo. Observe que a linguagem C
baseada na lngua inglesa, na qual se separa casas decimais por . e no por ,. Logo,
igual 3.14 e no 3,14.
in
a
Compilao e Execuo
Captulo 2
2.1
Pr
el
im
O processo de compilao
Ve
r
s
o
write(0x1,0x400623,0xe)
fd 1 "Ol Mundo!"
Aps a compilao vem a linkedio, o passo que junta o seu arquivo objeto a
outros arquivos objetos interessantes, como por exemplo um que contenha cdigo de
19
20
2.2
A IDE Code::Blocks
2.2.1
el
im
in
a
Criando um Projeto
Ve
r
s
o
Pr
21
el
im
in
a
botao com ... e escolha uma pasta para salvar o projeto; esta pode ser, por exemplo, a
pasta Meus Documentos ou uma pasta qualquer em um pen drive.2 Clique ento Next
e, na tela seguinte, clique em Finish.
s
o
Pr
Pronto, seu projeto foi criado. Mas e agora? Agora abra o arquivo main.cpp, que
est na pasta sources, dando um clique duplo no nome do arquivo.
Ve
r
Finalmente, clique em build e ento em build and run. Parabns, voc acaba de
executar seu primeiro programa.
2.2.2
Depurao
Todo programa de tamanho considervel, e mesmo aqueles de tamanho diminuto, possuiro, ao menos em suas verses iniciais, erros. Por razes histricas, nos referimos
a estes erros por bugs. Uma das formas de achar os bugs do seu programa fazer
com que o computador execute seu programa passo a passo, isto , linha a linha, e
acompanhar esta execuo verificando se o programa faz o que voc espera.
Para experimentarmos a depurao, processo pelo qual removemos bugs, modifique a mensagem "Hello world!"do seu programa para "Ol <seu nome>!"e execute
novamente o programa (build and run). Se o programa executou normalmente, voc
2O
importante aqui salvar o arquivo em um lugar em que voc possa voltar mais tarde para reler.
22
est no caminho certo. Agora, copie a toda a linha contendo a mensagem e cole-a
vrias vezes, substituindo o nome em cada linha. Seu programa deve ficar assim:
#include <iostream>
2
10
el
im
12
int main()
{
cout << "Hello
cout << "Hello
cout << "Hello
cout << "Hello
cout << "Hello
return 0;
}
in
a
s
o
Pr
Mais uma vez, compile e execute seu programa. Se a execuo foi bem sucedida,
voc est pronto para a depurao. Para depurar, clique ao lado direito do nmero 7
(stima linha do programa), at que uma bolinha vermelha aparea, como na figura a
seguir.
Ve
r
2.3
O Arquivo Executvel
2.4. EXERCCIOS
23
Code::Blocks. Nesta pasta voc encontrar um arquivo com extenso .exe; este o
arquivo executvel que deveria enviar para seu amigo.
2.4
Exerccios
2.4.1
in
a
Escreva o programa completo que calcula a rea de vrios retngulos do captulo anterior e execute-o.
2.4.2
Ve
r
s
o
Pr
el
im
Altere seu programa para usar, alm da funo de clculo de rea de um quadrado, as
funes definidas nos exerccios do captulo anterior.
Ve
r
s
o
Pr
el
im
in
a
24
el
im
in
a
Captulo 3
Declarao de Variveis
Ve
r
3.1
s
o
Pr
Na linguagem C, toda varivel deve ser declarada (isto , criada) logo depois da declarao da funo (aqueles blocos que vimos no Captulo 1). A declarao/criao de
uma varivel tem, pelo menos, duas partes:
Nome: atravs do qual ela pode ser acessada e atualizada no seu programa;
Tipo: para que o computador saiba como tratar a informao, ele precisa saber de que
tipo ela , ou seja, se um nmero, ou uma palavra, ou uma caractere, etc.
Existem algumas regrinhas bsicas para se nomear uma variveis:
o nome s pode conter os caracteres [a-z], [A-Z], [0-9] e o "_"; e,
o nome no pode comear com nmeros.
25
26
3.1.1
Atribuio e Uso
el
im
in
a
Ve
r
s
o
Pr
A memria do computador sempre tem algum dado, tenha ele sido colocado por
voc ou no, seja ele relevante ou no. Logo, para se usar o contedo de uma varivel,
necessrio ter certeza de que a mesma contm um valor que faa sentido. Isto ,
algo que tenha sido atribudo pelo seu programa quela varivel, via uma operao
de leitura, via uma computao qualquer, ou via uma atribuio como a do exemplo
anterior.
Denominamos a primeira atribuio de um valor a uma varivel de iniciao (ou
inicializao). E j que qualquer varivel s pode ser usada se tiver sido iniciada, o C
permite que as variveis sejam iniciadas j em sua declarao. Por exemplo, o cdigo
abaixo faz exatamente o que fazia o exemplo anterior, mas de forma mais compacta.
27
int inteiro1 = 0,
inteiro2 = 10;
float real = 10.0;
#include <iostream>
11
13
15
17
19
21
23
proximo de " << _c << " eh " << proxima_letra(_c) << endl;
Ve
r
25
int main() {
int r1;
float r2;
char _c;
_c = a;
cout << "O
r1 = 2;
r2 = 9.7;
cout << "r
cout << "r
r1 = 12;
r2 = 0.4;
cout << "r
cout << "r
return 0;
}
s
o
Pr
el
im
in
a
Observe que se pode iniciar vrias variveis do mesmo tipo, declaradas na mesma
linha, com valores distintos. Neste caso, note quebra de linha entre as declaraes de
inteiro1 e inteiro2; ela somente esttica, mas ajuda a separar a declarao e
iniciao das vrias variveis.
Agora que voc viu como declarar e iniciar uma varivel vem a parte fcil, us-la.
Veja como no seguinte exemplo.
27
29
31
33
35
= " << r1 << ", area = " << area_circulo(r1) << endl;
= " << r2 << ", area = " << area_circulo(r2) << endl;
= " << r1 << ", area = " << area_circulo(r1) << endl;
= " << r2 << ", area = " << area_circulo(r2) << endl;
simples assim: para se usar uma varivel, basta colocar seu nome na expresso a ser
computada.
28
3.1.2
Parmetros so Variveis
11
int main()
{
float area;
area = area_retangulo(2.0, 2.0);
cout << area;
return 0;
13
in
a
el
im
Nos exemplos de programas dos captulos anteriores, voc viu como o contedo de uma
parmetro definido e usado. Por exemplo, os dois parmetros da funo area_retangulo,
reproduzida abaixo, so declarados dizendo-se de que tipo eles so e quais so seus nomes. Em seguida, no corpo da funo, os parmetros so usados no clculo da rea
simplesmente multiplicando-se o nome de um pelo nome do outro; os valores dos
parmetros so aqueles passados na chamada da funo.
Entrada / Sada
s
o
3.2
Pr
Esta semelhana com a declarao e uso de variveis no coincidental: parmetros no so mais do que variveis declaradas e iniciadas de uma forma especial.
Impresso
Ve
r
3.2.1
O comando de impresso em tela que usaremos ser o cout, do qual j vimos diversos
exemplos. Seu uso bem simples e intuitivo: textos devem aparecer entre aspas duplas,
caracteres entre aspas simples e nmeros, variveis e chamadas de funes aparecem
diretamente. Todas as informaes impressas pelo mesmo comando cout devem ser
conectadas pelos caracteres <<. A seguir, podemos ver alguns exemplos:
...
char letra = a;
int num = 2;
cout << "letra = " << letra << endl << "num = " << num << endl;
29
Como pode ser observado no exemplo anterior, a palavra endl aparece algumas
vezes. Sua funo a de pular uma linha na tela (endl a contrao end line).
Sendo assim, o comando anterior teria a seguinte sada:
letra = a
num = 2
3.2.2
Leitura
cout << "Informe a letra inicial de seu nome e sua idade: ";
// a seguir eh feita a leitura
cin >> letra >> idade;
cout << "A letra eh " << letra;
cout << " e sua idade eh " << idade << endl;
Pr
char letra;
int idade;
el
im
in
a
Agora que voc consegue ler do teclado e escrever para a tela, veja como fcil fazer um programa que calcule a rea de retngulo cujos lados so digitados pelo
usurio.
s
o
int main()
{
float area,
b,
a;
cout << "Qual a altura do retangulo?" << endl;
cin >> a;
Ve
r
10
12
14
16
18
20
return 0;
22
30
3.3
Operadores
in
a
10
12
el
im
int main()
{
int n, dobro_de_n;
cout << "Entre um inteiro: ";
cin >> n;
dobro_de_n = 2*n;
cout << "O dobro de " << n << " eh " << dobro_de_n << endl;
return 0;
}
3.3.1
Pr
Construes Especiais
int
...
a =
b =
a =
a, b;
a + b;
b * 2;
a / 7;
Ve
r
s
o
Com a finalidade de agilizar o desenvolvimento e simplificar algumas operaes aritmticas mais comuns, a linguagem C permite algumas construes especiais envolvendo operadores. Considere o seguinte trecho de cdigo::
Observe que nas trs atribuies (indicadas pelo sinal de igualdade), as variveis
que so atualizadas tambm aparecem como primeiro elemento da operao aritmtica
esquerda. Nestas situaes, podemos reescrever as atribuies assim:
int a, b;
...
a += b;
b *= 2;
a /= 7;
3.4. EXERCCIOS
31
As operaes de incremento (aumento de uma unidade) e o decremento (diminuio de uma unidade) de uma varivel so muito comuns em programao. Sendo assim,
a linguagem C define dois operadores para as mesmas: ++ e --, respectivamente. Veja
o exemplo.
0;
1;
"a = " << a << endl;
"a = " << a << endl;
int a =
a = a +
cout <<
a += 1;
cout <<
a++;
cout <<
a--;
cout <<
in
a
3.3.2
Precedncia de Operadores
el
im
3.4
Exerccios
3.4.1
Pr
Em uma expresso onde aparecem diversos operadores, a seguinte ordem de precedncia deve ser obedecida: primeiramente os operadores de incremento/decremento; em
seguida os operadores %, e /; e por ltimo os operadores + e
int a, b = 0, c
a = ++b + ++c;
cout << a << ",
a = b++ + c++;
cout << a << ",
a = ++b + c++;
cout << a << ",
a = b-- + --c;
cout << a << ",
= 0;
Ve
r
s
o
Diga o que ser escrito na tela durante a execuo do seguinte trecho de cdigo:
3.4.2
Escreva uma funo em C que, dado uma temperatura em graus Clsius (do tipo float),
retorne a temperatura equivalente em Farenheit. Escreva tambm a funo main que
leia a temperatura em Clsius do teclado, invoque a funo de converso, e imprima o
resultado.
Dado: F = 9C
5 + 32
32
3.4.3
s
o
Pr
el
im
in
a
Escreva uma
Ve
r
o qu?
Captulo 4
Escopo de Variveis
el
im
4.1
in
a
Variveis (II)
No captulo anterior estudamos como declarar e utilizar variveis em nossos programas. Fizemos, por exemplo, um programa como o seguinte, que pede ao usurio que
entre com as medidas da base e altura de um retngulo e ento imprime na tela do
computador a rea deste retngulo.
11
13
Pr
int main()
{
float area,
b,
a;
cout << "Qual a altura do retangulo?" << endl;
cin >> a;
s
o
Ve
r
15
17
19
21
return 0;
23
34
int main()
{
float area,
base,
altura;
cout << "Qual a altura do retangulo?" << endl;
cin >> altura;
in
a
11
15
return 0;
}
e execute-o.
el
im
13
17
modifique somente a funo main do seu programa para que fique assim
Pr
s
o
Ve
r
35
float PI = 3.1416;
float resposta = 0;
11
17
19
21
23
int main()
{
float area,
base,
altura,
raio;
25
el
im
15
Pr
13
in
a
escopo presente possvel em C o escopo global. Uma varivel tem escopo global
se for definida fora de qualquer funo. Uma variel com escopo global poder ser
acessada de (quase) qualquer parte do seu cdigo. Para um exemplo de varivel de
escopo global, veja o cdigo a seguir.
27
s
o
29
31
33
35
Ve
r
cout << "Resposta da chamada de funcao " << resposta << endl;
37
39
area = area_circlo(raio);
cout << "A area do circulo de raio " << raio
<< " e PI arredondado para " << PI <<" eh " << area << endl;
41
43
cout << "Resposta da chamada de funcao " << resposta << endl;
return 0;
45
47
Observe a varivel PI. Esta varivel foi declarada fora de qualquer funo e, sendo
assim, visvel em qualque delas, como demonstrado pelo seu uso na funo main e
36
Faixas de Valores
in
a
4.2
area_circulo.
Observe tambm que a mesma varivel aread foi utilizada mais de uma vez. Isto
comum em programao pois, com a quantidade limitada de recursos, pode no fazer
sentido criar uma varivel para cada novo uso. Observe que a varivel resposta
foi alterada dentro das duas funes de clculo de rea e que estas mudanas foram
visveis funo main.
Verifique de forma experimental (copiando e executando )que o programa acima
funciona como esperado.
Colocar
4.3
Exerccios
4.4
Laboratrio
Ve
r
Colocar
s
o
Pr
el
im
Captulo 5
in
a
Seleo Simples
s
o
Pr
el
im
x = b
, sendo = b2 4ac.
2a
Comecemos ento definindo uma funo para o clculo do .
Ve
r
10
12
14
16
37
38
cout << "Digite o valor de b: ";
cin >> b;
cout << "Digite o valor de c: ";
cin >> c;
18
20
22
24
in
a
Agora, para clculo das razes! Comecemos por alterar o programa para imprimir
o nmero de razes da equao. O clculo do nmero de razes ser feito na funo
raizes. A equao tem ou 0 razes reais (se o < 0), ou duas razes iguais (se
= 0), ou duas raizes distintas (se > 0).
#include <iostream>
using namespace std;
4
10
12
Pr
14
se d menor que 0
{
qtd = 0;
}
senao e se d igual a 0
{
qtd = 1;
}
senao
{
qtd = 2;
}
16
22
Ve
r
24
s
o
18
20
el
im
26
return qtd;
28
30
32
34
36
38
40
int main()
{
float a, b, c;
cout << "Equacao do segundo grau: axx + bx + c = 0" << endl;
cout << "Digite o valor de a: ";
cin >> a;
cout << "Digite o valor de b: ";
cin >> b;
cout << "Digite o valor de c: ";
39
42
cin >> c;
44
46
5.1
in
a
Operadores Relacionais
s
o
Pr
el
im
Ve
r
10
12
14
16
18
return qtd;
20
40
5.2
if-else
Em C, testes simples (tudo o que voc realmente precisa) podem ser feitos com a estrutura if, que tem uma das seguintes sintaxes:
in
a
#include <iostream>
Pr
el
im
10
12
Ve
r
14
s
o
16
18
20
22
24
26
0;
== 0)
1;
2;
return qtd;
28
}
30
int main()
5.2. IF-ELSE
32
41
{
float a, b, c;
34
36
38
40
46
in
a
44
42
el
im
11
13
Pr
s
o
15
if(d < 0)
{
qtd =
}
else if(d
{
qtd =
}
else
{
qtd =
}
17
0;
== 0)
Ve
r
19
21
23
25
27
1;
2;
return qtd;
29
}
31
33
35
42
37
39
41
43
45
49
in
a
47
51
return qtd;
}
55
57
int main()
{
float a, b, c;
59
61
Pr
63
65
67
Ve
r
73
s
o
69
71
el
im
53
Note que a nova funo usa a funo sqrt para calcular a raz de . Esta funo
uma das muitas disponveis na linguagem C. Para usar esta funo preciso dizer ao
computador sua inteno. No nosso programa, isto feito na linha 2, isto ,
#include <math.h>
em que dizemos ao computador que queremos usar as funes da biblioteca matemtica da linguagem. Aproveitando a incluso desta biblioteca tambm alteramos a linha
8 para usar a funo pow para o clculo do b2 . Vrias outras funes esto disponveis e podem ser consultadas em http://www.cplusplus.com/reference/
clibrary/cmath/.
5.3
43
Funes e Procedimentos
el
im
in
a
Pr
int ler_idade()
{
int id;
cout << "Qual sua idade? " <<endl;
cin >> id;
return id;
}
Ve
r
s
o
44
in
a
5.4
3. Finalmente, todas as funes devem ser declaradas antes da serem usadas, pois
quando o computador tenta execut-la, j deve saber de usa existncia.
0 corresponde a falso.
el
im
Como vimos neste captulo, o if avalia uma expresso lgica para decidir-se por executar ou no um bloco de comandos. Expresses lgicas, como tambm j tido, so
aquelas que so avaliadas em verdadeiro ou falso. Na linguagem C(++), quaisquer
nmeros inteiros podem tambm ser avaliados como verdadeiro ou falso, seguindo a
seguinte regra:
Exerccios
s
o
5.5
Pr
5.5.1
Muitas pessoas acreditam que um ano bissexto se for mltiplo de 4. Contudo, a regra
um pouco mais complexa do que esta:
Ve
r
Escreva um programa que leia um ano, chame uma funo para calcular se o ano
bissexto e imprima sim ou no de acordo.
#include <iostream>
5.5. EXERCCIOS
45
14
16
18
20
22
26
28
el
im
}
else
{
return false;
}
24
}
30
32
in
a
12
if(ano % 100 == 0)
{
if (ano % 400 == 0)
{
return true;
}
else
{
return false;
}
}
else
{
return true;
}
10
int main()
{
int ano;
34
38
40
if(bissexto(ano))
cout << " e bissexto" << endl;
else
cout << " nao e bissexto" << endl;
s
o
42
Pr
36
44
return 0;
}
Ve
r
46
5.5.2
46
5.5.3
Escreva um programa que contenha
in
a
2. Uma funo fahrenheit_celsius que receba uma temperatura em fahrenheit e converta para graus celsius.
el
im
5.5.4
Faa uma funo denominada ehPar que receba um nmero inteiro como argumento
e retorne verdadeiro se este nmero for par ou falso, caso contrrio. A funo main
deve ser o nmero e imprimir o valor retornado pela funo auxiliar.
Pr
5.5.5
s
o
Uma funo que retorna verdadeiro se trs nmeros reais recebidos como argumentos formam um tringulo ou falso, caso contrrio.
Uma funo que recebe trs nmeros reais como argumento representado os lados de um tringulo e retorna 0 caso os nmeros formem um tringulo equiltero,
1 caso formem um tringulo issceles, ou 2 caso sejam os lados de um tringulo
escaleno.
Ve
r
Por fim, a funo main deve ler os 3 nmeros que representam os lados, e caso
formem um tringulo, imprimir se o tringulo formado equilatero, issceles ou
escaleno.
5.6
Laboratrio
in
a
Captulo 6
6.1
el
im
Uma vez apresentado a estrutura condicional if-else, veremos agora como realizar testes mais complexos utilizando operadores lgicos.
10
Ve
r
12
...
/*
* esta funcao retorna verdadeiro se a pessoa de sexo
* (1=Masculino, 2=Feminino) e idade passados como argumentos
* for maior que idade ou falso, caso contrario
*/
bool ehMaior(int sexo, int idade)
{
if(sexo == 1)
// masculino
{
if(idade == 18)
{
return true;
}
else
{
return false;
}
else if(sexo == 2) // feminino
{
if(idade == 21)
{
return true;
else
{
return false;
}
}
else
// sexo informado errado
s
o
Pr
At o ponto atual fizemos apenas testes simples dentro da condio dos nossos if, por
exemplo:
14
16
18
20
22
24
26
28
47
48
30
32
return false;
}
in
a
el
im
Ve
r
s
o
Pr
Voltando ao nosso exemplo, a funo anterior pode ser reescrita da seguinte forma:
2
...
/*
* esta funcao retorna verdadeiro se a pessoa de sexo
* (1=Masculino, 2=Feminino) e idade passados como argumentos
49
10
12
14
16
in
a
el
im
Pr
s
o
6.2
Ve
r
Quando mais de um operador lgico aparece em uma expresso, a precedncia pode ser
expressa da seguinte maneira: primeiro o NO, depois o E, por ltimo o OU. Quando
houver parnteses, primeiro avalia-se o que estiver dentro dos mesmos.
Em diversas expresses e testes, diversos operadores dos vrios tipos podem aparecer. A avaliao dessa expresso deve obedecer seguinte ordem de prioridade em
relao aos operadores:
1. Parnteses, incremento e decremento (++, )
2. Negao (!)
50
6.3
Exerccios
6.3.1
el
im
in
a
Embora os operadores lgicos faam sentido somente para operandos bool, importante relembrar que, para o computador, verdadeiro e falso so apenas formas de
interpretar nmeros na memria. Na linguagem C, qualquer nmero diferente de 0
tratado como true e 0 tratado como false. Sendo assim, possvel aplicar operadores lgicos tambm nmeros. Contudo, sempre que requisitado a representar o
valor true como nmero, o computador usar o valor 1, o que faz com que nem todas
as computaes tenham resultados bvios. Por exemplo, o cdigo cout<<(2||0); imprime, na tela, o valor 1. Isto por qu 2 tratado como verdadeiro e 0 como falso, e o
resultado de verdadeiro OU falso verdadeiro, que ento convertido para 1.
Da mesma forma, !!3 1, pois !3 falso e sua negao verdadeiro, que 1.
Pr
s
o
F || 20 18/3 != 21/3 / 2
!V || 3*3/3 < 15 - 35%7
Ve
r
!1+1
!2+1
!0+1
6.3.2
6.3. EXERCCIOS
51
6.3.3
Faa uma funo que receba 3 nmeros reais (float) correspondentes aos lados de um
tringulo e retorne true caso esse tringulo seja retngulo ou false caso no o seja.
A funo principal deve ler os valores dos lados do tringulo e imprimir se ou no
retngulo.
Ve
r
s
o
Pr
el
im
in
a
Ve
r
s
o
Pr
el
im
in
a
52
Captulo 7
in
a
Switch
7.1
el
im
Em diversas situaes em programao, necessrio testar se uma determinada varivel tem um dentre diversos possveis valores. Nesta situao, embora seja possvel usar
vrios if, outra soluo nos dada em linguagem C: o uso de switch.
switch-case-default
#include <iostream>
Pr
s
o
Ve
r
int main()
{
int dia, mes, ano;
10
12
14
16
18
20
if(mes == 1)
cout << "Janeiro";
else if(mes == 2)
cout << "Fevereiro";
else if(mes == 3)
cout << "Marco";
22
24
53
30
32
34
36
38
40
42
44
46
in
a
28
el
im
else if(mes == 4)
cout << "Abril";
else if(mes == 5)
cout << "Maio";
else if(mes == 6)
cout << "Junho";
else if(mes == 7)
cout << "Julho";
else if(mes == 8)
cout << "Agosto";
else if(mes == 9)
cout << "Setembro";
else if(mes == 10)
cout << "Outubro";
else if(mes == 11)
cout << "Novembro";
else if(mes == 12)
cout << "Dezembro";
else
cout << "Hein?-zembro";
cout << " de " << ano << endl;
return 0;
26
48
CAPTULO 7. SWITCH
54
s
o
Pr
Em vez de usar vrios if e else-if, uma soluo melhor seria usar switch, criado
exatamente para tratar estas situaes. A sintaxe do uso do switch a seguinte.
switch (identificador)
{
case valor1: bloco_comandos1
case valor2: bloco_comandos2
...
case valorN: bloco_comandosN
default: bloco_comandos_default
}
Ve
r
7.1. SWITCH-CASE-DEFAULT
55
#include <iostream>
in
a
int main()
{
int dia, mes, ano;
el
im
10
12
16
18
20
switch(mes)
{
case 1:
cout <<
case 2:
cout <<
case 3:
cout <<
case 4:
cout <<
case 5:
cout <<
case 6:
cout <<
case 7:
22
"Janeiro";
s
o
24
Pr
14
26
28
"Marco";
"Abril";
"Maio";
Ve
r
30
"Fevereiro";
32
34
"Junho";
...
case 11:
cout << "Novembro";
case 12:
cout << "Dezembro";
default:
cout << "Hein?-zembro";
}
cout << " de " << ano << endl;
return 0;
36
38
40
42
44
56
CAPTULO 7. SWITCH
Execute este cdigo e digite, por exemplo, a data 1/1/2012 para ver que ele funciona quase corretamente. O problema, voc deve ter observado, que alm de
imprimir o nome do ms correto, o programa imprime tambm o nome de todos os meses subsequentes e o valor default. Isso ocorre por que, na verdade, o switch comea
a executar o bloco correspondente ao case com o valor da varivel mas, a partir da,
executa todos os blocos a no ser que seja instrudo a fazer diferente, o que feito via
a instruo break.
7.2
in
a
break
A instruo break diz ao computador que pare de executar o switch no ponto em que
invocada.1 Sendo assim, podemos reescrever o programa mais uma vez para obter
exatamente o comportamento da verso usando if.
int main()
{
int dia, mes, ano;
12
Pr
10
14
18
20
22
Ve
r
24
s
o
16
26
28
30
32
34
36
38
el
im
#include <iostream>
2
1 Mais
"Janeiro";
"Fevereiro";
"Marco";
"Abril";
"Maio";
"Junho";
7.3. EXERCCIOS
46
48
50
52
54
56
58
60
"Agosto";
"Setembro";
44
"Julho";
"Outubro";
in
a
42
"Novembro";
"Dezembro";
"Hein?-zembro";
62
64
Exerccios
7.3.1
s
o
7.3
Pr
el
im
break;
case 7:
cout <<
break;
case 8:
cout <<
break;
case 9:
cout <<
break;
case 10:
cout <<
break;
case 11:
cout <<
break;
case 12:
cout <<
break;
default:
cout <<
break;
}
40
57
Ve
r
2. Mdia
3. Menor
4. Maior
#include <iostream>
#include <stdio.h>
58
10
int menu()
{
int opcao;
cout << "1 Soma" << endl << "2 Media" << endl << "3 Menor" << endl
<< "4 Maior" << endl;
cout << "Qual sua opcao? ";
cin >> opcao;
return opcao;
12
#include <math.h>
using namespace std;
14
16
18
22
return z;
24
}
26
32
34
36
38
40
Ve
r
42
Pr
30
s
o
28
el
im
20
in
a
CAPTULO 7. SWITCH
44
46
48
50
int main()
{
int a, b, c;
int opcao;
52
opcao = menu();
58
7.4. LABORATRIO
59
switch(opcao)
{
case 1:
cout << "A soma dos tres numeros eh " << soma(a,b,c);
break;
case 2:
cout << "A media dos tres numeros eh " << media(a,b,c);
break;
case 3:
cout << "O menor dentre os tres numeros eh " << menor(a,b,c
);
break;
case 4:
cout << "O maior dentre os tres numeros eh " << maior(a,b,c
);
break;
default:
cout << "Opcao invalida. Execute o programa novamente e
leia direito as opcoes.";
}
60
62
64
66
68
72
74
el
im
in
a
70
76
return 0;
78
Pr
7.3.2
7.3.3
s
o
Escreva um programa com uma funo que receba um inteiro entre 1 e 7, inclusive, e
escreva o dia correspondente da semana (1 para domingo e 7 para sbado).
Ve
r
7.4
Laboratrio
CAPTULO 7. SWITCH
Ve
r
s
o
Pr
el
im
in
a
60
Captulo 8
in
a
Repetio (I)
Motivao
Pr
8.1
el
im
Suponha de voc deseja fazer um programa para ler duas notas, calcular e imprimir a
mdia de dez alunos da disciplina. A maneira menos prtica de fazer isso seria:
Ve
r
...
float nota1, nota2, media;
cout << "Entre nota 1 e nota 2 do aluno 1: " << endl;
cin >> nota1 >> nota2;
media = (nota1 + nota2) / 2;
cout << "A media das notas eh " << media << endl;
cout << "Entre nota 1 e nota 2 do aluno 2: " << endl;
cin >> nota1 >> nota2;
media = (nota1 + nota2) / 2;
cout << "A media das notas eh " << media << endl;
cout << "Entre nota 1 e nota 2 do aluno 3: " << endl;
cin >> nota1 >> nota2;
media = (nota1 + nota2) / 2;
cout << "A media das notas eh " << media << endl;
cout << "Entre nota 1 e nota 2 do aluno 4: " << endl;
cin >> nota1 >> nota2;
media = (nota1 + nota2) / 2;
cout << "A media das notas eh " << media << endl;
cout << "Entre nota 1 e nota 2 do aluno 5: " << endl;
cin >> nota1 >> nota2;
media = (nota1 + nota2) / 2;
cout << "A media das notas eh " << media << endl;
cout << "Entre nota 1 e nota 2 do aluno 6: " << endl;
cin >> nota1 >> nota2;
media = (nota1 + nota2) / 2;
s
o
10
12
14
16
18
20
22
24
61
28
30
32
34
36
38
40
el
im
42
cout << "A media das notas eh " << media << endl;
cout << "Entre nota 1 e nota 2 do aluno 7: " << endl;
cin >> nota1 >> nota2;
media = (nota1 + nota2) / 2;
cout << "A media das notas eh " << media << endl;
cout << "Entre nota 1 e nota 2 do aluno 8: " << endl;
cin >> nota1 >> nota2;
media = (nota1 + nota2) / 2;
cout << "A media das notas eh " << media << endl;
cout << "Entre nota 1 e nota 2 do aluno 9: " << endl;
cin >> nota1 >> nota2;
media = (nota1 + nota2) / 2;
cout << "A media das notas eh " << media << endl;
cout << "Entre nota 1 e nota 2 do aluno 10: " << endl;
cin >> nota1 >> nota2;
media = (nota1 + nota2) / 2;
cout << "A media das notas eh " << media << endl;
...
in
a
26
62
Pr
Este cdigo tem vrios problemas. Primeiro, ele mais propenso a erros. Se, por
exemplo, voc resolve renomear a varivel nota2 para notab, voc ter que faz-lo
em diversos pontos do programa, aumentando a possibilidade de esquecer algum. Em
segundo lugar, o cdigo exigiu grande retrabalho, isto , a repetio de uma mesma
tarefa por parte do programador. Finalmente, se voc precisar aumentar a quantidade
de repeties para, digamos, 100 alunos, ter que estender o cdigo por pginas e
pginas.
Para evitar tais problemas, para estas situaes a linguagem C fornece estruturas de
repeties, as quais permitem repetir um determinado conjunto de comandos.
O comando while
s
o
8.2
Ve
r
O bloco de comandos entre as chaves ser repetido enquanto a condio dentro dos
parnteses for verdadeira.
Utilizando o while, o exemplo anterior pode ser reescrito de maneira bem mais
adequada:
...
float nota1, nota2, media;
int i = 1; // valor inicial do identificador do aluno
10
12
63
in
a
el
im
8.3
O comando do-while
do
{
\\ bloco de comandos
\\ a ser repetido
s
o
Pr
}
while (<condicao>);
Ve
r
...
float nota1, nota2, media;
int i = 1; // valor inicial do identificador do aluno
10
12
14
do
{
cout << "Entre nota 1 e nota 2 do aluno " << i << ": " << endl;
cin << nota1 << nota2;
media = (nota1 + nota2) / 2;
cout << "A media das notas eh " << media << endl;
i++; // aumentamos o valor de i no final de cada calculo da media
}
while (i <= 10);
...
64
Mais exemplos
8.4
Pr
10
...
int n = 2, // primeiro par maior do que 1
soma = 0; // soma inicialmente zerada
while (n < 999)
{
soma = soma + n;
n += 2;
}
cout << "O valor da soma eh " << soma << endl;
...
el
im
in
a
Considere que deseja-se somar todos os nmeros pares entre 1 e 999. Ou fazemos uma
soma com todos os valores em uma linha enorme, ou utlizamos o que apresendemos
sobre comandos de repetio. Utilizando o while, teramos:
...
int i = 0, // contador da qtde de numeros lidos
maior,
n;
do
{
cout << "Entre um numero: ";
cin >> n;
if (i == 0) // se for o primeiro numero lido
{
// ele serah o menor
maior = n;
}
else
// a partir do segundo
{
if(n > maior) // atualizo o maior
{
maior = n;
}
}
i++;
}
while (i < 10);
...
Ve
r
s
o
Observe que a cada iterao o valor de soma acrescido do prximo nmero par, o
qual obtido somando-se 2 ao valor de n.
Imagine que se deseja obter o maior entre 10 nmeros inteiros lidos. Utilizando o
do-while, uma possvel soluo seria:
10
12
14
16
18
20
22
65
Ve
r
s
o
Pr
in
a
...
int num;
do
{
cout << "Entre um numero: ";
cin >> num;
}
while (! num > 100);
...
el
im
Neste exemplo temos uma situao especial em que, no primeiro caso (i = 0), o
maior valor o nico valor lido. A partir do segundo nmero, se o nmero lido for
maior do que o valor armazenado na varivel maior, esta ser atualizada.
Em outro exemplo, imagine que queira ler nmeros at que leia um nmero maior
que 100. Neste caso, o seguinte programa resolveria nosso problema.
66
8.5
Exerccios
8.5.1
Faa uma funo que recebe um nmero inteiro positivo e retorna o fatorial deste nmero. A funo principal deve ler o nmero do qual se deseja calcular o fatorial e
imprimir o resultado.
in
a
8.5.2
el
im
Faa uma funo que recebe um nmero inteiro positivo e retorna true se o nmero
for primo ou false, caso contrrio. A funo principal (main) deve ler o nmero e
imprimir o resultado.
8.5.3
Modifique o programa anterior para imprimir todos os nmeros primos abaixo de dois
milhes.
8.5.4
Ve
r
s
o
Pr
Faa um programa que leia um nmero inteiro positivo e imprima esse nmero de trs
pra frente. A impresso deve ser feita pela funo auxiliar inverteNumero.
8.6. LABORATRIO
8.6
67
Laboratrio
8.6.1
Implemente os exerccios acima no Code::Blocks.
8.6.2
in
a
O exerccio 7.3.1 pedia que voc escrevesse uma funo que gerasse um menu na tela.
A funo que voc escreveu tinha um problema: ela aceitava qualquer valor, mesmo
algum no correspondendo a nenhuma opo do menu.
Usando do-while, altere sua funo para que continue exibindo o menu e lendo
uma opo at que uma opo vlida seja digitada pelo usurio.
el
im
8.6.3
Implemente uma funo chamada pot que receba dois nmeros reais base e expoente
como parmetro e que calcule baseexpoente . A funo pot deve usar multiplicaes
sucessivas para calcular seu resultado (isto , proibido o uso da funo pow).
8.6.4
Ve
r
...
int num = 10;
do
{
cout << num;
num *= 2;
}
while (1);
...
s
o
Pr
8.6.5
Escreva um programa que leia um numero inteiro positivo n e em seguida imprima n linhas do
chamado Tringulo de Floyd:
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
16 17 18 19 20 21
68
8.6.6
Faa um programa que gera um nmero inteiro aleatrio de 1 a 1000 em uma funo denominada
geraNumero. Na funo principal, o usurio deve tentar acertar qual o nmero foi gerado. A
cada tentativa o programa dever informar se o chute menor ou maior que o nmero gerado.
O programa acaba quando o usurio acerta o nmero gerado. O programa deve informar em
quantas tentativas o nmero foi descoberto.
8.6.7
Ve
r
s
o
Pr
el
im
in
a
Escreva um programa que receba como entrada o valor do saque realizado pelo cliente de um
banco e retorne quantas notas de cada valor sero necessrias para atender ao saque com a
menor quantidade de notas possvel. Sero utilizadas notas de 100, 50, 20, 10, 5, 2 e 1 reais. O clculo e impresso do resultado deve ser efetuado por uma funo auxiliar denominada
imprimeNotas.
Captulo 9
in
a
Repetio (II)
el
im
Voc deve ter percebido que no uso de do-while e while quase sempre seguimos os mesmos
passos:
declarar uma varivel que sirva de controle para a iterao;
iniciar a varivel de controle (e possivelmente outras);
verificar a condio para iterao
executar iterao
Pr
A linguagem C tem um comando iterao que agrega todos estes passos, chamado for.
for
s
o
9.1
Ve
r
for(DI; C; I)
{
\\bloco de comandos a ser repetido
}
O comando for tem trs partes em sua declarao, alm dos comandos a serem repetidos.
DI em DI variveis podem ser Declaradas e Iniciadas. Variveis j existentes tambm
podem ter seus valores ajustados em DI;
C C define a Condio necessria execuo do bloco de comandos. Enquanto a
condio for verdadeira, o bloco ser executado.
I comandos de modificao de variveis, como Incremento e decremento, so colocados
diretamente na declarao do for. O comando executado ao final de cada iterao.
A execuo do for segue os seguintes passos:
69
70
10
in
a
...
int n = 2, // primeiro par maior do que 1
soma = 0; // soma inicialmente zerada
while (n < 999)
{
soma = soma + n;
n += 2;
}
cout << "O valor da soma eh " << soma << endl;
...
el
im
Considere o exemplo do captulo anterior em que deseja-se somar todos os nmeros pares
entre 1 e 999. O cdigo pode ser escrito, como vimos, usando while.
...
int n, // primeiro par maior do que 1
soma = 0; // soma inicialmente zerada
for (n = 1; n < 999; n += 2)
{
soma = soma + n;
}
cout << "O valor da soma eh " << soma << endl;
...
Pr
...
int soma =
for (int n
{
soma =
}
cout << "O
...
Ve
r
s
o
soma + n;
valor da soma eh " << soma << endl;
possvel declarar e iniciar mais de uma varivel no DI, mas no possvel definir novas
variveis e iniciar outras j definidas. No exemplo abaixo, errado, a varivel soma sendo iniciada
no for diferente da varivel definida antes do comando, apesar do nome ser igual.
...
int soma = 0; // soma inicialmente zerada
for (int n = 1, soma = 0; n < 999; n += 2)
{
soma = soma + n;
71
}
cout << "O valor da soma eh " << soma << endl;
...
9.2
Mais Exemplos
10
12
14
16
18
el
im
Pr
...
int i, // contador da qtde de numeros lidos
maior,
n;
s
o
in
a
Tambm do captulo anterior, imagine o exemplo em que se deseja obter o maior entre 10 nmeros inteiros lidos. Utilizando o for, uma possvel soluo seria:
9.3
Declaraes especiais
Ve
r
Em certas situaes pode ser desejvel omitir partes da declarao do for. Por exemplo, se as
variveis de controle j tiverem sido iniciadas ou, simplesmente, se no existirem, ou se no
houver incremento a ser feito, ento estas partes da declarao podem ser deixadas em branco.
Por exemplo,
int menu()
{
int opcao = 0;
10
12
1 || opcao > 4 ; )
Soma" << endl
Media" << endl
Menor" << endl
Maior" << endl;
72
14
16
in
a
Observe que embora neste exemplo tanto DI quanto I esto vazias, isso no necessrio. Isto
, qualquer das partes da declarao podem estar vazias independentemente, inclusive a segunda
parte.
9.4
int menu()
{
int opcao;
10
"1
"2
"3
"4
Pr
for(;;)
{
cout <<
<<
<<
<<
el
im
Caso a segunda parte do comando esteja vazia, a repetio ser executada ad infinitum ou at que
seja interrompida. A interrupo de uma iterao pode ser feita usando-se o comando break.
Veja o exemplo anterior reescrito para usar tal comando.
14
16
18
20
return opcao;
Ve
r
22
s
o
12
Outra forma de se alterar o fluxo via o comando continue, que faz com que a o restante do bloco de comandos seja ignorado e, conseqentemente, incremento e condio sejam
reavaliados. Por exemplo, reescrevendo o cdigo acima para o usar o continue.
int menu()
{
int opcao;
for(;;)
{
cout << "1 Soma" << endl
<< "2 Media" << endl
9.5. EXERCCIOS
73
10
12
14
16
18
20
in
a
}
22
return opcao;
}
9.5
el
im
24
Exerccios
Laboratrio
Pr
9.6
9.6.1
Ve
r
..
..
..
s
o
Escreva uma funo que receba dois parmetros inteiros, X e Y, e imprima X linhas na tela, cada
uma com Y .. Por exemplo, se sua funo for invocada com X igual 3 e Y igual 2, o resultado
deveria ser o seguinte
9.6.2
Escreva uma funo que receba dois parmetros inteiros, X e Y, e imprima de forma decrescente
os nmeros de X*Y at 1, em X linhas de Y nmeros. Por exemplo, se sua funo for invocada
com X igual 4 e Y igual 3, o resultado deveria ser o seguinte
12 11 10
9 8 7
6 5 4
3 2 1
Ve
r
s
o
Pr
el
im
in
a
74
in
a
el
im
Captulo 10
At agora temos trabalhado essencialmente com os tipos numricos, inteiros e reais, e booleanos. Para que possamos usar outros tipos, essencial que antes entendamos como os dados so
representados na memria do computador.
Pr
10.1
10.1.1
s
o
Como dito anteriormente, a memria do computador pode ser entendida como uma grande planilha eletrnica, podendo cada clula ser endereada (atribuda, lida, nomeada) individualmente.
Na memria do computador no existem nmeros ou caracteres, mas vrias lampdas que podem estar ligadas ou desligadas. Ns humanos atribumos significado a tais estados como sendo
0s e 1s. Cada posio da memria, que pode armazenar 0 ou 1, denominado um bit. Por
serem mnimos, normalmente trabalhamos com conjuntos de 8 bits por vez, o que denominamos
bytes.
Base Binria
Ve
r
Os bits de um byte podem assumir todas as combinaes de ligado e desligado (0 e 1). Dado
um contexto, cada combinao corresponde a um certo valor. Por exemplo, se estiver usando um
byte para representar nmeros inteiros, ento provavelmente a correspondncia na Tabela 10.1
se aplica.
Talvez isso seja novidade para voc, mas voc representa nmeros na base decimal usando
10 dgitos (de 0 a 9). Contudo, outras bases existem. Como os bits s possuem dois estados,
natural na computao usar a base binria, que usa 2 dgitos (0 e 1). Os valores esquerda na
tabela podem ser entendidos como nmeros nesta base.1
Para conseguir converter nmeros de uma base para a outra, basta entender o que exatamente
significa a representao de um nmero em uma base genrica X. Nesta base, ABCDX significa
AX 3 +BX 2 +CX 1 +DX 0 . O nmero 123410 , por exemplo, significa 1X 3 +2X 2 +3
X 1 +4X 0 = 11000+2100+310+41 que igual a, t d, 123410 . Para um exemplo mais
1 sempre que no for colocada a base, considera-se a base 10, mais natural aos seres de vida baseada em
carbono do nosso planeta, A.K.A., voc.
75
76
el
im
in
a
Base Hexadecimal
s
o
10.1.2
Pr
interessante, o nmero 101010102 = 127 +026 +125 +024 +123 +022 +121 +020 =
128 + 0 + 32 + 8 + 2 = 170.
Observe que, pela tabela, o maior nmero que se pode representar com 8 bits 111111112 =
25510 . Via de regra, com X bits pode se representar 2X na base binria, de 0 a 2X 1.
Ve
r
Embora se possa usar qualquer base numrica, as que fazem mais sentido no mundo computacional so as binria e hexadecimal. A base hexadecimal usa 16 dgitos em cada posio
representando valores de 0 a 15. Para isto, usa os valores de 0 a 9 iguais aos da base decimal e
tambm as letras de A a F representado os valores de 10 a 15. Por exemplo, o nmero 1A2F16
equivale a 1 163 + 10 162 + 2 161 + 15 160 = 4096 + 2560 + 32 + 15 = 6703.
10.2
Enquanto ns trabalhamos com base decimal, o computador armazena informao e realiza operaes na base binria. Por isso, a todo momento ocorre a converso entre um decimal que
informamos como entrada em um programa, por exemplo, para a base binria (para efetuar o
clculo), bem como da base binria (resultado do clculo) para a base decimal exibida na tela.
77
el
im
in
a
A converso de decimal para binrio feita realizando-se divises sucessivas pela base de interesse (2, no nosso caso) at que o resultado seja zero. Os restos das divises, na ordem inversa,
correspondem ao nmero convertido.
Por exemplo, considere a converso do nmero 169 para a base binria. O processo de
converso o seguinte:
169/2 = 84, Resto = 1
84/2 = 42, Resto = 0
42/2 = 21, Resto = 0
21/2 = 10, Resto = 1
10/2 = 5, Resto = 0
5/2 = 2, Resto = 1
2/2 = 1, Resto = 0
1/2 = 0, Resto = 1
O nmero binrio equivalente , portanto, 101010012 .
s
o
10.3
Pr
Sabendo-se que com 4 bits possvel representar at 16 nmeros (de 0 a 15) e que a base hexadecimal tem exatamente 16 dgitos, conclumos que possvel representar cada dgito hexadecimal
com 4 dgitos binrios. Sendo assim, a converso binrio/hexadecimal pode ser feita facilmente
substituindo conjuntos de 4 bits binrios por um dgito hexadecimal e vice-versa.
Por exemplo, para convertermos 111010102 convertemos 11102 para E16 e 10102 para A16 ,
obtendo o nmero EA16 . Na direo inversa, para convertermos o nmero 7B16 para binrio
convertemos 716 para 01112 e B16 para 10112 , obtendo o nmero 011110112 .
Ve
r
10.3.1
in
a
78
Ve
r
s
o
Pr
el
im
79
in
a
Como a memria do computador armazena apenas 0s e 1s, uma possvel estratgia desperdiar um dos bits do nmero para o sinal. Adota-se, por padro, o zero para representar um
nmero positivo e o um para negativo. O bit do sinal armazenado na posio mais esquerda.
el
im
Para representar o valor de um nmero negativo h duas principais abordagens: sinalmagnitude e complemento de 2.
Na representao sinal-magnitude, o nmero negativo tem seu valor absoluto (magnitude)
representado da mesma forma que um nmero positivo e o bit mais significativo, que representa
o sinal, ser igual a um. A tabela a seguir mostra alguns exemplos de nmeros na base decimal
e na representao sinal-magnitude.
s
o
Pr
Ve
r
10.4
80
10.4.1
Nmeros positivos
A adio de nmeros positivos muito simples. Para faz-la, basta somar os valores na mesma
posio, do menos significativo para o mais significativo. O vai-um funciona da mesma forma
como fazemos na base decimal. Por exemplo, para somarmos 5 e 9, fazemos:
in
a
1
0101 +
1001
---1110
1 111
0111 +
1001
---1 0000 <-- overflow!
el
im
Como a quantidade de bits para determinado tipo de dados limitado, durante uma soma pode
ocorrer de o resultado ultrapassar o maior valor permitido para aquela quantidade de bits, quando
isto ocorre, temos um overflow (derramamento). Considere a soma de 7 e 9, ambos com 4 bits.
Houve um vai-um alm do bit mais significativo, caracterizando um overflow. Neste caso,
o resultado da operao est errado.
Nmeros em Complemento de 2
Pr
10.4.2
s
o
Como vimos anteriormente, o computador usa duas principais representaes para nmeros negativos. A representao complemento de 2 a mais utilizada porque permite que a soma de
nmeros negativos seja feita da mesma maneira que a soma de nmeros positivos. Por exemplo
considere as soma de -2 + 5 e -1+(-1), em complemento de 2:
1 1
1110 +
0101
---1 0011 <-- No overflow! Esse "vai-um" deve ser desprezado!
Ve
r
(-2)
(+5)
(-1)
(-1)
1 111
1111 +
1111
---1 1110 <-- No overflow! Esse "vai-um" deve ser desprezado!
Observe que nestes exemplos tivemos um vai-um alm do bit mais significativo. Em soma de
nmeros em complemento de 2 isto no suficiente para caracterizar um overflow. Um overflow
apenas ocorrer quando, ao somarmos dois nmeros de mesmo sinal, obtivermos um nmero de
sinal diferente. Desta maneira, no exemplo apresentado, este vai-um a mais deve simplesmente
ser ignorado.
J os exemplos a seguir mostram operaes problemticas.
(+7)
(+7)
81
111
0111 +
0111
---1110 <-- O resultado comea com 1, logo negativo. Absurdo!
10.4.3
in
a
1
(-3) 1101 +
(-6) 1010
---1 0111 <-- O resultado comea com 0, logo positivo. Absurdo!
E a subtrao?
10.5
el
im
Na verdade, a maioria dos computadores no sabe fazer subtrao. O que eles fazem utilizar
um truque para transformar uma subtrao em uma soma.
Por exemplo, a operao 7 5 pode ser reescrita como 7 + (5), ou seja, para realizar a
subtrao basta inverter o segundo nmero (em complemento de 2) e som-lo ao primeiro da
maneira usual.
Ve
r
s
o
Pr
Para representarmos nmeros reais no computador, definimos que uma quantidade de bits do
nmero ser usada para representar a mantissa e o restante o expoente do nmero. Por exemplo,
se dispusermos de 8 bits, podemos definir que os quatro primeiros bits sero a mantissa e os
quatro ltimos sero o expoente, em notao cientfica. Assim, 101010102 = 1, 0 1011 e
101110102 = 1, 1 1011 .
Antes que voc saia dizendo por a que o ideal usar tais nmeros pois podemos representar
nmeros to grandes como 111111112 = 15 1015 , que muito mais que os 216 1 da notao
binria convencional, pense em como representaria o nmero 16110 , j que a maior mantissa
representvel 1,5. Alm disso, como representar 1,1111, j que s dispomos de 4 dgitos na
mantissa?
Alm disso, se representaes de nmeros reais pecam em sua preciso, tambm pecam na
velocidade de processamento. A aritmtica de nmeros binrios muito mais simples que a de
nmeros reais (ou de ponto flutuante, como costumamos dizer na computao). Para manipular
nmeros reais, computadores normalmente precisam de componentes dedicados a este fim e que
tem alto tempo de execuo.
Para saber mais sobre representaes de nmeros em pontos flutuantes visite a URL http:
//en.wikipedia.org/wiki/Floating_point
10.6
Representao de caracteres
A converso de nmeros para o sistema binrio bem simples e intuitiva. No entanto, o computador no trabalha exclusivamente com nmeros. Como por exemplo, iremos armazenar uma
frase do tipo "eu amo programar em C"no nosso pen-drive?
Uma pessoa pode decidir que o a ser o 1, o b ser o 2 e assim por diante. Mas como
outra pessoa que receber a informao saber disso? Para evitar este problema a representao
82
de caracteres como nmeros foi padronizada. Os principais padres existentes so: ASCII,
EBCDIC e Unicode.
ASCII
Outras representaes
el
im
in
a
ASCII, ou American Standard Code for Information Interchange, o padro mais utilizado,
presente em todos os nossos computadores pessoais. Trata-se de uma codificao de caracteres
de oito bits baseada no alfabeto ingls.
A codificao define 256 caracteres (28 ). Desses, 33 no so imprimveis, como caracteres
de controle atualmente no utilizveis para edio de texto, porm amplamente utilizados em
dispositivos de comunicao, que afetam o processamento do texto. Exceto pelo caractere de
espao, o restante composto por caracteres imprimveis.
A Figura 10.1 exibe a tabela ASCII.
A linguagem C prov um atalho para que voc no tenha que recorrer tabela ASCII sempre
que precisar do valor de um caractere: para obter o valor de um caractere qualquer, basta coloclo entre aspas simples. Isto , para verificar se um caracter c uma letra maiscula, por exemplo,
basta efetuar o teste if(c >= A&& c <= Z).
10.7
Pr
Exerccios
10.7.1
s
o
10.7.2
Ve
r
1. 16
2. 45
3. 129
4. 23
5. 1290
10.7.3
Converta os nmeros a seguir para a base decimal:
1. 1616
2. D516
3. 11001011012
83
Ve
r
s
o
Pr
el
im
in
a
10.7. EXERCCIOS
4. 2C0416
5. 111012
10.7.4
Escreva os nmeros a seguir nas representaes sinal-magnitude e complemento de 2 com 8 bits:
84
10.7.5
in
a
1. 16 - 9
2. -45 - 7
3. -12 + 12
el
im
10.7.6
Escreva seu nome na codificao ASCII.
10.8
Laboratrio
Pr
10.8.1
No laboratrio veremos como utilizar a tabela ASCII para imprimir caracteres. Execute o seguinte programa e observe o que ser impresso. Atente para as atribuies!
#include<iostream>
2
int main()
{
int a;
char c;
for(a = 65; a < 91; a++)
{
c = a;
cout << c << endl;
}
return 0;
}
Ve
r
10
s
o
12
14
Voc deve ter observado que os nmeros no foram impressos, e sim as letras de A a Z.
Olhe a tabela na Figura 10.1 e descubra o porqu.
10.8.2
Modifique o programa a seguir para imprimir as letras de a a z, ou seja, as letras minsculas
do alfabeto ingls.
10.8. LABORATRIO
85
10.8.3
Agora faa um programa que leia caracteres informados pelo usurio enquanto ele no pressionar
a tecla ESC. Para cada caractere informado pelo usurio, escreva o nmero correspondente na
tabela ASCII.
10.8.4
Ve
r
s
o
Pr
el
im
in
a
Modifique o programa anterior para que solicite que o usurio entre com letras minsculas de a
a z e imprima na tela, para cada letra, a maiscula correspondente.
Ve
r
s
o
Pr
el
im
in
a
86
in
a
Arranjos Unidimensionais
Captulo 11
el
im
Pr
Fcil, certo? Basta declarar 6 variveis do tipo int, ler seus valores, somar seus valores e dividir
por 6.
Mas e se alterssemos o problema para que, em vez de 6, precisasse ler 10 nmeros? E 100?
Ter muitas variveis distintas com a mesma finalidade no vivel por duas razes:
s
o
difcil de manter: e se voc precisar renomear uma varivel, ter que faz-lo em todas as
variveis;
se precisar aumentar ou diminuir o nmero de variveis, ter que apagar/copiar e renomear.
evita reuso de cdigo: se uma mesma operao precisa ser aplicada a cada varivel, fica
difcil reusar o cdigo desta operao.
A soluo para esta situao o uso de vetores (ou variveis indexadas ou arranjo ou array).
Vetores
Ve
r
11.1
Continuando com nossa analogia da memria do computador com uma planilha eletrnica, um
vetor uma varivel que nomeia diversas clulas contguas da memria do computador. Isto
, de certa forma, enquanto uma varivel int corresponde a uma rea da memria que cabe 1
inteiro, um vetor de 10 int uma varivel que cabe 10 inteiros.
A sintaxe para a declarao esttica de vetores bem simples (em captulos futuros veremos
como declarar vetores dinmicos, isto , que podem variar seus tamanhos).
tipo identificador[tamanho];
Onde
tipo o tipo do dado a ser armazenado em cada posio do vetor;
identificador o nome do vetor;
87
88
O acesso a uma clula, para leitura ou atribuio, feito usando se o identificador seguido
pela posio a ser acessada, entre colchetes ([]). Por exemplo, x[3] = 0 atribui o valor 0
posio de ndice 3 do vetor x. Algo importante a ser observado aqui que a primeira posio
de um vetor de tamanho n tem ndice 0 e a ltima tem ndice n 1.
O exemplo a seguir resolve o problema apresentado na seo anterior usando vetores.
#include<iostream>
2
in
a
#define TAMANHO 10
6
10
int main()
{
int num[TAMANHO];
int soma = 0;
int media;
12
el
im
18
20
media = soma/TAMANHO;
22
cout << "Os valores acima da media " << media << " sao" << endl;
for(int i = 0; i < TAMANHO; i++)
{
if(num[i] > media)
cout << num[i] << endl;
}
14
Pr
16
24
28
s
o
26
return 0;
30
Ve
r
Observe a definio e o uso da palavra TAMANHO no programa. Uma vez definido que
TAMANHO tem o valor 10, o computador substituir toda ocorrncia desta palavra no programa
pelo valor correspondente, antes da compilao.
11.2
Vetores de Caracteres
Vetores podem conter dados de quaisquer tipos. Isto , voc pode declarar vetores de nmeros
reais ou inteiros, caracteres ou booleanos, e at tipos definidos por voc, uma vez que aprenda
como definir novos tipos. Por exemplo, vamos definir um programa que leia um vetor de 10
caracteres e depois o escreva de volta tela.
#include<iostream>
89
#define TAMANHO 10
6
int main()
{
char nome[TAMANHO];
10
cout << "Digite " << TAMANHO << " caracteres: ";
12
24
20
el
im
22
18
return 0;
26
in
a
16
14
#include<iostream>
int main()
{
char nome[TAMANHO];
int i = 0;
s
o
Pr
Agora, s para tornar as coisas mais interessantes, alteremos o programa para que leia at
100 caracteres, mas que pare de l-los to logo um . seja digitado.
11
Ve
r
cout << "Digite ate " << TAMANHO << " caracteres. Para terminar antes
, digite . ";
13
15
17
do
{
19
21
23
25
return 0;
90
29
11.2.1
in
a
Um vetor de caracteres essencialmente uma palavra ou uma frase. Assim, durante a leitura
de um vetor de caracteres dificilmente sabe-se quantos caracteres sero digitados pelo usurio,
por exemplo, quando deseja-se ler o nome de um indivduo. Por este motivo, a maioria das linguagem de programao fornece mtodos especiais de leitura, impresso e manipulao desses
vetores de caracteres, ou como chamaremos agora, strings.
Na linguagem C++, os comandos cout e cin permite imprimir e ler strings de maneira
direta:
#include<iostream>
2
int main()
{
char nome[TAMANHO];
10
el
im
12
Pr
cout << "Digite ate " << TAMANHO << " caracteres. Para terminar
pressione ENTER:";
cin >> nome;
cout << "Os caracteres digitados foram: " << nome << endl;
14
return 0;
16
s
o
Ve
r
Entretanto, o comando cin, no permite, da forma como vimos at agora, a leitura de uma
string que contenha espaos (uma frase, por exemplo). Para que isso seja possvel precisamos
utilizar a funo cin.getline(). Esta funo necessita de dois argumentos: o vetor de caracteres representando a string e o tamanho mximo de caracteres que ser lido. A leitura realizada
at que seja atingido ou nmero mximo de caracteres ou o usurio pressione a tecla ENTER. A
seguir uma modificao do exemplo anterior:
#include<iostream>
int main()
{
char nome[TAMANHO];
10
cout << "Digite seu nome completo. Para terminar pressione ENTER:";
12
cin.getline(nome, TAMANHO);
11.3. EXERCCIOS
91
cout << "Seu nome eh: " << nome << endl;
14
return 0;
16
Exerccios
in
a
11.3
Escreva um programa que leia 10 caracteres e os imprima na ordem inversa quela em que foram
digitados.
el
im
Escreva um programa que leia 10 caracteres e os imprima na ordem inversa quela em que foram
digitados, trocando maisculas e por minsculas e vice-versa.
Pr
Escreva um programa que leia 10 nmeros e calcule e imprima a mdia e desvio padro dos
mesmos. Lembre-se que o desvio padro definido como a raiz quadrada dos quadrados das
diferenas dos valores para a mdia dos valores.
11.4
s
o
Escreva um programa que leia 11 nmeros reais e imprima os valores dos 10 primeiros multiplicados pelo 11-simo. Por exemplo, se os valores digitados foram 1, 2, 3 ,4 ,5 ,6, 7, 8, 9, 10 e 1.1,
ento seu programa deve imprimir 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 e 11.0.
Laboratrio
Ve
r
Escreva um programa que leia 10 caracteres e os imprima na ordem inversa quela em que foram
digitados, trocando maisculas por minsculas e vice-versa.
Escreva um programa que leia 100 caracteres ou at que # seja digitado e os imprima na ordem
inversa quela em que foram digitados.
Escreva um programa que leia um nmero de 2 dgitos na base decimal e imprima o mesmo
nmero na base binria.
92
Escreva um programa que leia e imprima strings at que o usurio digite a palavra fim. Considere que cada string no possui espaos.
Ve
r
s
o
Pr
el
im
in
a
Escreva um programa que leia e imprima strings at que o usurio digite a palavra fim. As
strings podem conter espaos.
in
a
Strings e Funes
Captulo 12
12.1
el
im
Neste captulo veremos algumas funes muito usadas na manipulao de (strings) assim como
definir suas prprias funes que recebem vetores como parmetros.
s
o
Descrio
retorna o tamanho (em caracteres) da palavra passada como argumento.
copia o contedo da segunda string para a primeira.
concatena o texto da segunda string na primeira.
compara duas strings (vide exemplo a seguir).
compara duas strings sem diferenciar maisculas e minsculas.
converte uma string para o inteiro correspondente.
converte uma string para o nmero real correspondente.
Ve
r
Funo
strlen
strcpy
strcat
strcmp
stricmp
atoi
atof
Pr
Quando trabalhamos com strings muito comum a realizao de algumas tarefas como descobrir
o tamanho da palavra digitada pelo usurio, comparar duas palavras para saber a ordem, ou ainda,
concatenar duas palavras em uma nica.
Para isso, a biblioteca string.h fornece algumas funes prontas, como pode ser visto na
tabela 12.1
#include<string.h>
#include<iostream>
int main()
{
char str1[50], str2[50];
int i;
float f;
10
93
94
12
14
16
18
in
a
22
26
28
30
32
34
36
el
im
//comparacao de strings
if(strcmp(str1, str2) == 0)
{
cout << os dois nomes sao iguais. << endl;
}
else if(strcmp(str1, str2) < 0)
{
cout << str1 << vem antes de << str2 << endl;
}
else
{
cout << str2 << vem antes de << str1 << endl;
}
return 0;
24
Pr
38
20
s
o
No uso destas funes, importante manter-se em mente que o espao adequado deve ser
alocado para a string resultante das operaes. Por exemplo, ao se concatenar duas strings de no
mximo 100 caracteres, o resultado ter, no mximo, 200 caracteres.
12.2
Ve
r
As funes descritas acima recebem strings como parmetros. Agora, veremos como definir
suas funes prprias funes que recebem no somente strings, mas vetores de outros tipos de
dados.
A declarao de uma varivel do tipo vetor segue, como j visto, a seguinte forma.
tipo identificador[tamanho];
A declarao de parmetros segue uma sintaxe parecida, no qual o tamanho do vetor no
aparece
tipo identificador[]
Isto ocorre por que, para que a funo seja genrica e opere em qualquer vetor passado, o parmetro no pode ser especificado em cdigo. Assim, a declarao de uma funo que recebe um
vetor como parmetro segue a seguinte receita:
95
12
14
16
in
a
10
el
im
int main()
{
char str[50];
cout << Digite seu primeiro nome:;
cin >> str;
18
22
s
o
Pr
maiusculas(str, 50)
20
Ve
r
Observe que a funo altera a string passada como parmetro, um comportamento diferente
do que acontecei quando uma varivel que no um vetor passada. Este comportamento ser
estudado mais a fundo em captulos posteriores.
Da mesma forma que uma string, um vetor de outro tipo de dados pode ser passado como
parmetro. A funo a seguir, por exemplo, calcula qual o maior inteiro em um vetor de inteiros.
1
#include<iostream>
11
return maior;
13
96
12.3
Exerccios
12.3.1
in
a
O cdigo de Csar uma das mais simples e conhecidas tcnicas de criptografia. um tipo
de substituio na qual cada letra do texto substituda por outra, que se apresenta no alfabeto
abaixo dela um nmero fixo de vezes. Por exemplo, com uma troca de trs posies, A seria
substitudo por D, B se tornaria E, e assim por diante. Implemente um programa que faa uso
desse Cdigo de Csar (3 posies),entre com uma string e retorne a string codificada.
String orig.: a ligeira raposa marrom saltou sobre o cachorro cansado
Nova string : D OLJHLUD UDSRVD PDUURP VDOWRX VREUH R FDFKRUUR FDQVDGR
12.3.2
el
im
Faa um programa que dado uma string, retorne 1 se ela for palndromo e 0 se ela no for
palndromo. Lembrando que:Um palndromo uma palavra que tenha a propriedade de poder ser
lida tanto da direita para a esquerda como da esquerda para a direita. Deve-se obrigatoriamente
utilizar uma string auxiliar e a funo strcmp para fazer a resoluo.
Ex: SUBI NO ONIBUS
ARARA
ANOTARAM A DATA DA MARATONA
12.3.3
12.3.4
Pr
Faa um programa em que troque todas as ocorrncias de uma letra L1 pela letra L2 em uma
string. A string e as letras L1 e L2 devem ser fornecidas pelo usurio.
s
o
Altere os programas anteriores para que contenham funes que resolvam os problemas propostos.
12.3.5
Ve
r
12.3.6
Faa um programa com uma funo que receba um vetor de inteiros e um inteiro X, e que retorne
como resultado o maior inteiro do vetor que menor que o inteiro X.
12.3.7
Usando a resposta do problema anterior, faa um programa com uma funo que receba dois
vetores de inteiros, e que faa com que o segundo torne-se uma cpia do primeiro, ordenado de
forma decrescente.
Captulo 13
Funes Matemticas
el
im
13.1
in
a
Funes teis I
s
o
Pr
Descrio/Exemplo
valor absoluto do argumento. Ex: int x = abs(-9);
seno do argumento (em radianos). Ex: double x = sin(3.14159);
cosseno do argumento (em radianos). Ex: double x = cos(3.14159);
tangente do argumento (em radianos). Ex: double x = tan(3.14159);
arco cujo seno passado como argumento. Ex: double x = asin(1);
arco cujo cosseno passado como argumento. Ex: double x = acos(1);
arco cuja tangente passada como argumento. Ex: double x = atan(sqrt(2)/2);
piso do valor passado como argumento. Ex: double x = floor(3.2); //=3
teto do valor passado como argumento. Ex: double x = floor(3.2); //=4
arredonda o argumento para o inteiro mais prximo. Ex: double x = round(9.9); //=10
eleva o primeiro argumento ao expoente no segundo. Ex: double x = pow(2,3); //=8
retorna a raiz quadrada do argumento. Ex: double x = sqrt(169); //=13
retorna logaritmo natural do argumento.
retorna log. do argumento na base 10.
retornar log do argumento na base 2
Ve
r
Funo
abs
sin
cos
tan
asin
acos
atan
floor
ceil
round
pow
sqrt
log
log10
log2
Alm das funes em math.h, duas outras funes, da biblioteca stdlib.h, so particularmente interessantes na manipulao de nmeros. Estas funes so apresentadas na Tabela 13.2.
A funo rand() utiliza para gerar nmeros aleatrios. Um nmero aleatrio gerado
internamente pelo computador aplicando-se operaes aritmticas que o usurio desconhece a
partir de um valor inicial chamado de semente. O valor dessa semente definido com a funo
srand(). O exemplo a seguir imprime na tela 30 nmeros aleatrios.
97
98
Funo
rand
srand
Descrio/Exemplo
retorna um nmero aleatrio (biblioteca stdlib.h)
define a semente para a gerao de nmeros aleatrios por rand (biblioteca stdlib.h)
#include<stdlib.h>
#include<time.h>
. . .
int main()
{
for (int i = 0; i < 10; i++)
{
cout << rand() << endl;
}
10
el
im
in
a
12
14
18
20
22
24
Pr
//Configuracao da semente
//com valor que depende da hora atual.
//Isto garante maior aleatoriedade
srand(time(NULL));
for (int i = 0; i < 10; i++)
{
cout << rand() << endl;
}
return 0;
16
s
o
Ve
r
int main ()
{
int iSecret, iGuess;
11
13
15
13.2. EXERCCIOS
99
17
do {
printf ("Guess the number (1 to 10): ");
cin >> iGuess;
if (iSecret<iGuess) puts ("The secret number is lower");
else if (iSecret>iGuess) puts ("The secret number is higher");
} while (iSecret!=iGuess);
19
21
23
puts ("Congratulations!");
return 0;
25
13.2
in
a
27
Exerccios
el
im
13.2.1
Faa um programa que leia os catetos de um tringulo e imprima o valor de sua hipotenusa.
Utiliza as funes aritmticas.
13.2.2
Ve
r
s
o
Pr
O valor de
pela srie:
Ppode ser dado
4
= n=0 (1)n 2n+1
Faa uma funo chamada pi que recebe o valor de n e retorna o valor calculado de acordo
com a funo informada. A funo principal deve ler o valor de n, invocar a funo pi e
imprimir o resultado.
Ve
r
s
o
Pr
el
im
in
a
100
Captulo 14
in
a
14.1
Declarao e Iniciao
el
im
Pr
tipo identificador[tamanho];
A declarao de uma varivel do tipo matriz tem uma forma semelhante, apenas aumentando
uma segunda dimenso ao arranjo, como a seguir.
s
o
tipo identificador[tamanho1][tamanho2];
Assim, uma declarao como
1
int matriz[10][20];
Ve
r
declara uma matriz de 10 linhas por 10 colunas, cujas clulas so nmeros inteiros.
A matriz pode ser iniciada como em arranjos unidimensionais, colocando-se os valores do
elemento dentro de chaves aps a declarao da matriz. Os valores para cada linha devem ficar
dentro de chaves prprias e so separados por vrgula:
2
5
3
6
1 A bem da verdade, possvel representar qualquer matriz finita como um arranjo unidimensional, mas
a complexidade muito maior em relao ao uso de arranjos multidimensionais.
101
102
14.1.1
O acesso s clulas feito tambm como em arrajos unidimensionais, exceto que ambas as coordenadas devem ser especificadas. O exemplo seguir mostra a criao, iniciao, e impresso
dos elementos de uma matriz bidimensional.
1
#include<iostream>
#define M 5
#define N 10
in
a
int main()
{
int m[M][N];
11
cout << "Digite o valor dos elementos de uma matriz " << M << " por
" << N;
for(int i = 0; i < M; i++)
for(int j = 0; j < N; j++)
{
cout << i << "," << j;
cin >> m[i][j];
}
el
im
13
15
17
19
Pr
23
25
29
s
o
27
Observe que tanto na leitura como impresso da matriz, o lao mais externo percorre as
linhas. Para cada valor da varivel i, a varivel j, dentro do lao interno percorre os valores de
0 a N. Desta maneira, a matriz lida e impressa linha a linha.
Observe a impresso. Para que serve o comando cout<<endl;?
Ve
r
31
14.2
Matrizes de Caracteres
Da mesma forma que vetores de caracteres podem ser manipuladas de forma especial no C(++),
tambm podem as matrizes de caractere. Na verdade, se um vetor de caracteres o que chama-se
de uma string, ento uma matriz bidimensional de caracteres , na verdade, um vetor de strings.
Por exemplo,
char nomes[10][20];
103
pode ser visto como um vetor de 10 strings, cada uma com 20 caracteres, e cada string pode ser
manipulada como tal, como no exemplo a seguir.
1
#include<iostream>
#define M 10
#define N 11
int main()
{
char m[M][N];
in
a
11
17
cout << "Digite " << M << " palavras de no maximo " << N-1 << "
caracteres" << endl;
for(int i = 0; i < M; i++)
{
cout << i << ": ";
cin >> m[i];
}
19
21
13
23
14.3
s
o
25
Pr
el
im
15
Mais Dimenses
Ve
r
Agora voc j deve ter deduzido que para adicionar mais dimenses aos seus arranjos, basta
colocar esta dimenso na declarao dos mesmos. Por exemplo, o seguinte trecho de cdigo
declara um arranjo com trs dimenses, em que cada clula um inteiro.
char matriz[100][100][100];
Outra forma de ver tal arranjo como um livro com vrias pginas, em que cada uma
uma matriz bidimensional.
14.4
Multiplicao de Matrizes
Agora que voc viu alguns exemplos de declaraes de arranjos multidimensionais, vejamos
alguns usos reais, como a j mencionada multiplicao de matrizes.
Sejam duas matrizes A e B, tal
A tem dimenses m n e B, n o; ento, a matriz AB
Pque
m
tem dimenses m o, e Ci , j = k=1 Am,n Bn,o .
104
int main()
{
int soma = 0, m, n, o;
int a[100][100], b[100][100], ab[100][100]; //m,n e 0 precisam ser
menores que 100.
11
13
el
im
in
a
//ler as dimensoes
cout << "Quais as dimensoes das matrizes?";
cin >> m >> n >> o;
15
17
19
21
Pr
23
25
27
29
ab[i][j] = sum;
sum = 0;
s
o
31
33
Ve
r
Observe que fizemos nosso cdigo de manipulao da matriz dentro da funo main. Fizemos isso por que usar matrizes como parmetro bem mais complicado do que vetores unidimensionais. Contudo, no se aflija, pois veremos isso logo a seguir.
14.5
Exercicios
14.5.1
Escreva uma programa que leia e some duas matrizes, e imprima o resultado.
14.5.2
Escreva um programa que leia uma matriz e diga se ela a matriz identidade ou no.
14.5. EXERCICIOS
105
14.5.3
Ve
r
s
o
Pr
el
im
in
a
Ve
r
s
o
Pr
el
im
in
a
106
Captulo 15
Introduo
el
im
15.1
in
a
Como voc j percebeu, arranjos multimensionais so muito divertidos. Neste captulo, veremos
alguns tpicos mais avanados em seu uso.
15.2
Pr
Vimos que, ao passar vetores para uma funo, no era necessrio especificar o nmero de elementos no vetor. Em matrizes bidimensionais, no necessrio especificar o nmero de linhas
na matriz, apenas o nmero de colunas. O programa a seguir usa a funo exibeMatriz para
exibir o contedo de matrizes bidimensionais:
#include <iostream>
#define ncol 10
Ve
r
s
o
10
12
14
16
18
20
int main()
{
int a[1][10] = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};
22
24
107
108
26
28
exibeMatriz(a, 1);
exibeMatriz(b, 2);
exibeMatriz(c, 3);
return 0;
30
32
34
in
a
15.3
el
im
#include <iostream>
#define ncol 10
s
o
Pr
Uma matriz bidimensional pode ser utilizada sem precisar acessar os elementos em suas posies
de linha ou coluna. Ela pode ser tratada como se tivesse uma nica dimenso. O programa a
seguir calcula a soma dos valores em uma matriz bidimensional, inicialmente utilizando as duas
dimenses e em seguida da mesma forma que com vetores.
Ve
r
11
return soma;
13
15
17
19
21
23
}
25
27
int main()
{
int a[10] =
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
29
31
37
39
cout <<
<<
cout <<
<<
cout <<
<<
cout <<
<<
cout <<
<<
cout <<
<<
in
a
35
45
47
49
el
im
41
43
51
return 0;
}
Pr
53
33
s
o
Observe que a funo somaMatrizUni recebe como argumento o total de elementos e percorre a matriz da mesma forma que um vetor. Isto pode ser feito porque na memria do computador a matriz armazenada como um vetor de nlinha ncolunas elementos. A funo
somaMatrizBi recebe o nmero de linhas e faz a mesma soma utilizando as duas dimenses.
Uma vez que a matriz multidimensional pode ser acessada como unidimensional, voc pode
criar funes que recebam uma matriz unidimensional e passar, como parmetro, todas as suas
dimenses. Internamente a esta funo, a matriz pode ser percorrida usando-se as dimenses e
um pouco de aritmtica bsica.
Ve
r
#include <iostream>
2
10
12
}
14
16
int main()
{
int a[10] =
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
110
18
20
22
24
26
in
a
30
32
34
return 0;
}
15.4
Exerccios
15.4.1
el
im
36
28
15.4.2
Pr
Escreva uma funo que receba como parmetro uma matriz bidimensional e suas dimenses, e
que incremente cada elemento da matriz em 10%.
Ve
r
s
o
Altere a funo do exerccio anterior para que receba como parmetro uma matriz tridimensional
e suas dimenses, e que incremente cada elemento da matriz em 10%.
Introduo
el
im
16.1
in
a
Ordenao de Arranjos
Captulo 16
Pr
Uma das aplicaes mais estudadas e realizadas sobre arranjos a ordenao. Ordenar um
arranjo significa permutar seus elementos de tal forma que eles fiquem em ordem crescente, ou
seja, v[0] <= v[1] <= v[2] <= . . . <= v[n 1]. Por exemplo, suponha o vetor
v = 5, 6, 9, 9, 0, 4.
Uma ordenao desse vetor resultaria em um rearranjo de seus elementos:
v = 9, 0, 4, 5, 6, 9.
Exitem diversos algoritmos de ordenao para vetores. Eles variam em relao dificuldade
de implementao e desempenho. Usualmente algoritmos mais fceis de serem implementados
apresentam desempenho inferior. Veremos 3 algoritmos diferentes de ordenao:
1. Algoritmo de Insero (Insertion Sort);
s
o
Algoritmos de Ordenao
Ve
r
16.2
16.2.1
Trata-se de um dos algoritmos de implementao mais simples. Seu mtodo de ordenao semelhante ao que usamos para ordenar as cartas de um baralho. A idia bsica do algoritmo
descrita a seguir:
Compare a chave (x) com os elementos sua esquerda, deslocando para direita cada
elemento maior do que a chave;
Insira a chave na posio correta sua esquerda, onde os elementos j esto ordenados;
Repita os passos anteriores atualizando a chave para a prxima posio direita at o fim
do vetor.
A figura 16.1 apresenta um exemplo de uma etapa da execuo do algoritmo.
O cdigo a seguir implementa o algoritmo em C, considerando um vetor v de tamanho n.
111
112
10
12
14
in
a
el
im
16.2.2
Pr
A implementao deste mtodo de ordenao muito simples. A idia bsica descrita a seguir:
s
o
Ve
r
113
min = i;
for(j = i+1; j < n; j++)
{
if(v[j] < v[min])
{
min = j;
}
}
aux = v[i]; v[i] = v[min]; v[min] = aux; //troca
11
13
15
el
im
16.2.3
in
a
Outro algoritmo simples, muito til para ordenao de vetores pequenos, mas no indicado para
vetores maiores devido ao seu baixo desempenho computacional. Sua dia bsica apresentada
a seguir:
Pr
s
o
Ve
r
10
12
14
el
im
in
a
114
Exerccios
16.3.1
Pr
16.3
s
o
16.3.2
Ve
r
16.3.3
r
in
a
el
im
Parte II
Ve
r
s
o
Pr
Intermedirio
115
s
o
Ve
r
in
a
el
im
Pr
Introduo
el
im
17.1
in
a
Estruturas No-Homogneas
Captulo 17
Declarao
Ve
r
17.2
s
o
Pr
Imagine que voc deseje armazenar informaes sobre um funcionrio de uma empresa. Entre
estas informaes podemos ter, por exemplo, nome, endereo, telefone, sexo, estado civil, cargo,
setor e salrio. Em um programa, isto seria representado por oito variveis apenas para um funcionrio. Se voc desejar incluir mais informaes, isto implicar em mais variveis, aumentando
a complexidade do programa.
Por esta razo, em muitas aplicaes, importante a capacidade de se tratar todas as informaes de uma entidade (uma pessoa, por exemplo), como sendo uma nica unidade de armazenamento, ou seja, uma nica varivel. Por outro lado, deve ser possvel, que esta nica varivel
permita acesso a cada informao em separado. Outros exemplos de informao com esta caracterstica o endereo, que pode ser decomposto em: logradouro, nmero, complemento, CEP,
cidade, estado, pas.
Neste tipo de informao possvel observar que, diferentemente de variveis indexadas
(vetores e matrizes), no h homogeneidade quanto ao tipo de dados tratado. Por isso, deve haver um mecanismo para trabalhar com variveis estruturadas heterogneas, tambm conhecidas
simplesmente como estruturas ou structs.
117
118
struct endereco {
char logradouro[15];
int numero;
char complemento[6], bairro[10];
char cidade[10], estado[3], pais[10];
};
...
struct endereco e1, e2, e3;
17.2.1
in
a
O uso da palavra reservada struct obrigatrio na declarao de variveis, pois ela faz
parte do tipo da varivel. O uso repetido desta palavra reservada pode poluir o cdigo, e por
essa razo recomenda-se a definio de novos tipos baseados na estrutura.
typedef
el
im
A palavra chave typedef permite que se defina novos tipos de dados a partir de tipos j existentes. Por exemplo, possvel definir um tipo numero_real ou um tipo caractere. A sintaxe
para o uso typedef a seguinte:
typedef tipo_antigo tipo_novo;
Pr
struct end{
char logradouro[15];
int numero;
char complemento[6], bairro[10];
char cidade[10], estado[3], pais[10];
};
...
typedef end endereco;
Ve
r
s
o
Mais importante, possvel definir um tipo basedo na estrutura. Neste caso, h duas formas
de faz-lo. O exemplo a seguir mostra a mais verborrgica.
10
Embora mais explcita, esta forma no usada normalmente, em funo forma mais compacta a seguir.
typedef struct{
char logradouro[15];
int numero;
char complemento[6], bairro[10];
char cidade[10], estado[3], pais[10];
} endereco;
...
119
17.3
10
12
14
17.4
el
im
//Atribuicao na iniciacao.
//Atribuicao...
//... campo a ...
//... campo.
//Copia de valores de todos os campos.
Pr
Exemplo
s
o
in
a
Embora as estruturas agreguem vrios campos, com raras excees, o manuseio da mesma deve
ser feito campo a campo, como variveis normais. Para acessar um dos campos de uma estrutura,
usa-se o operador . (ponto). Diferentemente de variveis indexadas, variveis do tipo estrutura
podem receber o valor de outra do mesmo tipo (desde que nenhum dos campos seja vetor). Por
exemplo:
Ve
r
typedef struct{
float real, imag;
} complexo;
10
12
14
16
int main() {
int i, j;
complexo A[3][3] = {
{ {1.0, -0.1}, {2.0, -0.2}, {2.0, -0.2} }, //real
{ {4.0, -3.4}, {5.0, 4.1}, {6.0, -2.6} }
//imag
};
for ( i= 0; i < 3; i++) {
for (j = 0; j < 3; j++)
120
18
}
return 0;
20
Exerccios
17.5.1
in
a
17.5
Faa um programa que leia informaes sobre 15 pessoas. Essa informao deve ficar em um
vetor de variveis do tipo estruturado pessoa, o qual deve conter as seguintes informaes:
Nome: string de tamanho 30;
Idade: valor inteiro;
el
im
Estado Civil: tipo enumerativo com os valores solteiro, casado, separado, vivo.
Salrio: valor real.
Pr
17.5.2
s
o
Faa um programa que leia o nome, duas notas e nmero de faltas de 10 alunos. As informaes
desses alunos devem ser armazenadas em um vetor de variveis do tipo estruturado aluno, o
qual deve conter as seguintes informaes de cada aluno:
Nome: string de tamanho 30;
Mdia: nmero real resultado da mdia das duas notas lidas;
Situao: caractere representando situao, isto , A (Aprovado), se mdia maior ou
igual a 6 e nmero de faltas menor que 10, e R (Reprovado), caso contrrio.
Ve
r
17.6
Laboratrio
Primeiramente, implemente sua soluo para o exerccio anterior. Em seguida, implemente duas
funes, que ordenem os dados das pessoas por Nome e Idade, e imprimam todos os dados na
tela. Finalmente, demonstre o uso destas funes.
Captulo 18
in
a
Referncias
18.1
el
im
O uso da analogia da memria do computador com uma planilha eletrnica nos permitiu entender como variveis simples e tambm arranjos so alocados em nossos programas. Agora que
j conhecemos vetores, usaremos uma analogia mais precisa para entendermos referncias, ou
como so mais popularmente conhecidas, os famigerados ponteiros.
Ve
r
s
o
Pr
A memria de um computador pode ser vista como um grande vetor de bytes. O primeiro byte
denominado byte 0, o segundo, byte 1 e assim por diante at o tamanho da memria disponvel
ao seu programa.
Quando em seu programa voc, por exemplo, declara uma varivel do tipo caractere (char)
com o nome c, o compilador separa um byte da memria, digamos o byte 7542, e passa a chamlo de c. Assim, toda vez que se referir varivel c em seu programa, o computador sabe que
est se referindo ao byte 7542. Neste caso, dizemos que o endereo da varivel c 7542.
Similarmente, quando voc aloca uma varivel do tipo inteiro, o compilador reserva quatro
bytes para voc, digamos, os bytes 8012, 8013, 8014 e 8015. Tal varivel tem o endereo 8012
(como os tipos tem sempre tamanho fixo, o endereo do primeiro byte mais a informao sobre
o tipo da varivel suficiente para o computador determinar de onde at onde na memria cada
varivel fica armazenada).
Finalmente, quando voc aloca um vetor de tamanho n de algum tipo qualquer, o compilador
reserva um espao de tamanho n t, onde t o tamanho do tipo em questo. Se so 10 inteiros,
por exemplo, ento o vetor ter tamanho 40 bytes. O endereo desta varivel o endereo do
primeiro byte da primeira clula. Assim, quando voc, por exemplo, acessa a posio 5 de um
vetor de inteiros cujo endereo 1000, o computador faz o seguinte clculo para determinar a
posio de memria que voc est acessando, sabendo que cada inteiro ocupa 4 bytes: 1000 +
5 4.
18.2
Em certas situaes, o poder de se referir a posies de memria pelo seus endereos em vez de
por um nome de varivel muito til. Por exemplo, imagine que precisemos calcular uma srie
de estatsticas sobre os dados em um vetor. Neste caso, gostaramos de definir uma funo que
121
122
*identificador;
in
a
tipo
analisasse o vetor e desse como resultados as vrias estatsticas, como mdia, desvio padro, varincia, intervalo de confiana etc. Entretanto, como bem sabemos, funes em C(++) retornam
um nico resultado. Se, contudo, pudssemos passar como parmetro para a funo as referncias de onde gostaramos que os resultados fossem colocados, ento a funo poderia coloc-los
diretamente nestas posies de memria. Esse mecanismo o que chamamos de passagem de
parmetro por referncia.
Antes de se poder exercitar a passagem de parmetros por referncia, contudo, precisamos
aprender a declar-las, a obter referncias para posies de memria, e a usar tais referncias.
Estas operaes so feitas pelos operadores * e &. A declarao de variveis segue a seguinte
sintaxe:
Assim, para se declarar variveis de referncia para uma posies de memria que armazenam um inteiro, um caractere, e um float, voc usaria as seguintes declaraes:
int *ref_int;
char *ref_char;
float *zabumba;
el
im
Pr
s
o
declara duas referncias para inteiro (a e c), e um inteiro (b). Para se evitar confuses, sugere-se
que no se declare variveis do tipo referncia e no referncia em conjunto. Ou seja, a cdigo
acima deveria ser reescrito como
int *a, *c;
int b;
Ve
r
O operador & permite que se extraia o endereo (ou uma referncia) de uma varivel. No
cdigo,
int *a;
int b;
a = &b;
a recebe o endereo da varivel b. Logo, se b est nos bytes 2012, 2013, 2014 e 2015, a varivel
123
int *a;
int b;
int c;
a = &b;
*a = 20;
c = *a;
c++;
el
im
18.3
in
a
a varivel b termina com o valor 20, enquanto que a varivel c termina com o valor 21.
Variveis do tipo referncia, como outros tipos de variveis, podem ser passadas como parmetro
em chamadas de funo. A grande vantagem desta tcnica, tambm conhecida como passagem
de parmetros por referncia, a possibilidade de modificao da memria para qual a referncia
foi passada. Por exemplo, analise o seguinte cdigo.
#include<iostream>
#include<cmath>
10
s
o
12
14
Pr
int main()
{
float v = 0, s, c, t;
Ve
r
16
18
cout << "seno: " << s << " cosseno: " << c << " tangente: "<< t;
20
return 0;
22
Esse programa calcula em uma nica chamada, os valores do seno, cosseno e tangente da
varivel v. Enquanto o feito no parece muito impressionante, pense no caso em que voc precisa
calcular diversas estatsticas de um vetor de nmeros. Neste caso, devido forte dependncia do
clculo de uma estatstica no clculo de outras, esta funo poderia simplificar em muito o seu
cdigo.
124
18.4
Laboratrio
18.4.1
Escreva um programa que contenha funes que calculam a mdia, varincia e desvio padro de
um vetor de nmeros reais (uma funo por dado estatstico).
18.4.2
Ve
r
s
o
Pr
el
im
in
a
Altere o programa do exerccio anterior para que calcule as trs estatsticas em uma funo
apenas, reaproveitado os clculos uns dos outros.
Captulo 19
in
a
Referncias II
19.1
el
im
Continuando com o estudo de ponteiros, vamos ver como utiliz-los para referenciar estruturas
e arranjos.
typedef struct
{
int i;
char c;
float j;
} exemplo1;
s
o
Pr
Ve
r
Para responder a esta pergunta precisamos entender que uma estrutura ocupa espao equivalente soma do espao ocupado por cada um de seus campos. Desta forma, o espao total
ocupado por uma varivel do tipo exemplo1 ser a soma dos tamanhos de 1 int, 1 char e 1
float, ou seja, 4 + 1 + 4 = 9 bytes.
Assim, e voc cria uma varivel exemplo1 v[10], o compilador deve reservar um espao
de 10 9 = 90 bytes.
Assim como nos referimos a variveis dos tipos primitivos (inteiro, real, caractere) utilizando
ponteiros, podemos tambm utilizar ponteiros para acessar uma varivel do tipo struct e seus
campos. Veja o exemplo para a estrutura declarada anteriormente.
125
126
el
im
in
a
Este trecho mostra na linha 1 a criao de duas variveis do tipo exemplo1 e na linha 2 a
criao de uma varivel do tipo ponteiro para exemplo1. As linhas 3 e 5 atualizando o ponteiro,
fazendo com que referencie as variveis a e b, respectivamente. Desta maneira, a linha 4 ir
imprimir o valor de a.i, enquanto a linha 6 ir ler a partir do teclado um valor para b.c.
Quando usamos ponteiros e estruturas, aparece o incoveniente de termos que digitar toda vez
entre parnteses a varivel do tipo ponteiro ((*p).c). Para simplificar a utilizao de ponteiros
no acesso a campos de uma estrutura, a linguagem C permite escrever esta mesma instruo de
uma maneira mais fcil de digitar: p->c. O cdigo anterior pode ser reescrito como:
Por fim, a passagem de estruturas por referncia em funes auxiliares feita da mesma
forma que vimos no captulo anterior:
10
12
14
16
int main()
{
exemplo1 a = {1, a, 1.0}, b = {2, b, 2.0};
inverte_structs(&a, &b);
cout << a.i << ", " << a.c << "," << a.j << endl;
cout << b.i << ", " << b.c << "," << b.j << endl;
return 0;
}
Ve
r
18
Pr
s
o
20
A funo auxiliar troca os valores de duas variveis do tipo exemplo1 passadas por referncia. Aps a invocao da funo auxiliar a partir da main os valores iniciais das variveis a e b
sero trocados.
19.2
Arranjos e Ponteiros
At agora vimos vetores sem nenhuma relao com ponteiros. No fundo, quando criamos um
vetor com a instruo int a[10], estamos dizendo ao compilador para reservar na memria
127
espao para 10 inteiros (40 bytes) e armazenar o endereo em que comea o vetor na varivel a.
Em outras palavras, a varivel a um ponteiro para o primeiro elemento do vetor.
Por esta razo, a relao entre vetores e ponteiros mais direta e mais fcil de utilizar. Uma
vez que a varivel que usamos contm o endereo do comeo do vetor, um ponteiro pode receber
diretamente seu valor, sem necessidade do operador &. Considere o exemplo a seguir:
float a[10];
float *p;
p = a;
cout << "Digite 10 numeros reais: ";
for(int i = 0; i < 10; i++)
cin >> a[i];
cout << "Num. digitados: ";
for(int i = 0; i < 10; i++)
cout << p[i];
in
a
Pr
19.2.1
el
im
J sabemos a relao entre ponteiros e vetores. Veremos a seguir algumas maneiras diferentes
de acessar os elementos de um vetor utilizando ponteiros. Considere o trecho de um programa a
seguir:
Ve
r
char str[100];
char *s;
int totalletras = 0;
s = str;
cout << "entre uma frase com letras minusculas" << endl;
cin.getline(s,100);
for(int i = 0; i < strlen(s); i++)
{
if(s[i] >= a && s[i] <= z)
{
totalletras++;
}
}
cout << "O total de letras da frase eh " << totalletras;
s
o
10
12
14
Neste trecho utilizamos o ponteiro s como o vetor str, pois a partir da linha 3 ele aponta
para o vetor. Este mesmo trecho pode ser reescrito:
2
char str[100];
char *s;
int totalletras = 0;
s = str;
cout << "entre uma frase com letras minusculas" << endl;
128
6
10
12
cin.getline(s,100);
for(int i = 0; i < strlen(s); i++)
{
if( *(s+i) >= a && *(s+i) <= z )
{
totalletras++;
}
}
cout << "O total de letras da frase eh " << totalletras;
14
in
a
Observe a linha 9 de cada um dos dois trechos anteriores e veja a diferena na notao.
Quando utilizamos ponteiro, podemos acessar um vetor pelo ndice (colchetes) ou por um deslocamento sobre o valor do endereo inicial do vetor armazenado em s, ou seja, a notao *(s+i),
significa o caractere localizado i caracteres a partir do caractere na primeira posio do vetor.
O mesmo trecho pode ser reescrito ainda de uma terceira forma:
10
12
s
o
14
el
im
char str[100];
char *s;
int totalletras = 0;
s = str;
cout << "entre uma frase com letras minusculas" << endl;
cin.getline(s,100);
for(int i = 0; i < strlen(str); i++) //Observe que aqui usamos str e
nao s. Por que?
{
if( *s >= a && *s <= z )
{
totalletras++;
}
s++;
}
cout << "O total de letras da frase eh " << totalletras;
Pr
Qual a diferena entre esta verso e as verses anteriores? Qual a diferena entre s++ e
Ve
r
19.3
Laboratrio
19.3.1
Crie uma estrutura com os campos nome, idade e salario dos tipos string, inteiro e real, respectivamente.
Em seguida, crie uma funo que receba referncias para duas variveis de tal tipo e uma
varivel correspondente a uma porcentagem de aumento que deve ser aplicada sobre o campo
salrio de cada estrutura. A funo principal deve ler cada campo das duas variveis e imprimir
o novo salrio.
Finalmente, crie uma funo que recebe duas variveis de tal tipo e que troque os valores de
todos os campos das duas estruturas. A funo principal deve agora imprimir as estruturas antes
e depois da troca.
19.3. LABORATRIO
129
19.3.2
Ve
r
s
o
Pr
el
im
in
a
Execute as trs verses do programa da seo 19.2.1 e veja se h diferena no resultado. Responda s perguntas no final da seo.
Ve
r
s
o
Pr
el
im
in
a
130
in
a
Alocao Dinmica
Captulo 20
Pr
20.1
el
im
Por mais interessante que seja poder criar ponteiros para variveis j existentes e passar parmetros por referncia, o poder dos ponteiros s fica mesmo evidente quando se trabalha com
alocao dinmica de memria.
Alocao dinmica a habilidade de se criar novas variveis durante a execuo do programa, sem que elas tenham sido declaradas antes. Justamente por no terem sido declaradas
antes da compilao, estas variveis alocadas dinamicamente no tm nomes e, assim, s podem
ser acessadas por meio de referncias.
char *s1;
int *i1;
float *f1;
Ve
r
s
o
Existem vrias formas de se alocar memria dinamicamente, todas elas via funes que retornam
como resultado uma referncia para o comeo da memria alocada, na forma de uma referncia
genrica.
A funo mais simples para alocao de memria a malloc. Esta funo recebe como
nico parmetro o tamanho da memria a ser alocada, em bytes. Observe o seguinte cdigo para
alguns exemplos.
s1 = (char *) malloc(1);
i1 = (int *) malloc(4);
f1 = (float *) malloc(4);
No exemplo acima voc percebe que antes de cada malloc h, entre parnteses, o tipo da
varivel que guardar a referncia. Isso o que chamamos de casting, e serve para transformar
a referncia genrica retornada pela funo para o tipo de referncia da varivel. Este casting
obrigatrio em seu cdigo.
Voc tambm percebe que cada alocao especifica exatamente o tamanho do tipo para o
qual estamos alocando a memria. Isto , 1 para caracteres e 4 para inteiros e nmeros reais.
Estes tamanhos, contudo, podem variar de uma mquina/sistema operacional para outra, o que
tornaria complicado especificar tais tamanhos em cada invocao malloc. por isso que a
131
132
linguagem C(++) especifica o construto sizeof, que descobre o tamanho do tipo para voc,
conforme o seguinte exemplo.
s1
i1
f1
d1
=
=
=
=
(char *) malloc(sizeof(char));
(int *) malloc(sizeof(int));
(float *) malloc(sizeof(float));
(double *) malloc(sizeof(double));
20.2
char *s1;
int *i1;
float *f1;
double *d1;
in
a
el
im
Como visto nos captulos anteriores, a diferena entre referncias para tipos simples e vetores
... nenhuma! Isso quer dizer que podemos alocar vetores usando um cdigo similar ao anterior,
alterando apenas a quantidade de memria alocada, como no seguinte exemplo.
char *s2;
int *i2;
float *f2;
double *d2;
11
13
15
17
cin.getline(s2,100);
cout << s2;
Ve
r
19
=
=
=
=
Pr
s2
i2
f2
d2
s
o
21
23
25
27
29
31
20.3
133
Liberao de memria
Todos os exemplos mostrados at agora neste captulo so incompletos. Isso por qu nenhum
programa que faa alocao dinmica em C(++) pode ser completo sem que se faa a liberao
da memria alocada. Liberar ou desalocar a memria consiste simplesmente na invocao da
funo free, passando-se como parmetro a referncia a ser desalocada. O uso de free ser
exemplificado na prxima seo.
in
a
20.4
10
12
14
#define NUM_PESSOAS 10
typedef struct
{
char prim_nome[20],
char ult_nome[20],
int idade,
float salario,
char regiao,
char sexo
} pessoa_t;
int main()
{
pessoa_t *pessoas;
Pr
el
im
Assim como declarar uma referncia para uma estrutura to simples quanto declarar uma referncia para um tipo primitivo(simples), alocar um vetor de estruturas dinamicamente to
simples quanto alocar um vetor de tipos primitivos dinamicamente. O exemplo a seguir mostra
exatamente como alocar um vetor com 10 estruturas do tipo definido.
18
for(int
{
cin
cin
cin
cin
cin
cin
}
20
pessoas[i].prim_nome;
pessoas[i].ult_nome;
pessoas[i].idade;
pessoas[i].salario;
pessoas[i].sexo;
pessoas[i].regiao;
Ve
r
22
s
o
16
24
26
28
30
//Liberacao da memoria
free(pessoas);
32
return 0;
34
134
20.5
Exerccios
20.5.1
Escreva um programa que leia um numero inteiro N, aloque dinamicamente um vetor de N
inteiros, leia cada um dos N inteiros, e imprima os N inteiros na tela.
20.5.2
Laboratrio
20.6.1
Implemente os exerccios acima.
20.6.2
el
im
20.6
in
a
Escreva um programa que repita o seguinte procedimento X vezes: leia um numero inteiro N,
aloque dinamicamente um vetor de N carateres, leia uma palavra de N caracteres, transforme
todas as maisculas em minsculas e vice-versa na palara e imprima o resultado na tela. X deve
ser lido no incio da execuo do programa.
Ve
r
s
o
Pr
1 Se tudo funcionar, aumente o vetor para 1000000 e assim por diante. O objetivo neste laboratrio
mostrar que a quantidade de memria disponvel para seu programa limitada, e que se extrapolada, seu
programa incorrer em um erro.
Captulo 21
el
im
in
a
Arquivos
Pr
Muitas vezes desejamos guardar o resultado de alguma computao para consulta posterior.
Imagine, por exemplo, que voc fez um programa que calcula a mdia final e situao de toda
a turma. Se o resultado deste processamento no puder ser armazenado, toda vez que for necessrio consultar a situao de algum aluno, o programa dever ser executado e todos os dados
inseridos novamente. Para solucionar este problema, o usurio pode salvar resultados de computao em uma estrutura persistente. Esta estrutura de dados manipulada fora do ambiente do
programa (memria principal) conhecida como arquivo.
Um arquivo armazenado em um dispositivo de memria secundria (CD, DVD, disco
rgido, pendrive) e pode ser lido ou escrito por um programa. Em C, um arquivo pode representar
diversas coisas, como documentos, uma impressora, um teclado, ou qualquer dispositivo de
entrada ou sada. Consideraremos apenas dados em disco, iniciando por dados na forma textual.
Arquivos de texto
s
o
21.1
Ve
r
Nesta seo estudaremos apenas arquivos texto, ou seja, arquivos que contm apenas caracteres
e podem ser visualizados em editores de textos como Notepad, Gedit, Vim, etc.
A linguagem C++ d suporte utilizao de arquivos por meio da biblioteca fstream. Esta
biblioteca fornece vrias funes para manipulao de arquivos e define alguns tipos de dados
para serem usados especificamente com arquivos. O principal tipo definido nessa biblioteca que
ser usado o tipo fstream. Um varivel do tipo fstream capaz de identificar um arquivo no
disco, direcionando-lhe todas as operaes. Essas variveis so declaradas da seguinte maneira:
fstream arq;
21.1.1
Antes que o arquivo seja manipulado, preciso abr-lo, o que feito via funo open do
arquivo. Uma vez aberto, o arquivo funciona como o cin e cout, com os quais voc j est
acostumado a usar << e >>, como no exemplo a seguir. Ao terminar o uso do arquivo, importante fech-lo, para garantir que tudo que, em teoria, est escrito no arquivo, realmente foi
colocado no disco.
2
#include <iostream>
#include <fstream>
135
136
10
int main () {
fstream arquivo;
arquivo.open ("arquivo.txt");
arquivo << "O que eu deveria escrever neste arquivo?" << endl;
arquivo.close();
return 0;
}
#include <iostream>
#include <fstream>
using namespace std;
el
im
in
a
Nem sempre possvel abrir o arquivo como no exemplo, o que ser explicado adiante. Para
testar se o arquivo foi aberto ou no, use a funo is_open(). importante que voc teste se o
arquivo realmente est aberto, antes de tentar us-lo.
int main () {
fstream arquivo;
arquivo.open("arquivo.txt");
if(arquivo.is_open())
{
arquivo << "O que eu deveria escrever neste arquivo?" << endl;
arquivo.close();
cout << "tudo escrito";
}
else
cout << "falhou";
10
Pr
12
14
16
return 0;
18
s
o
Ve
r
Se voc tentou executar o cdigo acima, percebeu que a mensagem "falhou"foi escrita na
tela. O problema que o cdigo abre um arquivo e escreve no mesmo, mas somente se ele j
existir, o que no o caso. Por enquanto, v at a pasta onde est o seu projeto e crie o arquivo
manualmente. Na seo seguinte veremos como criar um arquivo de dentro do programa. J
no cdigo a seguir, veja como os dados do arquivo podem ser lidos.
11
13
#include <iostream>
#include <fstream>
using namespace std;
int main () {
fstream arquivo;
arquivo.open ("arquivo.txt");
if(arquivo.is_open())
{
cout << "yeah";
arquivo << "Sera que isso foi escrito?" << endl;
arquivo.close();
137
arquivo.open ("arquivo.txt");
char str[1000];
arquivo.getline(str,1000);
arquivo.close();
15
17
19
23
21
return 0;
25
Criao de Arquivos
el
im
21.1.2
in
a
Para abrir um arquivo que no existe, ou seja, criar o arquivo, necessrio passar um conjunto
especial de instrues para a funo de abertura. Infelizmente, o nico jeito de passar estas
instrues bem mais complicado do que o que vimos at agora. Veja o seguinte cdigo, em
especial a linha que abre o arquivo.
2
#include <iostream>
#include <fstream>
using namespace std;
Pr
int main () {
fstream arquivo;
arquivo.open ("arquivo.txt", ios::out | ios::in | ios::trunc);
if(arquivo.is_open())
cout << "yeah";
else
cout << "nope";
s
o
10
12
arquivo << "O que eu deveria escrever neste arquivo?" << endl;
arquivo.close();
14
16
22
Ve
r
20
arquivo.open ("arquivo.txt");
char str[1000];
arquivo.getline(str,1000);
arquivo.close();
18
return 0;
24
Na frente do parmetro com o nome do arquivo, na funo open, foram passadas trs opes
para o modo de abertura do arquivo, que especifica o tipo de operaes que se intende fazer no
arquivo (o caractere | combina as opes passadas). Algumas das opes possveis so:
ios::in Operaes de escrita.
138
21.1.3
in
a
As opes para leitura e escrita do arquivo, e somente estas, so implcitas, quando nenhuma
opo especificada. Se voc quiser, pode usar apenas uma destas por questes de segurana (o
arquivo pode ser lido mas no escrito, ou o arquivo pode ser aumentado mas no lido). Usando
somente as opes de leitura e escrita, contudo, o arquivo no criado caso no exista. Para que
seja criado, necessrio que se especifique ou ios::trunc ou ios::app, que faro com que o
arquivo seja ou truncado ou que toda modificao seja adicionada ao fim do arquivo (append).
#include <iostream>
#include <fstream>
using namespace std;
Pr
10
12
if(arquivo.is_open())
{
cout << "O arquivo foi aberto!";
arquivo << "Escrevendo um numero pequeno:" << endl;
arquivo << 10 <<endl;
arquivo << "Numero pequeno escrito." << endl;
Ve
r
14
int main () {
fstream arquivo;
arquivo.open ("arquivo.txt", ios::out | ios::in | ios::trunc);
char str[1000];
s
o
el
im
Quando se escreve um dado em um arquivo de texto, precisa-se entender que o dado ocupa
somente o espao que voc especificar. Isto , se voc escrever a sequncia de caracteres C(++)
bom!!!, 14 caracteres sero escritos, e pronto. Se escrever algo na linha seguinte depois
resolver mudar a string acima para C(++) no bom!!!, ento a diviso entre as linhas (o endl
) ter sido sobrescrito e as duas linhas se tornaro uma. Estes cuidados no precisam ser tomados
agora, com os exemplos simples com os quais estamos lidando, mas nos prximos capitulos voc
ter que tom-los. Assim, melhor que voc j saiba sobre estes problemas desde agora.
16
18
20
22
arquivo.open ("arquivo.txt");
24
26
28
30
21.2. LABORATRIO
139
32
arquivo.getline(str,1000);
cout << str;
arquivo.getline(str,1000);
cout << str;
arquivo.getline(str,1000);
cout << str;
34
36
38
arquivo.close();
40
42
in
a
else
cout << "nope";
44
return 0;
46
21.2
el
im
Laboratrio
21.2.1
Pr
21.2.2
Ve
r
s
o
Faa um programa que tente abrir um arquivo e, caso no consiga, tente cri-lo e abr-lo. Com
arquivo aberto, leia um vetor A de inteiros de tamanho 20 e guarde seus valores em um arquivo,
um por linha. Em seguida, reabra o arquivo e leia os elementos para o vetor B, verificando se os
valores foram gravados corretamente.
Ve
r
s
o
Pr
el
im
in
a
140
in
a
Captulo 22
el
im
Embora seja possivel trabalhar com arquivos usando apenas as ferramentas apresentadas at
agora, alguns problemas so de difcil resoluo, a no ser que extendamos nosso conhecimento.
Suponha por exemplo que voc tenha o seguinte arquivo
Pr
22.1
s
o
Observe que todas as linhas tem o mesmo tamanho (22 caracteres) e que a palavra remende
est escrita de forma incorreta. Para corrigir esta palavra, podemos reescrever toda a frase, ou
posicionar o cursor do arquivo examante sobre o caractere errado e corrig-lo. A vrias formas
de se fazer isso, como veremos agora.
Posicionmento no arquivo
Ve
r
Como visto no captulo anterior, operaes de leitura e escrita no arquivo vo mudando a posio
em que as prximas operaes sero executadas. Isto , se considerarmos que h um cursor
dentro do arquivo, na posio em escreveremos, caso uma escrita seja feita, ou leremos, caso
uma leitura seja executada, ento se lermos ou escrevermos 3 caracteres, ento o cursor andar
3 caracteres. Se quisermos colocar o cursor no fim do arquivo, podemos reabr-lo usando ios
::app. Caso queiramos colocar o cursor no comeo do arquivo, podemos podemos reabr-lo
simplesmente reabr-lo sem especificar qualquer opo ou usando ios::trunc (e com isso
tambm zerarmos nosso arquivo).
Caso precisemos posicionar o cursor no meio do arquivo, podemos usar a funo seekg,
que pode ser usada duas formas:
seekg(nova posio [em bytes])
seekg(diferena [em bytes] em relao ao marco, marco)
Na primeira forma voc pode especificar onde o cursor deve ser posicionado em relao ao
incio do arquivo, em nmero de bytes. Por exemplo, arq.seekg(10) posiciona o cursor no
141
142
dcimo byte do arquivo arq. J pela segunda forma, voc especifica onde posicionar o cursor em
relao a um marco no arquivo, que pode ser seu incio (ios_base::beg), fim (ios_base::
end), ou posio atual (ios_base::cur). A diferena em relao ao marco especificada como
um inteiro com sinal. Por exemplo, arq.seekg(-10,ios_base::end) posiciona o cursor no
dcimo caractere antes do fim do arquivo arq.
Para resolver o problema apresentado acima, podemos ento usar as seguintes solues.
#include <iostream>
#include <fstream>
int main()
{
fstream arq;
arq.open("arquivo.txt"); //Posicionando o cursor no inicio.
arq.seekg(23*3+20);
arq << d;
arq.close();
12
in
a
10
el
im
14
16
18
arq.open("arquivo.txt", ios::out |
arquivo.
arq << "O rato roeu a roupa do" <<
<< "rei de Roma e a rainha" <<
<< "Ruinha resolveu rir-se" <<
<< "pois o rei que remende" <<
<< "suas roidas roupagens.";
arq.close();
Pr
20
22
24
endl
endl
endl
endl
return 0;
}
"
Ve
r
30
ios::trunc); //Recriando o
s
o
26
28
22.2
Arquivos formatados
Para que se possa movimentar o cursor dentro de um arquivo, importante que se conhea a
estrutura do mesmo, principalmente se pretender sobrescrev-lo sem destru-lo. Por exemplo,
considere o seguinte problema.
Escrever um programa que leia matrcula e nome de alunos do curso de Engenharia Qumica
e armazene estas informaes em um arquivo. Em seguida, seu programa deve escrever todas
as informaes na tela, precedidas por um nmero identificando cada aluno. Finalmente, o
programa deve ler nmeros correspondentes a alunos e sobrescrever os dados do aluno com
novas informaes.
#include <iostream>
143
#include <fstream>
3
11
bool mais_info()
{
char resp = x;
cout << "Entrar com mais informacoes? (s/n)";
13
in
a
while(true)
{
cin >> resp;
15
17
21
23
25
el
im
switch(resp)
{
case s:
case S:
return true;
case n:
case N:
return false;
}
19
27
}
29
35
37
39
41
int main()
{
fstream arq;
Ve
r
43
Pr
33
s
o
31
45
int totalcount = 0;
int count;
char linha[1000];
47
49
51
53
char mat[15];
char nome[100];
arq.open(NOME_ARQ);
if(! arq.is_open())
arq.open(NOME_ARQ, ios::in | ios::out | ios::trunc);
55
57
while(mais_info())
{
ler_aluno(mat, 15, nome, 100);
144
59
}
61
count = 1;
arq.clear();
arq.seekg(0);
63
65
67
}
73
while(mais_info())
{
cout << "Sobrescrever qual linha?";
cin >> count;
if(count > totalcount)
{
cout << "Linha nao existente";
}
else
{
ler_aluno(mat, 15, nome, 100);
75
el
im
77
79
81
83
85
arq.clear();
arq.seekg(0);
while(count > 1)
{
arq.getline(linha,1000);
count--;
}
arq << mat << " " << nome << endl;
Pr
87
89
s
o
91
93
in
a
71
69
95
97
arq.clear();
count = 1;
arq.seekg(0, arq.beg);
cout << "Dados atuais" << endl;
while(arq.getline(linha,1000))
{
cout << count++ << " - "<< linha << endl;
}
Ve
r
99
101
103
105
107
return 0;
109
Este cdigo possui duas particularidades. Primeiro, ele usa a funo arq.clear(), ainda
no mencionada e, segundo, ele est errado.
22.3. EXERCCIOS
145
Toda vez que o arquivo lido at o seu fim, seu estado interno mudado para identificar
o fato. Isto verificvel pela funo arq.eof(), que testa se o arquivo chegou ao end of file.
Quando isso verdade, as funes de reposicionamento no funcionaro, a no ser que este
status seja reiniciado, o que feito com a funo clear(). No cdigo simplesmente usamos
esta funo sempre que formos fazer um seek, por simplicidade.
Sobre o cdigo no funcionar como esperado, execute-o e insira um aluno apenas, com
matrcula "aaaaaaaaaa"e nome "bbbbbbbbbb". Em seguida, altere os dados da linha 1 e insira
matrcula "cc"e nome "dd". Ao final, os dados impressos sero os seguintes:
in
a
22.3
Dados atuais
1 - cc dd
2 - aaaa bbbbbbbbbb
Exerccios
el
im
22.3.1
Ve
r
s
o
Pr
Corrija o programa exemplo mostrado acima para que escreva sempre linhas de um mesmo
tamanho e que, portanto, no tenha o problema de fragmentao de registros.