Você está na página 1de 210

Curso de Linguagem C

Em Construo
v0.003.11

Adriano Joaquim de Oliveira Cruz


Instituto de Matemti a
N leo de Computao Eletrni a
UFRJ
2011 Adriano Cruz

17 de outubro de 2013

Sumrio

Introduo

1.1 Su essos e Fra assos da Computao . . . . . . . . . . . . . . . .

1.2 Um Pou o da Histria da Computao . . . . . . . . . . . . . . .

1.2.1

O In io . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.2.2

A Era Moderna . . . . . . . . . . . . . . . . . . . . . . . .

1.2.3

O Desenvolvimento durante as Grandes Guerras . . . . .

11

1.2.4

As Geraes . . . . . . . . . . . . . . . . . . . . . . . . . .

13

1.3 O Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14

1.3.1

Mi ro omputadores . . . . . . . . . . . . . . . . . . . . .

15

1.3.2

Memrias . . . . . . . . . . . . . . . . . . . . . . . . . . .

16

1.3.3

Bits e Bytes . . . . . . . . . . . . . . . . . . . . . . . . . .

18

1.3.4

Perifri os . . . . . . . . . . . . . . . . . . . . . . . . . . .

19

1.4 O Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

19

1.5 Um programa em C . . . . . . . . . . . . . . . . . . . . . . . . .

25

1.6 Exer ios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

26

Algoritmos

27

2.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

27

2.2 Primeiros Passos . . . . . . . . . . . . . . . . . . . . . . . . . . .

28

2.3 Representao . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

2.3.1

Linguagem Natural . . . . . . . . . . . . . . . . . . . . . .

30

2.3.2

Fluxogramas . . . . . . . . . . . . . . . . . . . . . . . . .

30

2.3.3

Pseudo-Linguagem . . . . . . . . . . . . . . . . . . . . . .

31

2.4 Modelo de von Neumann . . . . . . . . . . . . . . . . . . . . . . .

33

2.5 Estruturas Bsi as de Algoritmos . . . . . . . . . . . . . . . . . .

34

2.5.1

Comandos de leitura . . . . . . . . . . . . . . . . . . . . .

35

2.5.2

Comandos de es rita . . . . . . . . . . . . . . . . . . . . .

35

2.5.3

Expresses . . . . . . . . . . . . . . . . . . . . . . . . . .

36

2.5.4

Comandos de atribuio . . . . . . . . . . . . . . . . . . .

38

2.5.5

Comandos de ontrole . . . . . . . . . . . . . . . . . . . .

39

2.5.6

Comandos de repetio . . . . . . . . . . . . . . . . . . .

40

2.6 Exemplos de Algoritmos . . . . . . . . . . . . . . . . . . . . . . .

41

2.7 Exer ios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

46

Tipos de Dados, Constantes e Variveis

48

3.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

48

3.2 Tipos de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . .

48

3.2.1

Tipos Bsi os . . . . . . . . . . . . . . . . . . . . . . . . .

48

3.2.2

Modi adores de tipos . . . . . . . . . . . . . . . . . . . .

49

3.3 Constantes Numri as . . . . . . . . . . . . . . . . . . . . . . . .

49

3.3.1

Constantes Inteiras na base 10 . . . . . . . . . . . . . . .

50

3.3.2

Constantes Inteiras O tais . . . . . . . . . . . . . . . . . .

51

3.3.3

Constantes Inteiras Hexade imais . . . . . . . . . . . . . .

52

3.3.4

Converso entre Bases . . . . . . . . . . . . . . . . . . . .

52

3.3.5

Constantes em Ponto Flutuante . . . . . . . . . . . . . . .

53

3.4 Constantes Cara teres . . . . . . . . . . . . . . . . . . . . . . . .

54

3.4.1

Constantes Cadeias de Cara teres . . . . . . . . . . . . .

55

3.5 Variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

55

3.5.1

Nomes das Variveis . . . . . . . . . . . . . . . . . . . . .

56

3.5.2

De larao de variveis . . . . . . . . . . . . . . . . . . .

56

3.5.3

Atribuio de valores . . . . . . . . . . . . . . . . . . . . .

57

3.6 Exer ios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

58

Entrada e Sada pelo Console

60

4.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

60

4.2 Bibliote a Padro . . . . . . . . . . . . . . . . . . . . . . . . . . .

60

4.3 Sada - A Funo printf . . . . . . . . . . . . . . . . . . . . . . .

61

4.3.1

Cdigos de Converso . . . . . . . . . . . . . . . . . . . .

62

4.4 Entrada - A Funo s anf . . . . . . . . . . . . . . . . . . . . . .

64

4.5 Lendo e Imprimindo Cara teres . . . . . . . . . . . . . . . . . . .

66

4.5.1

Funes get har e put har . . . . . . . . . . . . . . . . .

66

4.5.2

Lendo e Imprimindo Cadeias de Cara teres . . . . . . . .

67

4.5.3

Lendo e Imprimindo adeias om s anf e printf . . . . .

68

4.5.4

Lendo e Imprimindo adeias om gets e puts . . . . . . .

69

4.5.5

A Funo fgets . . . . . . . . . . . . . . . . . . . . . . .

69

4.6 Exer ios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

71

Operadores e Expresses

72

5.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

72

5.2 Operador de Atribuio . . . . . . . . . . . . . . . . . . . . . . .

72

5.3 Operadores Aritmti os . . . . . . . . . . . . . . . . . . . . . . .

73

5.4 Operadores Rela ionais e Lgi os . . . . . . . . . . . . . . . . . .

74

5.4.1

Operadores Rela ionais . . . . . . . . . . . . . . . . . . .

74

5.4.2

Operadores Lgi os . . . . . . . . . . . . . . . . . . . . .

74

5.5 Operadores om Bits . . . . . . . . . . . . . . . . . . . . . . . . .

77

5.6 Operadores de Atribuio Composta . . . . . . . . . . . . . . . .

78

5.7 Operador vrgula . . . . . . . . . . . . . . . . . . . . . . . . . . .

79

5.8 Operador sizeof() . . . . . . . . . . . . . . . . . . . . . . . . . .

79

5.9 Converso de Tipos . . . . . . . . . . . . . . . . . . . . . . . . . .

79

5.10 Regras de Pre edn ia . . . . . . . . . . . . . . . . . . . . . . . .

81

5.11 Exer ios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

82

Comandos de Controle

84

6.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

84

6.2 Blo os de Comandos . . . . . . . . . . . . . . . . . . . . . . . . .

84

6.3 Comandos de Teste . . . . . . . . . . . . . . . . . . . . . . . . . .

84

6.3.1

Comando if . . . . . . . . . . . . . . . . . . . . . . . . . .

85

6.3.2

Comando swit h . . . . . . . . . . . . . . . . . . . . . . .

86

6.3.3

Comando Ternrio . . . . . . . . . . . . . . . . . . . . . .

89

6.4 Laos de Repetio . . . . . . . . . . . . . . . . . . . . . . . . . .

89

6.4.1

Comando for . . . . . . . . . . . . . . . . . . . . . . . . .

89

6.4.2

Comando while . . . . . . . . . . . . . . . . . . . . . . .

94

6.4.3

Comando do-while . . . . . . . . . . . . . . . . . . . . .

95

6.5 Comandos de Desvio . . . . . . . . . . . . . . . . . . . . . . . . .

96

6.5.1

Comando break . . . . . . . . . . . . . . . . . . . . . . .

96

6.5.2

Comando ontinue . . . . . . . . . . . . . . . . . . . . .

96

6.5.3

Comando goto . . . . . . . . . . . . . . . . . . . . . . . .

96

6.5.4

Funo exit() . . . . . . . . . . . . . . . . . . . . . . . .

97

6.5.5

Comando return . . . . . . . . . . . . . . . . . . . . . . .

97

6.6 Exer ios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

98

Vetores e Cadeias de Cara teres

101

7.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101


7.2 De larao de Vetores Unidimensionais . . . . . . . . . . . . . . . 101
7.3 Cadeias de Cara teres . . . . . . . . . . . . . . . . . . . . . . . . 104
7.4 De larao de Vetores Multidimensionais . . . . . . . . . . . . . . 106
7.5 Vetores de Cadeias de Cara teres . . . . . . . . . . . . . . . . . . 110
7.6 Ini ializao de Vetores e Matrizes . . . . . . . . . . . . . . . . . 110
7.7 Exer ios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
8

Funes

117

8.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117


8.2 Forma Geral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
8.3 Prottipos de Funes . . . . . . . . . . . . . . . . . . . . . . . . 119
8.4 Es opo de Variveis . . . . . . . . . . . . . . . . . . . . . . . . . 119
8.4.1

Variveis Lo ais . . . . . . . . . . . . . . . . . . . . . . . 120

8.4.2

Variveis Globais . . . . . . . . . . . . . . . . . . . . . . . 122

8.5 Parmetros Formais . . . . . . . . . . . . . . . . . . . . . . . . . 123


8.5.1

Passagem de Parmetros por Valor . . . . . . . . . . . . . 123

8.5.2

Passagem de Parmetros por Refern ia . . . . . . . . . . 124

8.5.3

Passagem de Vetores e Matrizes . . . . . . . . . . . . . . . 124

8.6 O Comando return . . . . . . . . . . . . . . . . . . . . . . . . . 126


8.7 Re urso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
8.7.1

Como pensar re ursivamente? . . . . . . . . . . . . . . . . 130

8.7.2

O que faz re urso trabalhar? . . . . . . . . . . . . . . . . 131

8.8 Argumentos - arg e argv . . . . . . . . . . . . . . . . . . . . . . 131


8.9 Exer ios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
9

Ponteiros

136

9.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136


9.2 Operaes om Ponteiros . . . . . . . . . . . . . . . . . . . . . . 137
9.2.1

De larao de Ponteiros . . . . . . . . . . . . . . . . . . . 137

9.2.2

Os Operadores Espe iais para Ponteiros . . . . . . . . . . 138

9.2.3

Atribuio de Ponteiros . . . . . . . . . . . . . . . . . . . 139

9.2.4

In rementando e De rementando Ponteiros . . . . . . . . 141

9.2.5

Comparao de Ponteiros . . . . . . . . . . . . . . . . . . 142

9.3 Ponteiros e Vetores . . . . . . . . . . . . . . . . . . . . . . . . . . 143


9.4 Ponteiros e Cadeias de Cara teres . . . . . . . . . . . . . . . . . 144
9.5 Alo ao Dinmi a de Memria . . . . . . . . . . . . . . . . . . . 144
4

9.6 Ponteiros e Matrizes . . . . . . . . . . . . . . . . . . . . . . . . . 146


9.7 Vetores de Ponteiros . . . . . . . . . . . . . . . . . . . . . . . . . 149
9.8 Ponteiros para Ponteiros . . . . . . . . . . . . . . . . . . . . . . . 150
9.9 Exer ios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
10 Estruturas

158

10.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158


10.2 Denies Bsi as . . . . . . . . . . . . . . . . . . . . . . . . . . 158
10.3 Atribuio de Estruturas . . . . . . . . . . . . . . . . . . . . . . . 161
10.4 Matrizes de Estruturas . . . . . . . . . . . . . . . . . . . . . . . . 161
10.5 Estruturas e Funes . . . . . . . . . . . . . . . . . . . . . . . . . 162
10.6 Ponteiros para Estruturas . . . . . . . . . . . . . . . . . . . . . . 165
10.7 Exer ios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
11 Entrada e Sada por Arquivos

170

11.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170


11.2 Fluxos de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
11.2.1 Fluxos de Texto . . . . . . . . . . . . . . . . . . . . . . . 170
11.2.2 Fluxo Binrio . . . . . . . . . . . . . . . . . . . . . . . . . 171
11.2.3 Arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
11.3 Funes de Entrada e Sada . . . . . . . . . . . . . . . . . . . . . 172
11.4 In io e Fim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
11.4.1 Abrindo um Arquivo . . . . . . . . . . . . . . . . . . . . . 173
11.4.2 Fe hando um Arquivo . . . . . . . . . . . . . . . . . . . . 174
11.4.3 Fim de Arquivo . . . . . . . . . . . . . . . . . . . . . . . . 174
11.4.4 Volta ao In io . . . . . . . . . . . . . . . . . . . . . . . . 175
11.5 Lendo e Es revendo Cara teres . . . . . . . . . . . . . . . . . . . 175
11.6 Testando Erros . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
11.7 Lendo e Es revendo Cadeias de Cara teres . . . . . . . . . . . . . 179
11.8 Entrada e Sada Formatada . . . . . . . . . . . . . . . . . . . . . 180
11.9 Lendo e Es revendo Arquivos Binrios . . . . . . . . . . . . . . . 181
11.10Exer ios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
12 Problemas Extras

187

A Tabela ASCII

197

B Palavras Reservadas

199

Lista de Figuras

1.1 Fotograa de um ir uito integrado de mi ropro essador Pentium.

1.2 Imagem de um ba o. . . . . . . . . . . . . . . . . . . . . . . . .

1.3 Blaise Pas al . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.4 Charles Babbage . . . . . . . . . . . . . . . . . . . . . . . . . . .

10

1.5 Fotograa da Dieren e Engine . . . . . . . . . . . . . . . . . . .

10

1.6 Computador Enia . . . . . . . . . . . . . . . . . . . . . . . . . .

12

1.7 Diagrama Bsi o de um Computador Digital . . . . . . . . . . .

15

1.8 Nveis de hierarquia da memria de um omputador. . . . . . . .

16

1.9 Tamanho de Bits, Bytes e Palavras . . . . . . . . . . . . . . . . .

18

1.10 Ci lo de desenvolvimento de um programa. . . . . . . . . . . . .

23

2.1 Smbolos mais omumente usados em uxogramas. . . . . . . . .

31

2.2 Fluxograma para resolver uma equao do primeiro grau. . . . .

32

2.3 Modelo de memria . . . . . . . . . . . . . . . . . . . . . . . . .

35

2.4 Fluxograma do omando se ...

ento ... seno. . . . . . .

39

2.5 Fluxograma para de idir se deve levar um guarda- huva. . . . . .

41

2.6 Fluxograma do omando enquanto. . . . . . . . . . . . . . . . .

43

7.1 Mapa de memria de uma matriz. . . . . . . . . . . . . . . . . . 110


9.1 Mapa de memria om duas variveis e ponteiro. . . . . . . . . . 136
9.2 Ponteiro apontando para rea de memria ontendo vetor. . . . . 137
9.3 De larao de ponteiros. . . . . . . . . . . . . . . . . . . . . . . . 138
9.4 Atribuio de endereo de uma varivel a um ponteiro. . . . . . . 139
9.5 Uso de um ponteiro para opiar valor de uma varivel. . . . . . . 139
9.6 Exemplos de atribuies de ponteiros. . . . . . . . . . . . . . . . 140
9.7 Armazenamento de matrizes om vetores de ponteiros. . . . . . . 150
11.1 Fluxos de dados. . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

Lista de Tabelas

1.1 Transistores por ir uito integrado nos mi ropro essadores da Intel

1.2 Tempo de exe uo das instrues aritmti as no ENIAC . . . .

12

1.3 Exemplos de Mi ropro essadores . . . . . . . . . . . . . . . . . .

15

1.4 Abreviaes usadas em refern ias s memrias. . . . . . . . . . .

19

1.5 Exemplos de perifri os . . . . . . . . . . . . . . . . . . . . . . .

19

2.1 Operadores Aritmti os. . . . . . . . . . . . . . . . . . . . . . . .

38

3.1 Tipos de dados denidos pelo Padro ANSI C. . . . . . . . . . .

50

3.2 Constantes Inteiras na Base 10 . . . . . . . . . . . . . . . . . . .

51

3.3 Constantes o tais . . . . . . . . . . . . . . . . . . . . . . . . . . .

52

3.4 Constantes hexade imais . . . . . . . . . . . . . . . . . . . . . . .

52

3.5 Constantes em ponto utuante . . . . . . . . . . . . . . . . . . .

54

3.6 Exemplos de onstantes ara tere . . . . . . . . . . . . . . . . . .

55

3.7 Exemplos de ara teres invisveis. . . . . . . . . . . . . . . . . . .

55

3.8 Tabela do exer i io 6 . . . . . . . . . . . . . . . . . . . . . . . . .

59

4.1 Cdigos de Converso para es rita de dados. . . . . . . . . . . . .

62

5.1 Operadores aritmti os. . . . . . . . . . . . . . . . . . . . . . . .

73

5.2 Operadores Rela ionais. . . . . . . . . . . . . . . . . . . . . . . .

74

5.3 Operador Lgi o E. . . . . . . . . . . . . . . . . . . . . . . . . . .

75

5.4 Operador Lgi o OU. . . . . . . . . . . . . . . . . . . . . . . . . .

76

5.5 Operador Lgi o N O. . . . . . . . . . . . . . . . . . . . . . . . .

76

5.6 Pre edn ia dos operadores lgi os e rela ionais. . . . . . . . . .

76

5.7 Operadores om bits. . . . . . . . . . . . . . . . . . . . . . . . . .

77

5.8 Operador Lgi o OU. . . . . . . . . . . . . . . . . . . . . . . . . .

77

5.9 Pre edn ia dos operadores. . . . . . . . . . . . . . . . . . . . . .

81

7.1 Passos exe utados durante o algoritmo da bolha. . . . . . . . . . 103


7

11.1 Exemplos de funes de Entrada e Sada. . . . . . . . . . . . . . 173


A.1 Conjunto de ara teres ASCII . . . . . . . . . . . . . . . . . . . . 197
A.2 Conjunto de digos espe iais ASCII e seus signi ados . . . . . 198

Lista de Algoritmos

2.1 Exemplo de Algoritmo. . . . . . . . . . . . . . . . . . . . . . . . .

29

2.2 Algoritmo para resolver uma equao do primeiro grau. . . . . . .

29

2.3 Algoritmo para al ular a mdia das notas de um aluno. . . . . .

31

2.4 Algoritmo para al ular a maior nota de um grupo de notas. . . .

33

2.5 Modelo de memria e fun ionamento de um algoritmo . . . . . . .

34

2.6 Comando se em pseudo-linguagem . . . . . . . . . . . . . . . . . .

39

2.7 Algoritmo para de idir o que fazer no domingo. . . . . . . . . . .

40

2.8 Algoritmo para de idir se deve levar um guarda- huva. . . . . . .

40

2.9 Algoritmo para ler 10 nmeros e imprimir se so pares ou no. . .

42

2.10 Algoritmo para ler nmeros e imprimir se so pares ou no. A quantidade de nmeros a ser lida de
2.11 Algoritmo para al ular a maior nota de uma turma de 25 alunos.

44

2.12 Algoritmo para al ular a nota mdia de uma turma de 25 alunos.

44

2.13 Algoritmo para al ular a maior temperatura do ano. . . . . . . .

45

2.14 Algoritmo do exer io 11. . . . . . . . . . . . . . . . . . . . . . .

47

2.15 Algoritmo do exer io 11. . . . . . . . . . . . . . . . . . . . . . .

47

3.1 Algoritmo para onverter inteiros na base 10 para uma base b. . .

53

Listings

1.1 Exemplo de Programa em C. . . . . . . . . . . . . . . . . . . . .

25

4.1 Exemplo de impresso de resultados . . . . . . . . . . . . . . . .

61

4.2 Exemplo de justi ao de resultados. . . . . . . . . . . . . . . .

63

4.3 Exemplo de uso de espe i ador de pre iso. . . . . . . . . . . .

64

4.4 Exemplo de uso de s anf.

. . . . . . . . . . . . . . . . . . . . .

66

4.5 Exemplo de uso de get har e put har. . . . . . . . . . . . . . .

67

4.6 Exemplo de uso de get har e put har. . . . . . . . . . . . . . .

67

4.7 Exemplo de uso de printf e s anf na leitura de adeias. . . . .

68

4.8 Exemplo de uso de puts e gets na leitura de adeias.

. . . . . .

70

5.1 Exemplo de operadores de deslo amento. . . . . . . . . . . . . .

78

5.2 Exemplo do operador sizeof.

. . . . . . . . . . . . . . . . . . .

80

. . . . . . . . . . . . . . . . . . . . . . .

83

. . . . . . . . . . . . . . . . . . . . . .

86

6.2 Programas om if's em es ada e aninhados. . . . . . . . . . . . .

87

6.3 Exemplo de swit h.

. . . . . . . . . . . . . . . . . . . . . . . . .

90

6.4 Exemplo de omando ternrio. . . . . . . . . . . . . . . . . . . .

91

6.5 Exemplo de omando for. . . . . . . . . . . . . . . . . . . . . . .

92

6.6 Exemplo de omando for om testes sobre outras variveis. . . .

92

6.7 Exemplo de omando for sem alterao da varivel de ontrole.

93

6.8 Exemplo de omando for sem teste de m.

. . . . . . . . . . . .

93

. . . . . . . . . . . . . . . . . . . . . .

94

5.3 Variveis da questo 9.


6.1 Exemplo de omandos if.

6.9 Comando for aninhados.

6.10 Comando while om uma funo.


6.11 Programa do exer i io 17.

. . . . . . . . . . . . . . . . .

95

. . . . . . . . . . . . . . . . . . . . . 100

7.1 Exemplo de vetores. . . . . . . . . . . . . . . . . . . . . . . . . . 102


7.2 Produto es alar de dois vetores.
7.3 Ordenao pelo mtodo da bolha.

. . . . . . . . . . . . . . . . . . 104
. . . . . . . . . . . . . . . . . 105

7.4 Exemplos de funes para adeias. . . . . . . . . . . . . . . . . . 107


7.5 Leitura de uma matriz.

. . . . . . . . . . . . . . . . . . . . . . . 108
10

7.6 Multipli ao de duas matrizes.

. . . . . . . . . . . . . . . . . . 109

7.7 Leitura de um vetor de nomes. . . . . . . . . . . . . . . . . . . . 111


7.8 Exemplos de tratamento de vetores. . . . . . . . . . . . . . . . . 112
7.9 Exemplos de tratamento de vetores. . . . . . . . . . . . . . . . . 113
7.10 Programa do exer i io 14.

. . . . . . . . . . . . . . . . . . . . . 116

8.1 Exemplo de prottipos. . . . . . . . . . . . . . . . . . . . . . . . 120


8.2 Exemplos de variveis lo ais. . . . . . . . . . . . . . . . . . . . . 121
8.3 Denio de varivel dentro de um blo o. . . . . . . . . . . . . . 121
8.4 Denio de varivel global.

. . . . . . . . . . . . . . . . . . . . 122

8.5 Exemplo de passagem por valor. . . . . . . . . . . . . . . . . . . 123


8.6 Uso indevido de variveis lo ais. . . . . . . . . . . . . . . . . . . 124
8.7 Passagem de vetor om dimenses.

. . . . . . . . . . . . . . . . 125

8.9 Fatorial al ulado no re ursivamente.


8.8 Passagem de vetores sem dimenses.

. . . . . . . . . . . . . . 126
. . . . . . . . . . . . . . . 127

8.10 Fatorial al ulado re ursivamente. . . . . . . . . . . . . . . . . . 128


8.11 Chamada re ursiva direta.

. . . . . . . . . . . . . . . . . . . . . 128

8.12 Chamada re ursiva indireta.

. . . . . . . . . . . . . . . . . . . . 129

8.13 Funo re ursiva para al ular xn . . . . . . . . . . . . . . . . . . 129


8.14 Chamada re ursiva om auda.

. . . . . . . . . . . . . . . . . . 129

8.15 Chamada re ursiva sem auda. . . . . . . . . . . . . . . . . . . . 130


8.16 Soma de vetor re ursiva.

. . . . . . . . . . . . . . . . . . . . . . 131

8.17 Uso de arg e argv. . . . . . . . . . . . . . . . . . . . . . . . . . 132


8.18 Programa do exer io 8.

. . . . . . . . . . . . . . . . . . . . . . 134

8.19 Programa do problema 9. . . . . . . . . . . . . . . . . . . . . . . 134


9.1 Exemplo de atribuio de ponteiros. . . . . . . . . . . . . . . . . 140
9.2 Exemplos de operaes om ponteiros.

. . . . . . . . . . . . . . 141

9.3 Exemplo de subtrao de ponteiros. . . . . . . . . . . . . . . . . 142


9.4 Exemplo de omparao de ponteiros. . . . . . . . . . . . . . . . 142
9.5 Exemplo de alteraes invlidas sobre ponteiros. . . . . . . . . . 143
9.6 Exemplo de notaes de vetores. . . . . . . . . . . . . . . . . . . 143
9.7 Exemplo de ponteiro varivel.

. . . . . . . . . . . . . . . . . . . 144

9.8 Exemplo de ponteiro para adeia de ara teres.

. . . . . . . . . 145

9.9 Exemplo de pia de adeias de ara teres. . . . . . . . . . . . . 145


9.10 Exemplo de uso de allo e free.
9.11 Exemplo de uso de mallo .

. . . . . . . . . . . . . . . . . 146

. . . . . . . . . . . . . . . . . . . . . 147

9.12 Exemplo de matriz normal sem uso de ponteiros.


9.13 Exemplo de matriz mapeada em um vetor.
11

. . . . . . . . 148

. . . . . . . . . . . . 148

9.14 Exemplo de uso de vetor de ponteiros.

. . . . . . . . . . . . . . 149

9.15 Exemplo de uso de ponteiros para ponteiros.

. . . . . . . . . . . 151

9.16 Exemplo de uso de ponteiros para ponteiros usando funes.


9.17 Continuao do exemplo 9.16.

. . 152

. . . . . . . . . . . . . . . . . . . 153

9.18 Programa do exer i io 11.

. . . . . . . . . . . . . . . . . . . . . 155

9.19 Programa do exer i io 12.

. . . . . . . . . . . . . . . . . . . . . 156

9.20 Listagem do exer io 13. . . . . . . . . . . . . . . . . . . . . . . 156


9.21 Programa do exer io 14.

. . . . . . . . . . . . . . . . . . . . . 157

10.1 Denio de uma estrutura. . . . . . . . . . . . . . . . . . . . . . 159


10.2 Atribuio de Estruturas. . . . . . . . . . . . . . . . . . . . . . . 161
10.3 Ordenao de Estruturas. . . . . . . . . . . . . . . . . . . . . . . 162
10.4 Passando elementos para funes.

. . . . . . . . . . . . . . . . . 163

10.5 Passagem de estruturas para funes.


10.6 Funo que ordena estruturas.

. . . . . . . . . . . . . . . 164

. . . . . . . . . . . . . . . . . . . 164

10.7 Alo ao de espao para estruturas. . . . . . . . . . . . . . . . . 166


10.8 Alo ao de espao para vetores de estruturas. . . . . . . . . . . 167
10.9 Listagem do exer i io 3.
11.1 Uso da funo feof().

. . . . . . . . . . . . . . . . . . . . . . 168
. . . . . . . . . . . . . . . . . . . . . . . 175

11.4 Uso da funo ferror(). . . . . . . . . . . . . . . . . . . . . . . 176


11.2 Exemplo de leitura e es rita de ara teres.

. . . . . . . . . . . . 177

11.3 Exemplo de leitura e es rita de ara teres.

. . . . . . . . . . . . 178

11.5 Exemplo de leitura e es rita de adeias de ara teres.

. . . . . . 179

11.6 Exemplo de leitura e es rita de dados formatados. . . . . . . . . 180


11.7 Exemplo de leitura e es rita na forma binria.
11.8 Exemplo de leitura e es rita de estruturas.
11.9 (I) Tre ho de programa do problema 14.

. . . . . . . . . . 182

. . . . . . . . . . . . 183
. . . . . . . . . . . . . 186

11.10(II) Tre ho de programa do problema 14. . . . . . . . . . . . . . 186


12.1 Pro essando o CPF. . . . . . . . . . . . . . . . . . . . . . . . . . 190
12.2 Estrutura do problema 8. . . . . . . . . . . . . . . . . . . . . . . 194

12

Captulo 1
Introduo

1.1 Su essos e Fra assos da Computao


Os objetivos prin ipais deste aptulo so mostrar para o aluno ini iante alguns
aspe tos da histria da omputao e denir, informalmente, termos e palavras have que os prossionais da rea de omputao usam no seu dia a dia. Adriano
Cruz .
A histria do desenvolvimento dos omputadores tem sido impressionante.
O avano da te nologia e a presena da omputao na nossa vida so inegveis. Embora a histria deste fantsti o desenvolvimento seja re ente e bem
do umentada, h la unas e ontrovrsias impressionantes sobre diversos pontos.
Neste aptulo iremos ver histrias de espionagem e brigas na justia por roubo
de ideias. H oportunidades perdidas e gente que soube aproveitar a sua han e.
H verdades estabele idas que tiveram de ser revistas.
O avano na te nologia dos omputadores se deu em passos to largos que os
primeiros omputadores pare em to distantes no tempo quanto a Pr-Histria.
O aumento de velo idade, desde os anos 40, foi da vrias ordens de grandeza,
enquanto que o usto dos omputadores aiu de milhes de dlares para valores em torno de entenas de dlares. As primeiras mquinas tinham milhares
de vlvulas, o upavam reas enormes e onsumiam quilowatts de energia. O
mi ropro essador Pentium, lanado em 1993, tinha em torno de 3,1 milhes
de transistores, o upava uma rea de aproximadamente 25 cm2 e onsumia
alguns watts de energia, ustando aproximadamente 1000 dlares, somente o
mi ropro essador. A Figura 1.1 mostra a imagem de um ir uito integrado de
mi ropro essador Pentium.
No entanto, esta histria de reduo de tamanho, aumento de velo idade e
diminuio de gasto de potn ia, pode, para alguns pesquisadores, j ter uma
data xada para terminar. Em 1965, Gordon Moore, um dos fundadores da Intel, fabri ante do Pentium e uma dos maiores fabri antes de ir uitos integrados
do mundo, enun iou o que  ou onhe ido omo a Lei de Moore: Cada novo
ir uito integrado ter o dobro de transistores do anterior e ser lanado dentro
de um intervalo de 18 a 24 meses. Moore a hava que esta lei seria vlida somente at 1975, no entanto, ela ontinua vlida at hoje. Na tabela 1.1, pode-se
observar a evoluo dos mi ropro essadores usados em nossos omputadores.
13

Figura 1.1: Fotograa de um ir uito integrado de mi ropro essador Pentium.


Ano

1971
1972
1974
1982
1985
1989
1993
1997
1999
2000

Pro essador

4004
8008
8080
80286
80386
80486 DX
Pentium
Pentium II
Pentium III
Pentium 4

Transistores

2.250
2.500
5.000
120.000
275.500
1.180.000
3.100.000
7.500.000
24.000.000
42.000.000

Tabela 1.1: Transistores por ir uito integrado nos mi ropro essadores da Intel

Os transistores, que ompem os ir uitos eletrni os, esto diminuindo de


tamanho, e estamos nos aproximando da fronteira nal, os eltrons. J se houve
falar em tamanho de transistores medidos em nmeros de eltrons. Devemos nos
lembrar que toda a te nologia atual est baseada em uxo de eltrons, ou seja
uma orrente eltri a. Os os onduzem orrentes de eltrons e os transistores
ontrolam este uxo. Se o tamanho diminuir alm dos eltrons estaremos em
outro domnio.
No entanto, na histria da omputao, muitas promessas no foram umpridas e falhas gigantes as a onte eram. Como em diversas questes, artistas
geniais, apontam o que no onseguimos ou no queremos ver e mostram que
o rei est nu. H uma frase de Pi asso que diz: Computadores so estpidos, eles somente onseguem responder perguntas. Esta frase expe om ironia
um fra asso da omunidade de omputao que havia prometido riar rapidamente omputadores inteligentes, omputadores que poderiam questionar-se e
nos questionar. Muitos a reditaram nesta promessa e muitos livros de  o ient a foram publi ados em que este tipo de omputador estaria disponvel em
um futuro muito prximo. Com notvel exemplo podemos itar o lme 2001 Uma Odissia no Espao, de Stanley Kubrik que estreou em 1968 e foi baseado
no onto The Sentinel, es rito em 1950 por Arthur Clark, um dos mestres da
 o ient a. Neste lme o enlouque ido omputador HAL 9000, que era
apaz de ver, falar, ra io inar et , mata quase todos os tripulantes de uma nave
14

espa ial. Ora, j passamos por 2001 e no existe a menor possibilidade de se


ver um omputador omo o HAL ou to lou o de pedra omo ele.
Na omputao, um exemplo fantsti o de su esso a Internet. A Internet
est se tornando essen ial para o fun ionamento do mundo moderno. Freqentemente ouvimos dizer que ela o meio de omuni ao que mais rapidamente se
difundiu pelo mundo. Pode pare er verdade, j que onhe emos tantos internautas e as empresas esto se atropelando para fazer parte desta onda e aproveitar
as suas possibilidades. Esta orrida provo ou alguns a identes e muitos sonhos
de riqueza se esvaram no ar. Hoje, pode-se fazer quase tudo pela Internet,
namorar, omprar, pagar ontas, fazer amigos, estudar, jogar et . Quem sabe,
em um futuro prximo, voltaremos Gr ia Antiga e nos reuniremos em uma
enorme praa virtual para, demo rati amente, dis utir nossas leis, dispensando
intermedirios.

1.2 Um Pou o da Histria da Computao


1.2.1 O In io
A primeira tentativa de se riar uma mquina de ontar foi o ba o. A palavra
vem do rabe e signi a p. Os primeiros ba os eram bandejas de areia sobre
as quais se faziam guras para representar as operaes. Aparentemente, os
hineses foram os inventores do ba o de al ular. No entanto, h ontrovrsias,
e os japoneses tambm reivindi am esta inveno, que eles hamam de soroban.
Alm disso h os russos, que inventaram um tipo mais simples, hamado de
ts hoty. So onhe idos exemplares de ba o datados de 2500 A.C. A Figura
1.2 ilustra um exemplar om as suas ontas e varetas.

Figura 1.2: Imagem de um ba o.


Em 1901 mergulhadores, trabalhando perto da ilha grega de Antikythera,
en ontraram os restos de um me anismo, pare ido om um relgio, om aproximadamente 2000 anos de idade. O me anismo, de grande omplexidade, pare e
ser um dispositivo para al ular os movimentos de estrelas e planetas.

1.2.2 A Era Moderna


Em 1614 John Napier, matemti o es o s, inventou um dispositivo feito de
marm para demonstrar a diviso por meio de subtraes e a multipli ao por
15

meio de somas. A semelhana entre marm e ossos, fez om que o dispositivo


fosse onhe ido omo os ossos de Napier.
Um dos primeiros instrumentos modernos de al ular, do tipo me ni o, foi
onstrudo pelo lsofo, matemti o e fsi o fran s Blaise Pas al (Figura 1.3).
Em 1642 aos 19 anos, na idade de Rouen, Pas al desenvolveu uma mquina de
al ular, para auxiliar seu trabalho de ontabilidade. A engenho a era baseada
em 2 onjuntos de dis os interligados por engrenagens: um para a introduo
dos dados e outro para armazenar os resultados. A mquina utilizava o sistema
de imal para al ular, de maneira que quando um dis o ultrapassava o valor 9,
retornava ao 0 e aumentava uma unidade no dis o imediatamente superior.

Figura 1.3: Blaise Pas al


Pas al re ebeu uma patente do rei da Frana, o que lhe possibilitou o lanamento de sua mquina no mer ado. A omer ializao das al uladoras no foi
satisfatria devido a seu fun ionamento pou o onvel, apesar dele ter onstrudo er a de 50 verses. As mquinas de al ular, derivadas da Pas alina,
omo  ou onhe ida sua mquina, ainda podiam ser en ontradas em lojas at
alguns pou os anos atrs. Antes de morrer, aos 39 anos, em 1662, Pas al que
ontribura em vrios ampos da Cin ia, ainda teve tempo de riar uma variante de sua mquina, a aixa registradora.
Em 1666, Samuel Morland adaptou a al uladora de Pas al para resolver
multipli aes por meio de uma srie de somas su essivas. Independentemente,
em 1671 Leibniz projetou uma outra al uladora que somava e multipli ava.
Esta al uladora s foi on luda em 1694.
O primeiro omputador de uso espe  o omeou a ser projetado em 1819
e terminou em 1822, ou seja, h mais de 180 anos atrs, pelo britni o Charles (1791-1871, Figura 1.4), que o batizou de Dieren e Engine (Figura 1.5).
A motivao de Babbage era resolver polinmios pelo mtodo das diferenas.
Naquele tempo as tbuas astronmi as e outras tabelas eram al uladas por
humanos, em mtodos tediosos e repetitivos.
Em 1823, ele ini iou o projeto de onstruir uma outra mquina mais avanada e apaz de al ular polinmios de at sexta ordem. Ele esperava terminar
esta mquina em trs anos, mas a onstruo se arrastou at 1834. Este projeto
que no foi ompletado, usou dinheiro do governo ingls e possivelmente a maior
parte da fortuna pessoal de Babbage. A mquina, inteiramente me ni a, teria
as seguintes ara tersti as:
Arredondamento automti o;

16

Figura 1.4: Charles Babbage

Figura 1.5: Fotograa da Dieren e Engine

Pre iso dupla;


Alarmes para avisar m de l ulo;
Impresso automti a de resultados em pla as de obre.

Em 1834 ele tinha ompletado os primeiros desenhos da mquina que denominou Analyti al Engine que tinha as seguintes ara tersti as:
50 dgitos de imais de pre iso;
Memria para 1000 destes nmeros (165000 bits);
Controle por meio de artes perfurados das operaes e endereos dos
dados;
Tempo de soma e subtrao igual a 1 segundo; tempo de multipli ao e
diviso igual a 1 minuto;
Sub-rotinas;

17

Arredondamento automti o e dete o de transbordo (overow );

Babagge nun a onseguiu terminar este ambi ioso projeto. No entanto, os


mais importantes on eitos de omputao, que somente vieram a tona nos anos
40 do s ulo vinte, j tinham sido onsiderados por Charles Babbage em o seu
projeto.
Um fato urioso que entre os auxiliares de Babagge estava Augusta Ada
Byron, Countess of Lovela e. Considera-se, hoje, que ela es reveu para Charles
Babbage o primeiro programa para omputadores. Ada que mudou seu nome
para Augusta Ada King, aps seu asamento, estudava Matemti a om DeMorgan que provou um dos teoremas bsi os da lgebra Booleana, que a base
matemti a sobre a qual foram desenvolvidos os projetos dos modernos omputadores. No entanto, no havia nenhuma ligao entre o trabalho do projetista
dos primeiros omputadores e o do matemti o que estudava o que viria a ser
o fundamento teri o de todo a omputao que onhe emos hoje.

1.2.3 O Desenvolvimento durante as Grandes Guerras


Antes da Segunda Grande Guerra, em vrios pases, ientistas trabalhavam em
projetos que visavam onstruir omputadores om rels, que so dispositivos
eletrome ni os usados para ligar ou desligar ir uitos eltri os. Rels so os
dispositivos que ante ederam os transistores na onstruo de omputadores.
Alguns destes omputadores eram de uso geral, outros tinha nalidades espe  as. Alguns destes projetos esto listados a seguir.
Na Alemanha

Em 1934 na Alemanha Konrad Zuze, engenheiro projetista de avies, on ebeu


uma mquina de somar para resolver os l ulos que deveria realizar em seus
projetos. Em 1938, ele on luiu o Z1, um al ulador me ni o om uma unidade
aritmti a que usava a base 2 para representar os nmeros, base que hoje os
omputadores modernos empregam. Em 1938 ele melhorou o desempenho do
Z1, graas aos rels.
O governo alemo patro inou os trabalhos de Zuze e em 1941 estava pronto
o Z2, uma mquina eletrome ni a apaz de re eber instrues por meio de uma
ta de papel. Em 1941 foi introduzido o Z3, que al ulava trs a quatro adies
por segundo, uma multipli ao em 4 ou 5 segundos e era apaz de extrair a
raiz quadrada.
Nos Estados Unidos

Em 1944 a IBM e H. Haiken da Universidade de Harvard, on luam a onstruo de um verdadeiro omputador: o Harvard Mark I, que operava em base 10.
O Mark I efetuava as quatro operaes fundamentais, mais o l ulo de funes
trigonomtri as, exponen iais e logartmi as. As instrues eram forne idas por
meio de tas de papel e os dados lidos de artes perfurados. Os resultados eram
forne idos em forma de artes perfurados ou impressos por meio de mquinas
de es rever.
18

Em 1943 na Universidade da Pensilvnia, J. E kert e J. Mau hly ini iaram a


onstruo de um omputador vlvulas, ou seja eletrni o que foi hamado de
ENIAC. O projeto foi on ludo em 1946 e usado na segunda guerra mundial.
O ENIAC podia ser reprogramado para exe utar diversas operaes diferentes
atravs de ligaes por meio de os e one tores.
Durante muitos anos o omputador ENIAC foi onsiderado o primeiro omputador eletrni o onstrudo. A mquina projetada pelos Drs. E kert and
Mau hly era gigantes a quando omparada om os omputadores pessoais atuais. Quando foi terminado, o ENIAC (Figura 1.6) en hia um laboratrio inteiro,
pesava trinta toneladas, e onsumia duzentos quilowatts de potn ia.

Figura 1.6: Computador Enia


Ele gerava tanto alor que teve de ser instalado em um dos pou os espaos
da Universidade que possua sistemas de refrigerao forada. Mais de 19000
vlvulas, eram os elementos prin ipais dos ir uitos do omputador. Ele tambm tinha quinze mil rels e entenas de milhares de resistores, apa itores e
indutores. Toda esta parafernlia eletrni a foi montada em quarenta e dois
painis om mais 2,70 metros de altura, 60 entmetros de largura e 30 entmetros de omprimento, montados na forma da letra U. Uma leitora de artes
perfurados e uma perfuradora de artes eram usados para entrada e sada de
dados.
Os tempos de exe uo do ENIAC so mostrados na Tabela 1.2. Compare
estes tempos om os tempos dos omputadores atuais que esto na ordem de
nano segundos, ou 109 segundos.
Operao

soma
multipli ao
diviso

Tempo

200 s
2,8 ms
6,0 ms

Tabela 1.2: Tempo de exe uo das instrues aritmti as no ENIAC


Em 1939 John Vin ent Atanaso e Cliord E. Berry, na Universidade Estadual de Iowa onstruram um prottipo de omputador digital eletrni o, que
usa aritmti a binria. Em 19 de outubro de 1973, o juiz federal Earl R. Larson
assinou uma de iso, em seguida a uma longa batalha judi ial, que de larava
19

a patente do ENIAC de Mau hly e E kert invlida e atribua a Atanaso a


inveno omputador eletrni o digital, o ABC ou Atanaso-Berry Computer.
Na Inglaterra

Jnos von Neumann, emigrante hngaro que vivia nos EUA, sugeriu que a
memria do omputador deveria ser usada para armazenar as instrues do
omputador de maneira odi ada, o on eito de programa armazenado. Esta
idia foi fundamental para o progresso da omputao. Os primeiros omputadores, omo o ENIAC, eram programados por os que os ientistas usavam para
one tar as diversas partes. Quando um programa terminava, estes ientistas
tro avam os os de posio de a ordo om a nova tarefa a ser exe utada. Com o
programa armazenado na memria, juntamente om os dados, no era mais ne essrio interromper as atividades. Carregava-se o programa na memria, uma
tarefa extremamente rpida, junto om os dados e dava-se partida no programa.
Ao trmino da exe uo do programa passava-se imediatamente para a prxima
tarefa sem interrupes para tro a de os.
Em 1949, na Inglaterra, dois omputadores que usavam a memria para
armazenar tanto programas omo dados foram lanados. Na Universidade de
Cambridge foi lanado o EDSAC, (Ele troni Delay Storage Automati Cal ulator) e em Man hester o omputador hamado de Man hester Mark I. O EDSAC
onsiderado o primeiro omputador de programa armazenado a ser lanado.
Curiosamente, a Universidade de Man hester reivindi a que o primeiro omputador de programa armazenado foi o hamado Baby, um prottipo do Mark I,
que omeou a operar onze meses antes do EDSAC.
Outro fato urioso em relao Inglaterra e que foi divulgado re entemente
relata que um omputador hamado COLOSSUS entrou em operao se retamente na Inglaterra em 1943. Este omputador foi usado para auxiliar na
quebra dos digos de riptograa alemes durante a segunda grande guerra.

1.2.4 As Geraes
Costumava-se dividir os projetos de omputadores em geraes. Hoje em dia
omo a taxa de evoluo muito grande no se usa mais este tipo de terminologia. No entanto interessante men ionar estas divises.
Os omputadores onstrudos om rels e vlvulas so os
da primeira gerao. Estes omputadores onsumiam muita energia e
espao.

Primeira Gerao:

Os omputadores da segunda gerao foram onstrudos


om transistores, os quais tinham a vantagem de serem mais ompa tos e
onsumirem muito menos energia. Por gerarem menos alor eram mquinas mais onveis.

Segunda Gerao:

Com o advento dos ir uitos integrados, que so omponentes em que vrios transistores so onstrudos em uma mesma base
de semi ondutor, hegamos aos omputadores de ter eira gerao. Com
a integrao o tamanho dos omputadores e seu onsumo diminuiu ainda
mais e aumentou a apa idade de pro essamento.

Ter eira Gerao:

20

Os omputadores de quarta gerao utilizavam ir uitos


om a te nologia (Very Large S ale Integration), que permitia uma es ala
de integrao de transistores muito grande.

Quarta Gerao:

1.3 O Hardware
O hardware orresponde aos ir uitos eletrni os e omponentes me ni os que
ompem o omputador. Um tpi o diagrama em blo os de um omputador
digital monopro essado esta mostrado na Figura 1.7. A Unidade Central
de Pro essamento (UCP), em ingls Central Pro essing Unit (CPU), omo o
prprio nome diz, a unidade onde os dados so pro essados, ou seja alterados,
no omputador. Ou seja, dentro das UCPs os dados so somados, subtrados
et . A UCP tambm ontrola a movimentao dos dados dentro de todo o
sistema. Os mdulos que onstituem a UCP so os seguintes:
omanda a operao do omputador. Esta unidade l da memria tanto as instrues omo os dados e omanda todos
os ir uitos para exe utar ada instruo lida da memria. Atualmente as
unidades de ontrole so apazes de exe utar mais de uma instruo por
i lo de mquina, o que ara teriza o pro essamento paralelo. A t ni a
mais omum para onseguir este paralelismo onhe ida omo pipelining,
que ser detalhada mais adiante.

Unidade de Controle (UC):

lo al onde as transformaes sobre


os dados a onte em. Atualmente esta unidade bastante sosti ada e
diversos mtodos so empregadas para a elerar a exe uo das instrues.
Alguns pro essadores dupli am ir uitos para permitir que mais de uma
operao aritmti a seja exe utada por vez. muito omum, por exemplo, a existn ia de uma unidade aritmti a para exe utar instrues que
operam sobre nmeros inteiros e outra sobre nmeros reais, hamada de
unidade de ponto utuante. As vezes a UCP onta om mais de uma de
ada uma destas unidades.

Unidade Aritmti a e Lgi a (UAL):

ontrola a omuni ao om os usurios do omputador e os equipamentos perifri os tais omo dis os e impressoras. Em alguns omputadores mais simples esta unidade no existe
independentemente, sendo distribuda pela Unidade Central de Pro essamento. Em omputadores mais poderosos ao ontrrio as Unidades de
Entrada e Sada so omputadores ompletos que foram programados para
ontrolar a omuni ao om os perifri os.

Unidade de Entrada e Sada (UES):

O termo pipelining que men ionamos a ima se refere a um dos modos de


omo o pro essador pode paralelizar a exe uo de instrues. Este termo pode
ser traduzido por linha de montagem, porque exatamente isto que a t ni a
faz, uma linha de montagem de instrues. Por exemplo, em uma linha de
montagem de uma fbri a de automveis, mais de um automvel montado
ao mesmo tempo. No in io da linha o arro no existe. Em ada estgio da
linha de montagem os operrios vo adi ionando partes e ao m da linha sai
um arro novo. Se vo olhar a linha poder ver arros em diversos estgios da
21

Unidade
de
Controle

Unidade
de
Entrada
e
Sada
Memria

Unidade
Arimtica

Discos

Vdeo

Unidade
Central
de
Processamento

Figura 1.7: Diagrama Bsi o de um Computador Digital

montagem. Repare que a linha no pra, e a montagem de um arro no espera


que o que omeou a ser montado antes dele esteja terminado. Nas linhas de
montagem muitos arros so montados ao mesmo tempo. O efeito nal que
ada arro ontinua levando bastante tempo para ser montado, mas omo vrios
vo sendo montados ao mesmo tempo, algum que se olo asse no nal da linha
de montagem teria a impresso que ada arro leva muito pou o tempo para
ser montado. Isto porque no nal da linha de montagem sai um arro a ada
pou os minutos. O mesmo a onte e om a linha de montagem de instrues.

1.3.1 Mi ro omputadores
Uma UCP integrada em um ni o ir uito ( hip) omumente hamada de
Os mi ropro essadores atuais in luem outros ir uitos que
normalmente  avam fora da UCP, tais omo pro essadores de ponto utuante
e memrias a he. Alguns exemplos de mi ropro essadores so mostrados na
Tabela 1.3
mi ropro essador .

Mi ropro essador

Empresa

Arquitetura Intel X86


PowerPC
Power
MIPS
ARM
SPARC

Intel, AMD
Consr io Apple/IBM/Motorola
IBM
MIPS Te hnologies
ARM Te hnologies
SUN

Tabela 1.3: Exemplos de Mi ropro essadores


Usualmente se hama de omputador, o pro essador mais os seus perifri os
e os sistemas para ontrolar estes perifri os, ou seja todo o sistema de pro essamento de dados. Os perifri os so os dispositivos usados para fazer a entrada
e sada dos dados que sero pro essados.
Os mi ro omputadores so omputadores baseados em mi ropro essaAs assim hamadas pla as me dos mi ropro essadores atuais in luem

dores.

22

diversos omponentes que formam o mi ro omputador. Por exemplo, uma pla a


me pode in luir o mi ropro essador e seus ir uitos de suporte, que, no onjunto so onhe idos omo o hipset. Alm disso a pla a me pode in luir tambm a memria prin ipal e as pla as de ontrole de perifri os, omo a pla a de
vdeo, e os one tores para os perifri os, enm, quase todo o sistema.

1.3.2 Memrias
Os dados no omputador podem ser armazenados em diversos nveis de memria
semi ondutoras ou em perifri os (dis os, tas, et ). Quanto mais rpida a
memria, usualmente mais ara ela . A idia por traz da separao em nveis
olo ar mais perto do pro essador, em memrias rpidas e mais aras, os
dados que o pro essador ir pre isar mais freqentemente. A medida que vamos
nos afastando do pro essador as memrias vo, ao mesmo tempo,  ando mais
baratas, aumentando de apa idade e diminuindo de velo idade. A Figura 1.8
ilustra esta hierarquia.

PROCESSADOR

MEMRIA

DISCO

CACHE
REGISTRADORES

Figura 1.8: Nveis de hierarquia da memria de um omputador.


No nvel mais prximo do pro essador esto os registradores , que, na verdade,  am internamente ao pro essador. So pou os e extremamente rpidos
e, portanto, no podem armazenar grandes quantidades de dados. Somente os
dados que so ne essrios ao pro essador om rapidez extraordinria devem ser
olo ados nos registradores.
Durante o pro essamento normal, na memria prin ipal onde o pro essador bus a instrues e dados de um programa para exe utar. Alm da memria
prin ipal esto os dis os. Devido a sua velo idade menor que a da memria
prin ipal e a sua grande apa idade, os dis os so onsiderados dispositivos de
armazenamento se undrio. Os dis os tambm so memrias de armazenamento
permanente, isto , quando os omputadores so desligados o seu ontedo se
mantm. Ao ontrrio, a memria prin ipal e os registradores so memrias
semi ondutoras e perdem seus ontedos quando a energia eltri a desligada.
Em alguns omputadores os dis os esto sendo substitudos por memrias semi ondutoras.
Para a elerar o a esso aos dados freqentemente usados, os omputadores
dispem de memrias mais rpidas, porm de menor apa idade, que  am entre os registradores e a memria prin ipal. Estas fun ionam omo as bolsas ou
arteiras em que arregamos do umentos e outros itens que pre isamos freqentemente. Este tipo de memria onhe ido omo memria a he. O a he
opera de forma invisvel para o pro essador. Ao pedir um dado para memria,
23

ir uitos espe iais veri am se este dado est no a he, aso esteja, ele repassado para o pro essador. Para o pro essador o que a onte eu que a memria
entregou o dado om uma rapidez maior do que o normal.
Uma memria omo se fosse uma srie de ofres numerados apazes de
armazenar os dados, omo est ilustrado na Figura 2.3. Os dados e instrues
na memria so apontados ou referen iados por estes nmeros, onhe idos omo
endereos. Ou seja, para ler um dado da memria ne essrio forne er um
endereo para que a memria possa en ontrar e devolver o ontedo pedido. Isto
similar ao o que o orre quando enviamos uma arta, o endereo faz om que o
arteiro saiba onde ele deve entregar a orrespondn ia. Em operao normal,
toda vez que o pro essador pre isa de um dado ele envia um pedido de leitura
memria junto om o endereo da memria onde o dado est. Nas es ritas
o pro essador envia o endereo, o dado e pedido de es rita. Normalmente a
memria somente pode atender um pedido de ada vez. Portanto, para ler 1000
nmeros o pro essador ter de fazer 1000 a essos seqen ialmente.
Os dois tipos bsi os de memria mais omuns so ROM e RAM. Estas
siglas tm diversas variaes (PROM, EPROM, DRAM, et ), mas os prin pios
bsi os so os mesmos. Estas siglas indi am os dois tipos bsi os de memria
que so usadas em omputadores. A sigla bsi a ROM signi a Read Only
Memory, ou seja, memria de somente de leitura. A outra sigla RAM (Random
A ess Memory) signi a memria de a esso randmi o, portanto, memria que
se pode ler em qualquer endereo.
A sigla RAM muito onfusa porque em uma memria ROM tambm se
pode ler em qualquer endereo. A diferena real que nas RAMs se pode ler e
es rever om a mesma velo idade em qualquer endereo, enquanto que na ROM,
o a esso rpido somente para leituras, a es rita uma histria mais ompli ada.
A ROM normalmente ontm dados que no podem ser modi ados durante o
fun ionamento do omputador. Outro tipo de dados armazenados em ROMs so
os que no devem ser perdidos quando o omputador desligado. Exemplos de
uso de ROM so as memrias que armazenam os programas que so exe utados
quando os omputadores so ligados, os famosos BIOS (Basi Input Output
System). Um omputador ao ser ligado deve ter um programa mnimo apaz
de ini iar o seu fun ionamento normal, aso ontrrio seria omo uma pessoa
que perdeu totalmente a memria. Para isto so es ritos programas simples que
fazem a esso aos perifri os em bus a do Sistema Opera ional da mquina.
As primeiras memrias do tipo ROM eram gravadas nas fbri as e nun a
mais eram modi adas. Isto trazia algumas di uldades, por exemplo, quando
um programa pre isava ser atualizado. Para resolver este tipo de problemas
surgiram as PROMs, que so ROMs programveis. Ou seja possvel desgravar
o ontedo antigo e gravar novos programas nesta memria. Antigamente este
era um pro esso ompli ado e exigia que a memria fosse retirada si amente
do ir uito e olo ada em dispositivos espe iais apazes de apagar o ontedo
antigo. Em seguida um ir uito programador de PROMs era usado para gravar
o novo ontedo e somente aps tudo isto a memria era re olo ada no lo al.
O omputador  ava literalmente sem a memria dos programas ini iais. Hoje
em dia existem PROMs que podem ser apagadas e regravadas muito fa ilmente.
Por exemplo, as EEPROMs (Eletri aly Erasable PROMs), que so memrias
que podem ser apagadas eletri amente sem a ne essidade de serem retiradas
24

dos ir uitos. Flash memory uma forma de memria no voltil que pode
ser apagada e reprogramada eletri amente. Diferentemente das EEPROMs, ela
deve ser apagada em blo os de endereos. Este tipo de memria usta menos
do que EEPROMs e portanto so preferidas quando ne essrio usar memria
no voltil em forma de ir uitos integrados.
As memrias RAMs so as memrias onde os nossos programas omuns
rodam. Elas so modi veis e de a esso rpido tanto na leitura quanto na
gravao. Muitas siglas apare em e desapare em quando falamos de memrias
RAM. Existem as DRAM, memrias EDO, SIMM, et . Tudo isto ou se refere ao
mtodo de a esso dos dados na memria ou a te nologia de onstruo ou a outra
ara tersti a a essria. O erto que todas elas tem omo ara tersti a bsi a
o fato dos a essos de leitura e es rita poderem ser feitos na mesma velo idade.

1.3.3 Bits e Bytes


A memria do omputador omposta de bits, a menor unidade de informao
que o omputador armazena. Um bit pode onter o valor 0 ou 1, que so os
dgitos usados na base dois, a base usada nos omputadores. Um onjunto de
8 bits forma o byte. Uma palavra de memria um onjunto de bytes.
Atualmente a maioria dos omputadores tem palavras de memria om largura
de 32 (4 bytes) ou 64 (8 bytes) bits. Na Figura 1.9 mostramos os diversos
tamanhos dos dados.
BIT

BYTE
8 BITS

PALAVRA
32 BITS
4 BYTES

Figura 1.9: Tamanho de Bits, Bytes e Palavras


Observar que estamos falando de dados na memria e no do tamanho dos
dados que o omputador pode pro essar. Considere que este tamanho rela ionado om a quantidade mxima de algarismos que um nmero pode ter para ser
pro essado. Um omputador pode ter apa idade de pro essar 64 bits de ada
vez. Caso sua memria tenha palavras de 32 bits o pro essador dever, ento,
ler duas palavras da memria para poder pro essar um nmero. Lembre-se que
as duas leituras so atendidas uma de ada vez. Da mesma forma o omputador
pode pro essar 32 bits de ada vez e a memria ter largura 64 bits. Isto pode
a elerar o pro essamento, j que o pro essador est se adiantando e re ebendo
o que poder ser o prximo dado a ser pro essado, ou seja e onomizando uma
leitura.
Devido a base 2 o fator kilo tem um signi ado diferente em omputao.
Por exemplo 1 Kbyte de memria orresponde a 2 elevado a 10 (210 ), ou seja
25

1024 bytes. Da mesma forma 1 Megabyte orresponde a 1024 x 1024 bytes e 1


Gigabyte igual a 1024 x 1024 x 1024 bytes. Na Tabela 1.4 esto mostradas as
diversas abreviaes usadas quando se fazem refern ias s memrias.
Nome

Kilobyte
Megabyte
Gigabyte
Terabyte
Petabyte
Exabyte

Smbolo

Kb
MB
GB
TB
PB
EB

Multipli ador

210 = 1024
220
230
240
250
260

Tabela 1.4: Abreviaes usadas em refern ias s memrias.

1.3.4 Perifri os
Como j men ionamos antes, os dados no  am guardados somente na memria, h tambm os perifri os . H perifri os de entrada, outros de sada
e alguns que servem tanto para entrada omo sada de dados. Perifri os no
servem somente para armazenar dados. H perifri os que so usados para permitir a interao entre os usurios e o omputador. A tabela 1.5 ilustra alguns
destes perifri os.
Entrada

Te lados
Mouse
CD-ROM
S anner

Sada

Impressoras
Vdeo
Plotter
Alto-falantes

Ambos

Dis os Rgidos
Fitas Magnti as
Disquetes
Dis os Zip

Tabela 1.5: Exemplos de perifri os

1.4 O Software
Tudo isto que sobre o que a abamos de es rever onstitui o hardware do omputador, o que se v e o que se to a. A partir de agora falaremos brevemente
no software, o que no se v nem se to a, mas tambm est l.
Para que um omputador exe ute alguma tarefa primeiro se desenvolve um
algoritmo , que uma esp ie de re eita que diz pre isamente, ao omputador,
omo o problema deve ser resolvido. Esta denio informal de algoritmo
enganosamente simples, e a have para entender o engano est nas palavras
dizer pre isamente ao omputador. Por exemplo, uma re eita em gastronomia
normalmente no um algoritmo. Re eitas so entendidas pela omunidade de
ozinheiros, que as seguem fa ilmente durante o preparo do prato. No entanto,
re eitas esto heias de expresses omo, por exemplo, mexer at  ar no ponto
26

e  olo ar sal a gosto. Fora da omunidade de ozinheiros estas expresses so


passveis de vrias interpretaes. Para es rever algoritmos pre isamos de uma
linguagem matemati amente pre isa e sem ambigidades.
A es rita de um algoritmo onsta de uma denio do estado ini ial do
problema a ser resolvido e de regras pre isas que estabele em a ada instante
os passos a serem seguidos. Como em um jogo, alm de denir os passos, so
ne essrias regras que denam se aps a exe uo de um passo do algoritmo o
novo estado do problema vlido. As regras do xadrez denem o estado ini ial
do tabuleiro, os movimentos possveis de ada pea e se aps um movimento
de uma pea a ongurao atingida vlida. Ou seja pre isamos veri ar em
ada instante qual dos movimentos (instrues) pode ser usado.
Algoritmos podem ser hamados de pro edimentos efetivos e devem obede er
aos seguintes limites:
sempre dar alguma resposta;
sempre dar a resposta orreta e nun a uma resposta in orreta;
terminar em um nmero nito de passos;
trabalhar em todos os exemplos da lasse de problemas que o algoritmo
se prope a resolver.

Em seguida este algoritmo deve ser traduzido para uma linguagem que possa
ser entendida pelo omputador ou que possa ser traduzida para esta linguagem.
No in io da omputao eletrni a om programas armazenados, estes eram
es ritos diretamente em linguagem de mquina que a linguagem que o omputador realmente entende. Estas instrues so onjuntos de bits indi ando
a operao que deve ser exe utada e, aso ne essrio, onde omo a har os dados
que sero operados. Por esta razo tambm ostuma-se dizer que so programas
es ritos em binrio.
Com a evoluo da omputao os programas passaram a ser es ritos em
assembly , que uma representao em mnemni os das instrues de mquina.
Deste modo era mais f il es rever os algoritmos. Por exemplo, um fragmento
de um programa es rito em assembly do pro essador PowerPC :

li r3,4
* O primeiro numero a ser somado e 4.
li r4,8
* 8 e o segundo numero
add r5,r4,r3 * Some os ontedos de r3 (4) e r4 (8)
* e armazene o resultado em r5
Este pequeno tre ho de programa armazena os nmeros 4 e 5 em registradores internos do pro essador em seguida os soma e armazena o resultado em um
ter eiro registrador. As informaes aps os asteris os so omentrios usados
para expli ar o que o programa est fazendo naquela instruo.
O PowerPC um mi ropro essador riado em 1991 por um onsr io formado pela IBM, Apple e Motorola Os mi ropro essadores PowerPC podem ser
usados para equipar desde sistemas embutidos at omputadores de alto desempenho. A Apple usou este mi ropro essador para equipar suas mquinas at
2006.

27

Um programa es rito em assembly deve ser traduzido para a representao


binria, tarefa que normalmente se hama de montar o programa. A palavra
assembler frequentemente usada erradamente para signi ar a linguagem e
no o programa que traduz o programa de assembly para linguagem binria de
mquina. Este tipo de programao pode levar a se es rever programas muito
e ientes, devido ao ontrole quase que total do programador sobre a mquina.
No entanto devido ao fato de ser uma linguagem prxima do omputador e afastada da maneira de ra io inar do ser humano mais dif il de ser usada. Alm
deste fato h outros problemas tais omo: di uldade de leitura por humanos,
di uldade de manuteno dos programas, maior tempo de desenvolvimento et .
Para evitar estes problemas foram desenvolvidas as linguagens de programao hamadas de linguagens de alto nvel, por estarem mais prximas da
linguagem natural empregada pelos serem humanos. Alguns exemplos de linguagens de programao so:
Fortran:

Usada em ensino de linguagens e desenvolvimento de sistemas;

Pas al:

COBOL:
Basi :

Usada em programao ient a e engenharia;

Usada em ambientes omer iais;

O nome diz tudo, bsi a;

C: Mesmas ara tersti as do Pas al om fa ilidades que permitem mais ontrole


do omputador;
C++:

Linguagem originria do C om metodologia de orientao objetos;

Linguagem tambm baseada na sintaxe do C e tambm seguindo o modelo de orientao objetos.

Java:

Linguagem originria do Pas al om metodologia de orientao objetos;

Delphi:

Lisp e Prolog:

Arti ial.

Linguagens usadas para desenvolver programas de Intelign ia

Apli ativos importantes para os programadores so os ompiladores. Estes programas traduzem programas es ritos em linguagens de alto nvel para
a linguagem de mquina, de modo que o omputador possa exe ut-los. De
maneira geral um ompilador um programa que traduz um programa de uma
linguagem para outra.
Podemos resumir os passos ne essrios para riar um programa em uma
linguagem de programao, por exemplo C, nos passos des ritos a seguir. A
Figura 1.10 ilustra a ordem em que se desenvolvem estes passos.
neste passo riado o algoritmo que ir resolver o
problema. As diversas maneiras de des rever um algoritmo sero apresentadas no prximo aptulo.

Criao do Algoritmo:

28

O algoritmo preparado no passo anterior es rito em uma linguagem de programao. Neste passo o programador
onta, normalmente, om a ajuda de um editor de textos (no pro essador de textos). Para esta edio qualquer editor pode ser usado. Hoje
em dia muitos ambientes de desenvolvimento integram todas as ferramentas ne essrias para riar um programa, in lusive o editor, em um ni o
apli ativo.

Codi ao do Algoritmo:

O arquivo texto ontendo o programa passa por


um programa espe ial hamado ompilador que gera, aso no hajam erros, uma sada que quase o programa exe utvel, ou seja o programa
em digo binrio do pro essador em que ser exe utado. Os erros mais
omuns nesta etapa so erros de uso orreto da linguagem de programao. Estes erros so hamados de erros de ompilao. As linguagens de
programao so baseadas em regras gramati ais muito rgidas e qualquer
violao destas regras pode impli ar em erro. No aso de erros serem
en ontrados o programador deve voltar ao passo de odi ao para a
orreo dos erros.

Compilao do Programa:

Em ingls este passo onhe ido por link edition. Um programa


ompleto omposto por vrios mdulos que podem ter sido riados pelo
prprio programador ou por outras programadores. Por exemplo, em C
os tre hos de programa que interagem om os usurios, os omandos de
entrada e sada de dados, normalmente vm om o programa ompilador.
Estes tre hos podem estar guardados em bibliote as de programas e so
ligados ao programa do usurio para ompletar o programa.

Ligao:

Nesta etapa o programa ser testado para a retirada


dos possveis erros de lgi a que o programador ometeu. Caso algum
erro de exe uo seja en ontrado o programador deve reelaborar o que
estiver errado no algoritmo e em seguida ir para a etapa de odi ao do
algoritmo. Este i lo pode repetir-se inmeras vezes at que o desenvolvedor a redite que os erros foram orrigidos.

Depurao e Testes:

O programa foi entregue aos seus usurios para ser usado. Durante o uso, erros que no foram en ontrados durante o desenvolvimento do programa podem ser des obertos e pre isam ser orrigidos. A
orreo pode ser feita pelos mesmos programadores que desenvolveram o
programa ou por outro grupo devidamente treinado. Costuma-se hamar
esta orreo de manuteno do programa.

Uso do Programa:

Algumas linguagens de programao no so ompiladas e sim interpretadas.


Isto signi a que o programa para ser exe utado no pre isa ser traduzido diretamente para linguagem de mquina, gerando um arquivo exe utvel. Este arquivo nal, se torna independente do programa fonte. Para exe utar o programa
podemos usar somente o arquivo exe utvel. Em um programa interpretado um
apli ativo l o programa instruo por instruo, diretamente na prpria linguagem de alto nvel, traduz ada uma destas instrues para linguagem de
mquina e as exe uta. No h, portanto, o pro esso de traduo ante ipada
do programa. A interpretao de um programa fun iona omo o pro esso de
traduo simultnea do dis urso de um orador. A medida que ele pronun ia seu
29

Incio
Ligao

Criao de
Algoritmo

Depurao e
Testes

Sim

Codificao do
Algoritmo

Erros de
Execuo?
No

Compilacao do
Programa

Uso do programa

Sim

Sim

Erros de
Compilao?

Erros de
Execuo?

No

Figura 1.10: Ci lo de desenvolvimento de um programa.

dis urso um tradutor repete as frases na linguagem destino. Um programa ompilado fun iona omo se primeiro, o tradutor traduzisse todo o dis urso e depois
o lesse. A linguagem Basi uma linguagem interpretada. Em Java o orre um
pro esso um pou o diferente. Um programa em Java traduzido para uma linguagem intermediria e depois interpretado por meio de uma hamada mquina
virtual. No h efetivamente uma ompilao para linguagem de mquina. A
exe uo de um programa es rito em uma linguagem interpretada mais lenta,
j que o pro esso de interpretao e exe uo ao mesmo tempo mais lento do
que a simples exe uo de um programa traduzido ante ipadamente.
Hoje em dia a maior parte dos usurios de omputadores no so programadores e sim pessoas que usam programas para resolver seus problemas do dia
a dia. Apli ativos tpi os que rodam nos omputadores so: editores de texto,
pro essadores de texto, planilhas eletrni as, ompiladores, ban os de dados,
jogos, et .
Para geren iar os re ursos do omputador existe um programa espe ial normalmente hamado de Sistema Opera ional (S. O.). Por exemplo, onsidere o
problema de geren iar omo os diversos programas que um usurio normalmente
utiliza partilharo o pro essador do omputador. Um usurio pode estar ouvindo msi a, digitando um texto e imprimindo um outro do umento ao mesmo
tempo. Portanto, os omputadores so apazes de exe utar um nmero de tarefas muito maior do que o nmero de pro essadores disponveis. Atualmente
a maior parte dos omputadores possui somente um pro essador. O Sistema
Opera ional ontrola a alo ao de re ursos tais omo: omuni ao om os
usurios, espao em dis os, uso de memria, tempo que ada programa pode rodar et . Alguns dos sistemas opera ionais onhe idos so os baseados no padro
UNIX, por exemplo o LINUX. Outros sistemas muito usados so os da famlia
30

Windows.
Compilando Programas Simples em

Para resolver os exer ios deste livro vo ir pre isar de um ompilador para a
linguagem C e de um editor de textos simples (no pro essador omo o Word).
O editor pode ser to simples quanto o Notepad, na verdade re omendamos
fortemente que o editor seja simples para que vo possa ter ontato om todas
as etapas do pro esso de desenvolvimento de um programa. Para ompilar
empregaremos o ompilador g que gratuito e pode ser obtido na Internet
omo veremos adiante. No ser ne essrio nenhum ambiente mais omplexo,
tal omo um Integrated Development Environment (IDE).
A oleo de ompiladores da GNU (GNU Compiler Colle tion) usualmente
abreviada por g , uma oleo de ompiladores produzidos pelo projeto GNU.
A abreviao g , originalmente, signi ava GNU C Compiler. Este apli ativo
distribudo gratuitamente pela Free Software Foundation (FSF) sob a li ena
GNU GPL e GNU LGPL. Este o ompilador padro para os sistemas opera ionais livres do tipo Unix, omo o LINUX, e diversos sistemas opera ionais
proprietrios omo o Apple Ma OS X. Atualmente o g pode ompilar C++,
Obje tive-C, Java, Fortran e ADA, entre outras linguagens. Vamos onsiderar, omo exemplo, um programa hamado teste. . Para ompilar e gerar o
exe utvel para este programa digitamos o omando
g -o teste teste. -Wall
em uma janela de omandos no sistema Windows ou em um terminal nos sistemas Unix. O suxo . no nome do programa normalmente usado para indi ar
que o arquivo de um programa C. Este omando deve ser digitado no diretrio
onde est o arquivo fonte teste. . O arquivo exe utvel ser armazenado no
mesmo diretrio.
Nos sistemas Unix normalmente o g faz parte da distribuio padro e
nada pre isa ser feito. No Windows uma maneira f il de obter uma verso
do g instalar o MinGW (Minimalist GNU for Windows). MinGW uma
oleo de arquivos e bibliote as distribudas livremente as quais ombinadas
om outras ferramentas da GNU permitem que programas para Windows sejam
produzidos sem a ne essidade de bibliote as extras e pagas. O MinGW dispe
de um programa instalador que fa ilita enormemente o pro esso. Este programa
pode ser obtido no stio o ial do MinGW. Caso aps a instalao, o omando
indi ado no fun ione uma das razes para a falha pode ser que o sistema opera ional no sabe onde se en ontra o ompilador g . Suponha que o programa
g foi instalado no diretrio C:\MinGW\bin. Uma soluo digitar o aminho
ompleto do ompilador. Neste aso o omando se torna

C:\MinGW\bin\g -o teste teste. -Wall


Para que no seja ne essrio digitar o aminho ompleto, pre iso adi ionar este aminho varivel PATH do Windows. Consulte o manual para obter
informaes de omo fazer este passo no seu sistema Windows.

31

1.5 Um programa em C
Vamos terminar este aptulo mostrando um exemplo simples de programa es rito em C(Listagem 1.1). A ni a oisa que este programa faz imprimir Alo
Mundo! e terminar [?, ?, ?.
A primeira linha do programa avisa ao ompilador que ir usar funes de
entrada e sada de dados guardadas na bibliote a stdio. Neste aso a funo
usada printf. A segunda linha o in io real do programa. A linha indi a que
esta a funo main que todo programa C deve onter, pois nesta funo que
o programa obrigatoriamente omea sua exe uo. A funo vai retornar um
valor inteiro (int) ao nal de sua exe uo e no vai pre isar re eber nenhum
argumento para sua exe uo (void). As haves ({ e }) mar am o in io e o
m da funo. Para imprimir o texto Alo Mundo! o programa usa a funo
printf. O in io e o m do texto a ser impresso so mar ados pelo ara tere ".
A funo termina om o omando return 0, que avisa ao sistema opera ional,
que foi quem ini iou a exe uo do programa, que o programa terminou sem
problemas. Este programa simples ilustra alguns das estruturas bsi as que
sero usadas nos programas C que sero apresentados neste livro.

Listagem 1.1: Exemplo de Programa em C.

#in lude
int main
{
}

< stdio .h >


( void )

printf ( " Alo Mundo !\ n " ) ;


0;

return

32

1.6 Exer ios


1.1:

O que o hardware do omputador?

1.2:

Quais os prin ipais omponentes de um omputador?

1.3:

Quais as diferenas entre um mi ropro essador e o mi ro omputador?

1.4:

D exemplos de mi ropro essadores e de mi ro omputadores.

1.5:

Qual o nmero exato de bytes em 64 Kbytes?

1.6:

Se vo j usa omputadores, liste alguns apli ativos que vo normalmente

1.7:

Dena Sistema Opera ional.

1.8:

Qual a diferena bsi a entre memrias ROM e RAM?

usa.

1.9: Pro ure em manuais, internet e outras fontes quais so os tempos de a esso
das memrias RAMs atuais.

Faa trs listas, uma de perifri os de entrada, outra de perifri os de


sada e nalmente uma de perifri os de entrada e sada.

1.10:

1.11:

Explique o que faz um ompilador.

1.12: Dis uta as vantagens e desvantagens das linguagens interpretadas e as


ompiladas.
1.13:

O que so erros de ompilao e de exe uo.

Pro ure nomes de linguagens de programao no listadas no texto e diga


quais so as suas ara tersti as prin ipais.

1.14:

33

Captulo 2
Algoritmos

2.1 Introduo
O objetivo deste aptulo fazer uma breve introduo ao on eito de algoritmos e apresentar algumas formas mais omuns de representar algoritmos para
fa ilitar o entendimento dos demais aptulos deste livro. Iremos apresentar as
onstrues mais omuns empregadas no desenvolvimento de algoritmos e apresentaremos exemplos bsi os de algoritmos usando algumas destas formas de
representao e onstrues.
Para resolver um problema no omputador ne essrio que seja primeiramente en ontrada uma maneira de des rever este problema de uma forma lara
e pre isa. pre iso que en ontremos uma seqn ia de passos que permitam
que o problema possa ser resolvido de maneira automti a e repetitiva. Alm
disto pre iso denir omo os dados que sero pro essados sero armazenados no omputador. Portanto, a soluo de um problema por omputador
baseada em dois pontos: a seqn ia de passos e a forma omo os dados sero
armazenados no omputador. Esta seqn ia de passos hamada de algoritmo.
Usamos algoritmos em diversas atividades que realizamos diariamente. Uma
grande parte destas atividades no esto rela ionadas om omputao. Um
exemplo simples e prosai o, de omo um problema pode ser resolvido aso forneamos uma seqn ia de passos que mostrem a maneira de obter a soluo,
uma re eita para preparar um bolo.
Uma vez que foi riado um algoritmo para resolver um determinado problema usando omputadores passamos para a prxima fase que a es rita deste
algoritmo em alguma linguagem de programao.
A noo de algoritmo entral para toda a omputao. A riao de algoritmos para resolver os problemas uma das maiores di uldades dos ini iantes
em programao em omputadores. Isto porque no existe um onjunto de regras, ou seja um algoritmo, que nos permita riar algoritmos. Caso isto fosse
possvel a funo de riador de algoritmos desapare eria. Claro que existem
linhas mestras e estruturas bsi as, a partir das quais podemos riar algoritmos, mas a soluo ompleta depende em grande parte do riador do algoritmo.

34

Geralmente existem diversos algoritmos para resolver o mesmo problema, ada


um segundo o ponto de vista do seu riador.
No seu livro Fundamental Algorithms vol. 1 Donald Knuth [? apresenta
uma verso para a origem desta palavra. Ela seria derivada do nome de um
famoso matemti o persa hamado Abu Jafar Maom ibn Ms al-Khowrism
(825) que traduzido literalmente quer dizer Pai de Jafar, Maom, lho de
Moiss, de Khowrizm. Khowrizm hoje a idade de Khiva, na ex Unio
Soviti a. Este autor es reveu um livro hamado Kitab al jabr wal-muqabala
(Regras de Restaurao e Reduo). O ttulo do livro deu origem tambm a
palavra lgebra.
O signi ado da palavra muito similar ao de uma re eita, pro edimento,
t ni a, rotina. Um algoritmo um onjunto nito de regras que forne e uma seqn ia de operaes para resolver um problema espe  o. Segundo o di ionrio do prof. Aurlio Buarque de Holanda um algoritmo

um:

Pro esso de l ulo, ou de resoluo de um grupo de problemas semelhantes, em que se estipulam, om generalidade e sem restries,
regras formais para a obteno de resultado ou de soluo de problema.
Um algoritmo opera sobre um onjunto de entradas (no aso do bolo, farinha
ovos, fermento, et .) de modo a gerar uma sada que seja til (ou agradvel)
para o usurio (o bolo pronto).
Um algoritmo omputa ional tem in o ara tersti as importantes:
Finitude:

sos.

Um algoritmo deve sempre terminar aps um nmero nito de pas-

Cada passo de um algoritmo deve ser pre isamente denido. As


aes devem ser denidas rigorosamente e sem ambiguidades.

Denio:

Um algoritmo deve ter zero ou mais entradas. Entradas so as


quantidades que so lhe so forne idas para pro essamento.

Entradas:

Um algoritmo deve ter uma ou mais sadas, isto quantidades que tem
uma relao espe  a om as entradas.

Sadas:

Um algoritmo deve ser efetivo. Isto signi a que todas as operaes devem ser su ientemente bsi as de modo que possam ser, em prin pio, exe utadas om pre iso em um tempo nito por um humano usando
papel e lpis.

Efetividade:

2.2 Primeiros Passos


laro que todos ns sabemos onstruir algoritmos. Se isto no fosse verdade,
no onseguiramos sair de asa pela manh, ir ao trabalho, de idir qual o melhor
aminho para hegar a um lugar, voltar para asa, et . Para que tudo isto seja
feito ne essrio uma srie de entradas do tipo: a que hora a ordar, que hora
35

sair de asa, qual o melhor meio de transporte et . Um fator importante


que pode haver mais de um algoritmo para resolver um determinado problema.
Por exemplo, para ir de asa at o trabalho, posso es olher diversos meios de
transporte em funo do preo, onforto, rapidez, et . A es olha ser feita em
funo do ritrio que melhor se adequar as nossas ne essidades. Um exemplo
de algoritmo pode ser as instrues que um professor passa aos seus alunos em
uma a ademia de ginsti a, mostrado no Algoritmo 2.1. Observar que nesta
representao do algoritmo ada linha ontm uma instruo.
Algoritmo 2.1:

Exemplo de Algoritmo.

in io
enquanto

no fez 10 vezes faa


Levantar e abaixar brao direito
Levantar e abaixar brao esquerdo
Levantar e abaixar perna esquerda
Levantar e abaixar perna direita

m enqto
m

Computadores so mquinas muito e ientes na resoluo de problemas matemti os ou que envolvam nmeros. Como exemplo de um algoritmo matemti o, vamos onsiderar o problema de resolver uma equao do primeiro grau da
forma
ax + b = 0
A soluo desta equao
x = b/a

se o valor de a for diferente de 0. Caso a seja igual a 0, a equao no possui


soluo, j que no possvel dividir por 0. Este algoritmo es rito (Algoritmo
2.2) em uma pseudo-linguagem de programao  aria da seguinte maneira:
Algoritmo 2.2:

Algoritmo para resolver uma equao do primeiro grau.

Entrada: Coe ientes a e b da equao ax + b = 0


Sada: Resultado x da Equao
in io
ler a
ler b
se a = 0 ento
imprimir A equao nao tem soluo
seno

x b/a
imprimir
m se
m

A raiz da equao vale , x

As instrues do algoritmo so exe utadas passo a passo e uma instruo


somente exe utada quando a anterior terminou sua tarefa. Os dois primeiros
passos do algoritmo servem para o algoritmo obter os valores dos oe ientes a e
36

b. Os valores podem, por exemplo, serem digitados em um te lado pelo usurio


que est usando o algoritmo. O valor digitado vai para uma posio da memria
do omputador, que para fa ilitar o manuseio do dado, re ebe um nome. Neste
exemplo demos os nomes a, b e x as posies de memria usadas pelo programa
para armazenar dados. Aps os dois primeiros passos o algoritmo exe uta uma
instruo de teste para veri ar se o valor de a diferente de 0. Neste aso
podemos ter duas respostas e o omputador ir es olher entre dois aminhos
independentes e ex lusivos. Caso a seja igual a zero, o algoritmo exe uta as
instrues entre a palavra ento e seno, e portanto, imprime uma mensagem
de aviso para o usurio e termina. Esta mensagem normalmente apare e em
um monitor de vdeo. No aso de a ser diferente de zero, o algoritmo exe uta as
instrues entre seno e fim se. Isto signi a al ular o resultado da equao
e atribuir este resultado x. O ltimo passo, desta opo a impresso do
resultado da equao.

2.3 Representao
As formas mais omuns de representao de algoritmos so as seguintes:
Os algoritmos so expressos diretamente em linguagem
natural, omo nos exemplos anteriores.

Linguagem Natural:

Esta um representao gr a que emprega


formas geomtri as padronizadas para indi ar as diversas aes e de ises
que devem ser exe utadas para resolver o problema.

Fluxograma Conven ional:

Emprega uma linguagem intermediria entre a linguagem


natural e uma linguagem de programao para des rever os algoritmos.

Pseudo-linguagem:

No existe onsenso entre os espe ialistas sobre qual seria a melhor maneira de representar um algoritmo. Atualmente a maneira mais omum de
representar-se algoritmos atravs de uma pseudo-linguagem ou pseudo- digo.
Esta forma de representao tem a vantagem de fazer om que o algoritmo seja
es rito de uma forma que est mais prxima de uma linguagem de programao
de omputadores.

2.3.1 Linguagem Natural


A representao em linguagem natural tem a desvantagem de olo ar uma
grande distn ia entre a soluo en ontrada e o resultado nal do pro esso
que um programa em linguagem de programao. O Algoritmo 2.3 mostra
um algoritmo, es rito em linguagem natural, para al ular a mdia de um aluno
que faz trs provas e pre isa de obter mdia a ima de 5.0 para ser aprovado.

2.3.2 Fluxogramas
Esta forma de representao de algoritmos emprega vrias formas geomtri as
para des rever ada uma das possveis aes durante a exe uo do algoritmos.
37

Algoritmo 2.3:

Algoritmo para al ular a mdia das notas de um aluno.

Entrada: Notas n1 , n2 e n3 .
Sada: Resultado media do aluno
in io

e se ele foi aprovado ou no.

Obter as notas n1 , n2 e n3
Cal ular mdia. Usar a frmula ((n1 + n2 + n3 )/3.0).
Se a mdia for maior que 5.0 imprimir que o aluno foi aprovado
Caso ontrrio imprimir que o aluno foi reprovado.
Imprimir a mdia.

m

Existem algumas formas geomtri as que usualmente so empregadas neste mtodo. Estas formas esto mostradas na Figura 2.1. Cada uma destas formas se
apli a a uma determinada ao omo est indi ado na gura. Estas formas so
apenas alguns exemplos, existindo outras, no entanto, nesta apostila estas sero
su ientes para os exemplos que sero mostrados.
Incio e Fim de Fluxograma

Processamento

Ponto de Deciso

Entrada de Dados Manual

Impresso de Resultados

Conector para mesma pgina

Figura 2.1: Smbolos mais omumente usados em uxogramas.


Como exemplo de um algoritmo es rito em forma de uxograma, vamos
onsiderar o algoritmo 2.2 para resolver uma equao do primeiro grau da forma
ax + b = 0. A Figura 2.2 mostra um uxograma para resolver este problema.
Os dois primeiros passos do algoritmo lem os valores dos oe ientes a e
b da equao. Em seguida h um teste para des obrir se o valor de a igual
a zero. Se o valor de a for igual a zero o algoritmo manda que seja impressa
uma mensagem informando que a equao no tem soluo. Caso o valor de
a seja diferente os prximos passos al ulam o valor da soluo e em seguida
imprimem este resultado

2.3.3 Pseudo-Linguagem
Este modo de representar algoritmos pro ura empregar uma linguagem que esteja o mais prximo possvel de uma linguagem de programao de omputadores de alto nvel, mas evitando de denir regras de onstruo gramati al muito
rgidas. A idia usar as vantagens do emprego da linguagem natural, mas
restringindo o es opo da linguagem. Normalmente estas linguagens so verses
ultra reduzidas de linguagens de alto nvel do tipo Pas al ou C. O algoritmo 2.2
foi es rito em uma pseudo-linguagem. A maioria destas linguagens so muito
pare idas e tm a vantagem de serem fa ilmente entendidas. Vamos apresentar
38

Incio

Obter a

Obter b

Sim
a =0
No
No h razes
reais

x=-b/a

Imprime x

Fim

Figura 2.2: Fluxograma para resolver uma equao do primeiro grau.

agora um outro exemplo (Algoritmo 2.4) es rito em pseudo-linguagem. Este


algoritmo serve para des obrir qual a maior nota de um grupo de trs notas
de um aluno. O algoritmo ini ialmente l a primeira nota e guarda esta nota
omo a maior nota. Em seguida, l ada uma das outras notas e ompara om
a nota guardada omo a maior nota. Caso a nota lida seja maior substitui o
valor anterior pelo novo valor.
Apesar destas pseudo-linguagens terem pou as regras existem algumas que
normalmente so usadas para fa ilitar o entendimento entre os programadores.
Vamos detalhar algumas delas. As palavras in io e m indi am onde omea
e termina o algoritmo. As palavras em negrito indi am instrues que devem
ser exe utadas pelo omputador onde o algoritmo ser rodado. Por exemplo,
ler notaAluno uma instruo do algoritmo que ordena ao omputador para
obter a nota de um aluno para ser pro essada. Em algoritmos esta nota normalmente ser obtida de um perifri o de entrada de dados, sendo mais omum
o te lado. As palavras em itli o so normalmente hamadas de variveis e
representam lo ais na memria do omputador onde os valores a serem usados
durante o pro essamento esto armazenados. Os programadores podem in luir
nos algoritmos expli aes que fa ilitem o entendimento do seu fun ionamento.
Estes omentrios no so exe utados pelos omputadores e somente so lidos
pelos programadores. Existem diversas maneiras de indi ar que o texto no algoritmo apenas um omentrio. Neste exemplo usamos dois ara teres  para
indi ar que o restante da linha apenas um omentrio. Mais adiante outras
expli aes sero apresentadas.

39

Algoritmo 2.4:

notas.

Algoritmo para al ular a maior nota de um grupo de

Entrada: Trs notas de um aluno, (notaAluno).


Sada: Maior das notas do aluno, (maiorN ota)
in io

 L primeira nota

ler

notaAluno
maiorN ota notaAluno

 L segunda nota
ler notaAluno
se notaAluno >

maiorN ota ento


maiorN ota notaAluno

m se

 L ter eira nota


ler notaAluno
se notaAluno >

maiorN ota ento


maiorN ota notaAluno

m se
imprimir
m

A maior nota das notas , maiorN ota

2.4 Modelo de von Neumann


Algoritmos para omputadores se baseiam em alguns on eitos bsi os e em um
modelo de omputador, os quais devem ser bem entendidos para que se possa
riar algoritmos e ientes. Este modelo foi proposto pelo matemti o hngaro
Neumann Jnos Lajos Margittai. Em hngaro o nome de famlia apare e antes.
Assim em portugus o seu nome seria Jnos Lajos Margittai Neumann. O seu
pai, que era ri o, omprou um ttulo de nobreza e ele passou a se hamar Jnos
Lajos Margittai von Neumann. No modelo de omputador proposto por von
Neumann as instrues e os dados  am juntos na memria. O pro essador
bus a na memria e exe uta uma instruo de ada vez.
Para ilustrar omo este modelo fun iona vamos analisar passo a passo a
exe uo de um algoritmo simples. Na Figura 2.3 mostramos nos endereos 0, 1
e 2, de uma memria, um grupo de instrues formando parte de um algoritmo.
As instrues tambm podem ser a ompanhadas no Algoritmo 2.5. Vamos
assumir que o omputador ini ie exe utando o algoritmo a partir da instruo
que est no endereo 0. O pro edimento normal a Unidade de Controle (UC)
do omputador ontinuar bus ando e exe utando uma instruo de ada vez
nos endereos seguintes, a no ser que haja uma ordem para desviar o uxo das
instrues. importante observar que o omputador exe uta uma instruo de
ada vez, e omo veremos adiante, tambm um dado bus ado de ada vez.
Portanto, as transfern ias entre a memria e o pro essador so feitas passo a
passo. O i lo normal da exe uo de um programa ento:
1. Bus a instruo;
2. De odi a instruo;

40

3. Exe uta instruo;


4. Volta para o passo 1 bus ando a instruo seguinte na memria.
Portanto, aps a instruo do endereo 0 ser lida da memria e trazida para
a UCP, ela de odi ada pela UC, que des obre que a instruo manda arregar
o valor inteiro 2 na posio de memria 10, que hamada de a para fa ilitar.
A instruo seguinte ordena a arga do valor inteiro 8 na posio de memria
hamada de b, que a posio 11. A ltima instruo ordena a soma dos valores
armazenados em a e b e que o resultado seja armazenado na posio 12, que
hamada c.
Algoritmo 2.5:

Modelo de memria e fun ionamento de um algoritmo

 Armazena 2 na memria no lugar hamado a


a2

 Armazena 8 na memria no lugar hamado b


b8

 Soma a om b e armazena no lugar hamado


ca+b

Observe que no modelo de von Neumann instrues e dados  am na memria. Considere a ltima instruo do programa que pede para que os dados
da posio 10 (a) e 11 (b) sejam somados e o resultado armazenado na posio
12 (c). Para exe utar esta instruo, o omputador faz as seguintes operaes
na memria:
1. ler a instruo no endereo 2;
2. ler o dado a na posio 10;
3. ler o dado b na posio 11;
4. es rever o resultado da soma no endereo 12.
Portanto, temos 3 leituras e uma es rita. Destas operaes, a primeira
uma leitura de instruo e as restantes operaes om dados.

2.5 Estruturas Bsi as de Algoritmos


Com a nalidade de ilustrar omo riar algoritmos para omputadores usando
este modelo, vamos dis utir alguns tipos bsi os de estruturas usados nesta tarefa. Para isto, iremos usar a representao que for apropriada no momento.
No iremos neste livro dis utir em detalhes estes tpi os, nem apresentar de
uma maneira formal qualquer uma destas formas. O interesse apenas apresentar e dis utir algumas estruturas bsi as para ilustrar o pensamento usado pelos
programadores quando riam um algoritmo para resolver um problema espe  o. Estas estruturas so importantes e sero reapresentadas quando formos
apresentar a linguagem C. Para o programador ini iante esta dis usso serve
omo introduo.
41

a<-2

b<-8

12

13

14

15

c<-a+b
9

10

11

10

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

Endereo
Endereo
Endereo
Endereo
Endereo
Endereo

0: Instruo a <--2
1: Instruo b <--8
2: Instruo c <--a+b
10: Dado a
11: Dado b
12: Dado c

Figura 2.3: Modelo de memria

2.5.1 Comandos de leitura


Estes omandos servem para obter dados do mundo exterior, normalmente digitados por um usurio em um te lado. Outros exemplos de lugares de onde
podem ser obtidos dados so os arquivos em dis os rgidos, disquetes e tas
magnti as. Estes dados so lidos e guardados na memria para posterior uso.
Normalmente os lugares para onde vo estes dados re ebem um nome para
fa ilitar o seu manuseio durante a exe uo do algoritmo.
Por exemplo, o omando
ler

signi a que o algoritmo ir obter um dado do te lado e ir armazen-lo em uma


posio de memria que passar a ser onhe ida pelo nome a. Estas posies
so onhe idas por variveis em omputao. Costuma-se dizer ento que a
uma varivel do algoritmo. Apesar de a no algoritmo 2.2 representar uma das
onstantes da equao do primeiro grau no algoritmo ela uma das variveis.
Observe que ada vez que o algoritmo exe utado a pode assumir um valor
diferente, portanto varia de a ordo om a exe uo do algoritmo.
O omando pode ser seguido por uma lista de nomes separados por vrgulas.
Por exemplo o omando
ler

a, b

l dois valores do te lado e os atribui as variveis a e b. Observe que a ordem em


que os valores foram digitados determina omo os valores sero atribudos. O
primeiro valor lido atribudo a primeira varivel, no aso a. O segundo valor
lido atribudo a segunda varivel (b). Os valores normalmente so digitados
separados por um ou mais espaos em bran o ou em linhas diferentes.

2.5.2 Comandos de es rita


Aps a obteno dos resultados do algoritmo, estes devem ser apresentados ao
usurio, e para isto usamos os omandos de es rita. Por exemplo o omando
42

imprimir

imprime o valor atual que est na memria representada pelo nome x.


Da mesma forma que nos omandos de leitura possvel olo ar uma lista
de nomes de variveis aps o omando. Por exemplo, o omando
imprimir

x1, x2

imprime os valores das variveis x1 e x2. O meio de apresentao dos resultados,


normalmente, um monitor de vdeo.
O omando imprimir pode ser usado para mandar mensagens de texto
para o usurio do algoritmo das formas mais variadas. Alguns exemplos de
omandos de impresso so os seguintes:
imprimir
imprimir
imprimir

Entre om o valor do oe iente


O valor de x , x
O valor de x1 , x1,  e o de x2 , x2

Notar que os textos entre aspas indi am um texto que deve ser impresso no
perifri o de sada sem nenhuma modi ao. Vamos onsiderar que as variveis
destes exemplos valem x = 10, x1 = 5 e x2 = 8. Os trs omandos mostrariam
no perifri o de sada os seguintes resultados:

Entre om o valor do oefi iente.


O valor de x 10
O valor de x1 5 e o de x2 8

2.5.3 Expresses
Expresses so usadas para denir os l ulos requeridos pelo algoritmo, por
exemplo b/a. Iremos dis utir dois tipos bsi os de expresses: expresses aritmti as e expresses lgi as.
Expresses manipulam dados dentro dos algoritmos. Uma pergunta importante neste momento : que tipo de dados poderemos manipular? As linguagens
de programao normalmente estabele em regras pre isas para denir que tipos
de dados elas iro manipular. Nesta dis usso vamos estabele er, ainda que
informalmente, algumas regras que limitam os onjuntos de dados existentes na
Matemti a e estabele em que dados podero ser manipulados pelos algoritmos.
Isto o orre porque os omputadores possuem limitaes que os impedem de manipular todos os tipos de dados que um ser humano pode tratar. Mais adiante,
quando formos estudar a linguagem C iremos apresentar mais formalmente as
regras desta linguagem para estas representaes. Existem trs tipos bsi os de
dados que iremos dis utir:
Dados numri os:

omo o nome indi a so os nmeros que sero operados.

so os dados representados por ara teres. Como ara teres podem ser letras, algarismos e sinais diversos estes dados re ebem
este nome.

Dados alfa-numri os:

43

estes dados podem assumir dois valores verdadeiro e falso.


Estes dados resultam de expresses do tipo x > 0.

Dados Lgi os:

Os dados numri os que os algoritmos que iremos onstruir podem manipular


so de dois tipos: inteiros e reais. So exemplos de nmeros inteiros:

+3
3
-324
-50
So exemplos de nmeros reais:

+0.5
0.5
-8.175
2.0
Dados alfa-numri os servem para tratamento de textos e normalmente so
ompostos por uma seqn ia de ara teres ontendo letras, algarismos e ara teres de pontuao. Nos algoritmos so normalmente representados por uma
seqn ia de ara teres entre aspas, por exemplo:

Linguagem de programao
Qual o seu nome?
12345
Dados lgi os so intensamente apli ados durante o pro esso de tomada
de de ises que o omputador frequentemente obrigado a fazer. Em muitos
textos este tipo de dados tambm hamado de tipo de dados booleanos, devido
a George Boole, matemti o que deu ao nome lgebra (lgebra booleana) que
manipula este tipo de dados. Os dados deste tipo somente podem assumir
dois valores: verdadeiro e falso. Computadores tomam de ises, durante o
pro essamento de um algoritmo, baseados nestes dois valores. Por exemplo,
onsidere a de iso abaixo:
se

a = 0 ento

imprimir
seno

x b/a
imprimir
m se

A equao nao tem soluo

A raiz da equao vale , x

Neste algoritmo apare e a expresso a = 0, que pro ura des obrir se o valor
de raiz igual a 0. Esta expresso somente pode ter omo resultado os valores:
verdadeiro ou falso. Nos nossos algoritmos estes valores sero representados por
verdadeiro e falso.

44

Expresses Aritmti as

Para os nossos exemplos ini iais iremos adotar os operadores aritmti os binrios mostrados na Tabela 2.1. A oluna prioridade indi a a prioridade relativa
dos operandos. O menor nmero indi a a maior prioridade. Quando temos
dois operandos de mesma prioridade o omputador ir exe utar primeiro a operao mais esquerda. Em omputao, as expresses devem ser es ritas em
linhas e para alterar a prioridade deve-se usar parnteses. Maiores detalhes
sobre expresses sero apresentados no Captulo 5. No momento, estamos apenas apresentando alguns on eitos bsi os para fa ilitar a dis usso de alguns
algoritmos.
Operador

/
*
%
+
-

Des rio

Diviso
Multipli ao
Mdulo (resto da diviso de
operandos inteiros)
Soma
Subtrao

Prioridade

0
0
0
1
1

Tabela 2.1: Operadores Aritmti os.


Para ilustrar o uso de operadores aritmti os vamos onsiderar alguns exemplos de expresses. Os exemplos a seguir mostram omo onverter uma expresso matemti a para a forma que usaremos em pseudo-linguagem. Observer o
uso de parnteses para alterar a prioridade das operaes.
Expresso
Matemti a
a
b+c
a+b
c+d
2

b 4ac
1
1
1+ a+b

Expresso em
Pseudo-linguagem

a/(b+ )
(a+b)/( +d)
b*b-4*a*
1/(1 + 1/(a+b))

2.5.4 Comandos de atribuio


Servem para atribuir valores posies de memria. Normalmente estes valores
podem ser onstantes ou resultados de expresses dos diversos tipos. Exemplos
de omandos de atribuio so mostrados a seguir.
x b/a
media (n1 + n2)/2
inicio 0
nome Ze Sa
ii+1

A seta aponta sempre da direita para a esquerda. O valor ou o resultado da


expresso a direita da seta armazenado na varivel que est no lado esquerdo
45

da seta. A direo da seta no pode ser alterada. No aso da ltima expresso temos que o valor atual de i in rementado e depois substitui este valor,
portanto, se ele valia 10, ao nal da instruo ele vale 11.

2.5.5 Comandos de ontrole


So usados para ontrolar o uxo de exe uo das instrues. Nas linguagens
de programao existem diversos tipos de omandos de ontrole. Para estes
exemplos ini iais vamos mostrar somente o omando mais bsi o que serve para o
omputador es olher entre dois possveis aminhos qual o algoritmo deve seguir.
Este omando, representado em uxograma, pode ser visto na Figura 2.4 e em
pseudo linguagem tem a forma mostrada no algoritmo 2.6.

Algoritmando

Falso
Condio

Verdadeiro

Faa isto

Faa aquilo

Continuo
algoritmando

Figura 2.4: Fluxograma do omando se ...

Algoritmo 2.6:
se

ento ... seno.

Comando se em pseudo-linguagem

Condio sendo testada ento


Faa isto

seno

Faa aquilo

m se

Um exemplo de uso desta onstruo, es olhido a partir da vida real, pode


ser o seguinte. Tenho que de idir o que fazer em um domingo de folga. Se
estiver hovendo irei ao inema, aso ontrrio irei praia. Observe que para
ir para a praia basta apenas que no esteja hovendo, nenhum outro teste foi
46

feito. Esta de iso em forma de pseudo-linguagem  a da maneira mostrada no


Algoritmo 2.7.
Algoritmo 2.7:
se

Algoritmo para de idir o que fazer no domingo.

est hovendo ento


vou ao inema

seno

vou praia

m se

Nem sempre nos algoritmos pre isamos de duas alternativas. As vezes pre isamos somente de de idir se devemos fazer algo ou no Por exemplo, vamos
assumir que de idimos ir ao inema no domingo hova ou faa sol. No entanto,
pre iso de idir se levo um guarda- huva. O algoritmo para este aso est mostrado no Algoritmo 2.8. Observe que no aso de no estar hovendo nada pre isa
ser feito. A Figura 2.5 mostra esta de iso em forma de uxograma.
Algoritmo 2.8:

Algoritmo para de idir se deve levar um guarda- huva.

Vestir para ir ao inena


se est hovendo ento
pego guarda- huva
m se

Vou ao inema

2.5.6 Comandos de repetio


As linguagens de programao normalmente possuem diversos omandos que
permitem que um tre ho de algoritmo seja repetido um nmero de vezes. Para
estes exemplos ini iais iremos apresentar um omando de repetio que su ientemente geral para substituir todos os outros. Este omando, que hamaremos
de omando enquanto tem a forma mostrada na Figura 2.6.
O omando fun iona da seguinte maneira:
Testar se a ondio verdadeira. Caso seja verdade exe utar o blo o
de omandos situados entre o in io do omando e o nal do omando. O
nal do omando enquanto normalmente mar ado de alguma forma. Em
nossa pseudo-linguagem mar aremos o m pelas palavras fim enquanto
ou fim eqto.

Passo 1:

Exe utar o blo o de omandos at o m do enquanto. Quando hegar


ao m retornar automati amente para o in io do omando e refazer o
passo 1.

Passo 2:

Como exemplo onsideremos o aso em que pre isamos ler um onjunto de 10


nmeros e imprimir se ada um dos nmeros lidos par ou no. Para des obrir
se o nmero par vamos dividi-lo por 2 e testar o resto. Para simpli ar,
vamos onsiderar que aso o resto da diviso seja igual a zero o nmero par.
47

Vestir para
ir ao cinema

Falso
Chovendo?

Verdadeiro

Pegar
guarda-chuva

Ir ao
cinema

Figura 2.5: Fluxograma para de idir se deve levar um guarda- huva.

Neste algoritmo sabemos a quantidade de nmeros a serem lidos e portanto o


nmero de repeties pr-determinado. O Algoritmo 2.9 mostra omo seria
implementada uma soluo para este problema.
Vamos mostrar um exemplo onde o nmero de repeties no onhe ido.
Considere no exemplo anterior que o total de nmeros a ser lido no onhe ido.
Mas ento, omo o algoritmo ir terminar de ler nmeros? Usaremos o que
ostuma-se hamar de sentinela em omputao. O algoritmo ir se manter
lendo nmeros enquanto os nmeros forem positivos. No momento que for
lido um nmero negativo o algoritmo pra. A sentinela que indi a o nal da
lista de nmeros um nmero negativo. O Algoritmo 2.10 mostra omo  a
em pseudo-linguagem o algoritmo modi ado. Observe que neste algoritmo o
primeiro nmero tem de ser lido antes do omando enquanto. Isto porque
assumimos que o primeiro nmero que for digitado pode ser negativo e portanto
a lista de nmeros no tem nenhum nmero.

2.6 Exemplos de Algoritmos


Nesta seo iremos apresentar uma srie de algoritmos es ritos na pseudolinguagem que a abamos de apresentar.
Exemplo 2.1: Este algoritmo serve para des obrir qual a maior nota de uma
turma de alunos. Neste algoritmo iremos onsiderar que as notas podem variar
entre 0.0 e 10.0 e que a turma tem 25 alunos. O algoritmo 2.11 ini ialmente
ini ia a maiorN ota om zero, depois ompara ada nota om esta maiorN ota
aso ela seja maior substitui o valor anterior pelo novo valor. Observar que

48

Algoritmo 2.9:

ou no.

Entrada:
Sada: Se
in io

Algoritmo para ler 10 nmeros e imprimir se so pares

10 nmeros, (numero).
o nmero par ou no

totalN umeros 10
enquanto totalN umeros > 0 faa
ler numero
se numero%2 = 0 ento
imprimir numero,  par
seno
imprimir
m se

numero,  impar

totalN umeros totalN umeros 1

m enqto
m

Algoritmo 2.10: Algoritmo para ler nmeros e imprimir se so pares ou


no. A quantidade de nmeros a ser lida des onhe ida.
Entrada:

nmeros, (numero). O algoritmo para quando um nmero


negativo lido
Sada: Se o nmero par ou no
in io
ler numero
enquanto numero > 0 faa
se numero % 2 = 0 ento
imprimir numero,  par
seno
imprimir numero,  impar
m se
ler numero
m enqto
m

49

Algoritmando

Falso
Testa
Condio

Verdadeiro

Bloco de comandos
do enquanto

Continuo
algoritmando

Figura 2.6: Fluxograma do omando enquanto.

riamos uma varivel para armazenar a quantidade de alunos. Vo poderia


perguntar porque no usar o nmero 25 toda vez que for ne essrio. A razo
simples. Suponha que vo gostaria de usar este algoritmo para al ular a maior
nota de uma turma de 40 alunos. Neste algoritmo bastaria substituir o nmero
25 por 40. No entanto, existe uma soluo mais geral ainda que permite que
o algoritmo possa ser usado para qualquer tamanho de turma. Este problema
est apresentado na lista de exer ios deste aptulo.
Exemplo 2.2: Vamos mostrar outro exemplo de algoritmo muito usado. Pre isamos ler as notas de uma turma de alunos e al ular a mdia destas notas.
Vamos assumir que a turma tem 25 alunos e as notas esto entre 0 e 10. O
algoritmo est mostrado em Algoritmo 2.12.
Exemplo 2.3: Neste exemplo onsidere o seguinte problema. Um es ritrio de
previso do tempo armazena diariamente a temperatura mdia de uma determinada regio. A tarefa des obrir qual a maior temperatura do ano passado.
Assuma que foram armazenadas 365 temperaturas, uma para ada dia do ano.
Neste aso no podemos apli ar o algoritmo 2.11 usado para des obrir a maior
nota da turma. Antes de ontinuar pro ure en ontrar a razo. Como di a,
onsidere que estamos no plo sul e portanto todas as temperaturas lidas so
negativas.

Uma soluo possvel para este exemplo est mostrada no algoritmo 2.13.
Este algoritmo faz o seguinte. Pega a primeira temperatura e a anota omo a
maior j en ontrada. A partir da o algoritmo  a repetidamente lendo temperaturas dos registros do es ritrio omparando om a temperatura que no
50

Algoritmo 2.11:

25 alunos.

Algoritmo para al ular a maior nota de uma turma de

Entrada: Nota de ada um


Sada: Maior das notas dos
in io

dos dos 25 alunos da turma, (notaAluno).


alunos, (maiorN ota)

totalAlunos 25
maiorN ota 0.0
enquanto totalAlunos > 0 faa
ler notaAluno
se notaAluno > maiorN ota ento
maiorN ota notaAluno
m se

totalAlunos totalAlunos 1

m enqto
imprimir
m

A maior nota das notas , maiorN ota

Algoritmo 2.12:

25 alunos.

Algoritmo para al ular a nota mdia de uma turma de

Entrada: Nota de ada


Sada: Mdia das notas
in io

um dos dos 25 alunos da turma, (notaAluno).


dos alunos, (mediaN otas)

totalAlunos 25
i0
somaN otas 0.0
enquanto i < totalAlunos faa
ler notaAluno
somaN otas somaN otas + notaAluno
ii+1
m enqto

mediaN otas somaN otas/totalAlunos


imprimir A mdia das notas , mediaN otas

m

51

momento onsta omo a maior de todas. Se a temperatura tirada dos arquivos


for maior que a menor atual, o algoritmo joga fora a temperatura anotada e
guarda a que foi lida omo a nova maior temperatura. Quando no houver mais
temperaturas para ler a que estiver anotada omo a maior a maior verdadeiramente.
Algoritmo 2.13:

Algoritmo para al ular a maior temperatura do ano.

Entrada: Temperaturas registradas em ano, (temperatura).


Sada: Maior das temperaturas, (maiorT emperatura)
in io

totalT emperaturas 365


ler temperatura

 J li uma temperatura
totalT emperaturas totalT emperaturas 1

 A primeira temperatura a maior temperatura


maiorT emperatura temperatura
enquanto totalT emperaturas > 0 faa
ler temperatura
se temperatura > maiorT emperatura ento
maiorT emperatura temperatura
m se

totalT emperaturas totalT emperaturas 1


m enqto
imprimir
m

A maior nota das temperaturas , maiorT emperatura

52

2.7 Exer ios


Uma empresa paga R$10.00 por hora normal trabalhada e R$ 15.00 por
hora extra. Es reva um algoritmo que leia o total de horas normais e o total
de horas extras trabalhadas por um empregado em um ano e al ule o salrio
anual deste trabalhador.

2.1:

2.2: Assuma que o trabalhador do exer io anterior deve pagar 10% de imposto
se o seu salrio anual for menor ou igual a R$ 12000.00. Caso o salrio seja maior
que este valor o imposto devido igual a 10% sobre R$ 12000.00 mais 25% sobre
o que passar de R$ 12000.00. Es reva um programa que al ule o imposto devido
pelo trabalhador.
2.3: Es reva um algoritmo que des ubra a maior nota de uma turma de alunos.
O tamanho da turma deve ser o primeiro dado pedido ao usurio.

Modique o algoritmo anterior de modo que ele imprima tambm quantas


vezes a maior nota apare e.

2.4:

Nos exer ios anteriores assumimos que os usurios sempre digitam uma
nota entre 0 e 10. Vamos assumir agora que o usurio sempre digita um nmero,
mas este nmero pode estar fora do intervalo 0 a 10. Ou seja, poderemos ter
uma nota menor que zero ou maior que 10. Modique o algoritmo anterior
para que ele verique a nota digitada e, aso o aluno tenha digitado uma nota
invlida, uma mensagem avisando o usurio seja impressa e uma nova nota seja
pedida. O algoritmo deve insistir at que o usurio digite um valor vlido.

2.5:

2.6: Es reva um programa que leia um onjunto de 100 temperaturas e imprima


a menor temperatura lida. Observe que temperaturas podem assumir valores
menores do que zero.

Es reva um algoritmo que leia trs nmeros e os imprima em ordem res ente.

2.7:

2.8: Es reva um algoritmo que leia um nmero inteiro entre 100 e 999 e imprima
na sada ada um dos algarismos que ompem o nmero. Observe que o nmero
lido om um valor inteiro, e, portanto, ele tem de ser de omposto em trs
nmeros: os algarismos das entenas, dezenas e unidades.

Es reva um algoritmo que leia uma hora em horas, minutos e segundos e


some um segundo a hora lida.

2.9:

2.10: Es reva um algoritmo que leia duas datas em dia, ms e ano e imprima
a data mais re ente.
2.11: Um aluno est es revendo um programa que l uma nota no intervalo
entre 0 e 100, in lusive. Foi pedido ao aluno que o programa a eite as notas
vlidas e rejeite as invlidas. Marque a letra que mostra a expresso que falta
no tre ho pontilhado do algoritmo mostrado em 2.14.

(a) (nota < 0) e (nota > 100)


(b) (nota <= 0) e (nota >= 100)
53

( ) (nota < 0) ou (nota > 100)


(d) (nota <= 0) ou (nota >= 100)
(e) (nota >= 0) e (nota <= 100)
Algoritmo 2.14:

Algoritmo do exer io 11.

in io
imprimir Entre om a nota
ler nota
se .............. ento
imprimir Nota invlida
seno
imprimir Nota vlida
m se
m

Considere que os valores -3, -4 e -5, nesta ordem, foram forne idos ao
algoritmo 2.15:

2.11:

Algoritmo 2.15:
Dados:

Algoritmo do exer io 11.


t1, t2, t3, maior

in io
ler

(t1, t2, t3)


maior 0
se t1 > maior ento
maior t1
m se
se t2 >

maior ento
maior t2

m se
se t3 >

maior ento
maior t3

m se
imprimir
m

(maior)

Marque a letra que indi a o que foi impresso em ada vez que o programa
foi exe utado.
(a) 0
(b) -3
( ) -4
(d) -5
(e) nenhuma das respostas anteriores.

54

Captulo 3
Tipos de Dados, Constantes e
Variveis

3.1 Introduo
Variveis e onstantes so os elementos bsi os que um programa manipula.
Uma varivel orresponde a um espao reservado na memria do omputador
para armazenar um determinado tipo de dado. Variveis devem re eber nomes para poderem ser mais fa ilmente referen iadas e modi adas sempre que
ne essrio. Muitas linguagens de programao exigem que os programas de larem todas as variveis antes que elas possam ser usadas. Estas de laraes
espe i am de que tipo so as variveis usadas pelos programas e as vezes um
valor ini ial. Tipos podem ser por exemplo: inteiros, reais, ara teres, et . As
expresses ombinam variveis e onstantes para al ular novos valores.

3.2 Tipos de Dados


3.2.1 Tipos Bsi os
Os dados em C podem assumir in o tipos bsi os que so os seguintes:
har:

O valor armazenado um ara tere. Cara teres geralmente so armazenados em digos (usualmente o digo ASCII). A Tabela A.1 mostra
este digo. Cara teres so armazenados em um byte.

int:

O valor armazenado um nmero inteiro e o tamanho do sub onjunto que


pode ser representado pelo omputador normalmente depende da mquina
em que o programa est rodando. Atualmente em C os nmeros inteiros
so armazenados em 32 bits.

oat:

Nmero em ponto utuante de pre iso simples, normalmente 32 bits.


So onhe idos omo nmeros reais, no entanto, os omputadores somente
podem armazenar e trabalhar om uma pequena parte do onjunto dos
nmeros reais.
55

double:

Nmero em ponto utuante de pre iso dupla, om isto a pre iso e


as vezes a ex urso dos nmeros aumenta. Este tipo armazenado em 64
bits.

void:

Este tipo serve para indi ar que um resultado no tem um tipo denido. Uma das apli aes deste tipo em C riar um tipo vazio que pode
posteriormente ser modi ado para um dos tipos anteriores.

3.2.2 Modi adores de tipos


Modi adores podem ser apli ados a estes tipos. Estes modi adores so palavras que alteram o tamanho do onjunto de valores que o tipo pode representar.
Por exemplo, um modi ador permite que possam ser usados mais bits para armazenar nmeros inteiros. Um outro modi ador obriga que s nmeros inteiros
sem sinal possam ser armazenados pela varivel. Deste modo no ne essrio
guardar o bit de sinal do nmero e somente nmeros positivos so armazenados.
O resultado prti o que o onjunto prati amente dobra de tamanho.
Os modi adores de tipos so os seguintes:
Este modi ador pode ser apli ado aos tipos int e har e faz om
que o bit de sinal no seja usado, ou seja o tipo passa a ter um bit a mais.

unsigned:

Este modi ador tambm pode ser apli ado aos tipos int e har. O
uso de signed om int redundante.

signed:

long:

Modi ador que pode ser apli ado aos tipos int e double aumentando o
nmero de bytes reservado para armazenamento de dados.

possvel ombinar estes modi adores de diversas maneiras omo est mostrado na Tabela 3.1 que lista os tipos bsi os denidos no padro ANSI e a sua
ex urso.

3.3 Constantes Numri as


Constantes so valores que o programa no pode modi ar durante a exe uo
de um programa. Elas so usadas em expresses para representar vrios tipos de
valores. Em C existem regras rgidas para determinar omo devem ser es ritos
estes valores. A seguir iremos mostrar estas regras.
Para es rever onstantes numri as vamos usar as seguintes denies:
dgito:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9

dgito_sem_zero:
dgito_o tal:

1, 2, 3, 4, 5, 6, 7, 8, 9

0, 1, 2, 3, 4, 5, 6, 7

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, A, b, B, , C, d, D,
e, E, f, F

dgito_hexa:

sinal:

+, 56

Tipo

Bytes

Faixa Mnima

unsigned long int

1
1
1
4
4
4
2
2
2
4
4
4

long long int


long long

signed long long int


signed long long

-127 a 127
0 a 255
-127 a 127
-2.147.483.648 a 2.147.483.647
0 a 4.294.967.295
-2.147.483.648 a 2.147.483.647
-32.768 a 32.767
0 a 65.535
-32.768 a 32.767
-2.147.483.648 a 2.147.483.647
-2.147.483.648 a 2.147.483.647
0 a 4.294.967.295
-9.223.372.036.854.775.808 a
9.223.372.036.854.775.807
-9.223.372.036.854.775.808 a
9.223.372.036.854.775.807

8
4
8
12

0 a 18.446.744.073.709.551.615
oito dgitos de pre iso
16 dgitos de pre iso
16 dgitos de pre iso

har
unsigned har
signed har
int
unsigned int
signed int
short int, short
unsigned short int
signed short int
long int, long
signed long int

unsigned long long int


unsigned long long
oat
double
long double

Tabela 3.1: Tipos de dados denidos pelo Padro ANSI C.

ponto_de imal:
suxo:

sufixo_sem_sinal, sufixo_longo

suxo_sem_sinal:
suxo_longo:

u, U

l, L

suxo_utuante:

f, F, l, L

O uso destas ara teres ser mostrado om exemplos nas sees seguintes.

3.3.1 Constantes Inteiras na base 10


So valores numri os sem ponto de imal, pre edidos ou no por um sinal. No
possvel separar, por espaos em bran o, o sinal do valor numri o. Podemos
des rever este formato om uma notao simpli ada da seguinte maneira:

[sinaldgito_sem_zero{dgito}[sufixo_sem_sinal|sufixo_longo
Esta notao deve ser entendida da seguinte maneira. Col hetes indi am
opo, portanto, o fato de sinal (+ ou -) estar entre ol hetes signi a que um
nmero inteiro pode ou no ter sinal, isto o sinal op ional. Em seguida temos
57

um dgito_sem_zero que obrigatrio. Isto dados inteiros devem omear


por, pelo menos, um algarismo entre 1 e 9. A seguir temos a palavra dgito
entre haves. As haves indi am que o fator entre elas pode ser repetido zero ou
mais vezes. Portanto, um nmero inteiro, aps o algarismo ini ial obrigatrio,
pode ser seguido por uma seqn ia de zero ou mais algarismos. Como suxo
podemos ter op ionalmente as letras u (U) ou l (L) ou uma mistura, em qualquer
ordem, das duas. Para onstantes inteiras o suxo U (u) representa o modi ador
unsigned. O suxo L (l) representa o modi ador long. Um par de L's (l's)
indi a que a onstante do tipo long long. A tabela 3.2 mostra exemplos de
nmeros inteiros:
Tipo
int
unsigned int
long int
unsigned long int
long long
unsigned long long

1997
1997U
1234L
1997UL
134LL
1997ULL

Constantes

-3
45u
1997L
45Lu
1997Ll
45LLu

+5
12345U
-3l
23Ul
-3ll
23Ull

7
0U
+0L
0LU
+0LL
0LLU

Tabela 3.2: Constantes Inteiras na Base 10


Alguns exemplos de erros na es rita de onstantes inteiras so:
1.0 (No possvel usar ponto de imal.)
- 345 (No possvel olo ar um espao entre o sinal e o valor numri o.)
23 (No possvel usar notao de expoentes.)

Nos ompiladores modernos o nmero de bytes usados para armazenar os


valores inteiros o mesmo tanto para tipos inteiros (int) quanto para tipos
inteiros longos (long int), omo est mostrado na Tabela 3.1. Por esta razo,
a diferena entre estes dois tipos de onstantes perdeu a razo de ser. Alguns
exemplos de onstantes inteira longas esto mostrados na Tabela 3.2.

3.3.2 Constantes Inteiras O tais


So onstantes representadas na base 8. Normalmente so representadas sem
sinal e devem omear om um 0. Usando a notao apresentada na seo
anterior podemos denir a forma que deve ter uma onstante o tal omo:

0 {dgito_o tal}[sufixo_sem_sinal|sufixo_longo
Na Tabela 3.3 mostramos exemplos de onstantes o tais e o seu valor na base 10.
Nmeros es ritos na base 8 somente podem ser es ritos om algarismos entre 0
e 7 in lusive.

58

Base 8

Base 10

025
077
011
010ul
0175

21
63
9
8
125

Tabela 3.3: Constantes o tais

3.3.3 Constantes Inteiras Hexade imais


So onstantes representadas na base 16. So ini iadas om um 0x ou 0X
. Usando a notao podemos denir uma ontante hexade imal omo:

[0x|0Xdgito_hexa{dgito_hexa}[sufixo_sem_sinal|sufixo_longo
Na Tabela 3.4 mostramos exemplos de onstantes hexade imais e o seu valor
na base 10. Para es rever onstantes na base 16 usamos todos os algarismos e
ainda as letras A (ou a), B (ou b), C (ou ), D (ou d), E (ou e), F (ou f), que
representam respe tivamente os seguintes valores 10, 11, 12, 13, 14 e 15.
Base 16

Base 10

0xF
0X25
0XAB
0XBEEF

15
37
171
48879

Tabela 3.4: Constantes hexade imais

3.3.4 Converso entre Bases


A onverso de nmeros inteiros entre a base 8 e a base 10 tem uma frmula
simples, que pode ser estendida para onverter nmeros entre qualquer base e
a base 10. Vamos onsiderar que um nmero (N )8 es rito na base 8 tenha a
seguinte forma
(N )8 = dn1 dn2 . . . d1 d0
onde 7 di 0
A frmula para onverter um nmero da base 8 para a base 10 a seguinte
N10 = dn1 8n1 + dn2 8n2 + + d1 81 + d0 80

(3.1)

Esta equao est es rita na base 10. Por exemplo, apli ando a equao 3.1
para onverter o nmero 0175 da base 8 para a base 10  amos om
(0175)8 = 1 82 + 7 81 + 5 80 = (125)10

59

A frmula para onverso da base 8 para a base 10 pode se estendida para


uma base qualquer om a substituio do algarismo 8. Considere uma base
qualquer representada por b. Nesta base os dgitos di  am no intervalo b 1
di 0. A equao 3.2 mostra a frmula para onverter um nmero em uma
base b qualquer para a base 10.
N10 = dn1 bn1 + dn2 bn2 + + d1 b1 + d0 b0

(3.2)

Vamos onsiderar a ontante inteira (3AF )16 . Apli ando a frmula 3.2 temos
(3AF )16 = 3 162 + 10 161 + 15 160 = (943)10

O algoritmo para onverter um nmero inteiro da base 10 para uma determinada base b feito por um onjunto de divises su essivas do nmero pela base
at que o resultado da diviso seja 0. O Algoritmo 3.1 mostra omo onverter
um nmero (N )10 para uma base b. importante notar que os algarismos na
base b vo sendo impressos na ordem inversa, do menos signi ativo para o mais
signi ativo. Por exemplo, aso forneamos para o algoritmo o nmero (943)10
e a base 16, o algoritmo iria imprimir os resultados 15, 10 e 3 nesta ordem. Isto
orresponderia aos seguintes dgitos da base 16: F, A e 3 e, portanto, a resposta
seria (3AF )16 .
Algoritmo 3.1:

base b.

Algoritmo para onverter inteiros na base 10 para uma

Entrada: nmero, (numero) e base b


Sada: Dgitos do nmero na base b
in io
ler numero
ler base
enquanto numero > 0 faa

(baseb).

resto numero % base


numero numero / base
imprimir resto
m enqto
m

3.3.5 Constantes em Ponto Flutuante


Constantes em ponto utuante so usadas para representar nmeros reais. O
nome ponto utuante devido ao modo omo os valores so armazenados pelo
omputador. Constantes de ponto utuante podem ser do tipo oat , double
, long ou long double. Constantes sem nenhum suxo so onsideradas do tipo
double. Caso seja usado o suxo F ou o f a onstante ser onsiderada omo
do tipo oat . O suxo L ou o l torna a onstante long double.
Uma onstante em ponto utuante pode ser denida de duas maneiras. Vo
pode es rever um nmero om ponto de imal (1.5) ou na hamada forma ient a, em que um expoente usado (0.15E1). Na segunda forma o nmero
igual a 0.15 101 . possvel omitir ou os dgitos antes do ponto (a parte
60

inteira) ou aps (a parte fra ionria), mas nun a os dois grupos. possvel
es rever um nmero em ponto utuante sem ponto, desde que um expoente seja
usado. Portanto, os nmeros .8, 1234., 1E1 so nmeros de ponto utuante.
Para mostrar mais formalmente omo se deve es rever as onstantes de ponto
utuante vamos usar a mesma notao usada at aqui, mas usando uma hierarquia de denies para fa ilitar o entendimento. Primeiro damos uma denio
mais geral que vai sendo mais detalhada a medida que avanamos. Lembrar
que termos entre haves podem ser repetidos 0 ou mais vezes e termos entre
ol hetes so op ionais.
Portanto, usando a forma hierrqui a, uma onstante de ponto utuante
(CPF) pode ser denida das seguintes maneiras:

CPF = [sinalfrao[expoente[sufixo_flutuante
CPF = [sinalseq_dgitos expoente[sufixo_flutuante
A seguir denimos ada um dos omponentes. Uma frao denida omo:

frao = [seq_digitos ponto_de imal seq_dgitos ou


frao = seq_dgitos ponto_de imal
O expoente e a seqen ia de dgitos so denidos omo:

expoente = [e | E[sinalseq_dgitos
seq_dgitos = dgito{dgito}
A Tabela 3.5 mostra exemplos de onstantes em ponto utuante.
Des rio

sinal frao expoente


frao
frao expoente
frao sufixo
seq_dgitos ponto_de imal

Nmero

+23.45e-10
123.45
123.45E+10
123.45F
123.

Tabela 3.5: Constantes em ponto utuante

3.4 Constantes Cara teres


Uma onstante ara tere um ni o ara tere es rito entre ', omo em 'a'. Alm
disso, uma onstante de tamanho igual a um byte pode ser usada para denir um
ara tere, es revendo-se, por exemplo, '\ddd', onde ddd uma onstante om
entre um e trs dgitos o tais. Em C, ara teres podem parti ipar normalmente
de expresses aritmti as. O valor que entra na expresso o do digo usado
para representar o ara tere. Exemplos de onstantes do tipo ara tere so
mostrados na Tabela 3.6.
Certos ara teres que no so visveis podem ser representados antepondo-se
o ara tere '\' (barra invertida), omo no exemplo nova linha da Tabela 3.6.
Este ara tere tambm onhe ido omo ara tere de es ape. Exemplos so
mostrados na Tabela 3.7.
61

Cara tere

'a'
'A'
'\0141'
'('
'9'
'\n'

Signi ado

ara tere a
ara tere A
Constante o tal orrespondente ao ara tere 'a'
ara tere abre parnteses
algarismo 9
Nova linha, posi iona o ursor no in io da nova linha.
Tabela 3.6: Exemplos de onstantes ara tere

Cara tere

'\n'
'\t'
'\b'
'\f'
'\r'
'\a'
'\0'

Signi ado

Passa para uma nova linha.


Tabulao horizontal, move o ursor
para a prxima parada de tabulao.
Retorna um ara tere.
Salta uma pgina.
Carriage return, posi iona o ursor
no in io da linha atual.
Alerta, faz soar a ampainha do sistema.
Null, ara tere que em C termina
uma adeia de ara teres.

Tabela 3.7: Exemplos de ara teres invisveis.

3.4.1 Constantes Cadeias de Cara teres


Neste livro vamos usar em alguns asos a palavra adeia para signi ar adeia
de ara teres (string em ingls). Uma onstante do tipo adeia de ara teres
uma seqn ia de qualquer nmero de ara teres entre " omo no exemplo:
"alo mundo!!!".
importante notar que a linguagem C insere automati amente ao nal de
uma adeia de ara teres um ara tere null ('\0'). Este ara tere ser usado
em diversos algoritmos omo sinal de m de adeia. Os ara teres '\' ( ara tere
es ape) e '"' (in io e m de adeia) tm signi ados espe iais em adeias de
ara teres e para serem representados pre isam ser ante edidos pelo ara tere
es ape. Portanto, \\ e \" devem ser usados dentro de adeias de ara teres para
representar \ e " respe tivamente. Por exemplo,

"Estas so \" (aspas) dentro de adeias."


As aspas no meio da adeia no indi am o m, j que elas esto pre edidas
do ara tere de es ape.

3.5 Variveis
Variveis so nomes dados para posies de memria a m de fa ilitar o manuseio dos dados durante a riao dos programas. Os dados podem ser de
62

qualquer dos tipos denidos para a linguagem C.

3.5.1 Nomes das Variveis


Existem algumas regras bsi as que regulam o batismo de variveis. Estas regras
so as seguintes:
Nomes de varivel s podem onter letras, dgitos e o ara tere '_';
Todo primeiro ara tere deve ser sempre uma letra ou o ara tere '_';
Letras mais ulas e mins ulas so onsideradas ara teres diferentes, isto
, C diferen ia a aixa das letras;
Palavras reservadas no podem ser usadas omo nome de variveis. Palavras reservadas so palavras usadas para indi ar os omandos da linguagem, tipos de dados ou outras funes. O Anexo B mostra as palavras
reservadas da linguagem C.

boa polti a es olher nomes que indiquem a funo da varivel. Por exemplo:
soma
mediaNotas

total
salarioMensal

nome
taxa_imposto

raio
_ini io

Em C nomes omo raio, Raio e RAIO referem-se a diferentes variveis. No


entanto, para afastar onfuses, evite diferen iar nomes de variveis por letras
mais ulas e mins ulas. Normalmente, os programadores usam letras mais ulas para representar onstantes.
Observe que em alguns nomes ombinamos duas palavras para melhor indi ar o dado armazenado na varivel. Note tambm que o ara tere espao no
pode ser usado em nomes de variveis. Os programadores ao longo do tempo
desenvolveram algumas regras informais para fazer esta ombinao. Por exemplo, usa-se o ara tere '_' para separar as palavras que ompem o nome, omo
em taxa_imposto. Outra maneira usar letras mais ulas para indi ar quando
omea uma palavra, omo em mediaNotas. Alguns programadores usam a onveno de no omear nomes de variveis por letras mais ulas. No existem
regras formais para denir omo nomes devem ser riados. O melhor analisar
as regras que programadores mais experientes usam ou os padres que empresas
adotam, para ento es olher o que mais lhe agrada e segui-lo. Uma vez adotado
um padro ele deve ser seguido para evitar in oern ias.

3.5.2 De larao de variveis


Para serem usadas, as variveis pre isam ser de laradas de modo que o ompilador possa reservar espao na memria para o valor a ser armazenado. A forma
geral de uma de larao :
tipo

lista_de_variveis;

onde uma lista_de_variveis uma lista de nomes de variveis separadas


por vrgulas. Por exemplo:
63

int i ;
unsigned int a , b , ;
unsigned short int dia ,
f l o a t raio , diametro ;
double salario ;

mes , ano ;

3.5.3 Atribuio de valores


Aps ser de larada, uma varivel pode re eber valores. O operador de atribuio
= indi a que o resultado da expresso direita do operador ser atribudo
varivel. Nada se pode armar sobre o ontedo de uma uma varivel que j
foi de larada mas ainda no re ebeu um valor.
A seguir so mostrados exemplos de atribuies de valores s variveis durante as de laraes.

int i = 0 , j = 10;
f l o a t raio = 2.54;
har = 'd ';
double pre isao = 0.00001 L ;
A seguir mostramos um tre ho de programa om exemplos de atribuio de
valores aps a denio das variveis.

int i , j ;
f l o a t raio ;
har ;

i = 0;
j = 10;
raio = 2.54;
= 'd ';

64

3.6 Exer ios


3.1:

dos.

3.2:

Indique os nomes de variveis que so vlidos. Justique os nomes invli(a)


(b)
( )
(d)

tempo
nota_final
us$
har

(e)
(f)
(g)
(h)

2dias
teste 1
raio.do. ir ulo
DiaHoje

Marque a letra que ontm pelo menos um nome de varivel invlido.


(a)
(b)
( )
(d)
(e)

raio, _ nome, hoje, provaFinal


2dia, aluno, real, podeSer = 2dia
Alo, ALO, alo, aLO
errado, erto, ok, dia2
nome_, prova_final, raio, nao_sei_nao

3.3: Indique quais dos nmeros abaixo so onstantes inteiras (longas ou no)
vlidas. Justique suas respostas.
(a) 100
(e) - 234
(b) 2 345 123 (f) 0L
( ) 3.0
(g) 21
(d) -35
(h) 0xF1
3.4:

Qual o valor na base 10 das onstantes abaixo?


(a)
(b)
( )
(d)

3.5:

025
0123
0xD
0x1D

Considere um omputador que armazene nmeros inteiros em 32 bits.


(a) Caso um bit seja reservado para o sinal diga qual o menor nmero
inteiro negativo que este omputador pode armazenar?
(b) Para os nmeros sem sinal, qual o maior nmero positivo?

3.6: Indique na tabela 3.8 os tipos que vo usaria para armazenar os dados
indi ados.

Marque a opo que indi a quantos dos nmeros abaixo representam resultados da operao (175)8 + (AB)16 .

3.7:

(602)7 , (100101000)2, (128)16 , (450)8


(a) 0
(b) 1
( ) 2
(d) 3
(e) 4

65

Des rio

total de alunos em uma sala


a nota de aluno em Computao I
Primeira letra de um nome
pontos de um jogador de voleibol ao nal do ano;
o raio de um r ulo.
Tabela 3.8: Tabela do exer i io 6

66

Tipo da varivel

Captulo 4
Entrada e Sada pelo Console

4.1 Introduo
Neste aptulo vamos apresentar on eitos bsi os de entrada e sada de dados
para que os exemplos e exer ios ini iais possam ser onstrudos. Um programa
que no forne e resultados nem pede valores para operar no deve ter grande
utilidade. A entrada de dados ser feita pelo te lado e a sada poder ser vista
na tela do omputador. Em C, quando um programa se ini ia, normalmente trs
uxos (arquivos) de dados so abertos para operaes de entrada e sada: um
para entrada, um para sada e um para imprimir mensagens de erro ou diagnsti o. Normalmente o uxo de entrada est one tado ao te lado, enquanto que
o uxo de sada e o de mensagens de erro, para serem visualizados, esto one tados ao monitor. Estas onguraes podem ser alteradas de a ordo om as
ne essidades dos usurios e estas operaes so hamadas de redire ionamento.
O uxo de entrada hamado de entrada padro (standard input); o uxo de
sada hamado de sada padro (standard output) e o uxo de erros hamado
de sada padro de erros (standard error output). Estes termos so substitudos
pelas suas formas abreviadas: stdin, stdout e stderr.

4.2 Bibliote a Padro


Na linguagem C no existem omandos de entrada e sada. As operaes de
entrada e sada so exe utadas om auxlio de variveis, ma ros e funes espe iais. Para termos a esso bibliote a que ontm estas ferramentas o programa
deve onter a de larao

#in lude

<stdio.h>

no in io do programa.
A diretiva #in lude instrui o ompilador a ler o arquivo indi ado entre '<'
e '>', e pro ess-lo omo se ele fosse parte do arquivo original e seu ontedo
estivesse no ponto onde a diretiva foi es rita. Se o nome do arquivo estiver
entre os sinais de maior e menor, omo no exemplo, ele ser pro urado em
um diretrio espe  o de lo alizao pr-denida, onde esto os arquivos de
67

in luso. Quando se usa aspas o arquivo pro urado de maneira denida pela
implementao, isso pode signi ar pro urar no diretrio de trabalho atual,
ou em um diretrio indi ado no omando usado para ompilar o programa.
Normalmente os programadores usam maior e menor para in luir os arquivos
de abealho padro e aspas para a in luso de arquivos do prprio projeto.

4.3 Sada - A Funo printf


A funo printf faz om que dados sejam es ritos na sada padro, que normalmente a tela do omputador. O prottipo da funo :

int

printf( ontrole, arg1, arg2, ...);

onde os argumentos arg1, arg2, ... so impressos de a ordo om o formato


indi ado pela adeia de ara teres que ompe ontrole. O formato ao mesmo
tempo de uso simples e bastante exvel, permitindo que os resultados possam
ser apresentados de diversas maneiras. A funo retorna o nmero de ara teres
impressos, no in luindo o nulo em vetores de ara teres. No aso de um erro
de sada um valor negativo retornado.
Um exemplo simples pode tornar a expli ao mais lara. O programa 4.1
imprime o valor da varivel ano.

Listagem 4.1: Exemplo de impresso de resultados

#in lude < stdio .h >


int main ( void ) {
int ano = 1997;

/* Imprime o valor do ano */


printf ( " Estamos no ano % d " , ano ) ;
return 0;

Este programa ir imprimir na tela do omputador:

Estamos no ano 1997


Como ontrole uma adeia ele apare e entre " ". Ele dene omo sero
impressos os valores representados pelos argumentos. No ontrole podem existir dois tipos de informaes: ara teres omuns e digos de formatao. Os
ara teres omuns, omo no exemplo o texto Estamos no ano, so es ritos na
tela sem nenhuma modi ao. Os digos de formatao, apare em pre edidos
por um ara tere'%' e so apli ados aos argumentos na ordem em que apare em. Deve haver um digo de formatao para ada argumento. O digo
%d indi a que o valor armazenado em ano deve ser impresso na notao inteiro
de imal. importante notar que o ampo de ontrole apare e somente uma
vez na funo printf e sempre no in io.

68

4.3.1 Cdigos de Converso


Os digos de onverso esto mostrados na tabela 4.3.1.
Cdigo

%
%d
%i
%E
%e
%f
%G
%g
%o
%s
%u
%x
%X
%p
%%

Comentrio

Cara ter simples


Inteiro de imal om sinal
Inteiro de imal om sinal
Real em notao ient a om E
Real em notao ient a om e
Real em ponto utuante
%E ou %f, o que for mais urto
%g ou %f, o que for mais urto
Inteiro em base o tal
Cadeia Cara teres
Inteiro de imal sem sinal
Inteiro em base hexade imal (letras mins ulas)
Inteiro em base hexade imal (letras mais ulas)
Endereo de memria
Imprime o ara tere %

Tabela 4.1: Cdigos de Converso para es rita de dados.


Entre o ara tere % e o digo de onverso podem ser inseridos ara teres
que alteram o formato. A seguir so mostrados a ordem de insero destes
ara teres e o seu signi ado:

%[modifi adores[largura[.pre iso[ omprimento digo


modifi adores: Usados logo aps o ara tere %.
'-' Um sinal de menos serve para espe i ar que o argumento deve ser
justi ado esquerda no seu ampo de impresso. Caso nenhum
sinal seja usado o argumento ser ajustado direita. O programa
4.2 ilustra os dois tipos de justi ao.
'+' Fora que o resultado seja pre edido por sinal de menos ou de mais,
mesmo para nmeros positivos. O padro que somente negativos
sejam pre edidos por sinal de menos.
espao Caso nenhum sinal v ser es rito, um espao inserido antes do
valor.
'#' Usado om o, x ou X pre ede o valor om 0, 0x ou 0X respe tivamente para valores diferentes de zero. Usado om e, E e f, fora
que a sada ontenha um ponto de imal mesmo que no haja parte
fra ionria. Por padro, se no h parte fra ionria o ponto de imal
no es rito. Usado om g ou G o resultado o mesmo que om e
ou E, mas os zeros nais no so retirados.
'0' Completa o ampo, pela esquerda, om zeros (0) ao invs de espaos,
sempre que a opo para ompletar seja espe i ada (ver espe i ador de largura do ampo).
69

largura: Caso seja usado um nmero inteiro, este espe i a o tamanho mnimo
do ampo onde o argumento ser impresso. Na listagem 4.2 o nmero
espe i a que 8 espaos so reservados para imprimir o resultado. Os
espaos livres sero ompletados om espaos em bran o. Se o argumento
pre isar de mais espao que o espe i ado ele ser es rito normalmente e
o tamanho mnimo ignorado.
.pre iso Este nmero tem diferentes signi ados dependendo do digo usado.
No aso de impresso de adeia de ara teres (s), este nmero espe i a o nmero mximo de ara teres de uma adeia de
ara teres a serem impressos.

ara teres:

No aso de formato (e, E, f) o nmero de dgitos a


serem impressos a direita do ponto, ou seja o nmero de asas de imais. Para o formato g ou G o nmero mximo dgitos signi ativos.

ponto utuante:

No formatos inteiros (d, i, o, u, x, X) a pre iso espe i ou o nmero mximo de dgitos a serem impressos. Se o nmero de
ara teres a serem impressos menor que este o resultado ompletado om bran os. O valor no trun ado

inteiros:

omprimento: Modi a os formatos da seguinte maneira:


l Apli ado aos formatos de tipo d, i, o, u, x e X indi ando que o dado
do tipo long int e no int.
h Modi a o dado, nos formatos d, i, o, u, x e X para tipo short int.
L Nos formatos e, E, f, g e G o argumento modi ado para long double.
O programa 4.2 ir imprimir o seguinte resultado:

Justifi ado para direita Ano =


1997
Justifi ado para esquerda Ano = 1997

Listagem 4.2: Exemplo de justi ao de resultados.

#in lude < stdio .h >


int main ( void ) {
int ano = 1997;
printf ( " Justifi ado para direita Ano = %8 d \ n " , ano ) ;
printf ( " Justifi ado para esquerda Ano = % -8 d \ n " , ano ) ;
}

return

0;

O programa exemplo 4.3 imprimir o seguinte resultado:

O resultado e = 0.333
.
Alo
Nos exemplos anteriores verique que '\n' no impresso. A barra in linada
hamada de seqen ia de es ape, indi ando que o prximo ara tere no para
70

Listagem 4.3: Exemplo de uso de espe i ador de pre iso.

#in lude < stdio .h >


int main () {
f l o a t r = 1.0/3.0;
har s [ = " Alo Mundo " ;
printf ( " O resultado e = %9.3 f \ n " , r ) ;
printf ( " %9.3 s \ n " , s ) ;
}

return

0;

ser impresso mas representa ara teres invisveis ou ara teres que no esto
representados no te lado. Esta seqn ia de es ape indi a que o programa deve
passar a imprimir na prxima linha.

4.4 Entrada - A Funo s anf


A funo s anf pode ser utilizada para entrada de dados a partir do te lado e
seu prottipo :
s anf( ontrole, arg1, arg2, ...);

Uma diferena fundamental que existe entre esta funo e a funo printf
est nos argumentos que vm depois do ontrole. No aso de s anf os argumentos so os endereos das variveis que iro re eber os valores lidos e no,
omo em printf, as prprias variveis. A indi ao que estamos referen iando
um endereo e no a varivel se faz pelo operador &. Por exemplo, o omando
s anf("%d %d", &a, &b);

espera que dois valores inteiros sejam digitados no te lado. O primeiro armazenado na varivel a e o segundo em b. Os valores sero armazenados diretamente
nos endereos indi ados por &a e &b respe tivamente.
Um outro exemplo in luindo variveis reais :

int i ;
float x;

s anf ( " % d % f " , &i , & x ) ;

Assumindo que a linha de entrada no te lado fosse

34 56.43
a exe uo do exemplo iria terminar om o valor inteiro 34 sendo armazenado
na varivel i e o valor real 56.43 em x.
Usualmente o ampo de ontrole s ontm espe i aes de onverso, omo
os listados na Tabela 4.3.1, que so utilizadas para interpretar os dados que sero

71

lidos, no entanto, omo em printf, outros ara teres podem apare er. O ampo
de ontrole pode onter:
A funo l e ignora todos os ara teres bran o e/ou
<enter> e/ou tab que apare erem antes de qualquer ara tere diferente
destes.

Cara teres bran o:

(no %) que devem asar om o prximo ara tere diferente de bran o da entrada. Isto signi a que qualquer ara tere que no
for igual a bran o e/ou <enter> e/ou tab ou parte de um espe i ador de
formato faz om que a funo leia o prximo ara tere da entrada (stdin)
e se for igual a este ele des artado. Caso os ara teres sejam diferentes
a funo falha e retorna deixando os ara teres seguintes no lidos.

Cara teres omuns:

Um espe i ador de onverso de formato seguindo um modelo similar ao da funo printf.

Espe i aes de onverso:

O modelo o seguinte:

%{*}{largura}{modifi adores}tipo
O ara teres entre haves so op ionais. O asteris o indi a que o dado ser lido
de stdin mas ignorado. A largura espe i a o nmero mximo de ara teres a
serem lidos.
Os modi adores alteram o tamanho do espe i adores de tipo que vm logo
a seguir. Existem os seguintes modi adores:
h:

Os tipos d, i e n, que so int passam a ser short int e os tipos o, u e x,


tambm int passam a ser unsigned short int.

l:

Os tipos d, i e n passam a ser long int e os tipos o, u e x passam a


unsigned long int. Os tipos e, f e g passam de oat para double.

L:

Os tipos e, f e g passam de oat para long double.

Por exemplo, para que os valores digitados sejam separados por vrgulas, o
omando deveria ser es rito da seguinte maneira:
s anf("%d, %f", &i, &x);

Observar que deve haver uma orrespondn ia exata entre os ara teres no
bran os do ontrole e os ara teres digitados. Neste aso a entrada deveria ser:

35, 46.3
O programa 4.4 mostra exemplos de uso da funo s anf.
O resultado da exe uo deste programa :
Entre om um ara tere qualquer.
d
Codigo ASCII do ara tere d vale 100.
Agora dois inteiros separados por espa o.
2 4
A soma destes numeros vale 6.
A funo s anf retorna o nmero de itens lidos om su esso. Este nmero
pode ser usado para veri ar se todos os valores pedidos foram lidos. No aso
de o orrer uma falha antes da leitura se ini iar a onstante EOF retornada.
72

Listagem 4.4: Exemplo de uso de s anf.

#in lude < stdio .h >


int main () {
har ;
int num1 , num2 ;

printf ( " Entre om um ara tere qualquer .\ n " ) ;


s anf ( " % " , & ) ;
printf ( " Codigo ASCII do ara tere % vale % d .\ n " , ,
);
printf ( " Agora dois inteiros separados por espa o .\ n " ) ;
s anf ( " % d % d " , & num1 , & num2 ) ;
printf ( " A soma destes numeros vale % d .\ n " , num1 + num2 ) ;
return 0;

4.5 Lendo e Imprimindo Cara teres


4.5.1 Funes get har e put har
Para ler e es rever ara teres do te lado as funes de entrada e sada mais
simples so get har e put har, que esto na bibliote a stdio.h e ujos prottipos
so os seguintes:

int
int

get har ( void ) ;


put har ( int ) ;

Apesar da funo get har retornar um parmetro inteiro possvel atribuir


este valor a uma varivel do tipo har porque o digo do ara tere est armazenado no byte ordem mais baixa. O mesmo a onte e om a funo put har que
re ebe um inteiro, mas somente o byte de ordem mais baixa passado para a
tela do omputador. A funo put har retorna o ara tere que foi es rito e EOF
em aso de erro. O programa da listagem 4.5 mostra exemplos de uso destas
funes, e o seu resultado :

Entre om um algarismo entre 0 e 9.


7
O ara tere lido foi o 7
Observar que, normalmente, quando algum dado forne ido pelo te lado
termina-se a digitao om a te la <enter>. No entanto, o <enter> um
ara tere tambm, e isto pode ausar problemas. Vamos analisar o que a onte e
quando antes do omando get har, se l um dado do tipo inteiro, por exemplo.
O omando s anf l o nmero inteiro mas no o <enter> digitado. Deste modo,
quando logo em seguida o programa exe utar a funo get har, o que ser lido
o <enter> digitado ao nal do nmero. A listagem 4.6 um exemplo de
programa onde isto pode o orrer. Considere que o usurio digitou 35<enter>
omo resposta ao omando s anf. O omando get har ir ler o <enter> e em
73

Listagem 4.5: Exemplo de uso de get har e put har.

#in lude < stdio .h >


int main ( void ) {
har ;
printf ( " Entre om um algarismo entre 0 e 9.\ n " ) ;
= get har () ;
printf ( " O ara tere lido foi o " ) ;
put har ( ) ;
}

return

0;

seguida o programa ir imprimir o nmero 35, lido no s anf, e apenas uma linha
em bran o orrespondente ao ara tere <enter>, lido pelo get har, omo est
indi ado a seguir. Mais adiante mostraremos omo resolver este problema.

Entre om um numero inteiro.


35
Agora um ara tere.
Numero lido 35
Cara tere lido

Listagem 4.6: Exemplo de uso de get har e put har.

#in lude < stdio .h >


int main ( void ) {
har ;
int i ;
printf ( " Entre om um numero inteiro .\ n " ) ;
s anf ( " % d " , & i ) ;
printf ( " Agora um ara tere .\ n " ) ;
= get har () ;

printf ( " Numero lido % d \ n " , i ) ;


printf ( " Cara tere lido % \ n " , ) ;
return 0;

4.5.2 Lendo e Imprimindo Cadeias de Cara teres


Uma adeia de ara teres (string) em C um vetor de ara teres. Vetores, que
sero vistos mais adiante no Captulo 7, so onjuntos de ara teres em que
74

ada um deles pode ser a essado independentemente dos outros por meio de
um endereo. Nesta etapa iremos apresentar rapidamente alguns on eitos que
nos permitiro riar alguns exemplos simples om adeias de ara teres. Para
usar adeias pre iso primeiro denir um espao para armazen-las. Para isto
pre iso de larar o nome, o tamanho e o tipo do vetor. Considere que pre isamos armazenar uma adeia de ara teres hamada nome om 40 ara teres. A
denio desta adeia  aria da seguinte maneira:

har

nome [41;

Quando denir o tamanho do vetor de ara teres, observar que toda adeia
em C termina om o ara tere NULL ('\0'), que automati amente inserido
pelo ompilador. Portanto o vetor nome deve ser denido om um espao a
mais. Aps este passo, o vetor nome pode ser usado durante a exe uo do
programa.

4.5.3 Lendo e Imprimindo adeias om s anf e printf


O programa 4.7 mostra omo ler e imprimir um adeia usando os omandos
s anf e printf respe tivamente.

Listagem 4.7: Exemplo de uso de printf e s anf na leitura de adeias.

#define DIM 40
#in lude < stdio .h >
int main ( void ) {
har nome [ DIM ;

/* linha de ara teres lidos */

/* Entrada de dados do vetor */


printf ( " Por favor , qual o seu nome ?\ n " ) ;
s anf ( " % s " , nome ) ;
printf ( " Sou um omputador . Posso ajuda - lo % s ?\ n " , nome
);
return 0;

Considere que este programa se hama util. Uma possvel interao entre
este programa e um usurio poderia ser da seguinte maneira.

$ util
Por favor, qual o seu nome?
Ze Sa
Sou um omputador. Posso ajuda-lo Ze?
O smbolo $ o prompt tpi o dos sistemas Unix. Aparentemente o omputador se tornou ntimo do usurio Ze Sa e o tratou apenas pelo primeiro nome. A
expli ao para esta intimidade est no modo de leitura. Quando se usa s anf
para ler uma adeia deve-se empregar o digo de onverso %s. Este omando
no l o nome todo, mas en erra a leitura dos ara teres quando en ontra um
75

ara tere espao (ou bran o), ou seja o separador de adeias no omando s anf
o ara tere espao. Mas omo ler para um vetor um nome inteiro, ou um
adeia que ontenha bran os? Para isto deve-se usar a funo gets que ser
nosso prximo assunto.

4.5.4 Lendo e Imprimindo adeias om gets e puts


Diferentemente do omando s anf a funo gets l toda a adeia at que a te la
<enter> seja digitada. No vetor so olo ados todos os digos dos ara teres
lidos ex etuando-se o da te la <enter>, que no armazenado sendo substitudo
pelo digo NULL. Caso a funo s anf do exemplo anterior fosse substituda pela
gets o programa imprimiria

Posso ajuda-lo Ze Sa?


O omando que substitui o s anf gets(nome). O prottipo da funo gets
o seguinte:

#in lude < stdio .h >


har * gets ( har * str ) ;
A funo gets retorna str aso nenhum erro o orra. Caso o nal do arquivo seja en ontrado antes de qualquer ara tere ser lido, o vetor permane e
inalterado e um ponteiro nulo retornado. Caso um erro o orra durante a leitura, o ontedo do array  a indeterminado e novamente um ponteiro nulo
retornado.
A funo puts tem o seguinte prottipo:

#in lude < stdio .h >


int puts ( onst har

* str ) ;

Ela imprime a adeia apontado por str. O programa 4.8 semelhante ao


exemplo anterior om as funes printf substitudas por puts. Observe que a
impresso sempre termina e passa para a prxima linha. A funo puts retorna
um valor positivo aso nenhum erro o orra. Em aso de erro retornado um
valor negativo.

Entre om o seu nome, por favor.


Ze Sa
Alo
Ze Sa
Eu sou um omputador, em que posso ajuda-lo?

4.5.5 A Funo fgets


A funo gets pode abrir porta para invases de omputadores pelo fato dela
no ontrolar o nmero de ara teres lido de stdin. Apesar do usurio denir
um tamanho mximo para o vetor que ir armazenar os ara teres a funo
76

Listagem 4.8: Exemplo de uso de puts e gets na leitura de adeias.

#define DIM 41
#in lude < stdio .h >
int main ( void ) {
har nome [ DIM ;

/* linha de ara teres lidos */


/* Entrada de dados do vetor */
puts ( " Entre om o seu nome , por favor . " ) ;
gets ( nome ) ;
puts ( " Alo " ) ;
puts ( nome ) ;
puts ( " Eu sou um omputador , em que posso ajuda - lo ? " );
return 0;

ignora o limite e ontinua lendo valores at que o usurio digite o ara tere
<enter>.
Para evitar este problema re omenda-se o emprego da funo fgets ujo
prottipo

#in lude < stdio .h >


int * fgets ( onst har

* str ,

int

tam , FILE * fluxo ) ;

A funo fgets l no mximo um ara tere a menos que o nmero de ara teres espe i ado no parmetro tam a partir do uxo de entrada de dados
denido por fluxo. No aso de leitura do te lado, omo temos feito, uxo
igual a stdin. A leitura interrompida quando um ara tere <enter> en ontrado ou o nal do arquivo foi atingido. Diferentemente do que o orre na
funo gets, aqui o ara tere <enter> armazenado no vetor onde os demais
ara teres esto sendo guardados. O ara tere nulo adi ionado aps o ltimo
ara tere lido.
A funo retorna str aso seja bem su edida. Se o nal do arquivo for
atingido e nenhum ara tere tiver sido lido, o vetor str permane e inalterado
e um ponteiro nulo retornado. Caso o orra um erro de leitura o ontedo do
vetor  a indeterminado e um ponteiro nulo retornado.

77

4.6 Exer ios


4.1: Es reva um programa que de lare variveis do tipo int, har e float,
ini ialize-as, e imprima os seus valores.

Es reva um programa que dena variveis do tipo int e armazene nelas


onstantes o tais e hexade imais e imprima o seu ontedo no formato original
e em formato de imal.

4.2:

4.3: Faa um programa que leia um valor inteiro no formato de imal e es reva,
na tela, este mesmo valor nas bases hexade imal e o tal.

Exemplo de Entrada e Sada:


Entre om o valor:
10
Hexade imal: A
O tal: 12
Faa um programa apaz de ler um valor real e es rev-lo om apenas uma
asa de imal.

4.4:

Faa um programa que leia trs palavras de at 10 letras e rees reva estas
palavras alinhadas direita da tela.

4.5:

4.6: Sabendo que os argumentos da funo printf podem ser expresses (a+b,
a/b, a*b, 3*a...), e no somente argumentos, faa um programa apaz de ler
um valor inteiro e es rever seu triplo, seu quadrado, e a sua metade.

Exemplo de Entrada e Sada:


Valor:
6
Triplo: 18
Quadrado: 36
Meio: 3
4.7: Es reva um programa que leia 3 nmeros reais e imprima a mdia aritmti a destes nmeros.
4.8: Es reva um programa que pegue o valor de uma onta de restaurante e
imprima o valor total a ser pago, onsiderando que o restaurante obra 10% de
taxa para os atendentes.

Faa um programa que pea ao usurio a quilometragem atual, a quilometragem anterior, os litros onsumidos e informe a taxa de onsumo (quilmetros
por litro) de um automvel.

4.9:

Es reva um programa que onverta uma temperatura de Farenheit para


Celsius.

4.10:

4.11:

rea.

Es reva um programa que, dado o permetro de um r ulo, al ule sua

Faa um programa que utilize a funo gets para ler duas adeias de
tamanho at 20 e em seguia s rees reva na linha de baixo, uma ao lado da
outra e separadas por "/-/ ";

4.12:

78

Captulo 5
Operadores e Expresses

5.1 Introduo
O objetivo deste aptulo apresentar os operadores existentes na linguagem
C e a forma orreta de onstruir expresses que envolvam estes operadores,
onstantes e variveis.

5.2 Operador de Atribuio


Este o operador usado para transferir o resultado de uma expresso para uma
varivel. Em C este operador o sinal de igual (=). Esta es olha do sinal de
igual para servir de operador de atribuio pode ausar problemas. Isto porque
este sinal no est representando que o resultado da expresso do lado direito
igual ao resultado do lado esquerdo e sim uma atribuio. Observe que o
omando de atribuio termina em ponto e vrgula. Isto faz parte das regras da
linguagem C, que determina que omandos terminam om este ara tere. Por
exemplo:

soma = a + b;
pi = 3.1415;
possvel fazer-se vrias atribuies em uma ni a linha, omo no exemplo
a seguir:

a = b = = 1.0;
as trs variveis re ebem o mesmo valor. As atribuies so feitas na seguinte
ordem:
1. = 1.0; re ebe o valor 1.0.
2. b re ebe o resultado da expresso sua direita, que o valor atribudo
, ou seja 1.0.
3. a re ebe o resultado da expresso sua direita, que o valor atribudo
b, ou seja 1.0.
79

5.3 Operadores Aritmti os


A Tabela 5.3 mostra os operadores aritmti os e as suas ordens de pre edn ia.
Operador

+
++

*
/
%
+
-

Des rio
Mais unrio
Menos unrio
In remento
De remento
Multipli ao
Diviso
Resto da diviso
Soma
Subtrao

Prioridade
0
0
1
1
2
2
2
3
3

Tabela 5.1: Operadores aritmti os.


Os smbolos mostrados na Tabela 5.3 so os ni os que podem ser usados
para representar as operaes a ima listadas. Expresses aritmti as em C devem ser es ritas no formato linear para fa ilitar a digitao dos programas e
tambm porque alguns smbolos usados em Matemti a no existem nos te lados. O exemplo mais omum deste formato a operao de diviso que deve
ser es rita a/b.
Parnteses tm um papel importante nas expresses e permitem que a ordem
das operaes seja alterada. Expresses entre parnteses so al uladas em
primeiro lugar, portanto eles onferem o maior grau de prioridade as expresses
que eles envolvem. Podemos ter pares de parnteses envolvendo outros pares.
Dizemos que os parnteses esto aninhados. Neste aso as expresses dentro
dos parnteses mais internos so avaliadas primeiro.
Outro ponto importante so as regras de pre edn ia que determinam que
operao deve ser exe utada primeiro. Na tabela os operadores esto listados
em ordem de res ente de prioridade. Para os operadores aritmti os a operao
de mais alta pre edn ia o - unrio, vindo em seguida ++,  om a mesma
prioridade. Os operadores de multipli ao, diviso e mdulo tem a mesma
prioridade. O operador menos unrio multipli a seu operador por -1. Quando
duas operaes de mesmo nvel de prioridade tm de ser avaliadas, a operao
mais esquerda ser avaliada primeiro.
Um ponto importante que deve ser sempre levado em onsiderao quando
uma expresso for al ulada so os tipos das variveis, porque eles alteram radi almente os resultados das expresses. Por exemplo, a diviso entre operandos
do tipo inteiro tem omo resultado um valor inteiro. Portanto, se o resultado
possuir uma parte fra ionria ela ser trun ada. No possvel apli ar a operao de mdulo a operandos do tipo float e double. Algumas regras de
onverso simples existem e sero dis utidas em detalhes mais adiante. Por
exemplo a operao 1/3 em C forne e omo resultado o valor 0, enquanto que
1 % 3 igual a 1.
A seguir mostramos alguns exemplos de expresses aritmti as es ritas na
80

notao da linguagem C. Observe o uso de parnteses para evitar ambigidades


que poderiam fazer om que a expresso fosse al ulada erradamente.
Exemplo 5.4:

1. a +

b
b+c

= a + b/(b+ )

2. b2 + c2 = b*b + *
3.

x
a+ cb

= x/(a+b/ )

5.4 Operadores Rela ionais e Lgi os


5.4.1 Operadores Rela ionais
Os operadores rela ionais esto mostrados na Tabela 5.2. Nesta tabela mostramos somente a ordem de pre edn ia destes operadores. A ordem de pre edn ia
que in lui todos os operadores est mostrada na Tabela 5.10.
Operador

>=
>
<=
<
==
!=

Des rio

Maior ou igual a
Maior que
Menor ou igual a
Menor que
Igual a
Diferente de

Prioridade

0
0
0
0
1
1

Tabela 5.2: Operadores Rela ionais.


Os operadores >, >=, < e <= tm a mesma pre edn ia e esto a ima de ==
e !=. Estes operadores tm pre edn ia menor que os aritmti os, portanto
expresses omo ( i < limite - 1) e i < (limite -1) tm o mesmo signi ado.

5.4.2 Operadores Lgi os


Os operadores lgi os denem as maneiras omo as relaes a ima podem ser
one tadas. Por exemplo podemos querer testar se ao mesmo tempo uma nota
maior ou igual a 5.0 e a taxa de presena maior que 75%.
Para simpli ar a apresentao destes operadores sero usadas variveis para
substituir as relaes. Neste aso a expresso a ima seria representada omo
p e q, onde p est representando nota maior ou igual a 5.0 e q taxa de presena maior que 75%. Estas expresses podem ter dois resultados verdadeiro
e falso. Observar que, assim omo em operaes aritmti as, podemos ter
ombinaes de mais de duas relaes em uma ni a expresso. Por exemplo,
podemos ter a seguinte ombinao: ano maior que 2000 e ms menor que 6
e dia maior que 15. Nas linguagens de programao os valores verdadeiro e
falso podem ser representados de diversas maneiras. Uma das maneiras mais
81

omum representar verdadeiro por true e falso por false. Em C o valor


falso representado por 0 e verdadeiro por qualquer valor diferente de 0. A
seguir iremos mostrar os operadores lgi os existentes na linguagem C.
E lgi o

O smbolo usado para representar o operador E lgi o &&. A Tabela 5.3


mostra a tabela verdade do operador. O resultado da expresso verdadeiro
se e somente se todas as variveis forem iguais a verdadeiro. Por exemplo,
onsidere o seguinte tre ho de programa:

int i = 3 , j =
f l o a t z = 3.0;
int resultado ;

-5;

resultado = (10 > 5) && ( i > -5) && ( z != 0) ;


printf ( " O resultado e vale % d . " , resultado ) ;

O resultado deste tre ho a impresso de um valor diferente de 0, ou seja o


valor orrespondente a verdadeiro. Isto porque 10 maior que 5 E i maior
que -5 E z diferente de 0.

p
0
0
1
1

q
0
1
0
1

p && q
0
0
0
1

Tabela 5.3: Operador Lgi o E.

OU lgi o

O smbolo usado para representar o operador OU lgi o ||. A Tabela 5.4


mostra a tabela verdade do operador. Para que o resultado da expresso seja
verdade basta que uma das variveis seja verdade. Por exemplo, onsidere o
seguinte tre ho de programa:

f l o a t x = 3.0;
int n = 55 , i =
int resultado ;

0;

resultado = ( i != 0) || ( x == 0) || ( n < 100) ;


printf ( " O resultado e % d " , resultado ) ;

O resultado deste tre ho a impresso do valor 1. Isto porque, apesar de i


no ser diferente de 0 e x no ser diferente de zero, temos que n menor que
100. Como basta um dos testes ser verdade para o resultado ser verdade ser
impresso um valor diferente de 0.
82

p
0
0
1
1

q
0
1
0
1

p || q
0
1
1
1

Tabela 5.4: Operador Lgi o OU.

No lgi o

O smbolo usado para representar o operador N O lgi o !. A Tabela 5.5


mostra a tabela verdade do operador. Este operador unrio e quando apli ado
uma varivel ele tro a seu valor. Por exemplo, onsidere o seguinte tre ho de
programa:

int
int

dia = 25 , ano = 1959;


resultado ;

resultado = ! ( ( dia < 30) && ( ano > 1950) )


printf ( " O resultado vale \% d . " , resultado ) ;

Este tre ho de programa imprime 0 (falso), porque dia menor que 30 E


ano maior que 1950. Portanto, o resultado do parnteses vale 1 (verdadeiro).
No entanto, o operador ! nega este valor que vira 0.

p
0
1

!p
1
0

Tabela 5.5: Operador Lgi o N O.


A tabela 5.6 mostra, em ordem de res ente, a pre edn ia dos operadores
lgi os e rela ionais.
Operador

!
>, >=, <, <=
==, !=
&&
||

Prioridade
0
1
2
3
4

Tabela 5.6: Pre edn ia dos operadores lgi os e rela ionais.

83

5.5 Operadores om Bits


Para operaes om bits, a linguagem C dispe de alguns operadores que podem
ser usados nos tipos har, int, long e long long mas no podem ser usados
em float, double, long double e void. A diferena entre estes operadores
e os lgi os que estes operam em pares de bits enquanto que os operadores
lgi os anteriores onsideram a palavra toda. Por exemplo, para um valor int
ser falso ne essrio que todos os 32 bits sejam iguais a zero. Os operadores
em bits esto mostrados na Tabela 5.7.
[fragileOperadores om bits
Operador

Des rio

Prioridade



~
&
^
|

Deslo a para direita


Deslo a para esquerda
No
E
Ou ex lusivo
OU

0
0
1
2
3
4

Tabela 5.7: Operadores om bits.


Os operadores &, | e ~ tm a mesma tabela verdade que os operadores &&, ||
e ! respe tivamente. O operador ^ (OU Ex lusivo) est des rito pela Tabela
5.8. O resultado da operao verdadeiro se e somente se os dois operandos
so diferentes.

p
0
0
1
1

q
0
1
0
1

p ^ q
0
1
1
0

Tabela 5.8: Operador Lgi o OU.


Os operandos de deslo amento tm os seguintes modos de operao:
operando

vezes:

o operando deslo ado vezes bits para a direita.

operando

vezes:

o operando deslo ado vezes bits para a esquerda.

Observaes:
Nos deslo amentos direita em variveis unsigned e nos deslo amentos
esquerda, os bits que entram so zeros;
Nos deslo amentos direita em variveis signed, os bits que entram orrespondem ao sinal do nmero (1= sinal negativo, 0 = sinal positivo).

84

Um deslo amento para a direita equivalente a uma diviso por 2. Deslo amento para a esquerda equivalente a uma multipli ao por 2. Assim
a = a * 2; e a = a  1; so equivalentes.

O exemplo 5.1 ilustra o uso dos operandos de deslo amento:

Listagem 5.1: Exemplo de operadores de deslo amento.

#in lude < stdio .h >


int main ( void ) {
unsigned int
int d = -7;

= 7;

= < <1; printf ( " %3 d = %08 X \ n " , , ) ;


= > >1; printf ( " %3 d = %08 X \ n " , , ) ;
d = d < <1; printf ( " %3 d = %08 X \ n " , d , d ) ;
d = d > >1; printf ( " %3 d = %08 X \ n " , d , d ) ;
}

return

0;

Este programa teria omo resposta os seguintes resultados.

14 = 0000000E
7 = 00000007
-14 = FFFFFFF2
-7 = FFFFFFF9
Os resultados mostram que o nmero 7 aps o primeiro deslo amento de 1
bit para a esquerda  ou igual a 14, portanto um 0 entrou no nmero. Quando
o nmero foi deslo ado para direita 1 bit, ele retornou ao valor original. Observe
que quando o nmero -14 foi deslo ado para a direita entrou um bit 1, que
igual ao sinal negativo.

5.6 Operadores de Atribuio Composta


Em C qualquer expresso da forma:

variavel = variavel operador expressao


pode ser es rita omo:

variavel operador= expressao


Por exemplo:

ano = ano + 10;


equivalente a

ano += 10;
Outros exemplos so:
85

raiz = raiz * 4;
raiz *= 4;
soma = soma / ( a + b);
soma /= (a + b);
a = a  1;
a = 1;
i = i % 2;
i %= 2;

5.7 Operador vrgula


O operador vrgula (,) usado para separar duas ou mais expresses que so
es ritas onde somente uma esperada. Quando o onjunto de expresses tem
de ser reduzido a somente um valor, somente a expresso mais direita onsiderada. Por exemplo, onsidere o seguinte tre ho de digo:
y = ( x =5 , x +2) ;

A expresso omea a ser avaliada da esquerda para a direita. Portanto,


primeiro seria atribudo o valor 5 a varivel x. Em seguida atribui x+2 para a
varivel y. Ao nal a varivel x ontm o valor 5 e y o valor 7.

5.8 Operador sizeof()


O operador sizeof() um operador unrio que retorna o tamanho em bytes
da expresso ou tipo forne ido entre parnteses. Por exemplo, suponha que o
tipo float tenha quatro bytes ento o operador sizeof(float) retorna o valor
4. Para se al ular o tamanho de bytes de uma expresso no ne essrio o uso
de parnteses. No exemplo 5.2 ilustramos alguns exemplos de uso do operador
sizeof().
Este programa imprime os seguintes resultados:

Tamanho
Tamanho
Tamanho
Tamanho
Tamanho
Tamanho

em
de
do
do
do
do

bytes de alguns tipos


int 4
float 4
double 8
har 1
vetor de 10 inteiros 40

5.9 Converso de Tipos


Quando operandos de tipos diferentes apare em em expresses so onvertidos
para um tipo omum, que permita o l ulo da expresso da forma mais e iente.
Por exemplo, uma operao que envolva um tipo int e um float, o valor int
onvertido para float.

86

Listagem 5.2: Exemplo do operador sizeof.

#define DIM 10
#in lude < stdio .h >
#in lude < onio .h >
int main () {
int i =0;
f l o a t f =3.0;
har = 'a ';
int v [ DIM ;

printf ( " Tamanho em bytes de alguns tipos \ n " ) ;


printf ( " Tamanho de int % d \ n " , s i z e o f i ) ;
printf ( " Tamanho do float % d \ n " , s i z e o f f ) ;
printf ( " Tamanho do double % d \ n " , s i z e o f ( double ) ) ;
printf ( " Tamanho do har % d \ n " , s i z e o f ) ;
printf ( " Tamanho do vetor de % d inteiros % d \ n " ,
DIM , s i z e o f ( v ) ) ;
return 0;

Observar que onverses o orrem somente quando ne essrio. Por exemplo,


em uma diviso de inteiros o resultado do tipo inteiro. Isto pode ausar
surpresas desagradveis para programadores ini iantes. A expresso 1/3*3 tem
omo resultado o valor inteiro 0. J que a primeira expresso exe utada 1/3
tem omo resultado 0.
Operandos do tipo har e int podem ser livremente misturados em expresses aritmti as. Os tipos har so onvertidos para int. Caso o onjunto de
ara teres esteja odi ado segundo a tabela ASCII, esta fa ilidade permite a
realizao de algumas transformaes interessantes. Por exemplo, a onverso
de uma letra mais ula para mins ula pode ser fa ilmente implementada om
o omando:

l = l - 'A' + 'a';
A letra mais ula armazenada na varivel l subtrada do digo da letra
mais ula 'A', forne endo a posio desta letra no alfabeto. Em seguida este
valor somado ao digo da letra mins ula 'a', resultando da onverso para
mins ula.
Portanto, onverses aritmti as o orrem de maneira quase que natural. Em
operaes binrias as seguintes onverses o orrem quando diferentes tipos esto
envolvidos:
har onvertido para int;
float onvertido para double.

Ento, se algum dos operandos double o outro onvertido para double


e o resultado double. Caso ontrrio, se algum dos operandos long, o
outro onvertido para long e o resultado long. Caso ontrrio, se algum
87

dos operandos unsigned, o outro onvertido para unsigned e o resultado


deste tipo. Caso ontrrio os operandos so int e o resultado int. Note que
todos os floats em uma expresso so onvertidos para double e a expresso
avaliada em double.
O resultado de uma expresso onvertido para o tipo da varivel onde o resultado ser armazenado. Um resultado float ao ser arregado em uma varivel
do tipo int ausa o trun amento da parte fra ionria, porventura existente.
A onverso de inteiro para ara tere bem omportada, mas o ontrrio
nem sempre o orre onvenientemente. A linguagem no espe i a se o tipo
har um tipo om sinal ou no. Quando um ara tere armazenado em uma
varivel do tipo inteiro podem o orrer problemas om ara teres que tm o bit
mais esquerda igual a 1. Isto porque algumas arquiteturas podem estender
este bit e outras no.

5.10

Regras de Pre edn ia

A Tabela 5.10 mostra, em ordem de res ente de prioridade, as regras de pre edn ia dos operadores em C. Os operadores que esto na mesma linha da tabela
e om a mesma ordem tm a mesma prioridade. Alguns dos operadores listados
na Tabela somente sero mostrados nos aptulos seguintes.
Pri

0
1
1
2
3
4
5
6
7
8
9
10
11
12
13
13
14

Operador

() [ -> .
!  ++  * &
(tipo) sizeof()
* / %
+  
< <= >= >
== !=
&
^
|
&&
||
? () : ()
= += -= *= /= %=
= = &= |=
,

Des rio

Agrupamento; a esso vetor; a esso membro


Unrias lgi as, aritmti as e om ponteiros;
Conformao de tipo; tamanho
Multipli ao, diviso e mdulo
soma e subtrao
Deslo amento de bits direita e esquerda
Operadores rela ionais
Igualdade e diferena
E bit a bit
Ou ex lusivo bit a bit
Ou bit a bit
E
Ou
Ternrio
Atribuies
Atribuies
Separador de expresses

Tabela 5.9: Pre edn ia dos operadores.

88

5.11 Exer ios


5.1:

Es reva as expresses C abaixo na sua forma matemti a usual:

1. (a/b)*( /d)
2. (a/b* /d)
3. (a/(b* )/d)
4. a*x*x+b*x+
5.2:

Es reva as expresses matemti as na linguagem C.

1. b2 4 b c
2.
3.

1
1+

1+

a+b
c+d

4. a
5.3:

1
1
1+x

x
c+d

Diga a ordem de l ulo e o resultado das expresses abaixo:

1. x = 5 * 4 / 6 + 7;
2. x = 5 * 4.0 / 6 + 7;
3. x = 5 * 4 % 6 + 7;
4. x = ((4 / 2) + (3.0 * 5));
5.4:

sivo.

Es reva um programa que imprima a tabela verdade da funo ou ex lu-

Es reva um programa que al ule o produto entre um valor x e 2n , onde


n e x so inteiros. Utilize operadores binrios.

5.5:

Es reva um programa que leia um ngulo em segundos e imprima quantos


graus, minutos e segundos h neste ngulo.

5.6:

Es reva um programa que leia um tempo em segundos e imprima quantas


horas, minutos e segundos h neste tempo.

5.7:

Es reva um programa que leia um omprimento em entmetros e imprima


quantos metros, de metros e entmetros h neste omprimento.

5.8:

5.9: Uma empresa est sele ionando entre seus empregados os que iro fazer um
treinamento espe ial. O fun ionrio sele ionado deve satisfazer a dois ritrios.
O primeiro ritrio para que um fun ionrio seja pr-sele ionado que ele deve
ter um salrio menor ou igual a R$ 400,00 ou maior ou igual a R$ 1.000,00.
O segundo ritrio leva em onta o tempo de trabalho e o fun ionrio deve ter
mais de 5 anos na empresa. Marque a resposta que indi a a expresso lgi a
que representa este ritrio. Considere que existem as seguintes variveis.

89

Listagem 5.3: Variveis da questo 9.

f l o a t salario ;
int tempo ;
(a) (salario <= 400.00) && (salario >= 1000.00) && (tempo > 5)
(b) (salario <= 400.00) || (salario >= 1000.00) && (tempo > 5)
( ) ((salario <= 400.00) || (salario >= 1000.00)) || (tempo >
5)
(d) ((salario <= 400.00) || (salario >= 1000.00)) && (tempo >
5)
(e) ((salario <= 400.00) && (salario >= 1000.00)) || (tempo >
5)

90

Captulo 6
Comandos de Controle

6.1 Introduo
Este aptulo tem por objetivo apresentar os omandos de ontrole da linguagem
C. Estes omandos servem para ontrolar o uxo de exe uo das instrues
de um programa. Estes omandos permitem que o omputador tome de ises
independentemente do usurio que est rodando o programa.

6.2 Blo os de Comandos


Blo os de omando so grupos de omandos que devem ser tratados omo uma
unidade lgi a. O in io de um blo o em C mar ado por uma have de abertura
({) e o trmino por uma have de fe hamento (}). O blo o de omandos serve
para agrupar omandos que devem ser exe utados juntos. Por exemplo, usase blo o de omandos quando em omandos de teste deve-se es olher entre
exe utar dois blo os de omandos. Um blo o de omandos pode ser utilizado em
qualquer tre ho de programa onde se pode usar um omando C. interessante
observar que um blo o de omandos pode ter zero omandos C. Um blo o de
omandos om 0 ou 1 omando pode dispensar as haves. Um blo o de omandos
mostrado a seguir.
/* blo o_de_ o ma nd o s */
{
i = 0;
j = j + 1;
printf ( " % d % d \ n " , i , j ) ;
}

6.3 Comandos de Teste


Os omandos de teste permitem ao omputador de idir o aminho a seguir,
durante a exe uo do programa, independentemente do usurio. Estes testes
91

so baseados em estados internos disponveis ao pro essador. Estes estados


podem ser resultantes de uma operao aritmti a anterior, de uma operao
anterior et .

6.3.1 Comando if
O omando if utilizado quando for ne essrio es olher entre dois aminhos.
A forma geral do omando if a seguinte:

if

( expresso )
blo o_de_ o ma n do s 1 ;

else

blo o_de_ o ma n do s 2 ;

Neste omando a expresso avaliada, e aso o resultado seja verdadeiro


(qualquer resultado diferente de zero) o blo o_de_ omandos1 exe utado, aso
ontrrio o blo o_de_ omandos2 exe utado. Pela denio do omando a expresso deve ter omo resultado um valor diferente de zero para ser onsiderada
verdade. Observar que somente um dos dois blo os ser exe utado. Como a
lusula else op ional a forma abaixo do omando if perfeitamente vlida.

if

( expresso )
blo o_de_ om a nd o s ;

Lembrar que os blo os de omandos devem ser delimitados pelas haves,


a no ser quando o blo o omposto por 0 ou 1 omando. Na listagem 6.1
mostramos alguns exemplos de uso de omando if.
Uma onstruo que pode apare er so os omandos if's em es ada, uja
forma geral a seguinte:

if

( expresso )
blo o_de_ o ma nd o s
e l s e i f ( expresso1 )
blo o_de_ o m an d os 1
e l s e i f ( expresso2 )
blo o_de_ o ma nd o s2
...

else

blo o_de_ o ma nd o sn

O programa 6.2 mostra um exemplo om if's em es ada e aninhados. Um


exemplo de uso deste programa o seguinte:

92

Listagem 6.1: Exemplo de omandos if.


s anf ( " % d " , & dia ) ;
i f ( dia > 31 || dia < 1 )
printf ( " Dia invalido \ n " ) ;
s anf ( " % d " , & numero ) ;
i f ( numero > 0 )
printf ( " Numero positivo \ n " ) ;

else

printf ( " Numero negativo \ n " ) ;

s anf ( " % f " , & salario ) ;


i f ( salario < 800.00) {
printf ( " Aliquota de imposto = 0.1\ n " ) ;
imposto = salario * 0.1;
}
else {
printf ( " Aliquota de imposto = 0.25\ n " ) ;
imposto = salario * 0.25;
}

Este programa simula uma al uladora simples.


Por favor entre om os dois operandos.
3 5
Qual a opera ao
+
O resultado da + vale 8.000000.
Para evitar que o re uo da es ada seja muito profundo o omando if em
es ada foi es rito da seguinte maneira:

if

( expresso )
blo o_de_ om a nd o s ;
e l s e i f ( expresso )
blo o_de_ om a nd o s ;
e l s e i f ( expresso )
blo o_de_ om a nd o s ;
...
e l s e blo o_de_ o ma n do s ;

6.3.2 Comando swit h


O omando if, em todas suas formas, su iente resolver problemas de seleo
de omandos. Porm em alguns asos, omo no exemplo 6.2 o programa se
torna mais trabalhoso para ser es rito e entendido. O omando swit h fa ilita

93

Listagem 6.2: Programas om if's em es ada e aninhados.

#in lude < stdio .h >


int main ( void ) {
f l o a t num1 ,
har

/* primeiro operando */
num2 ,
/* segundo operando */
res ; /* resultado da opera ao */
oper ;
/* ara tere que define a opera ao */

printf ( " \ nPrograma que simula al uladora simples .\ n " )


;
printf ( " Entre om os dois operandos .\ n " ) ;
s anf ( " % f % f " , & num1 , & num2 ) ; get har () ; /* tirar o r
*/
printf ( " Qual a opera ao ? \ n " ) ;
oper = get har () ;
i f ( oper == '+ ')
res = num1 + num2 ;
e l s e i f ( oper == ' - ')
res = num1 - num2 ;
e l s e i f ( oper == '* ')
res = num1 * num2 ;
e l s e i f ( oper == '/ ') {
i f ( num2 == 0.0) {
printf ( " Opera ao de divisao por 0 invalida !\
n");
return 1;
}
e l s e res = num1 / num2 ;
}
else {
printf ( " Opera ao invalida !\ n " ) ;
return 1;
}
printf ( " O resultado da % vale % f .\ n " , oper , res ) ;
return 0;

94

a es rita de tre hos de programa em que a seleo deve ser feita entre vrias
alternativas.
A forma geral do omando swit h a seguinte:

swit h ( expresso ) {
ase onstante1 :

seqn ia_ d e _ o ma n d os ;

ase

break ;

onstante2 :
seqn ia_ d e _ o ma n d os ;
break ;
ase onstante3 :
seqn ia_ d e _ o ma n d os ;
break ;
...
default :
seqn ia_ d e_ om a n do s ;

Uma seqn ia de omandos diferente de um blo o de omandos. Um


blo o de omandos ini ia om uma have e termina om uma have, enquanto
que uma seqn ia apenas uma srie de omandos. Por exemplo, uma vez que
um blo o de omandos foi sele ionado por um omando if ele ser exe utado
at a ltima instruo do blo o, a menos que haja um omando de desvio. Uma
srie de omandos so apenas omandos olo ados um aps outro. A exe uo
do omando swit h segue os seguintes passos:
1. A expresso avaliada;
2. O resultado da expresso omparado om os valores das onstantes que
apare em nos omandos ase;
3. Quando o resultado da expresso for igual a uma das onstantes, a exe uo se ini ia a partir do omando asso iado om esta onstante. A
exe uo ontinua at o m do omando swit h, ou at que um omando
break seja en ontrado;
4. Caso no o orra nenhuma oin idn ia os omandos asso iados ao omando default so exe utados. O omando default op ional, e se ele
no apare er nenhum omando ser exe utado.
O omando break um dos omandos de desvio da linguagem C. O break
usado dentro do omando swit h para interromper a exe uo da seqn ia
de omandos e pular para o omando seguinte ao omando swit h.
H alguns pontos importantes que devem ser men ionados sobre o omando
swit h.
O resultado da expresso deve ser um tipo enumervel, por exemplo o
tipo int. Tambm podem ser usados tipos ompatveis om int, isto ,
expresses om resultados tipo har podem ser usadas;

95

Notar que aso no aparea um omando de desvio, todas as instrues


seguintes ao teste ase que teve su esso sero exe utadas, mesmo as que
estejam rela ionadas om outros testes ase;
O omando swit h s pode testar igualdade;
No podem apare er duas onstantes iguais em um ase;

O programa 6.3 mostra um exemplo de uso de omandos swit h.

6.3.3 Comando Ternrio


O omando ternrio tem este nome porque ne essita de trs operandos para ser
avaliado. O omando ternrio tem a seguinte forma:

expresso1 ? expresso2 : expresso3


Para avaliar o resultado total da expresso, primeiro a expresso1 avaliada. Caso este resultado seja orrespondente ao valor verdadeiro ento o
resultado da expresso ser igual ao resultado da expresso2. Caso ontrrio
a expresso3 avaliada e se torna o resultado. O programa 6.4 mostra um
exemplo de uso de omando ternrio.

6.4 Laos de Repetio


Estes omandos permitem que tre hos de programa sejam repetidos um erto
nmero de vezes ontrolado pelo programa. O nmero de vezes que um lao
ser exe utado pode ser xo ou depender de ondies que mudam durante a
exe uo do lao.

6.4.1 Comando for


Este omando apare e em vrias linguagens de programao, mas na linguagem
C ele apresenta um grau maior de exibilidade. A idia bsi a do omando for
a seguinte. Uma varivel de ontrole, geralmente um ontador, re ebe um valor
ini ial. O tre ho de programa que perten e ao lao exe utado e ao nal a
varivel de ontrole in rementada ou de rementada e omparada om o valor
nal que ela deve al anar. Caso a ondio de trmino tenha sido atingida o
lao interrompido. A forma geral do omando for a seguinte:

for

( expresso1 ; expresso2 ; expresso3 )


blo ode oman do s ;

As trs expresses geralmente tm os seguintes signi ados:


1. A expresso1 utilizada para ini ializar a varivel de ontrole do lao;
2. A expresso2 um teste que ontrola o m do lao;

96

Listagem 6.3: Exemplo de swit h.

#in lude < stdio .h >


int main ( void ) {
float
num1 ,
num2 ,
res ;
har oper ;
*/

/* primeiro operando */
/* segundo operando */
/* resultado da opera ao */
/* ara ter que define a opera ao

printf ( " \ nEste programa simula uma al uladora simples


.\ n " ) ;
printf ( " Por favor entre om os dois operandos .\ n " ) ;
s anf ( " % f % f " , & num1 , & num2 ) ; get har () ;
printf ( " Qual a opera ao \ n " ) ;
oper = get har () ;
printf ( " A opera ao e % \ n " , oper ) ;
swit h ( oper ) {
ase '+ ':
res = num1 + num2 ;
break ;
ase ' - ':
res = num1 - num2 ;
break ;
ase '* ':
res = num1 * num2 ;
break ;
ase '/ ':
i f ( num2 == 0.0) {
printf ( " Divisao por zero e uma op ao
invalida .\ n " ) ;
return 1;
}
else {
res = num1 / num2 ;
break ;
}
default :
printf ( " Opera ao invalida !\ n " ) ;
return 2;
}
printf ( " O resultado da % vale % f .\ n " , oper , res ) ;
return 0;

97

Listagem 6.4: Exemplo de omando ternrio.

#in lude < stdio .h >


int main ( void ) {
float
num1 ,
num2 ,
max ;

/* primeiro operando */
/* segundo operando */
/* resultado da opera ao */

printf ( " Imprime o maior valor de dois numeros .\ n " ) ;


printf ( " Por favor entre om os dois mumeros .\ n " ) ;
s anf ( " % f % f " , & num1 , & num2 ) ;
max = ( num1 > num2 ) ? num1 : num2 ;
printf ( " O maior dos numeros lidos e % f .\ n " , max ) ;
return 0;

3. A expresso3 normalmente faz um in remento ou de remento da varivel


de ontrole.
A exe uo do omando for segue os seguintes passos:
1. A expresso1 avaliada;
2. A expresso2 avaliada para determinar se o omando deve ser exe utado;
3. Se o resultado da expresso2 for verdadeiro o blo o de omandos
exe utado, aso ontrrio o lao terminado;
4. A expresso3 avaliada;
5. Voltar para o passo 2.
O tre ho a seguir imprime todos os nmeros entre 1 e 100.

for
}

( i = 1; i <= 100; i ++) {


printf ( " Numero % d \ n " , i ) ;

O programa 6.5 mostra omo se pode al ular o fatorial de um nmero


usando-se o omando for.
Laos

for

om mais de um omando por expresso

Outra possibilidade que o omando for em C permite a in luso de vrios


omandos, separados por vrgulas, nas expresses. O tre ho de programa a
seguir mostra um exemplo de uso de omando for om vrios omandos nas
expresses.

98

Listagem 6.5: Exemplo de omando for.

#in lude < stdio .h >


#in lude < stdlib .h >
int

main () {
int numero , fat =1 , i ;
printf ( " \ nEntre om um numero positivo . " ) ;
s anf ( " % d " , & numero ) ;
for ( i = numero ; i >1; i - -) fat = fat * i ;
printf ( " O fatorial de % u vale % u . " , numero , fat ) ;
return 0;

int
for
}

Laos

i,j;
( i =1 , j = 10; i <= 10; i ++ , j += 10) {
printf ( " i = %d , j = % d \ n " , i , j ) ;

for

om testes usando outras variveis

A expresso de ontrole no pre isa ne essariamente envolver somente um teste


om a varivel que ontrola o lao. O teste de nal do lao pode ser qualquer
expresso rela ional ou lgi a. No programa 6.6 o lao pode terminar porque
a varivel de ontrole j hegou ao seu valor limite ou foi batida a te la '*', e
neste aso o lao termina ante ipadamente.

Listagem 6.6: Exemplo de omando for om testes sobre outras variveis.

#in lude < stdio .h >


int main () {
har = ' ';
int i ;
for ( i =0 ; (i <5)
}
}

Laos

&& ( != '* ') ; i ++ ) {


printf ( " % \ n " , ) ;
= get har () ;

return

for

0;

om expresses faltando

Um outro ponto importante do for que nem todas as expresses pre isam estar
presentes. No exemplo 6.7 a varivel de ontrole no in rementada. A ni a
maneira do programa terminar o usurio bater o nmero -1.
99

Listagem 6.7: Exemplo de omando for sem alterao da varivel de ontrole.

#in lude < stdio .h >


int main () {
int i ;
for ( i =0 ; i
}

!= -1 ; ) {
printf ( " % d \ n " ,i ) ;
s anf ( " % d " , & i ) ;

return

0;

possvel omitir qualquer uma das expresses. Por exemplo, se a expresso2


for omitida o programa assume que ela sempre verdade de modo que o lao
s termina om um omando de desvio omo o break. O programa do exemplo
6.8 pra quando o valor da varivel de ontrole for igual a 5. Neste aso o teste
ser verdade o lao termina por meio do break.

Listagem 6.8: Exemplo de omando for sem teste de m.

#in lude < stdio .h >


int main () {
int i ;
for ( i = 0; ;
}
}

i ++) {
printf ( " numero % d \ n " , i ) ;
i f ( i == 5) break ;

return

0;

Lao innito

Uma onstruo muito utilizada o lao innito. No lao innito o programa


pra quando se exe uta o omando break. O tre ho de programa a seguir
somente pra quando for digitada a te la 's' ou 'S '.

for

( ; ; ) {
printf ( " \ nVo e quer parar ?\ n " ) ;
= get har () ;
i f ( == 'S ' || == 's ') break ;

100

Laos

for

aninhados

Uma importante onstruo apare e quando olo amos omo omando a ser repetido um outro omando for. Esta onstruo pode apare er quando estamos
trabalhando om matrizes. O exemplo 6.9 mostra um programa que imprime
uma tabuada.

Listagem 6.9: Comando for aninhados.

#in lude < stdio .h >


int main ( void ) {
int i , j ;
printf ( " Imprime tabuada de multipli a ao .\ n " ) ;
for ( i =1 ; i <10 ; i ++) {
printf ( " Tabuada de % d \ n " , i ) ;
for ( j =1; j <10; j ++) {
printf ( " % d x % d = % d \ n " , i , j , i * j ) ;
}
}
return 0;

6.4.2 Comando while


O omando while tem a seguinte forma geral:

while

( expresso )
blo o_de_ o ma nd o s

A expresso pode assumir o valor falso (igual a 0) ou verdade (diferente


de 0). Os passos para exe uo do omando so os seguintes:
1. A expresso avaliada;
2. Se o resultado for verdadeiro ento o blo o de omandos exe utado,
aso ontrrio a exe uo do blo o terminada;
3. Voltar para o passo 1.
Uma ara tersti a do omando while, omo pode ser visto dos passos a ima,
que o blo o de omandos pode no ser exe utado aso a ondio seja igual a
falso logo no primeiro teste.
O tre ho de abaixo imprime os 100 primeiros nmeros usando um omando
while.
i = 1;

101

while
}

( i <= 100) {
printf ( " Numero % d \ n " , i ) ;
i ++;

A expresso do omando pode in luir hamadas de funo. Lembrar que


qualquer atribuio entre parnteses onsiderada omo uma expresso que
tem omo resultado o valor da atribuio sendo feita. Por exemplo, o programa
6.10 repete um blo o de omandos enquanto o usurio usar a te la ' ' para
ontinuar, qualquer outra te la o blo o interrompido.

Listagem 6.10: Comando while om uma funo.

#in lude < stdio .h >


int main ( void ) {
int ;
puts ( " Te le para ontinuar .\ n " ) ;
(( = get har () ) == ' ') {
puts ( " Nao A abou .\ n " ) ;
get har () ; /* tira o enter */
}
puts ( " A abou .\ n " ) ;
return 0;

while

6.4.3 Comando do-while


A forma genri a do omando a seguinte:

do

blo o_de_ o ma nd o s
( expresso ) ;

while

Observar que neste omando a expresso de teste est aps a exe uo do


omando, portanto o blo o de omandos exe utado pelo menos uma vez. A
exe uo do omando segue os seguintes passos:
1. Exe uta o omando;
2. Avalia a expresso;
3. Se o resultado da expresso for verdadeiro ento volta para o passo 1,
aso ontrrio interrompe o do-while
O exemplo de omando for para imprimir os 100 primeiros nmeros es rito
om omando do-while  a da seguinte maneira:

102

i = 1;
{
printf ( " Numero % d \ n " , i ) ;
i ++;
} while ( i <= 100) ;

do

6.5 Comandos de Desvio


6.5.1 Comando break
O omando break pode ser tanto usado para terminar um teste ase dentro
de um omando swit h quanto interromper a exe uo de um lao. Quando o
omando utilizado dentro de um omando for o lao imediatamente interrompido e o programa ontinua a exe uo no omando seguinte ao omando
for. No tre ho de programa abaixo o omando for deve ler 100 nmeros inteiros
positivos. No entanto, se for digitado um nmero negativo o omando for
interrompido imediatamente sem que o nmero seja impresso.

for

( i = 0; i < 100; i ++) {


s anf ( " % d " , & num ) ;
i f ( num < 0) break ;
printf ( " % d \ n " , num ) ;

6.5.2 Comando ontinue


O omando ontinue pare ido om o omando break. A diferena que o
omando ontinue simplesmente interrompe a exe uo da iterao orrente
passando para a prxima iterao do lao, se houver uma. No omando for o
ontrole passa a exe uo da expresso3. Nos omandos while e do-while o
ontrole passa para a fase de testes.
No tre ho de programa abaixo o lao l 100 nmeros inteiros, aso o nmero
seja negativo, um novo nmero lido.

for

( i = 0; i < 100; i ++) {


s anf ( " % d " , & num ) ;
i f ( num < 0) ontinue ;
printf ( " % d \ n " , num ) ;

6.5.3 Comando goto


O omando goto ausa um desvio in ondi ional para um outro ponto da funo
em que o omando est sendo usado. O omando para onde deve ser feito o
103

desvio indi ado por um rtulo, que um identi ador vlido em C seguido por
dois pontos. importante notar que o omando goto e o ponto para onde ser
feito o desvio pode estar em qualquer ponto dentro da mesma funo. A forma
geral deste omando :

goto rtulo;
...

rtulo:
Este omando durante muito tempo foi asso iado a programas ilegveis. O
argumento para esta armao se baseia no fato de que programas om omandos goto perdem a organizao e estrutura porque o uxo de exe uo pode
 ar saltando errati amente de um ponto para outro. Atualmente as restries
ao uso do omando tem diminudo e seu uso pode ser admitido em alguns asos.

6.5.4 Funo exit()


A funo exit provo a a terminao de um programa, retornando o ontrole ao
sistema opera ional. O prottipo da funo a seguinte:

void exit (int odigo);


Observar que esta funo interrompe o programa omo um todo. O digo
usado para indi ar qual ondio ausou a interrupo do programa. Usualmente o valor 0 indi a que o programa terminou sem problemas. Um valor
diferente de 0 indi a um erro.

6.5.5 Comando return


O omando return usado para interromper a exe uo de uma funo e retornar um valor ao programa que hamou esta funo. Caso haja algum valor
asso iado ao omando return este devolvido para a funo, aso ontrrio um
valor qualquer retornado. A forma geral do omando :

return expresso;
Notar que a expresso op ional. A have que termina uma funo equivalente a um omando return sem a expresso orrespondente. possvel haver
mais de um omando return dentro de uma funo. O primeiro que for en ontrado durante a exe uo ausar o m da exe uo. Uma funo de larada
omo do tipo void no pode ter um omando return que retorne um valor.
Isto no faz sentido, j que funes deste tipo no podem retornar valores.

104

6.6 Exer ios


6.1: Es reva um programa que al ule x elevado a n. Assuma que n um valor
inteiro.

Es reva um programa que exiba as opes


1-multipli ar e 2-somar
de um menu, leia a opo desejada, leia dois valores, exe ute a operao (utilizando o omando if) e exiba o resultado.
6.2:

6.3: Utilizando if's em es ada, in lua, no programa do exer io anterior, as


opes 3-Subtrair e 4-Dividir.
6.4:

Simplique os programas anteriores da seguinte forma:

Rees reva o programa do exer io 1 substituindo o omando if pelo omando ternrio.


Rees reva o programa do exer io 2 substituindo os if's em es ada pelo
omando swit h.

Utilizando um lao for dentro de outro, es reva um programa que exiba


as tabuadas de multipli ao dos nmeros de 1 9.

6.5:

6.6: Es reva um programa om menu de 5 opes que utilize o omando de


desvio goto para exe utar a opo desejada e s saia do programa aso a opo
5-Sair seja sele ionada.
6.7:Es reva um programa que tenha um nmero (inteiro) omo entrada do
usurio e es reva omo sada a seqen ia de bits que forma esse numero. Por
exemplo, aps digitado o nmero 10, a sada deve ser 0000000000001010.
6.8:Es reva

um programa que imprima todos os pares entre 0 e 50 e em seguida


imprima todos os impares. Deixar um espao entre os nmeros.

6.9: Es reva um programa que leia 10 nmeros. O programa deve imprimir a


media, o maior e o menor deles.
Obs: Os nmeros devem ser entre 0 e 10.
6.10: Es reva um programa que leia 10 nmeros. O programa deve imprimir a
media, o maior e o menor deles.
Obs: Considere agora que os nmeros podem ser quaisquer.
6.11:

Es reva um programa que exibe a tabela as ii.

6.12:

Crie um programa para veri ar se um nmero dado primo.

Es reva um programa que leia um numero do te lado e a he todos os seus


divisores.

6.13:

6.14:

Es reva um programa que imprima a seqn ia


987654321876543217654321654321543214321321211

105

No use nenhuma onstante, use apenas variveis. Em outra linha imprima


as letras mais ulas de A at Z (ABCD...).
Es reva um programa que onte de 100 a 999 (in lusive) e exiba, um
por linha, o produto dos trs dgitos dos nmeros. Por exemplo, ini ialmente o
programa ir exibir:

6.15:

0 (1*0*0)
0 (1*0*1)
0 (1*0*2)
(...)
0 (1*1*0)
1 (1*1*1)
2 (1*1*2)

9*9*9=729
Faa seu programa dar uma pausa a ada 20 linhas para que seja possvel
ver todos os nmeros pou o a pou o. Soli ite que seja pressionada alguma te la
para ver a prxima seqn ia de nmeros.
6.16:

Es reva um programa que imprima uma gura omo a mostrada abaixo. O


nmero de linhas da gura deve ser pedido ao usurio.

******
*****
****
***
**
*

O que ser impresso pelo programa 6.11. Indique os nmeros que vo


ir digitar para o programa. Os nmeros devem ser todos diferentes.

6.17:

106

Listagem 6.11: Programa do exer i io 17.

#in lude < stdio .h >


int main ( void ) {
int i , j , m ;
for ( i = 0; i

}
}

< 6; i ++) {
s anf ( " % d " , & m ) ;
i f ( m % 2) {
for ( j = 0; j < m ; j ++) {
printf ( " # " ) ;
}
}
else {
for ( j = m ; j > 0; j - -) {
printf ( " * " ) ;
}
}
printf ( " \ n " ) ;

return

0;

107

Captulo 7
Vetores e Cadeias de
Cara teres

7.1 Introduo
Vetores so usados para tratamento de onjuntos de dados que possuem as
mesmas ara tersti as. Uma das vantagens de usar vetores que o onjunto
re ebe um nome omum e elementos deste onjunto so referen iados atravs
de ndi es. Pelo nome vetor estaremos referen iando estruturas que podem
ter mais de uma dimenso, omo por exemplo matrizes de duas dimenses.
Neste aptulo estaremos mostrando vetores de tamanhos xos. Somente aps
apresentarmos ponteiros iremos abordar alo ao de memria para vetores.

7.2 De larao de Vetores Unidimensionais


A forma geral da de larao de vetores de uma dimenso :
tipo nome [tamanho;

onde tipo um tipo qualquer de dados, nome o nome pelo qual o vetor vai
ser referen iado e tamanho o nmero de elementos que o vetor vai onter.
Observar que em C o primeiro elemento tem ndi e 0 e o ltimo tamanho - 1.
Exemplos de de laraes de vetores so:

int numeros [1000;


f l o a t notas [65;
har nome [40;

/* vetor de 1000 inteiros */


/* onjunto de 65 numeros reais */
/* onjunto de 40 ara teres */

O espao de memria, em bytes, o upado por um vetor de tipo qualquer


igual a:
espao = tamanho *

sizeof(tipo)

importante notar que em C no h veri ao de limites em vetores. Isto


signi a que possvel ultrapassar o m de um vetor e es rever em outras
108

variveis, ou mesmo em tre hos de digo. tarefa do programador fazer om


que os ndi es dos vetores estejam sempre dentro dos limites estabele idos pela
de larao do vetor.
O programa 7.1 ilustra omo se de lara um vetor, ini ializa seus valores
e imprime o ontedo. Notar o uso da diretiva #define DIM 5 para denir
uma onstante, que posteriormente foi usada para estabele er o tamanho do
vetor. Esta onstante passa a ser usada nas refern ias ao vetor, por exemplo no omando de gerao do onjunto de dados armazenado no vetor. Caso
seja ne essrio tro ar o tamanho do vetor basta alterar o valor da onstante e
re ompilar o programa.

Listagem 7.1: Exemplo de vetores.

#define DIM 5
#in lude < stdio .h >
int main ( void ) {
int vetor [ DIM ;
unsigned int i ,

num ;

puts ( " Este programa gera um vetor de inteiros .\ n " ) ;


puts ( " Entre om o numero ini ial do onjunto . " ) ;
s anf ( " % d " , & num ) ;
/* Gera ao do onjunto */
for ( i = 0 ; i < DIM ; i ++) vetor [ i = num ++;
/* Impressao do onjunto */
for ( i = 0; i < DIM ; i ++)
printf ( " Elemento % d = % d \ n " , i , vetor [ i ) ;
}

return

0;

O programa 7.2 al ula o produto es alar de dois vetores inteiros. Observar


omo na leitura dos elementos do vetor usa-se o operador de endereo & antes
do nome de ada elemento.
O programa 7.3 ilustra o mtodo da bolha para ordenao em ordem res ente de um vetor de inteiros. Neste mtodo a ada etapa o maior elemento
movido para a sua posio. A ada iterao os elementos do vetor so omparados dois a dois, sendo tro ados aso seja ne essrio. Ao trmino da primeira
passada pelo vetor, o maior elemento levado para a sua posio, no nal do
vetor. Portanto, ele no pre isa ser mais onsiderado, da o valor da varivel
que aponta para o nal do vetor (fim) diminuda de 1. O pro esso repetido
at que todos os elementos sejam levados para as suas posies ou que nenhuma
tro a seja realizada. Quando nenhuma tro a realizada o vetor est ordenado.
A Tabela 7.1 mostra os passos exe utados pelo algoritmo at ordenar o vetor.

109

v[0

v[1

v[2

v[3

v[4

v[4

20
15
15
15
15
15
15
15

15
20
20
8
8
8
8
8

8
8
8
20
20
12
12
12

12
12
12
12
12
20
20
5

5
5
5
5
5
5
5
20

v[1?
v[0 e v[1
v[2?
v[1 e v[2
v[3?
v[2 e v[3

15
8
8
8
8
8

8
15
15
12
12
12

12
12
12
15
15
5

5
5
5
5
5
15

20
20
20
20
20
20

8
8
8

12
12
5

5
5
12

15
15
15

20
20
20

8
5

5
8

12
12

15
15

20
20

Operao
Passo 1

v[0 >
Tro ar
v[1 >
Tro ar
v[2 >
Tro ar
v[3 >
Tro ar

v[1?
v[0 e
v[2?
v[1 e
v[3?
v[2 e
v[4?
v[3 e

v[1
v[2
v[3

Passo 2

v[0 >
Tro ar
v[1 >
Tro ar
v[2 >
Tro ar

Passo 3

v[0 > v[1?


v[1 > v[2?
Tro ar v[1 e v[2
Passo 4

v[0 > v[1?


Tro ar v[0 e v[1?

Tabela 7.1: Passos exe utados durante o algoritmo da bolha.

110

Listagem 7.2: Produto es alar de dois vetores.

#define DIM 5
#in lude < stdio .h >
int

main ( void ) {
int vetor1 [ DIM , vetor2 [ DIM , i , prod =0;
printf ( " Entre om um vetor de % d elementos \ n " , DIM ) ;
for ( i = 0; i < DIM ; i ++) {
printf ( " Elemento % d " , i ) ;
s anf ( " % d " , & vetor1 [ i ) ;
}
printf ( " Entre om outro vetor de % d elementos \ n " , DIM )
;
for ( i = 0; i < DIM ; i ++) {
printf ( " Elemento % d " , i ) ;
s anf ( " % d " , & vetor2 [ i ) ;
}
for ( i = 0; i < DIM ; i ++)
prod += vetor1 [ i * vetor2 [ i ;
printf ( " O produto vale % d " , prod ) ;

return

0;

7.3 Cadeias de Cara teres


Um adeia de ara teres (string) um onjunto de ara teres terminado por um
ara tere nulo, que representado omo '\0'. Para espe i ar um vetor para
armazenar um adeia deve-se sempre reservar um espao para este ara tere.
Por exemplo, para armazenar um adeia de 40 ara teres deve-se reservar um
vetor de 41 de ara teres. Em C possvel haver onstantes adeia, que so
denidas omo uma lista de ara teres entre aspas. Por exemplo,

"programando em C"
No ne essrio a olo ao do ara tere nulo ao nal da adeia. Em C
no h o tipo adeia (string) e, portanto, onjuntos de ara teres teriam de
ser tratados omo onjuntos de nmeros inteiros, por exemplo. Para fa ilitar a
programao foram riadas algumas funes para manipular adeias. Algumas
das funes mais omuns esto resumidamente des ritas a seguir:
Nas denies a seguir, size_t o tipo inteiro sem sinal que volta omo
resultado do operador sizeof.
har *str at( har *dest, onst har *orig): Con atena adeia orig ao
nal de dest. O primeiro ara tere de orig substitui o ara tere nulo de
dest. A funo retorna o valor de dest.
har *strn at ( har *dest, onst har *orig, size_t n): Con atena adeia orig ao nal de dest, usando no mximo n ara teres de orig. O

111

Listagem 7.3: Ordenao pelo mtodo da bolha.

#define
#define
#define

DIM 5
FALSO 0
VERDADE 1

#in lude
int main
int
int

< stdio .h >


( void ) {
vetor [ DIM , i ;
tro ou = FALSO , fim = DIM , temp ;

printf ( " Entre om um vetor de % d elementos \ n " , DIM ) ;


for ( i = 0; i < DIM ; i ++) {
printf ( " Elemento % d " , i ) ;
s anf ( " % d " , & vetor [ i ) ;
}

do

tro ou = FALSO ;
for ( i =0; i < fim -1; i ++) {
i f ( vetor [ i > vetor [ i +1) {
temp = vetor [ i ;
vetor [ i = vetor [ i +1;
vetor [ i +1 = temp ;
tro ou = VERDADE ;
}
}
fim - -;
} while ( tro ou ) ;

for
}

( i =0; i < DIM ; i ++) printf ( " % d \ n " , vetor [ i ) ;

return

0;

112

primeiro ara tere de orig substitui o ara tere nulo de dest. A funo
retorna o valor de dest.
har *str mp ( onst har * ad1, onst har * ad2): Compara lexi ogra amente as duas adeias. Retorna zero se as adeias so iguais, menor
que 0 se ad1 < ad2, maior que 0 se ad1 > ad2.
har *strn mp ( onst har * ad1, onst har * ad2, size_t n): Compara lexi ogra amente at n ara teres das duas adeias. Retorna zero se
as adeias so iguais, menor que 0 se ad1 < ad2, maior que 0 se ad1
> ad2.
size_t strlen( onst har * ad): Cal ula o omprimento da adeia sem
ontar o ara a ter nulo. O omprimento da adeia determinado pelo
ara tere nulo. No onfundir o tamanho da adeia om o tamanho do
vetor que armazena a adeia.
har *str py( har *dest, onst har *orig): Copia adeia orig para
dest. A adeia destino deve ter espao su iente para armazenar orig.
O valor de dest retornado.

Estas funes esto na bibliote a string.h. O programa 7.4 mostra exemplos de uso de algumas das funes de adeia. Neste exemplo, o programa
primeiro l um nome e em seguida um sobrenome. O programa ir ento on atenar as duas adeias. Observe que sempre olo ado um bran o ao nal
do nome para separ-lo do sobrenome. Este bran o inserido usando a funo
str at, e esta razo das aspas, ou seja, uma adeia de um ara tere apenas.
A seguir mostramos um resultado da exe uo do programa 7.4.

Entre om um nome Ze
Ze
Entre om um sobrenome Sa
Sa
Ze Sa
Qual ara ter? a
O ara tere apare e na posi ao 4

7.4 De larao de Vetores Multidimensionais


Em C existe a possibilidade de de lararmos vetores de mais de uma dimenso.
A forma geral da de larao a seguinte:

tipo nome [dim1[dim2[dim3...[dimN;


onde dimI o tamanho da dimenso I. Deve-se tomar uidado om armazenamento de matrizes multidimensionais, por que a memria ne essria para
guardar estes dados igual a

sizeof(tipo)*dim1*dim2*dim3*...*dimN
113

Listagem 7.4: Exemplos de funes para adeias.

#in lude < string .h >


#in lude < stdio .h >
int

void ) {
har , nome [81 ,
int i ;

main (

sobrenome [41;

printf ( " Entre om um nome " ) ;


fgets ( nome , 41 , stdin ) ;
nome [ strlen ( nome ) -1 = ' \0 '; /* tira r do fim */
puts ( nome ) ;
printf ( " Entre om um sobrenome " ) ;
fgets ( sobrenome , 41 , stdin ) ;
sobrenome [ strlen ( sobrenome ) -1 = ' \0 ';
puts ( sobrenome ) ;
str at ( nome , " " ) ;
str at ( nome , sobrenome ) ;
puts ( nome ) ;
printf ( " Qual ara ter ? " ) ;
= get har () ;

for

}
}

( i =0; i < strlen ( nome ) ; i ++) {


i f ( == nome [ i ) {
printf ( " O ara tere apare e na posi ao % d \ n "
, i);
}

return

0;

114

Por exemplo a de larao

int

matriz[10[20;

dene uma matriz quadrada de 10 linhas por 20 olunas, enquanto o omando


= 2 * matriz[3[8;

armazena o dobro do elemento que est na quarta linha e nona oluna na varivel
. Observar que o primeiro ndi e indi a a linha e o segundo a oluna. Lembrar
que o nmero da primeira linha ( oluna) igual a 0. O programa 7.5 l uma
matriz de trs linhas e in o olunas e imprime os valores lidos.

Listagem 7.5: Leitura de uma matriz.

#define DIML 3
#define DIMC 5
#in lude < stdio .h >
int main ( void ) {
int i , j ;
int matriz [ DIML [ DIMC ;
for

( i =0; i < DIML ; i ++)


for ( j =0; j < DIMC ; j ++)
s anf ( " % d " , & matriz [ i [ j ) ;

for

( i =0; i < DIML ; i ++) {


for ( j =0; j < DIMC ; j ++)
printf ( " %4 d " , matriz [ i [ j ) ;
printf ( " \ n " ) ;

}
}

return

0;

A matriz armazenada na memria linha a linha e a Figura 7.4 ilustra esta


idia om uma matriz de nmeros inteiros de trs por trs. Estamos assumindo
que ada nmero inteiro o upa quatro bytes, o endereo aponta um byte e a
matriz est armazenada a partir do endereo 1000.
Uma operao muito omum em matemti a a multipli ao de matrizes.
Considere a matriz M 1 om L1 linhas e C1 olunas e a matriz M 2 om L2
linhas e C2 olunas. O nmero de olunas C1 de M 1 deve ser igual ao nmero
de linhas L2 de M 2. O elemento M Rij da matriz resultado M R do produto
destas matrizes denido pela equao 7.1. O programa 7.6 multipli a duas
matrizes de a ordo om a frmula.
M Rij =

C1
X

M 1ik M 2kj

k=1

115

(7.1)

Listagem 7.6: Multipli ao de duas matrizes.

#in lude < stdio .h >


#define
#define
#define
#define
int

3
3
3
3

void ) {
f l o a t m1 [ L1 [ C1 ,
f l o a t mr [ L1 [ C2 ,
int i , j , k ;

main (

for

for

for

for

}
}

L1
L2
C1
C2

m2 [ L2 [ C2 ;
m;

( i =0; i < L1 ; i ++) {


for ( j =0; j < C1 ; j ++) {
printf ( " %d , % d " , i , j ) ;
s anf ( " % f " , & m1 [ i [ j ) ;
}
( i =0; i < L2 ; i ++) {
for ( j =0; j < C2 ; j ++) {
printf ( " %d , % d " , i , j ) ;
s anf ( " % f " , & m2 [ i [ j ) ;
}
( i =0; i < L1 ; i ++) {
for ( j =0; j < C2 ; j ++) {
m = 0;
for ( k =0; k < C1 ; k ++) {
m += m1 [ i [ k * m2 [ k [ j ;
}
mr [ i [ j = m ;
}
( i =0; i < L1 ; i ++ ) {
for ( j =0; j < C2 ; j ++) {
printf ( " %.3 f " , mr [ i [ j ) ;
}
printf ( " \ n " ) ;

return

0;

116

1000

m[0][0]

1004

m[0][1]

1008

m[0][2]

1012

m[1][0]

1016

m[1][1]

1020

m[1][2]

1024

m[2][0]

1028

m[2][1]

1032

m[2][2]

Figura 7.1: Mapa de memria de uma matriz.

7.5 Vetores de Cadeias de Cara teres


A de larao abaixo mostra uma matriz de adeias de ara teres om 30 linhas
de 80 ara teres.

har nome_turma[30[80;
O Programa 7.7 mostra um programa que l uma matriz de nomes e imprime
os seus ontedos. importante notar que para ler um nome o programa no
l um ara ter de ada vez mas usa a funo fgets. Como ada linha da matriz
uma adeia de ara teres, o programa l o nome que est na linha i omo
fgets(nomes[i, DIMC-1, stdin).

7.6 Ini ializao de Vetores e Matrizes


Em C possvel ini ializar vetores da mesma forma que variveis, isto , no
momento em que so de larados. A forma de fazer isto a seguinte:

tipo nome[dim = {lista_de_valores};


onde lista_de_valores um onjunto de valores separados por vrgulas. Por
exemplo, a de larao abaixo ini ializa um vetor inteiro de in o posies.

int vetor[5 = { 10, 15, 20, 25, 30 };

117

Listagem 7.7: Leitura de um vetor de nomes.

#define DIML 5
#define DIMC 41
#in lude < stdio .h >
#in lude < string .h >
int main ( void ) {
int i ;
har nomes [ DIML [ DIMC ;
for

for
}
}

( i =0; i < DIML ; i ++) {


printf ( " Entre om a linha % d " , i ) ;
fgets ( nomes [ i , DIMC -1 , stdin ) ;
nomes [ i [ strlen ( nomes [ i ) -1 = ' \0 ';
( i =0; i < DIML ; i ++) {
printf ( " O nome % d e " , i ) ;
puts ( nomes [ i ) ;

return

0;

Observe que nesta de larao ne essrio que o tamanho do onjunto seja


onhe ido ante ipadamente. No entanto, tambm possvel ini ializar vetores
em que no se onhe e o seu tamanho. Neste aso, ento, importante que o
programador preveja um modo de indi ar o m do vetor.
O Programa 7.8 mostra os asos ilustrados a ima. No primeiro exemplo o
tamanho do vetor onhe ido e foi denido pela onstante DIM. Para des obrir o
omo parar de pro essar o vetor, quando des onhe emos seu tamanho, apresentamos duas solues possveis. No primeiro aso a ondio de m do vetor o
nmero negativo -1. Neste aso uma posio do vetor perdida para armazenar
esta ondio. No segundo aso usado o operador sizeof para des obrir o
tamanho do vetor. Observe que sizeof al ula o tamanho do vetor em bytes e
por esta razo ne essrio uma diviso pelo tamanho em bytes do tipo de ada
elemento.
possvel ini ializar matrizes multidimensionais e neste aso ne essrio
espe i ar todas as dimenses menos a primeira, para que o ompilador possa
reservar memria de maneira adequada. A primeira dimenso somente espe i a
quantos elementos o vetor ir armazenar e isto lendo a ini ializao o ompilador
pode des obrir.
A de larao a seguir ilustra omo de larar e ini ializar uma matriz de trs
linhas por quatro olunas de nmeros reais.

float

mat [[4 = { {1.0 , 2.0 , 3.0 , 4.0} ,


// linha 0
{8.0 , 9.0 , 7.5 , 6.0} ,
// linha 1
{0.0 , 0.1 , 0.5 , 0.4} }; // linha 2

118

Listagem 7.8: Exemplos de tratamento de vetores.

#define DIM 5
#in lude < stdio .h >
int

main () {
int vetor [ DIM = {10 , 15 , 20 , 25 , 30};
int vetor1 [ = {10 , 20 , 30 , 40 , 50 , 60 , -1};
int vetor2 [ = {3 , 6 , 9 , 12 , 15 , 18 , 21 , 24};
unsigned int i , tam ;
printf ( " Este programa imprime vetores " ) ;
printf ( " ontendo numeros inteiros e \ n " ) ;
printf ( " que foram ini ializado s durante " ) ;
printf ( " a sua de lara ao .\ n " ) ;
/* Impressao dos onjuntos */
printf ( " \ nVetor om tamanho pre - definido \ n " ) ;
for ( i =0; i < DIM ; i ++)
printf ( " Elemento % d = % d \ n " , i , vetor [ i ) ;
printf ( " \ nVetor terminando por -1\ n " ) ;
for ( i =0; vetor1 [ i >0; i ++)
printf ( " Elemento % d = % d \ n " , i , vetor1 [ i ) ;
tam = s i z e o f ( vetor2 )
printf ( " \ nDes obrindo
for ( i =0; i < tam ;
printf ( " Elemento

return

/ s i z e o f ( int ) ;
o tamanho do Vetor \ n " ) ;
i ++)
% d = % d \ n " , i , vetor2 [ i ) ;

0;

119

O Programa 7.9 ilustra a denio de um vetor de adeia de ara teres, que


nada mais do que uma matriz de ara teres. Note que as adeias so separadas
uma das outras por vrgulas.

Listagem 7.9: Exemplos de tratamento de vetores.

#define DIM 5
#in lude < stdio .h >
int

main (

har

};

int

void

) {
dis iplinas [[40 = {
" dis 0: Computa ao para Informati a " ,
" dis 1: Ban o de Dados I " ,
" dis 2: Ban o de Dados II " ,
" dis 3: Arquitetura de Computadores I "

i;

printf ( " Qual a dis iplina ? " ) ; s anf ( " % d " , & i ) ;
puts ( dis iplinas [ i ) ;
}

return

0;

120

7.7 Exer ios


Es reva um programa que leia uma linha de at 80 ara teres do te lado e
imprima quantos ara teres foram lidos.

7.1:

7.2: Es reva um programa que leia uma linha de ara teres do te lado e imprima
quantas vezes um ara tere, tambm forne ido pelo te lado, apare e nesta linha.
O programa tambm deve imprimir em que posies o ara tere foi en ontrado.

Es reva um programa que leia uma linha do te lado e em seguida um par


de ara teres. O programa deve pro urar este par na linha e imprimir em que
posies o par foi en ontrado. Obs. No use funes da bibliote a de strings
do C

7.3:

7.4: Es reva um programa que leia uma linha do te lado e imprima todas as
vogais en ontradas no texto e o total de vezes que elas apare em.
Obs: Tamanho mximo da linha deve ser 40 ara teres.

O imperador romano Csar usava um sistema simples para odi ar as


mensagens que enviava aos seus generais. Neste sistema ada letra era substituda por trs letras frente no alfabeto. A sua misso mais simples ainda,
es rever um programa que onverta ada letra, e somente as letras, de uma
mensagem de at 80 ara teres para a letra imediatamente posterior. Note que
a letra 'z' deve ser onvertida para a letra 'a', e a letra 'Z' para 'A'.

7.5:

Es reva um programa que leia uma frase de 80 ara teres e a imprime


retirando os espaos em bran o.

7.6:

Es reva um programa que leia uma linha de ara teres do te lado de


tamanho 80. A linha somente ontm letras. Divida a linha em blo os de 5
letras. Dentro de ada blo o o seu programa deve tro ar a primeira letra pela
letra seguinte no alfabeto, a segunda letra por duas letras adiante no alfabeto,
a ter eira por trs letras adiante e assim at a quinta. Os espaos em bran o
devem ser retirados da frase. Considere o seguinte exemplo.

7.7:

1. Frase lida:
EVA VIU A UVA
2. Retirada dos espaos em bran o:
EVAVIUAUVA
3. Diviso em blo os de 5 (blo os indi ados por tipos diferentes):
EVAVIUAUVA
4. Criptograa:
FYDANVCYAF
Portanto, o que ser impresso pelo programa :
FYDANVCYAF
7.8: Es reva um programa que leia uma matriz de 3x3 que ontm somente
ara teres 0 e X e pro ure linhas que ontenham somente um dos dois ara teres.
O ara tere a ser pro urado deve ser lido do te lado.

121

7.9: Es reva um programa que leia uma linha de ara teres do te lado e onverta
o primeiro ara tere de ada palavra para mais ulas. Assuma que as palavras
so sempre separadas por um bran o.

Es reva um programa que leia para um vetor um onjunto de nmeros


inteiros. Assuma que o onjunto de nmeros lidos menor que o tamanho do
vetor. O programa deve inserir no vetor, em uma posio espe i ada pelo
usurio, um nmero lido do te lado. Assuma que a posio espe i ada pelo
usurio orresponde ao ndi e do vetor.
7.10:

7.11: Faa um programa que inverta uma adeia de ara teres. O programa
deve ler a adeia om gets e armazen-la invertida em outra adeia. Use o
omando for para varrer a adeia at o seu nal.

Es reva um programa que leia um onjunto de nomes para uma matriz


e imprima estes nomes em ordem alfabti a. Assuma que os nomes sero lidos
somente em letras mais ulas. Assuma tambm que os nomes tm no mximo
40 ara teres e sero lidos 10 nomes ao todo.
7.12:

Es reva um programa que leia um onjunto N (1 N 1000000000) de


nmeros inteiros e imprima os seguintes resultados:

7.13:

media dos nmeros;


maior dos nmeros;
menor dos nmeros;
produto de todos os nmeros.
7.14: Considere que vo digitou o seu nome para o programa mostrado na
listagem 7.10. O que ser impresso? Indique o que vo digitou. Justique
sua resposta om detalhes.

122

Listagem 7.10: Programa do exer i io 14.

#in lude < stdio .h >


#in lude < string .h >
#define MAX 50
int main ( void ) {
har texto [ MAX +2 ,
int tam , i ;

temp ;

gets ( texto ) ;
tam = strlen ( texto ) ;
for ( i = 0; i < tam ; i ++) {
temp = texto [ i ;
texto [ i = texto [ tam -1 - i ;
texto [ strlen ( texto ) -1 - i = temp ;
}
puts ( texto ) ;
return 0;

123

Captulo 8
Funes

8.1 Introduo
Em C, diferentemente de outras linguagens omo Pas al, todas as aes o orrem
dentro de funes. Na linguagem C no h on eito de um programa prin ipal, o
que existe uma funo hamada main que sempre a primeira a ser exe utada.
Um programa pode ser es rito apenas om a funo main e mais as funes
existentes nas bibliote as da linguagem C. No entanto o uso de funes pode
fa ilitar o desenvolvimento de programas de diversas maneiras.
Em primeiro lugar temos as vantagens do reuso de digo desenvolvido por
outros programadores. As funes de entrada e sada so o exemplo mais direto
deste reuso. Em C no existem estes tipos de omandos omo na maioria das
linguagens. Programas es ritos em C usam funes de entrada e sada es ritas
e testadas por outros programadores. Este reuso de digo apresenta vrias
vantagens. Primeiro, diminui o tempo de desenvolvimento do programas. Em
segundo lugar, omo estas funes foram testadas por diversos usurios, a quantidade de erros bastante reduzida. Estes fatores ontribuem para a reduo
dos ustos de desenvolvimento dos projetos.
Uma outra vantagem do uso de funes e a maior fa ilidade na diviso do
trabalho ne essrio para onstruir um apli ativo. Funes podem ser desenvolvidas por programadores trabalhando independentemente. Para isto basta que
alguns a ordos sejam feitos entre os programadores que iro programar a funo
e os que iro us-las. Estes a ordos pre isam denir que parmetros a funo
ir re eber, que resultados ir forne er e que operaes ela deve realizar sobre
estes parmetros para obter os resultados ne essrios. Esta diviso do trabalho
on orre para a elerar o desenvolvimento dos programas e na reduo dos ustos
deste desenvolvimento.
A diviso de um programa em funes tambm permite que os testes do
sistema ompleto sejam feitos mais fa ilmente e om mais garantia de orreo.
Os programadores podem testar suas funes separadamente em testes menos
omplexos, j que as funes normalmente so simples e tm requisitos menos
ompli ados de serem avaliados. Isto permite que muitos erros do sistema ompleto possam ser retirados antes que ele esteja ompleto. Normalmente testar
um programa omplexo requer testes omplexos.
124

Mesmo quando um programa desenvolvido por um ni o programador a


sua diviso em funes traz vantagens, por dividir um trabalho omplexo em
diversas fatias menores permitindo ao programador se on entrar a ada vez em
problemas mais simples.

8.2 Forma Geral


A forma geral de uma funo em C a seguinte:
tipo nome ( tipo nome1 , tipo nome2 , ... , tipo nomeN ) {
de larao das variveis
orpo da funo
}

Uma funo re ebe uma lista de argumentos (nome1, nome2, ..., nomeN),
exe uta omandos om estes argumentos e pode retornar ou no um resultado
para a funo que hamou esta funo. A lista de argumentos, tambm hamados de parmetros, uma lista, separada por vrgulas, de variveis om seus
tipos asso iados. No possvel usar uma ni a denio de tipo para vrias
variveis. A lista de argumentos pode ser vazia, ou seja, a funo no re ebe
nenhum argumento. O nome da funo pode ser qualquer identi ador vlido.
O tipo que apare e antes do nome da funo espe i a o tipo do resultado que
ser devolvido ao nal da exe uo da funo. Caso nenhum tipo seja espe i ado o ompilador assume que um tipo inteiro retornado. O tipo void pode
ser usado para de larar funes que no retornam valor algum.
H basi amente duas maneiras de terminar a exe uo de uma funo. Normalmente usa-se o omando return para retornar o resultado da funo. Portanto, quando o omando

return

expresso;

for exe utado, o valor da expresso devolvido para a funo que hamou.
Quando no h valor para retornar o omando return no pre isa ser usado e
a funo termina quando a have que indi a o trmino do orpo da funo
atingido.
Os parmetros so valores que a funo re ebe para realizar as tarefas para
as quais foi programada. Por exemplo, uma funo que al ule a raiz quadrada
de um nmero do tipo oat , deve de larar omo parmetro uma varivel deste
tipo para re eber o valor.
importante notar que diferentemente de de laraes de variveis onde
podemos asso iar vrios nomes de variveis a uma de larao omo em

int

a, dia, mes, i;

na lista de parmetros ne essrio asso iar um tipo a ada varivel omo


no exemplo a seguir:

oat

media (oat n1,

oat

n2,

oat

n3);

Neste exemplo, uma funo hamada media que do tipo oat , isto retorna
um resultado oat , re ebe trs argumentos (n1, n2, n3) tambm do tipo oat .
125

Um ponto importante omo usar a funo. Suponha que uma determinada


funo, A, deseje usar uma outra funo, B. A funo A deve olo ar no lo al
desejado o nome da funo (B) e a lista de valores que deseja passar. Por
exemplo, um programador que deseje usar a funo media em seu programa
para al ular a mdia de trs valores, nota1, nota2 e nota3, deve es rever no
lo al onde quer que a mdia seja al ulada o seguinte omando:
resultado = media(nota1, nota2, nota3);

onde resultado a varivel que vai re eber a mdia al ulada.


importante notar que o nome da funo pode apare er em qualquer lugar
onde o nome de uma varivel apare eria. Alm disso os tipos e o nmero de
parmetros que apare em na de larao da funo e na sua hamada devem
estar na mesma ordem e ser tipos equivalentes. Se os tipos so in ompatveis,
o ompilador no gera um erro, mas podem ser gerados avisos na ompilao e
resultados estranhos.
Outro ponto importante a ser notado e que ser detalhado mais adiante
que os nomes das variveis nos programas que usam a funo media podem ser
diferentes dos nomes usados na denio da funo.

8.3 Prottipos de Funes


O padro ANSI estendeu a de larao da funo para permitir que o ompilador
faa uma veri ao mais rgida da ompatibilidade entre os tipos que a funo
espera re eber e queles que so forne idos. Prottipos de funes ajudam a
dete tar erros antes que eles o orram, impedindo que funes sejam hamadas
om argumentos in onsistentes. A forma geral de denio de um prottipo
a seguinte:
tipo nome (tipo nome1, tipo nome2, ..., tipo nomeN);

O exemplo 8.1 mostra a de larao de uma funo e seu prottipo.


Tambm possvel de larar um prottipo sem dar os nomes das variveis
somente os tipos das funes. No exemplo 8.1 o prottipo da funo soma pode
ser de larada da seguinte maneira

int

soma (int,

int)

8.4 Es opo de Variveis


Variveis podem ser denidas para serem usadas somente dentro de uma funo
parti ular, ou pode o orrer que variveis pre isem ser a essveis diversas funes diferentes. Por esta razo, temos que apresentar os lo ais onde as variveis
de um programa podem ser denidas e a partir destes lo ais podermos inferir
onde elas estaro disponveis. As variveis podem ser de laradas basi amente
em trs lugares:
dentro de funes,
fora de todas as funes,

126

Listagem 8.1: Exemplo de prottipos.

#in lude < stdio .h >


/* Prototipo da fun ao */
int soma ( int a , int b ) ;
/* Fun ao Prin ipal */
int main () {
int a =5 , b =9;
printf ( " % d \ n " , soma (a , b ) ) ;
return 0;
}
/* Defini ao da fun ao */
int soma ( int a , int b ) {
return a + b ;
}

na lista de parmetros das funes.

As variveis denidas dentro das funes so hamadas de variveis lo ais, as


que apare em fora de todas as funes hamamos de variveis globais e aquelas
que apare em na lista de parmetros so os parmetros formais. importante
notar que em C todas as funes esto no mesmo nvel, por esta razo no
possvel denir uma funo dentro de outra funo.

8.4.1 Variveis Lo ais


As variveis lo ais so aquelas de laradas dentro de uma funo ou um blo o
de omandos. Elas passam a existir quando do in io da exe uo do blo o de
omandos ou funo onde foram denidas e so destrudas ao nal da exe uo
do blo o. Uma varivel lo al s pode ser referen iada, ou seja usada, dentro
da funo (ou blo o) onde foi de larada. Outro ponto muito importante que
omo as variveis lo ais deixam de existir ao nal da exe uo da funo (ou
blo o), elas so invisveis para outras funes do mesmo programa. O digo
que dene uma funo e os seus dados so parti ulares da funo (do blo o).
No programa 8.2 podemos ver o uso de variveis lo ais. A varivel i denida
em ada uma das funes do programa (pares, impares). Os valores da varivel
no podem ser a essados a partir de nenhuma outra funo e as modi aes
feitas dentro da funo somente valem enquanto a funo est sendo exe utada.
Alguns autores usam o termo variveis automti as para se referir as variveis lo ais. Em C existe a palavra have auto que pode ser usada para de larar
que variveis perten em lasse de armazenamento padro. No entanto, omo
todas as variveis lo ais so por denio automti as raramente se usa esta
palavra have.

127

Listagem 8.2: Exemplos de variveis lo ais.

#in lude
void

pares ( void ) {
int i ;
for ( i = 2; i <= 10; i += 2) {
printf ( " % d : " , i ) ;
}

void

int

< stdio .h >

impares ( void ) {
int i ;
for ( i = 3; i <= 11; i += 2) {
printf ( " % d : " , i ) ;
}
main ( int arg ,
pares () ;
printf ( " \ n " ) ;
impares () ;

return

har

* argv [) {

0;

Observe que um blo o de omandos se ini ia em um { e termina em um


}. O blo o de omandos, dentro do qual mais omumente se dene uma varivel a funo. Todas as variveis que sero usadas dentro de um blo o de
omandos pre isam ser de laradas antes do primeiro omando do blo o. De laraes de variveis, in luindo sua ini ializao, podem vir logo aps o abre
haves que ini ia um blo o de omandos, no somente o que omea uma funo.
O programa 8.3 ilustra este tipo de de larao.

Listagem 8.3: Denio de varivel dentro de um blo o.

#in lude < stdio .h >


int main () {
int i ;
for ( i =0; i <10;
int t = 2;
}
}

i ++) {

printf ( " % d \ n " , i * t ) ;

return

0;

Existem algumas vantagens em se de larar variveis dentro de blo os. Como


as variveis somente existem durante a exe uo do blo o, o programa pode
o upar menos espao de memria. Por exemplo, se a exe uo do blo o for
ondi ional a varivel pode nem ser alo ada. Outra vantagem que omo a
128

varivel somente existe dentro do blo o, pode-se ontrolar melhor o uso da


varivel, evitando erros de uso indevido da varivel.

8.4.2 Variveis Globais


As variveis globais so denidas fora de qualquer funo e so portanto disponveis para qualquer funo. Este tipo de varivel pode servir omo uma anal
de omuni ao entre funes, uma maneira de transferir valores entre elas. Por
exemplo, se duas funes tem de partilhar dados, mais uma no hama a outra,
uma varivel global tem de ser usada.
O programa 8.4 ilustra este tipo de de larao. O resultado da exe uo
deste programa o seguinte:
Fun ao soma1: i = 1
Fun ao sub1: i = 9
Fun ao main: i = 1
Observe que a varivel global i re ebe o valor 0 no in io da funo main. A
funo soma1 ao exe utar um omando que aumenta o valor de i em uma unidade
est aumentando a varivel global. Em seguida vemos que a funo sub1 dene
uma varivel lo al tambm hamada i e, portanto, a alterao feita por esta
funo somente modi a esta varivel. Finalmente, a funo main imprime o
valor nal da varivel global.

Listagem 8.4: Denio de varivel global.

#in lude
int
void
}

void

int

< stdio .h >

i;
soma1 ( void ) {
i += 1;
printf ( " Fun ao soma1 : i = % d \ n " , i ) ;
sub1 ( void ) {
int i = 10;
i -= 1;
printf ( " Fun ao sub1 : i = % d \ n " , i ) ;
main ( int arg , har * argv [) {
i = 0;
soma1 () ;
sub1 () ;
printf ( " Fun ao main : i = % d \ n " , i ) ;
return 0;

129

8.5 Parmetros Formais


As variveis que apare em na lista de parmetros da funo so hamadas de
parmetros formais da funo. Eles so riados no in io da exe uo da funo
e destrudos no nal. Parmetros so valores que as funes re ebem da funo
que a hamou. Portanto, os parmetros permitem que uma funo passe valores
para outra. Normalmente os parmetros so ini ializados durante a hamada da
funo, pois para isto foram riados. No entanto, as variveis que atuam omo
parmetros so iguais a todas as outras e podem ser modi adas, operadas, et ,
sem nenhuma restrio. Parmetros podem ser passados para funes de duas
maneiras: passagem por valor ou passagem por refern ia.

8.5.1 Passagem de Parmetros por Valor


Na passagem por valor uma pia do valor do argumento passado para a
funo. Neste aso a funo que re ebe este valor, ao fazer modi aes no
parmetro, no estar alterando o valor original que somente existe na funo
que hamou.
O exemplo 8.5 mostra o uso de passagem de parmetros por valor. Observe
que as funo Eleva re ebe dois parmetros (a,b) e opera usando os valores
re ebidos. O resultado da funo retornado por meio da varivel lo al res.

Listagem 8.5: Exemplo de passagem por valor.

#in lude < stdio .h >


#in lude < stdlib .h >
float

int

Eleva ( f l o a t a , int b ) {
res = 1.0;

float

for ( ; b >0;
return res ;

b - -) res *= a ;

main () {
f l o a t numero ;
int poten ia ;
har linha [80;
puts ( " Entre om um numero " ) ;
gets ( linha ) ; numero = atof ( linha ) ;
puts ( " Entre om a poten ia " ) ;
gets ( linha ) ; poten ia = atoi ( linha ) ;
printf ( " \ n % f Elevado a % d e igual a % f \ n " ,
numero , poten ia , Eleva ( numero , poten ia ) ) ;

return

0;

130

Para ilustrar o fato de que somente o valor passado vamos usar o exemplo
8.6. Neste programa as variveis a e b re ebem os valores 10 e 20 respe tivamente. Na funo tro ar estes valores so re ebidos e so tro ados lo almente.
Aps o retorno da funo, o programa imprime os valores originais das variveis,
j que estes no sofreram nenhuma alterao. O resultado da exe uo deste
programa o seguinte:

a = 10, b = 20

Listagem 8.6: Uso indevido de variveis lo ais.

#in lude < stdio .h >


void tro ar ( int a , int
int temp ;
}

int

b) {

temp = a ; a = b ; b = temp ;

main ( int arg , har * argv [) {


int a = 10 , b = 20;
tro ar (a , b ) ;
printf ( " a = %d , b = % d \ n " , a , b ) ;

return

0;

8.5.2 Passagem de Parmetros por Refern ia


Na passagem por refern ia o que passado para a funo o endereo do
parmetro e, portanto, a funo que re ebe pode, atravs do endereo, modi ar
o valor do argumento diretamente na funo que hamou. Para a passagem de
parmetros por refern ia ne essrio o uso de ponteiros. Este assunto ser
dis utido no prximo aptulo e portanto, por agora, usaremos somente funes
om passagem por valor.

8.5.3 Passagem de Vetores e Matrizes


Matrizes so um aso espe ial e ex eo a regra que parmetros so passados
sempre por valor. Como veremos mais adiante, o nome de um vetor orresponde
ao endereo do primeiro elemento do array, Quando um vetor passado omo
parmetro, apenas o endereo do primeiro elemento passado.
Existem basi amente trs maneiras de de larar um vetor omo um parmetro
de uma funo. Na primeira ele de larado omo tem sido apresentado em todos
os exemplos at agora. O exemplo 8.7 mostra um programa que usa uma funo
para des obrir quantas vezes um ara tere o orre em um vetor. Observe que na
denio da funo a dimenso do vetor foi de larada expli itamente.
Uma outra maneira, leva em onta que apenas o endereo do vetor passado.
Neste modo o parmetro de larado omo um vetor sem dimenso. Isto
131

Listagem 8.7: Passagem de vetor om dimenses.

#in lude < stdio .h >


#in lude < onio .h >
#define DIM 80
har
int

har

onta ( har v [ ,

har

);

main () {
har , linha [ DIM ;
int maius ulas [26 , minus ulas [26;
puts ( " Entre om uma linha " ) ;
gets ( linha ) ;
for ( = 'a '; <= 'z '; ++)
minus ulas [ - 'a ' = onta ( linha , ) ;
for ( = 'A '; <= 'Z '; ++)
maius ulas [ - 'A ' = onta ( linha , ) ;
for ( = 'a '; <= 'z '; ++)
i f ( minus ulas [ - 'a ' )
printf ( " % apare eu % d vezes \ n " , , minus ulas [
- 'a ' ) ;
for ( = 'A '; <= 'Z '; ++)
i f ( maius ulas [ - 'A ' )
printf ( " % apare eu % d vezes \ n " , , maius ulas [
- 'A ' ) ;
return 0;
onta ( har v [ DIM ,
int i =0 , vezes =0;

har

) {

while
}

( v [ i != ' \0 ' )
i f ( v [ i ++ == ) vezes ++;
return vezes ;

132

perfeitamente possvel porque a funo somente pre isa re eber o endereo onde
se en ontra o vetor. Alm disso C no onfere limites de vetores e portanto a
funo pre isa do endereo ini ial do vetor e uma maneira de des obrir o nal
do vetor. Esta maneira pode ser, por exemplo, uma onstante, ou o ara tere
'\0' em um vetor de ara teres. O exemplo 8.8 mostra este modo de passar
vetores om um programa que inverte o ontedo de um vetor.
A ter eira maneira de passagem de parmetros impli a no uso de ponteiros,
o que somente iremos ver no prximo aptulo.

8.6 O Comando return


O omando return usado para retornar o valor al ulado para a funo que
hamou. Qualquer expresso pode apare er no omando, que tem a a seguinte
forma geral:

return

expresso

A funo que hamou livre para ignorar o valor retornado. Alm disso a
funo pode no onter o omando e portanto nenhum valor retornado e neste
aso a funo termina quando o ltimo omando da funo exe utado. Quando
o omando return no existe o valor de retorno onsiderado indenido. As
funes que no retornam valores devem ser de laradas omo do tipo void.
importante observar que funes que so de laradas om um tipo vlido podem
ser in ludas em qualquer expresso vlida em C.

8.7 Re urso
Funes em C podem ser usadas re ursivamente, isto uma funo pode hamar
a si mesmo. omo se pro urssemos no di ionrio a denio da palavra
re urso e en ontrssemos o seguinte texto:
re urso: s.f. Veja a denio em re urso
Um exemplo simples de funo que pode ser es rita om hamadas re ursivas
o fatorial de um nmero inteiro. O fatorial de um nmero, sem re urso,
denido omo
n! = n (n 1) (n 2) 2 1

A partir desta denio podemos es rever a funo fatorial omo mostrado


na listagem 8.9.
Listagem 8.9: Fatorial al ulado no re ursivamente.

unsigned long int fat


unsigned long int
for
}

( unsigned long
fato =1 , i ;

int

num ) {

( i = num ; i >1; i - -) fato = fato * i ;

return

fato ;

133

Listagem 8.8: Passagem de vetores sem dimenses.

#in lude < stdio .h >


#in lude < onio .h >
#define DIM 6
void Le_vetor ( int
void Imprime_vetor
void Inverte_vetor
int

void

main () {
int v [ DIM ;
Le_vetor (v , DIM ) ;
Imprime_vetor (v , DIM ) ;
Inverte_vetor (v , DIM ) ;
Imprime_vetor (v , DIM ) ;
return 0;
Le_vetor ( int v [ ,
int i ;

for

void

tam ) {

( i = 0; i < tam ; i ++) {


printf ( " % d = ? " , i ) ;
s anf ( " % d " , & v [ i ) ;

int

tam ) {

( i = 0; i < tam ; i ++)


printf ( " % d = % d \ n " , i , v [ i ) ;

Inverte_vetor ( int v [ ,
int i , temp ;

for

int

Imprime_vetor ( int v [ ,
int i ;

for
void

v [ , int tam ) ;
( int v [ , int tam ) ;
( int v [ , int tam ) ;

int

( i = 0; i < tam /2; i ++) {


temp = v [ i ;
v [ i = v [ tam -i -1;
v [ tam -i -1 = temp ;

134

tam ) {

Alternativamente, o fatorial pode ser denido omo o produto deste nmero


pelo fatorial de seu prede essor, ou seja
n! = n (n 1)!

Deste modo podemos es rever uma funo re ursiva em que ada hamada
da funo que al ula o fatorial hama a prpria funo fatorial. O exemplo,
mostrado na listagem 8.10 ilustra omo a funo pode ser es rita re ursivamente.
Listagem 8.10: Fatorial al ulado re ursivamente.

unsigned long int fat ( unsigned long int


i f ( num == 0)
return 1;
else
return num * fat ( num -1) ;

num ) {

Quando a funo fatorial re ursiva hamada, primeiro veri ado se o


nmero re ebido omo parmetro vale 0 e neste aso a funo retorna o valor 1.
No aso ontrrio ela devolve o valor da expresso num * fat(num-1), ou seja o
produto do nmero pelo valor do fatorial do nmero prede essor. Ou seja para
retornar um valor a funo pre isa hamar ela mesma passando omo parmetro
o valor do nmero menos 1. Este pro esso ontinua se repetindo at que o valor
passado igual a 0, o que indi a o nal da re urso. Neste ponto o pro esso se
reverte e as hamadas omeam a ser respondidas.
Um ponto importante que toda funo re ursiva deve prever uidadosamente omo o pro esso de re urso deve ser interrompido. No aso da funo
fat o pro esso interrompido quando o valor do nmero passado omo parmetro vale 0. Se este teste no tivesse sido in ludo na funo as hamadas
ontinuariam indenidamente om valores negativos ada vez menores sendo
passados omo parmetro.
Quando uma funo hama a si mesmo re ursivamente ela re ebe um onjunto novo de variveis na pilha que usada para transfern ia de valores entre
funes. importante notar que re urso no traz obrigatoriamente e onomia
de memria porque os valores sendo pro essados tem de ser mantidos em pilhas.
Nem ser mais rpido, e as vezes pode ser at mais lento porque temos o usto
de hamada as funes. As prin ipais vantagens da re urso so digos mais
ompa tos e provavelmente mais f eis de serem lidos.
Uma funo re ursiva se ela hama a si mesmo, podendo ser diretamente
(listagem 8.11) ou indiretamente (listagem 8.12).
Listagem 8.11: Chamada re ursiva direta.

void

f () {
/* ... */
f ()
/* ... */

135

Listagem 8.12: Chamada re ursiva indireta.

void

f () {
/* ... */
g ()
/* ... */

void

g () {
... f () ...

Um outro exemplo simples de funo que pode ser resolvida por re urso
xn , assumindo que n 0. Esta funo pode es rita na sua forma re ursiva
omo
xn = x x(n1)
que nos leva a es rever a funo da maneira mostrada no exemplo 8.13. Na
funo onsideramos que x do tipo oat .

Listagem 8.13: Funo re ursiva para al ular xn .

float

Elevar ( f l o a t x ,
( n <= 1) {
return x ;

if
}

else

return

int

n) {

x * Elevar (x , b -1) ;

Para fa ilitar pode-se pensar que quando uma hamada re ursiva feita, a
funo faz uma pia de si mesmo, das variveis lo ais, om seus valores ini iais,
e dos parmetros.
Cada pia da funo in lui uma mar ao indi ando o ponto atual onde a
funo est sendo exe utada. Quando uma hamada re ursiva feita, o mar ador na funo que hamou  a logo aps a hamada. O mar ador na funo
hamada vai para o in io da funo.
Quando a funo retorna, a pia some, e a funo que hamou ontinua aps
a hamada, posio indi ada pela mar ao. As pias anteriores ontinuam
sabendo de onde ontinuar porque as mar aes esto em suas posies.
Funes podem ser re ursivas om auda ou no. Em uma funo re ursiva
om auda, nenhuma das hamadas re ursivas exe utam algo aps a hamada
re ursiva ompletar, ex eto para retornar o valor da funo.
A listagem 8.14 mostra o return de uma tpi a funo re ursiva om auda e
a listagem 8.15 mostra uma sem auda. A hamada sem auda ara terizada
porque primeiro f feita e depois soma 5, portanto, algo exe utado aps a
hamada.

136

Listagem 8.14: Chamada re ursiva om auda.

int
}

f ( int x , int y ) {
return f (x , y ) ;

Listagem 8.15: Chamada re ursiva sem auda.

int
}

f ( int x , int y ) {
return f (x , y ) + 5;

8.7.1 Como pensar re ursivamente?


Primeiro es reva o prottipo da funo. Dena o que a funo re ursiva deve
fazer em portugus. Considere o seguinte exemplo.
/* Soma os primeiros n elementos de um vetor */
int soma ( int vetor [ , int n ) ;

Quando a hamada soma( vetor, 10 ); for exe utada sabemos que os primeiros 10 elementos do vetor vetor sero somados.
Em seguida, repita vrias vezes para si mesmo o seguinte ra io nio:
re urso resolve um grande problema (de tamanho n, por
exemplo), resolvendo um ou mais problemas de tamanho
menor, e usando as solues destes pequenos problemas
para resolver o grande problema.
Caso bsi o

Portanto, re urso um pro esso que quebra um problema em problemas


menores que sero quebrados em problemas menores at que hegamos no menor
problema possvel e na sua soluo ( aso bsi o) e retornamos esta soluo.
Uma vez que vo es reveu o prottipo, pense em omo resolver o prximo
problema menor. Ento se a hamada
soma(vetor, n),

o prximo aso menor


soma(vetor, n-1)

Suponha que algum lhe daria a resposta para esta segunda soma. O que
vo teria? Vo teria a soma dos n1 primeiros elementos do vetor. Agora que
vo tem esta soluo (por hiptese), o que falta para resolver todo o problema?
A har a soluo do aso base, que o menor problema. Neste exemplo seria:
sum(vetor, 1 );

Quanto falta apenas um elemento a soma a ser al ulada o prprio elemento. Deste modo a soluo para este problema  a omo mostrado na listagem 8.16.
137

Listagem 8.16: Soma de vetor re ursiva.

int

soma (

vetor [ ,

int menor ;
i f ( n == 1 )
return v [0

else

int

int

n )

{ /* aso base */
/* sem hamada re ursiva */

{
menor = soma ( vetor , n - 1 ) ; /* resolve problema
menor */
/* usa solu ao do menor para resolver o maior */
return menor + vetor [ n - 1 ;

Os passos para es rever uma funo re ursiva so:


1. Es reva um prottipo da funo re ursiva.
2. Es reva um omentrio que des reve o que a funo deve fazer.
3. Determine o aso base (pode haver mais que um) e sua soluo.
4. Determine qual o problema menor a resolver. Se fa ilitar use variveis
para armazenar o resultado em variveis lo ais.
5. Use a soluo do problema menor para resolver o problema maior.

8.7.2 O que faz re urso trabalhar?


Re urso somente fun iona quando um problema tem uma estrutura re ursiva.
Isto signi a que a soluo do problema a mesma para diferentes tamanhos.
Caso reduzir o tamanho do problema faz om que a soluo seja diferente
ento re urso no a soluo. Do mesmo modo, vo deve ser apaz de usar
os problemas menores para resolver o problema maior.
Todavia, pela mesma razo, deve ser dif il resolver usar laos para resolver
o problema. Laos tambm dependem de fazer a mesma oisa diversas vezes,
em diferentes ndi es.
Se vo onseguir resolver um problema por meio de um lao, deve ser possvel resolve-lo por meio de re urso.

8.8 Argumentos - arg e argv


A funo main omo todas as funes podem ter parmetros. Como a funo
main sempre a primeira a ser exe utada, os parmetros que ela re ebe so
forne idos pela linha de omando ou pelo programa que ini iou a sua exe uo.
No aso da funo main so usados dois argumentos espe iais int arg e har
**argv.

138

O primeiro argumento, arg , uma varivel inteira que indi a quantos argumentos foram forne idos para a funo. Observar que arg vale sempre pelo
menos 1, porque o nome do programa sempre o primeiro argumento forne ido
ao programa. A partir do segundo argumento em diante que apare em os
outros argumentos.
O outro parmetro um vetor de adeias de ara teres, e portanto, aso
sejam forne idos nmeros, estes devem ser onvertidos para o formato requerido.
Cada um dos argumentos do programa um elemento deste vetor. A primeira
linha da funo main pode ter a seguinte forma

void

main (int arg ,

har

*argv[)

O programa exemplo 8.17 al ula o fatorial dos nmeros forne idos omo
argumentos.

Listagem 8.17: Uso de arg e argv.

#in lude < stdio .h >


#in lude < stdlib .h >
unsigned long int fat ( unsigned long int
i f ( num == 0)
return 1;
else
return num * fat ( num -1) ;
}

int

main ( int arg ,

har * argv [) {
unsigned long int numero , fatorial ,
if

for

}
}

num ) {

i;

( arg < 2) {
printf ( " Para rodar : % s num1 num2 ... .\ n " , argv
[0) ;
return 1;
( i =1; i < arg ; i ++) {
numero = ( unsigned long int ) ( atoi ( argv [ i ) ) ;
fatorial = fat ( numero ) ;
printf ( " O fatorial de % lu vale % lu .\ n " , numero ,
fatorial ) ;

return

0;

Os nomes arg e argv so omumente usados mas o programador livre para


es olher os nomes mais apropriados.

139

8.9 Exer ios


Es rever um programa que de lare, ini ialize e imprima um vetor de 10
inteiros. O vetor deve onter os 10 primeiros mltiplos de 5. A ini ializao do
vetor e a sua impresso devem ser feitas por funes.

8.1:

8.2: Es reva um programa para de larar um vetor de ara teres de tamanho 26 e


imprimir o seu ontedo. O vetor deve ser ini ializado om as letras mins ulas
do alfabeto. A ini ializao do vetor e a sua impresso devem ser feitas por
funes.
8.3: Es reva um programa que armazene em uma matriz trs nomes de pessoas
e em seguida os imprima. Assuma que o tamanho mximo de ada nome 40
ara teres. Neste programa a leitura dos nomes dever ser feita por uma funo
e a impresso dos nomes por outra.
8.4: Es reva um programa que imprima o digo ASCII de todos os ara teres,
das seguintes maneiras:

1. ara tere a ara tere, a es olha do usurio;


2. a tabela inteira, a partir de um determinado valor de imal.
Cada item deste exer io deve orresponder a uma funo.
Es reva um programa que rie uma tabela de temperaturas Celsius - Fahrenheit. O programa deve usar uma funo que onverta de Celsius para Fahrenheit. A tabela deve ini iar na temperatura 0 graus Celsius e terminar na
temperatura 100 graus Celsius.

8.5:

Es reva um programa, usando funes, que gere um vetor a partir de uma


matriz. Cada elemento do vetor igual a soma dos elementos de uma das linhas
da matriz. Considere que a matriz tenha tamanho 10 por 10.

8.6:

Es reva um programa usando re ursividade para gerar a seqn ia do


Fibona i. A seqn ia de Fibona i denida omo:

8.7:

f (0) =
f (1) =

0
1

f (n) =

f (n 1) + f (n 2)

O programa deve ler um numero e exibir o valor dele na seqn ia de Fibona i.


Exemplos de entrada e sada do programa so mostrados abaixo.
Entre om um numero inteiro: 0
Fibona i (0) = 0
Entre om um numero inteiro: 1
Fibona i (1) = 1
Entre om um numero inteiro: 2
Fibona i (2) = 1
Entre om um numero inteiro: 3
Fibona i (3) = 2
140

Entre om um numero inteiro: 6


Fibona i (6) = 8
O que o programa mostrado na listagem 8.18 imprime, aso sejam forne idos os valores 48 e 256. Justique a sua resposta.

8.8:

Listagem 8.18: Programa do exer io 8.

#in lude < stdio .h >


#define MAX 1000
int

int

ab ( int x , int y ) {
printf ( " % d % d \ n " , x , y ) ;
i f ( y == 0) {
return x ;
}
else {
return ab (y , x % y ) ;
}
main ( void ) {
int a , b ;
s anf ( " % d % d " , &a , & b ) ;
printf ( " % d \ n " , ab (a , b ) ) ;
return 0;

O programa mostrado na listagem 8.19 onverte adeias de ara teres


ontendo nmeros na base 16 para a base 10. Neste programa est faltando um
tre ho. A sua tarefa e ompletar o tre ho que est faltando.

8.9:

Listagem 8.19: Programa do problema 9.

#in lude < stdio .h >


#in lude < string .h >
#in lude < stdlib .h >
int fromHexatoD e im a l ( har
int toNumero ( har ) ;
har toLower ( har ) ;
int

[) ;

main ( void ) {
har numeroC [80;
fgets ( numeroC , 80 , stdin ) ;
{
numeroC [ strlen ( numeroC ) -1 = ' \0 ';
printf ( " % s = % d \ n " , numeroC , fromHexatoD e i ma l (
numeroC ) ) ;
fgets ( numeroC , 80 , stdin ) ;
}
return 0;

while (! feof ( stdin ) )

141

int fromHexatoD e im a l ( har numeroC [)


{ /* Aqui falta odigo */ }
har

int

toLower ( har ) {
i f ( >= 'A ' && <= 'Z ') {
= - 'A ' + 'a ';
}
return ;
toNumero ( har ) {
int resultado ;

if
}

( >= '0 ' && <= '9 ') {


resultado = - '0 ';

else i f

}
}

( toLower ( ) >= 'a ' && toLower ( ) <= 'f ') {


resultado = toLower ( ) - 'a ' + 10;

return

resultado ;

142

Captulo 9
Ponteiros

9.1 Introduo
Ponteiros so usados em situaes em que ne essrio onhe er o endereo
onde est armazenada a varivel e no o seu ontedo. Um ponteiro uma
varivel que ontm um endereo de uma posio de memria e no o ontedo
da posio. A memria de um omputador pode ser vista omo uma seqn ia
de bytes ada um om seu prprio e ni o endereo. No h dois bytes om
o mesmo endereo. O primeiro endereo sempre 0 e o ltimo geralmente
uma potn ia de 2. Por exemplo um omputador om memria igual a 512
Mbytes tem 512x1024x1024 bytes. A Figura 9.1 mostra o mapa de um tre ho
de memria que ontm duas variveis inteiras (num, res) o upando 4 bytes
ada uma e mais um ponteiro (pint), que tambm o upa 4 bytes. Observar que
os endereos esto pulando de quatro em quatro bytes devido ao espao que
ada um destas variveis o upa.
0
4

10

num

120

res
*pint

12
16

Figura 9.1: Mapa de memria om duas variveis e ponteiro.


Ponteiros so importantes, por exemplo, quando se deseja que uma funo
retorne mais de um valor. Neste aso uma soluo a funo re eber omo
argumentos no os valores dos parmetros mas sim ponteiros que apontem para
seus endereos. Assim esta funo pode modi ar diretamente os ontedos
143

destas variveis, que aps o m da funo estaro disponveis para a funo que
hamou. Neste aso os argumentos podem fun ionar omo entrada e sada de
dados da funo.
Uma outra apli ao importante de ponteiros apontar para reas de memria que devem ser geren iadas durante a exe uo do programa. Com ponteiros,
possvel reservar as posies de memria ne essrias para armazenamento
destas reas somente quando for ne essrio e no quando as variveis so de laradas. Neste esquema o programador pode reservar o nmero exato de posies
que o programa requer. A Figura 9.2 ilustra omo um ponteiro faz refern ia
para uma rea de memria. Na gura a varivel ponteiro pi aponta para a rea
de memria que ontm um vetor de 10 inteiros. Com ponteiros, o programador
pre isa, no in io, denir a varivel ponteiro e seu tipo. Durante a exe uo do
programa, aps des obrir o tamanho do vetor, reserva a rea ne essria para
guardar os dados. Observe a diferena do que o orre quando se usa vetores de
tamanho xo. Neste aso a denio do tamanho do vetor dada na de larao
do vetor e mantida at o nal da exe uo do programa.
0
pi ponteiro
para vetor

1000

4
8

120

1000

Vetor de
10 inteiros
1036

97

Figura 9.2: Ponteiro apontando para rea de memria ontendo vetor.

9.2 Operaes om Ponteiros


9.2.1 De larao de Ponteiros
Antes de serem usados os ponteiros, omo as variveis, pre isam ser de larados.
A forma geral da de larao de um ponteiro a seguinte:

tipo *nome;
Onde tipo qualquer tipo vlido em C e nome o nome da varivel ponteiro.
Por exemplo:

144

int * res ; /* ponteiro para inteiro


f l o a t * div ; /* ponteiro para ponto

*/
flutuante */

Como as variveis, os ponteiros devem ser ini ializados antes de serem usados. Esta ini ializao pode ser feita na de larao ou atravs de uma atribuio.
Aps a de larao o que temos um espao na memria reservado para armazenamento de endereos. O valor ini ial da memria indenido omo a onte e
om variveis. A Figura 9.3 ilustra esta situao. Um ponteiro pode ser ini ializado om um endereo ou om o valor NULL. O valor NULL, que equivalente a
0, uma onstante denida no arquivo <stdio.h> e signi a que o ponteiro no
aponta para lugar nenhum. A atribuio de inteiros a ponteiros no faz sentido a no ser em apli aes muito espe iais e o ni o valor inteiro que se pode
atribuir a um ponteiro o 0. Este tipo de atribuio no faz sentido porque na
maioria das apli aes o sistema opera ional que alo a e geren ia a posio
dos programas na memria e, portanto, o usurio no tem ontrole sobre estes
endereos.
996

1000

endereo indefinido

*res

1004

endereo indefinido

*div

Figura 9.3: De larao de ponteiros.

9.2.2 Os Operadores Espe iais para Ponteiros


Existem dois operadores espe iais para ponteiros: * e &. Os dois operadores
so unrios, isto requerem somente um operando. O operador & devolve o
endereo de memria do seu operando. Considere a Figura 9.1. Aps a exe uo
da instruo
pint = &num; /*o endere o de num e arregado em pint */

a varivel ponteiro pint termina om o valor 4, omo est mostrado na Figura


9.4. Lembre-se que o valor 4 no tem sentido prti o na maioria das apli aes.
O fato importante que o ponteiro pint passou a apontar para a varivel num.
O operador * o omplemento de &. O operador * devolve o valor da varivel
lo alizada no endereo apontado pelo ponteiro. Por exemplo, onsidere que o
145

0
4

10

num

120

12

res
*pint

16

Figura 9.4: Atribuio de endereo de uma varivel a um ponteiro.

omando res = *pint; foi exe utado logo aps pint = &num;. Isto signi a que
a varivel res re ebe o valor apontado por pint, ou seja a varivel res re ebe o
valor 10, omo est mostrado na Figura 9.5.
0
4

10

120 10

12

num
res = *pint
*pint

16

Figura 9.5: Uso de um ponteiro para opiar valor de uma varivel.


Estes operadores no devem ser onfundidos om os j estudados em aptulos anteriores. O operador * para ponteiros no tem nada a ver om o operador
multipli ao *. O operador ponteiro * unrio e, omo o operador &, tem
pre edn ia maior que do que todos os operadores aritmti os.

9.2.3 Atribuio de Ponteiros


Da mesma maneira que o orre om uma varivel omum, o ontedo de um
ponteiro pode ser passado para outro ponteiro do mesmo tipo. Por exemplo,
uma varivel ponteiro de larada omo apontador de dados inteiros deve sempre
apontar para dados deste tipo. Observar que em C possvel atribuir qualquer
endereo a uma varivel ponteiro. Deste modo possvel atribuir o endereo de
uma varivel do tipo oat a um ponteiro do tipo int. No entanto, o programa
no ir fun ionar da maneira orreta. O programa 9.1 mostra exemplos de
atribuies de ponteiros. Neste exemplo o endereo do ter eiro elemento do
146

vetor v arregado em p1 e o endereo da varivel i arregado em p2. A


Figura 9.6 a situao da memria aps estas operaes. Alm disso no nal o
endereo apontado por p1 arregado em p2. Os omandos printf imprimem os
valores apontados pelos ponteiros respe tivos, mostrando os seguintes valores:

30
100
30

Listagem 9.1: Exemplo de atribuio de ponteiros.

#in lude < stdio .h >


int main ( void ) {
int vetor [ =
int
int

{ 10 , 20 , 30 , 40 , 50 };

* p1 , * p2 ;
i = 100;

p1 = & vetor [2;


printf ( " % d \ n " , * p1 ) ;
p2 = & i ;
printf ( " % d \ n " , * p2 ) ;
p2 = p1 ;
printf ( " % d \ n " , * p2 ) ;
return 0;

0
4

10

v[0]

20

v[1]

12

30

v[2]

16

40

v[3]

20

50

v[4]

24

12

*p1

28

32
100

*p2

32

p1 = &v[2];

p2 = &i;
i

Figura 9.6: Exemplos de atribuies de ponteiros.

147

9.2.4 In rementando e De rementando Ponteiros


O exemplo 9.2 mostra que operaes de in remento e de remento podem ser
apli adas em operandos. O primeiro printf imprime 30, que o elemento de
ndi e igual a 2 no vetor vetor. Aps o in remento do ponteiro o segundo
printf imprime 40 e o mesmo a onte e om o ter eiro printf que imprime 50.

Listagem 9.2: Exemplos de operaes om ponteiros.

int

main ( void ) {
int vetor [ = { 10 , 20 , 30 , 40 , 50 };
int * p1 ;
p1 = & vetor [2;
printf ( " % d \ n " , * p1 ) ;
p1 ++;
printf ( " % d \ n " , * p1 ) ;
p1 = p1 + 1;
printf ( " % d \ n " , * p1 ) ;
return 0;

Pode pare er estranho que um ponteiro para um nmero inteiro, que armazenado em quatro bytes, seja in rementado por um e passe para apontar para
o prximo nmero inteiro. A primeira vista, para que passasse a apontar para
o prximo endereo, seria ne essrio aumentar o endereo em quatro. Ou seja,
sempre que um ponteiro in rementado (de rementado) ele passa a apontar
para a posio do elemento seguinte (anterior). O ompilador interpreta o omando p1++ omo: passe a apontar para o prximo nmero inteiro e, portanto,
aumenta o endereo do nmero de bytes orreto. Este ajuste feito de a ordo
om o tipo do operando que o ponteiro est apontando. Do mesmo modo, somar
trs a um ponteiro faz om que ele passe apontar para o ter eiro elemento aps o
atual. Portanto, um in remento em um ponteiro que aponta para um valor que
armazenado em n bytes faz que n seja somado ao endereo. ento possvel
somar-se e subtrair-se inteiros de ponteiros. A operao abaixo faz om que o
ponteiro p passe a apontar para o ter eiro elemento aps o atual.
p = p + 3;

Tambm possvel usar-se o seguinte omando


*(p+1)=10;

Este omando armazena o valor 10 na posio seguinte quela apontada por

p. A operao realizada nos seguintes passos:

1. A expresso p+1 al ulada e o seu resultado aponta para o prximo


endereo de dado inteiro;
2. A expresso do lado direito do sinal de atribuio, al ulada e forne e
omo resultado o valor 10;
3. Este resultado atribudo ao endereo al ulado no primeiro passo.
148

A diferena entre ponteiros forne e quantos elementos do tipo do ponteiro


existem entre os dois ponteiros. No exemplo 9.3 impresso o valor 2.

Listagem 9.3: Exemplo de subtrao de ponteiros.

#in lude < stdio .h >


int main ( void ) {
f l o a t vetor [ =
f l o a t * p1 , * p2 ;

{ 1.0 , 2.0 , 3.0 , 4.0 , 5.0 };

p1 = & vetor [2; /* endere o do ter eiro elemento */


p2 = vetor ;
/* endere o do primeiro elemento
*/
printf ( " Diferen a entre ponteiros % d \ n " , p1 - p2 ) ;
return 0;

No possvel multipli ar ou dividir ponteiros, e no se pode adi ionar ou


subtrair o tipo oat ou o tipo double a ponteiros.

9.2.5 Comparao de Ponteiros


possvel omparar ponteiros em uma expresso rela ional. No entanto, s
possvel omparar ponteiros de mesmo tipo. O Programa 9.4 ilustra um exemplo
deste tipo de operao.

Listagem 9.4: Exemplo de omparao de ponteiros.

#in lude < stdio .h >


int main ( void ) {
har * , *v ,

a, b;

s anf ( " % % " , &a , & b ) ;


= &a;
v = &b;

if

( == v )
printf ( " As variveis estao na mesma posi ao . " ) ;

else

printf ( " As variaveis nao estao na mesma posi ao . "


);

return

0;

149

9.3 Ponteiros e Vetores


Ponteiros e Vetores esto fortemente rela ionados na linguagem C. O nome de
um vetor um ponteiro que aponta para a primeira posio do vetor. A de larao int vetor[100 ria um vetor de inteiros de 100 posies e permite que
algumas operaes om ponteiros possam ser realizadas om a varivel vetor.
No entanto, existe uma diferena fundamental entre de larar um onjunto
de dados omo um vetor ou atravs de um ponteiro. Na de larao de vetor,
o ompilador automati amente reserva um blo o de memria para que o vetor
seja armazenado. Quando apenas um ponteiro de larado a ni a oisa que
o ompilador faz alo ar um ponteiro para apontar para a memria, sem que
espao seja reservado. O nome de um vetor hamado de ponteiro onstante
e, portanto, no pode ter o seu valor alterado. O nome de um ponteiro onstante no pode apare er em expresses no lado esquerdo do sinal de igual, ou
seja, no pode re eber valores diferentes do valor ini ial atribudo na de larao
da varivel. Assim, os omandos que alteram o ponteiro list, mostrados no
exemplo 9.5, no so vlidos:

Listagem 9.5: Exemplo de alteraes invlidas sobre ponteiros.

int

list [5 , i ;

/* O ponteiro list nao pode ser modifi ado


re ebendo o endere o de i */
list = & i
/* O ponteiro list nao pode ser in rementado */
list ++;

O ontedo de vetores pode ser a essado usando-se o operador * para obter


o ontedo do vetor. O Programa 9.6 mostra a notao que usa ndi es para
bus ar o elemento de um vetor e o uso do operador * de ponteiros. Neste
programa o ontedo do vetor impresso usando-se estas duas notaes.

Listagem 9.6: Exemplo de notaes de vetores.

#in lude < stdio .h >


int main ( void ) {
f l o a t v [ = {1.0 , 2.0 , 3.0 ,
int i ;
for ( i = 0; i < 7; i ++)

4.0 , 5.0 , 6.0 , 7.0};

printf ( " %.1 f " , v [ i ) ;


printf ( " \ n " ) ;
for ( i = 0; i < 7; i ++)
printf ( " %.1 f " , *( v + i ) ) ;
return 0;

Para per orrer um vetor alm da maneira mostrada no programa 9.6 pos150

svel usar um ponteiro varivel omo ilustrado no Programa 9.7. Observe omo
o ponteiro p re ebe seu valor ini ial e a maneira omo ele in rementado.

Listagem 9.7: Exemplo de ponteiro varivel.

#in lude < stdio .h >


int main ( void ) {
f l o a t v [ = {1.0 ,
int i ;
float *p;

2.0 , 3.0 , 4.0 , 5.0 , 6.0 , 7.0};

for ( i = 0; i < 7; i ++) printf ( " %.1 f " , v [ i ) ;


printf ( " \ n " ) ;
for ( i = 0; i < 7; i ++) printf ( " %.1 f " , *( v + i ) ) ;
printf ( " \ n " ) ;
for ( i = 0 , p = v ; i < 7; i ++ , p ++) printf ( " %.1 f " , * p
);
return 0;

9.4 Ponteiros e Cadeias de Cara teres


Uma adeia de ara teres onstante es rita omo no exemplo:
"Esta e uma adeia de ara teres."

At agora um dos usos mais omuns de adeias de ara teres onstantes tem
sido na funo printf, omo no exemplo abaixo
printf("A abou o programa.\n");

Quando uma adeia de ara teres omo esta enviada para a funo, o que
passado o ponteiro para a adeia. possvel ento arregar o endereo da
adeia em um ponteiro do tipo har, omo no exemplo 9.8. Neste programa
ontado o nmero de ara teres de uma adeia. Observe o ponteiro *(s+tam++)
apontando ara tere a ara tere.
Um outro exemplo (Programa 9.9) mostra uma funo que opia um adeia
de ara teres para outra.

9.5 Alo ao Dinmi a de Memria


O uso de ponteiros e vetores exige que aps a denio da varivel ponteiro uma
rea de memria deve ser reservada para armazenar os dados do vetor. Para
obter esta rea o programa deve usar funes existentes na bibliote a stdlib.
Estas funes pedem ao sistema opera ional para separar pedaos da memria
e devolvem ao programa que pediu o endereo ini ial deste lo al. As funes
bsi as de alo ao de memria que iremos dis utir so:

151

Listagem 9.8: Exemplo de ponteiro para adeia de ara teres.

#in lude < stdio .h >


int main ( void ) {
har *s , * lista = " 1234567890 " ;
int tam =0;

s = lista ;
while (*( s + tam ++) != ' \0 ') ;
tam - -;
printf ( " O tamanho do string \"% s \" e % d ara teres .\ n "
,
lista , tam ) ;
return 0;

Listagem 9.9: Exemplo de pia de adeias de ara teres.

#in lude < stdio .h >


int str op ( har *d , har * o ) ;
int main ( void ) {
har destino [20;
har * origem = " adeia de ara tere

int

str op ( destino , origem ) ;


printf ( " % s \ n " , origem ) ;
printf ( " % s \ n " , destino ) ;
return 0;

de origem " ;

str op ( har *d , har * o ) {


while ((* d ++ = * o ++) != ' \0 ') ;
return 0;

void *mallo (size_t size); Reserva espao na memria para algum item
de um programa. O tamanho em bytes reservado denido pela varivel size.
O valor armazenado no espao indenido. A funo retorna um ponteiro de
tipo void para o espao reservado ou NULL no aso de algum erro o orrer.
void * allo (size_t num, size_t size); Reserva espao na memria para
um vetor de num itens do programa. Cada item tem tamanho size e todos os
bits do espao so ini ializados om 0. A funo retorna um ponteiro de tipo
void para o espao reservado ou NULL no aso de algum erro o orrer.
void free(void *pont); O espao apontado por pont devolvido ao sistema
para uso. Caso pont seja um ponteiro nulo nenhuma ao exe utada. No aso
do ponteiro no ter sido resultado de uma reserva feita por meio de uma das
funes allo , reallo ou mallo o resultado indenido.
void reallo (void *pont, size_t size); A funo altera o tamanho do objeto na memria apontado por pont para o tamanho espe i ado por size. O
152

ontedo do objeto ser mantido at um tamanho igual ao menor dos dois tamanhos, novo e antigo. Se o novo tamanho requerer movimento, o espao reservado
anteriormente liberado. Caso o novo tamanho for maior, o ontedo da poro de memria reservada a mais  ar om um valor sem espe i ao. Se o
tamanho size for igual a 0 e pont no um ponteiro nulo o objeto previamente
reservado liberado.
Estas funes podem ser en ontradas na bibliote a stdlib.h. O Programa
9.10 ilustra o uso das funo allo e free.

Listagem 9.10: Exemplo de uso de allo e free.

#in lude < stdio .h >


#in lude < stdlib .h >
int main ( void ) {
float *v;
int i , tam ;

printf ( " Qual o tamanho do vetor ? " ) ;


s anf ( " % d " , & tam ) ;
v = allo ( tam , s i z e o f ( f l o a t ) ) ;
i f (! v ) {
printf ( " Nao onsegui alo ar memoria . " ) ;
return 1;
}
for ( i =0; i < tam ; i ++) {
printf ( " Elemento % d ? " , i ) ;
s anf ( " % f " , v + i ) ;
printf ( " Li valor % f \ n " , *( v + i ) ) ;
}
free ( v ) ;
return 0;

Um outro exemplo, agora empregando a funo mallo () est mostrado no


Programa 9.11. Observe que neste programa tambm mostramos exemplos onde
um endereo de varivel foi passado para uma funo de modo que a funo
main possa re eber um valor (vezes).

9.6 Ponteiros e Matrizes


Um ponteiro aponta para uma rea de memria que endereada de maneira
linear. Portanto, vetores podem ser fa ilmente manipulados om ponteiros. No
entanto, quando usamos estruturas de dados om maior dimensionalidade, omo
matrizes, por exemplo, que so arranjos bidimensionais de dados, ne essrio
mapear o espao bidimensional (ou de maior ordem) para uma dimenso. No
aso das matrizes ne essrio mapear o endereo de ada elemento na matriz,
que denido por um par (linha, oluna) em um endereo linear.
Considere uma matriz hamada matriz de tamanho LIN,COL que poderia ser
de larada e ter um de seus elementos lidos da maneira mostrada no tre ho de
153

Listagem 9.11: Exemplo de uso de mallo .

#in lude < stdio .h >


#in lude < stdlib .h >
void LeVetor ( f l o a t *v , int tam ) ;
f l o a t Pro uraMaior ( f l o a t *v , int
int main ( void ) {
f l o a t *v , maior ;
int i , tam , vezes ;

tam ,

int

* vezes ) ;

printf ( " Qual o tamanho do vetor ? " ) ;


s anf ( " % d " , & tam ) ;
v = ( f l o a t *) mallo ( tam * s i z e o f ( f l o a t ) ) ;
i f (v) {
LeVetor (v , tam ) ;
maior = Pro uraMaior (v , tam , & vezes ) ;
printf ( Maior = % f e apare e % d vezes .\ n . " ,
maior , vezes ) ;
free ( v ) ;
}
else {
printf ( " Nao onsegui alo ar memoria . " ) ;
return 1;
}
return 0;

}
void LeVetor ( float *v , int tam ) {
int i ;
for ( i =0; i < tam ; i ++) {
printf ( " Elemento % d ? " , i ) ;
s anf ( " % f " , v + i ) ;
printf ( " Li valor % f \ n " , *( v + i ) ) ;
}
}
float Pro uraMaior ( float *v , int tam , int * vezes ) {
int i ;
float maior ;

maior = v [0; * vezes = 1;


for ( i =1; i < tam ; i ++) {
if ( v [ i & gt ; maior ) {
maior = v [ i ;
* vezes = 1;
}
else if ( maior == v [ i ) * vezes =* vezes +1;
}
return maior ;

154

programa listado em 9.12. Caso o programa utilizasse ponteiros ao invs de


notao de matrizes, poderamos usar uma soluo que mapeasse a matriz que
um objeto de duas dimenses em um vetor que tem apenas uma. Neste aso
o programa deve fazer a translao de endereos toda vez que pre isar ler ou
es rever na matriz. O tre ho de programa  aria omo mostrado no exemplo
9.13. A expresso matriz+(i*COL+j) al ula a posio do elemento matriz
[i[j a partir do primeiro elemento da matriz que est no endereo ini ial
matriz.

Listagem 9.12: Exemplo de matriz normal sem uso de ponteiros.

#define
#define

LIN 3
COL 4

int matriz [ LIN [ COL ;


for ( i =0; i < LIN ; i ++) {
for ( j =0; j < COL ; j ++)
}

{
printf ( " Elemento % d % d = " , i , j ) ;
s anf ( " % d " , & matriz [ i [ j ) ;

Listagem 9.13: Exemplo de matriz mapeada em um vetor.

#define
#define
int
int

LIN 3
COL 4
* matriz ;
i, j;

matriz = mallo ( LIN * COL * s i z e o f ( int ) ) ;


i f (! matriz ) {
printf ( " Erro .\ n " ) ;
return 1;
}
for ( i = 0; i < LIN ; i ++) {
for ( j = 0; j < COL ; j ++)
{
printf ( " Elemento % d % d = " , i , j ) ;
s anf ( " % d " , matriz +( i * COL + j ) ) ;
}

No entanto, esta soluo ainda no a melhor j que o usurio ne essita


es rever diretamente uma expresso para mapear o endereo bidimensional da
matriz matriz[i[j em um endereo linear. O ideal usar uma notao que
use somente ponteiros. Esta notao ser dis utida nas sees seguintes.

155

9.7 Vetores de Ponteiros


Uma possibilidade mais interessante utilizar vetores de ponteiros. Esta no
a notao ideal, mas um passo na direo da notao mais efetiva. Neste aso
ada linha da matriz orresponde a um vetor que apontado por um ponteiro
armazenado no vetor de ponteiros. Como ponteiros tambm so variveis
possvel ento riar vetores de ponteiros e utiliz-los. O exemplo mostrado em
9.14 mostra um programa onde utilizado um vetor de ponteiros para vrias
linhas de ara teres. Observe na funo main a de larao har *linha[LINHAS
; que dene um vetor de tamanho LINHAS. Este vetor ontem ponteiros e no
valores. At este momento do programa temos apenas posies reservadas para
armazenar ponteiros. A alo ao de espao e a ini ializao dos ponteiros feito
no primeiro omando for. Como ada elemento do vetor linha um ponteiro
temos que o endereo retornado pela funo mallo armazenado em ada
um dos elementos deste vetor. A leitura das linhas de ara teres feita pela
funo gets(linha[i) que passa o elemento do vetor onde os ara teres sero
armazenados.

Listagem 9.14: Exemplo de uso de vetor de ponteiros.

#in lude < stdio .h >


#in lude < stdlib .h >
#define LINHAS 10
#define COLUNAS 60
int

main ( void ) {
har * linha [ LINHAS ;
int i ;

for

for
}

for
}
}

( i = 0; i < LINHAS ; i ++) {


i f (!( linha [ i = mallo ( COLUNAS * s i z e o f ( har ) ) ) ) {
printf ( " Sem memria para vetor % d .\ n " , i ) ;
return i ;
}
( i = 0; i < LINHAS ; i ++) {
printf ( " Entre om a linha % d .\ n " , i ) ;
gets ( linha [ i ) ;
( i = 0; i < LINHAS ; i ++) {
printf ( " Linha % d % s .\ n " , i , linha [ i ) ;

return

0;

156

9.8 Ponteiros para Ponteiros


No exemplo anterior podemos observar que o nmero de linhas da matriz
xa, e portanto, h uma mistura de notao de ponteiros om matrizes. Vamos onsiderar um exemplo onde tanto o nmero de linhas omo o de olunas
des onhe ido. Neste exemplo iremos riar um vetor de ponteiros que ir armazenar o endereo ini ial de ada linha. Portanto, para obter um elemento da
matriz primeiro devemos des obrir onde est a linha no vetor que armazena os
endereos das linhas, em seguida pro uramos na linha o elemento. A Figura 9.7
ilustra omo ser feito o armazenamento desta matriz.
Vetor de ponteiros
**matriz

linha 0

*(matriz+0)
*(matriz+1)

linha 1

*(matriz+2)
linha 2

*(matriz+n)
linha n

Figura 9.7: Armazenamento de matrizes om vetores de ponteiros.


O Programa 9.15, listado a seguir, ir pedir ao usurio que digite o nmero
de linhas e olunas da matriz. Em seguida ler todos os elementos da matriz e
por ltimo ir tro ar duas linhas da matriz de posio. Observe que agora foi
riado um ponteiro para ponteiro hamado de **matriz. O programa primeiro
pergunta o nmero de linhas da matriz para poder alo ar espao para armazenar
os ponteiros para ada uma das linhas. Em seguida alo ado espao para
armazenar ada uma das linhas. O omando
matriz = (int **)mallo (lin *

sizeof(int

*));

foi usado pelo programa para reservar espao para armazenar lin linhas de
ponteiros para ponteiros. Observe que o omando sizeof(int *) al ula o espao
para armazenar um ponteiro na memria. Note tambm que o valor retornado
pela funo mallo foi onformado ao tipo ponteiro para ponteiro pela operao
(int **). O interessante do programa que a tro a de linhas da matriz envolve
simplesmente a tro a de dois ponteiros e no a tro a de todos os elementos das
linhas. Esta soluo muito mais rpida do que tro ar elemento a elemento,
espe ialmente para matrizes grandes.
A seguir mostramos o programa nas listagens 9.16 e 9.17 que o exemplo
anterior modi ado para utilizar funes. O propsito mostrar omo  am as
hamadas e as denies das funes que utilizam ponteiros para ponteiros.
157

Listagem 9.15: Exemplo de uso de ponteiros para ponteiros.

#in lude < stdio .h >


#in lude < stdlib .h >
int main ( void ) {
int ** matriz ; /* ponteiro para os ponteiros */
int lin , ol ; /* nmero de linhas e olunas */
int i , j ;
int linha1 , linha2 ; /* linhas que serao tro adas */
har linha [80; /* linha de ara teres om os dados
int * temp ;

*/

puts ( " Qual o numero de linhas ? " ) ;


gets ( linha ) ; lin = atoi ( linha ) ;
matriz = ( int **) mallo ( lin * s i z e o f ( int *) ) ;
i f (! matriz ) {
puts ( " Nao h espao para alo ar memria " ) ;
return 1;
}
puts ( " Qual o numero de olunas ? " ) ;
gets ( linha ) ; ol = atoi ( linha ) ;
for ( i =0; i < lin ; i ++) {
*( matriz + i ) = ( int *) mallo ( ol * s i z e o f ( int ) )
;
i f (! *( matriz + i ) ) {
printf ( " Sem espao para alo ar a linha % d " ,
i);
return 1;
}
}
puts ( " Entre om os dados " ) ;}
for ( i =0; i < lin ; i ++) {
printf ( " Entre om a linha % d \ n " , i ) ;
for ( j =0; j < ol ; j ++) {
printf ( " Elemento % d % d \ n " , i , j ) ;
s anf ( " % d " , *( matriz + i ) + j ) ;
}
}
puts ( " Qual a primeira linha a ser tro ada ? " ) ;
gets ( linha ) ; linha1 = atoi ( linha ) ;
puts ( " Qual a segunda linha a ser tro ada ? " ) ;
gets ( linha ) ; linha2 = atoi ( linha ) ;
temp = *( matriz + linha1 ) ;
*( matriz + linha1 ) = *( matriz + linha2 ) ;
*( matriz + linha2 ) = temp ;
puts ( " Dados tro ados . " ) ;
for ( i =0; i < lin ; i ++) {
for ( j =0; j < ol ; j ++) {
printf ( " %7 d " , *(*( matriz + i ) + j ) ) ;
}
printf ( " \ n " ) ;
}
return 0;

158

Listagem 9.16: Exemplo de uso de ponteiros para ponteiros usando funes.

#in lude < stdio .h >


#in lude < stdlib .h >}
int ** alo a_linhas ( int ) ;
void alo a_ olunas ( int ** , int , int ) ;
void le_dados ( int ** , int , int ) ;
void imprime_matri z ( int ** , int , int ) ;
void tro a_linhas ( int ** , int , int ) ;
int main ( void ) {
int ** matriz ;
int lin , ol ;& nbsp ;& nbsp ;
int linha1 , linha2 ;
har linha [80;
puts ( " Qual o numero de linhas ? " ) ;
gets ( linha ) ; lin = atoi ( linha ) ;
matriz = alo a_linhas ( lin ) ;
puts ( " Qual o numero de olunas ? " ) ;
gets ( linha ) ; ol = atoi ( linha ) ;

int

void

printf ( " Alo ando espao para linhas .\ n " ) ;


alo a_ olunas ( matriz , lin , ol ) ;
le_dados ( matriz , lin , ol ) ;
imprime_matri z ( matriz , lin , ol ) ;
puts ( " Qual a primeira linha a ser tro ada ? " ) ;
gets ( linha ) ; linha1 = atoi ( linha ) ;
puts ( " Qual a segunda linha a ser tro ada ? " ) ;
gets ( linha ) ; linha2 = atoi ( linha ) ;
tro a_linhas ( matriz , linha1 , linha2 ) ;
imprime_matri z ( matriz , lin , ol ) ;
return 0;
** alo a_linhas ( int lin ) {
int ** m ;}
m = ( int **) mallo ( lin * s i z e o f ( int *) ) ;
i f (! m ) {
puts ( " Sem espao para alo ar memria " ) ;
return 1;
}
return m ;
alo a_ olunas ( int ** matriz , int lin , int ol ) {
int i ;
for ( i =0; i < lin ; i ++) {
*( matriz + i ) = ( int *) mallo ( ol * s i z e o f ( int ) )
;
i f (! *( matriz + i ) ) {
printf ( " Sem espao para linha % d " , i ) ;
return 1;
}
}

159

Listagem 9.17: Continuao do exemplo 9.16.

void

void

void

le_dados ( int ** matriz , int lin , int ol ) {


int i , j ;
puts ( " Entre om os dados " ) ;
for ( i =0; i < lin ; i ++) {
printf ( " Entre om a linha % d \ n " , i ) ;
for ( j =0; j < ol ; j ++) {
printf ( " Elemento % d % d \ n " , i , j ) ;
s anf ( " % d " , *( matriz + i ) + j ) ;
}
}
imprime_matri z ( int ** matriz , int lin , int ol ) {
int i , j ;
for ( i =0; i < lin ; i ++) {
for ( j =0; j < ol ; j ++) {
printf ( " %7 d " , *(*( matriz + i ) + j ) ) ;
}
printf ( " \ n " ) ;
}
tro a_linhas ( int ** matriz , int linha1 ,
int * temp ;
temp = *( matriz + linha1 ) ;
*( matriz + linha1 ) = *( matriz + linha2 ) ;
*( matriz + linha2 ) = temp ;

160

int

linha2 ) {

9.9 Exer ios


Es reva um programa que gere um vetor de trs dimenses (X, Y e Z) em
que ada posio guarda a soma de suas oordenadas. As dimenses da matriz
devero ser determinadas em tempo de exe uo e o programa dever informar
os valores gerados.
9.1:

Es reva um programa que leia uma frase de at 80 ara teres do te lado


e imprima a freqn ia om que apare e ada uma das letras do alfabeto na
frase.

9.2:

9.3: Es reva um programa que leia uma frase de at 80 ara teres e a imprima
em ordem reversa onvertendo todos os ara teres mins ulos para mais ulos.
9.4: Es reva um programa que leia uma matriz e a imprima. O programa deve
ler o numero de olunas e linhas do te lado. O programa deve ainda tro ar duas
linhas da matriz de posio. Os nmeros das linhas a serem tro adas devem ser
lidos do te lado.

Es reva um programa que simule uma pilha usando vetores. O programa


deve implementar as seguintes operaes na pilha:

9.5:

Inserir
Remover
Listar
9.6: Es reva uma funo que re eba um ponteiro para uma adeia de ara tere
e troque todo o ara ter aps um bran o pelo seu equivalente mais ulo.

Es reva um programa que leia seu nome ompleto e pergunte quantas letras
tem o seu primeiro nome. Assuma que a letra 'a' tem ndi e 0, a letra 'b' ndi e
1 e assim por diante. O programa deve imprimir quantas letras iguais a letra
ujo ndi e o nmero de letras do seu primeiro nome existem no seu nome
ompleto.
9.7:

Es reva um programa que leia seu nome ompleto e pergunte quantas letras
tem o seu primeiro nome. O seu programa deve usar a funo posi ao que tem
o seguinte prottipo:
9.8:

int

posi ao( har *substr,

har

*str);

Esta funo deve veri ar se a adeia apontada por substr est presente na
adeia apontada por str e retornar a posio em que a sub- adeia apare e em
adeia.
9.9: Es reva um programa que pro ure em uma matriz elementos que sejam
ao mesmo tempo o maior da linha e o menor oluna. As dimenses da matriz
devem ser pedidas ao usurio.

Es reva um programa que leia duas adeias de ara teres e on atene a


segunda adeia ao nal da primeira.

9.10:

161

Listagem 9.18: Programa do exer i io 11.

#in lude < string .h >


#in lude < stdio .h >
#define
void
int

MAX 80

misterio ( har * p1 ,

har

* p2 ) ;

main ( void ) {
har palavra1 [ MAX ;
har palavra2 [ MAX ;
puts ( " Palavra 1? " ) ;
fgets ( palavra1 , MAX , stdin ) ;
palavra1 [ strlen ( palavra1 ) -1 = ' \0 ' ;
puts ( " Palavra 2? " ) ;
fgets ( palavra2 , MAX , stdin ) ;
palavra2 [ strlen ( palavra2 ) -1 = ' \0 ' ;
misterio ( palavra1 , palavra2 ) ;

return

void

misterio ( har * p1 , har * p2 ) {


(* p1 != ' \0 ' && * p2 != ' \0 ') {
put har (* p1 ) ;
put har (* p2 ) ;
p1 = p1 + 1;
p2 = p2 + 1;
}

while

if

if

0;

(* p1 != ' \0 ') {
(* p1 != ' \0 ') {
put har (* p1 ) ;
p1 = p1 + 1;
}

while

(* p2 != ' \0 ') {
(* p2 != ' \0 ') {
put har (* p2 ) ;
p2 = p2 + 1;
}

while

162

O que ser impresso pelo programa mostrado na listagem 9.18 aso a


primeira palavra forne ida seja o seu primeiro nome e a segunda o seu ltimo
sobrenome.
9.11:

O que ser impresso pelo programa mostrado na listagem 9.19 aso a


primeira palavra forne ida seja o seu primeiro nome e a segunda o seu ltimo
sobrenome. Indique os nomes que usou e justique a sua resposta.
9.12:

Listagem 9.19: Programa do exer i io 12.

#in lude < string .h >


#in lude < stdio .h >
#define
void

MAX 80

nMisterio ( har * p1 ,
(* p1 != ' \0 ') {
p1 = p1 + 1;

while
}

har

* p2 ) {

while

(* p2 != ' \0 ') {
* p1 = * p2 ;
p1 = p1 + 1;
p2 = p2 + 1;

int

}
* p1 = ' \0 ';

main ( void ) {
palavra1 [ MAX ;
palavra2 [ MAX ;

har
har

puts ( " Palavra 1? " ) ;


fgets ( palavra1 , MAX , stdin ) ;
palavra1 [ strlen ( palavra1 ) -1= ' \0 ';
puts ( " Palavra 2? " ) ;
fgets ( palavra2 , MAX , stdin ) ;
palavra2 [ strlen ( palavra2 ) -1= ' \0 ';
nMisterio ( palavra1 , palavra2 ) ;
puts ( palavra1 ) ;
return 0;

9.13:

O que ser impresso pelo programa 9.20. Justique sua resposta.


Listagem 9.20: Listagem do exer io 13.

#in lude < stdio .h >


#in lude < string .h >
int main ( void ) {
har * frase = " Otimo teste " ;
har *p , misterio [80;
163

int
int

i = 0;
j = 0;

p = frase + strlen ( frase ) - 1;


while (* p != ' ') {
misterio [ i = * p ;
i ++; p - -;
}
misterio [ i = ' '; i ++;
while ( frase [ j != ' ') {
misterio [ i = frase [ j ;
j ++; i ++;
}
misterio [ i = ' \0 ';
puts ( misterio ) ;
return 0;

9.14: O que ser impresso pelo programa mostrado na listagem 9.21. Justique
sua resposta.

Listagem 9.21: Programa do exer io 14.

#in lude < stdio .h >


void
}

void

int

int

f1 ( int v ) {
v = v + 1;
printf ( " f1 = % d \ n " , v ) ;
f2 ( int * v ) {
* v = * v + 1;
printf ( " f2 = % d \ n " , * v ) ;
f3 ( int v ) {
v = v + 1;
printf ( " f3 = % d \ n " , v ) ;
return v ;
main ( void ) {
int v = 1;
f1 ( v ) ;
f2 (& v ) ;
v = f3 ( v ) ;
printf ( " main = % d \ n " , v ) ;
return 0;

164

Captulo 10
Estruturas

10.1 Introduo
Uma estrutura um onjunto de uma ou mais variveis, que podem ser de tipos diferentes, agrupadas sob um ni o nome. O fato de variveis agrupadas
em uma estrutura poderem ser referen iadas por um ni o nome fa ilita a manipulao dos dados armazenados nestas estruturas. Um exemplo poderia ser
uma estrutura que armazenasse as diversas informaes sobre os alunos de uma
Universidade. Nesta estrutura estariam armazenadas, sob o mesmo nome, informaes do tipo: nome, registro, data de nas imento, data de ingresso, CPF,
et . Uma estrutura pode in luir outras estruturas alm de variveis simples.
As estruturas fa ilitam manipular estes agrupamentos omplexos de dados. Por
exemplo, onsidere o problema de ordenar as informaes sobre os alunos da
Universidade exemplo. A ordenao pode ser efetuada omo se todos os dados
que ompem a estrutura fossem uma entidade ni a.

10.2 Denies Bsi as


Uma estrutura, ento, uma oleo de variveis, de tipos diversos ou no,
agrupadas sob um ni o nome. As variveis que ompem a estrutura so os
seus membros, elementos ou ampos. Normalmente os elementos da estrutura
tem alguma relao semnti a. Por exemplo: alunos de uma universidade, dis os
de uma oleo, elementos de uma gura geomtri a, et . Vamos onsiderar o
exemplo do aluno e assumir que estaremos armazenando o seu nome, registro,
ano de entrada e urso. Para este m podemos riar uma estrutura omo a
des rita no tre ho de programa 10.1.
A palavra have stru t ini ia a de larao da estrutura, em seguida pode
apare er um identi ador (ALUNO), que subseqentemente pode ser usado omo
abreviao da denio da estrutura. A de larao ontinua om a lista de
de laraes entre haves e termina om um  ;. Um membro da estrutura e
uma varivel no membro da estrutura podem ter o mesmo nome, j que
possvel distingui-las por ontexto.

165

Listagem 10.1: Denio de uma estrutura.

stru t ALUNO {
har nome [40;
int registro ;
int ano_entrada ;
har urso [20;

};

A de larao a ima ainda no alo ou espao de memria j que nenhuma


varivel foi realmente denida. Esta de larao apenas um modelo de omo
estruturas do tipo ALUNO devem ser onstrudas. Para denir estruturas deste
tipo podemos usar a seguinte de larao.

stru t

ALUNO paulo, arlos, ana;

Nesta de larao trs estruturas do tipo ALUNO foram riadas. Esta de larao alo ou espao para armazenar os dados dos trs alunos. A de larao a ima
idnti a, na forma, a de larao de variveis de um tipo pr-denido, omo
por exemplo:

int

a, b, ;

possvel de larar ao mesmo tempo o modelo da estrutura e as variveis do


programa. Por exemplo,

stru t ALUNO {
har nome [40;
int registro ;
int ano_entrada ;
har urso [20;

} paulo , arlos , ana ;

Para referen iar um elemento da estrutura usa-se o nome da varivel do tipo


da estrutura seguida de um ponto e do nome do elemento. Por exemplo,
paulo.ano_entrada = 1999;

armazena o ano em que aluno paulo entrou na universidade. Para ler o nome
do urso que paulo ursa pode-se usar o omando
gets(paulo. urso);

Estruturas podem onter outras estruturas omo membros. Por exemplo,


vamos denir uma estrutura para armazenar uma data om a seguinte denio:

stru t DATA {
int dia ,

};

mes , ano ;

Agora vamos modi ar a estrutura aluno de modo que ela in lua a data de
nas imento do aluno. A estrutura  a om a seguinte denio:
166

stru t aluno {
har nome [40;
int registro ;
int ano_entrada ;
har urso [20;
stru t DATA data_nas im en to ;

};

Para se referir ao ms de nas imento de uma varivel paulo do tipo estrutura

aluno usamos a de larao

paulo.data_nas imento.mes

Note que o operador ponto (.) asso ia da esquerda para a direita.


Uma forma mais onveniente de denio de estruturas possvel om o
uso do omando typedef. Este omando permite dar a um tipo de dados um
novo nome. A inteno aumentar a legibilidade do programa. Por exemplo,
possvel usar o seguinte digo

typedef int
typedef int
typedef int

ores ;
laranja ;
manga ;

...
laranja lima ;
manga espada ;
ores = AMARELO ;
...
espada ++;

Ao mesmo tempo que typedef tem a vantagem de tornar mais laro a nalidade de ada varivel ele pode trazer problemas na medida em que es onde o
real tipo da varivel.
omum o uso de typedef em onjunto om stru t. Considere a denio
de uma estrutura para guardar tempos gastos em tarefas. Esta estrutura deve
guardar horas, minutos e segundos. Usando esta ombinao, a denio
usualmente feita da seguinte maneira:

stru t _TEMPO {
int hora , minuto ,

};

typedef stru t
...
TEMPO t1 ;

segundo ;

_TEMPO TEMPO ;

Uma forma ainda mais abreviada, junta as duas denies,  ando a denio da estrutura da seguinte maneira:

typedef stru t
int hora ,

} TEMPO ;

_TEMPO {
minuto , segundo ;

167

...
TEMPO t1 ;

possvel dispensar o nome da estrutura (_TEMPO) e a denio  a ainda


mais simples, om a seguinte forma:

typedef stru t
int hora ,

} TEMPO ;
...
TEMPO t1 ;

{
minuto , segundo ;

10.3 Atribuio de Estruturas


possvel atribuir o ontedo de uma estrutura a outra estrutura do mesmo
tipo, no sendo ne essrio atribuir elemento por elemento da estrutura. Esta
uma das grandes vantagens de estruturas j que o tamanho do digo reduzido
e a lareza dos programas aumenta. O programa 10.2 ilustra omo podemos
atribuir uma estrutura a outra. O omando temp = emp1; faz om que todos os
dados armazenados na estrutura emp1 sejam transferidos para a estrutura temp.
Listagem 10.2: Atribuio de Estruturas.

#in lude < stdio .h >


typedef stru t _EMPREGADO
har nome [40;
f l o a t salario ;

} EMPREGADO ;

int

main () {
EMPREGADO temp , emp1 ;
puts ( " Entre om nome . " ) ;
gets ( emp1 . nome ) ;
puts ( " Qual o salario ? " ) ; s anf ( " % f " , & emp1 . salario ) ;
temp = emp1 ;
printf ( " O salario de % s e %.2 f \ n " ,
temp . nome , temp . salario ) ;
return 0;

10.4 Matrizes de Estruturas


Estruturas apare em freqentemente na forma de matrizes. Por exemplo, a
de larao stru t ALUNO turma[100; dene uma matriz de 100 estruturas do
tipo stru t ALUNO.
168

O exemplo 10.3 mostra atribuies entre estruturas e operaes aritmti as


envolvendo membros de estruturas. O programa olo a um vetor de estruturas em ordem res ente usando omo have de ordenao um dos membros da
estrutura (media).
Listagem 10.3: Ordenao de Estruturas.

#in lude
#in lude

< stdio .h >


< string .h >

typedef stru t _ALUNO {


har nome [40;
f l o a t n1 , n2 , media ;

} ALUNO ;

int

main ( void ) {
ALUNO turma [4 , temp ;
int jaOrdenados = 0 , foraOrdem , i ;

for

do

( i = 0; i < 4; i ++) {
gets ( turma [ i . nome ) ;
s anf ( " % f " , & turma [ i . n1 ) ;
do {} while ( get har () != '\ n ') ;
s anf ( " % f " , & turma [ i . n2 ) ;
do {} while ( get har () != '\ n ') ;
turma [ i . media =( turma [ i . n1 + turma [ i . n2 ) /2.0;
{

foraOrdem = 0;
for ( i = 0; i < 4 - 1 - jaOrdenados ; i ++) {
i f ( turma [ i . media > turma [ i +1. media ) {
temp = turma [ i ;
turma [ i = turma [ i +1;
turma [ i +1 = temp ; foraOrdem = 1;
}
}
jaOrdenados ++;
} while ( foraOrdem ) ;
for ( i =0; i <4; i ++) {
printf ( " \ nDados do aluno % d \ n " , i ) ;
printf ( " % s : %0.1 f , %0.1 f , %0.1 f \ n " ,
turma [ i . nome , turma [ i . n1 , turma [ i . n2 , turma [
i . media ) ;
}
return 0;

10.5 Estruturas e Funes


Primeiro vamos onsiderar o aso de passar elementos da estrutura para funes.
Caso os elementos da estrutura sejam variveis de um dos tipos j vistos, a
169

passagem efetuada da maneira normal. O exemplo 10.4 mostra omo passar


um elemento ( .raio) de uma estrutura para uma funo.
Listagem 10.4: Passando elementos para funes.

#in lude < stdio .h >


typedef stru t _CIRCULO
f l o a t x , y , raio ;

} CIRCULO ;

float
}

int

Area ( f l o a t r ) {
3.141516 * r * r ;

return

main ( void ) {
CIRCULO ;
. x = . y = . raio = 1.0;
printf ( " % f \ n " , Area ( . raio ) ) ;
return 0;

A funo que re ebe este parmetro est preparada para re eber uma varivel
de ponto utuante simples. Caso seja ne essrio passar o endereo de um dos
membros ou elementos da estrutura basta olo ar o operador & antes do nome
da estrutura. Por exemplo, para tro ar os valores das oordenadas x dos entros
de dois r ulos 1 e 2 usaramos hamadas da seguinte forma.
tro a_x (& 1 .x , & 2 . x ) ;

Para trabalhar om endereos ne essrio usar ponteiros dentro da funo

tro a_x, mas isto veremos no prximo item. Antes vamos veri ar omo

possvel passar uma estrutura inteira para uma funo.

Estruturas, quando passadas para funes, se omportam da mesma maneira


que as variveis dos tipos que j estudamos. Ao passar uma estrutura para uma
funo estaremos passando os valores armazenados nos membros da estrutura.
Como este tipo de passagem feito por valor, alteraes nos membros da estrutura no modi am os valores da estrutura na funo que hamou. A passagem
de estruturas para funes ilustrada no exemplo 10.5 onde o omprimento da
reta que liga dois pontos p1 e p2 al ulado e impresso.
Para ilustrar a passagem de vetores de estruturas para funes onsidere o
programa 10.3. Neste programa iremos substituir o tre ho que ordena o vetor de
alunos por uma funo, ujo digo mostrado na listagem 10.6. No programa
o tre ho que hama a funo tem a seguinte forma
Ordena(turma, 4);

170

Listagem 10.5: Passagem de estruturas para funes.

#in lude < stdio .h >


#in lude < math .h >
typedef stru t _PONTO
float x, y;

} PONTO ;
f l o a t omp ( PONTO p1 , PONTO p2 ) {
return sqrt ( pow ( p2 .x - p1 .x ,2) + pow ( p2 .y - p1 .y ,2) ) ;
}
int main ( void ) {
PONTO p1 , p2 ;

puts ( " Coordenadas do ponto 1 " ) ;


printf ( " x1 = ? " ) ; s anf ( " % f " , & p1 . x ) ;
printf ( " y1 = ? " ) ; s anf ( " % f " , & p1 . y ) ;
puts ( " Coordenadas do ponto 2 " ) ;
printf ( " x2 = ? " ) ; s anf ( " % f " , & p2 . x ) ;
printf ( " y2 = ? " ) ; s anf ( " % f " , & p2 . y ) ;
printf ( " \ nComprimento da reta = % f \ n " , omp ( p1 , p2 ) ) ;
return 0;

Listagem 10.6: Funo que ordena estruturas.

void

Ordena ( ALUNO turma [ , int tam ) {


int i , foraOrdem , jaOrdenados = 0;
ALUNO temp ;
do {
foraOrdem = 0;
for ( i = 0; i < 4 - 1 - jaOrdenados ; i ++) {
i f ( turma [ i . media > turma [ i +1. media ) {
temp = turma [ i ;
turma [ i = turma [ i +1;
turma [ i +1 = temp ;
foraOrdem = 1;
}
}
jaOrdenados ++;
} while ( foraOrdem ) ;

171

10.6 Ponteiros para Estruturas


Para denir ponteiros para estruturas a de larao similar a de larao de um
ponteiro normal. O exemplo abaixo mostra a denio de um ponteiro hamado
maria para uma estrutura hamada aluno.

stru t aluno {
har nome [40;
int ano_entrada ;
f l o a t n1 , n2 , media ;

} * maria ;

Ponteiros so uteis quando passamos estruturas para funes. Ao passar


apenas o ponteiro para estrutura e onomizamos tempo e memria. O espao
de memria, e onomizado por que se evita passar os dados que ompem a
estrutura um por um. O tempo e onomizado porque no ne essrio gastar o
tempo de empilhar e desempilhar todos os elementos da estrutura no pro esso
de passagem para a funo. Empilhar e desempilhar se referem a pilha de dados
usada para transferir os dados entre funes.
Para a essar elementos da estrutura apontada por um ponteiro usa-se o
hamado operador seta (->). Por exemplo para imprimir a mdia da aluna
maria usaramos o omando
printf ( " A media vale %.1 f " , maria - > media ) ;

Para alo ar espao para estruturas apontadas por ponteiros ne essrio usar
o operador unrio sizeof, isto porque o tamanho de uma estrutura sempre
igual ou maior que a soma dos tamanhos dos seu omponentes. Para expli ar
esta fato devemos onsiderar omo os dados so armazenados na memria dos
omputadores.
Algumas arquiteturas de omputadores endeream os dados na memria por
bytes, isto ada endereo de memria se refere a um byte. No entanto, estas
arquiteturas lem sempre uma palavra inteira da memria. Usualmente, palavras podem ser ompostas de dois bytes e omeam em endereos pares, omo
est mostrado na gura abaixo. Sabemos que existem variveis que o upam
mais de um byte, por exemplo inteiros que so ompostos de dois bytes.
Imagine ento uma estrutura omposta de um ara tere (1 byte) e um nmero de inteiro (2 bytes). Caso a memria do omputador seja organizada em
palavras de 16 bits ou 2 bytes a estrutura a ima o uparia 3 bytes ou uma palavra e meia. Para ler o nmero inteiro o programa deveria ler duas palavras.
Lembrar que se os dados fossem sempre armazenados seqen ialmente, metade
do nmero inteiro estaria em uma palavra e a metade restante na outra, omo
est indi ado na gura abaixo (parte a). Para fa ilitar o a esso s variveis,
alguns ompiladores armazenam as variveis de a ordo om o que est indi ado na gura (parte b). Observar que agora a estrutura o upa quatro bytes.
Neste aso o a esso ao nmero inteiro ser sempre feito em um passo e portanto
ganhou-se em tempo de a esso ao usto de gasto de memria. Este uma tro a
onstante em omputao.
172

Vimos ento que embora o total de bytes dos elementos da estrutura fosse
trs o ompilador pode armazenar a estrutura em quatro bytes, da a ne essidade
de sempre usar o operador sizeof quando alo ar espao.
O programa 10.7 mostra omo alo ar espao para uma varivel simples e
omo usar esta varivel em diversos tipos de omandos.

Listagem 10.7: Alo ao de espao para estruturas.

#in lude < stdio .h >


#in lude < string .h >
#in lude < stdlib .h >
typedef stru t _ALUNO {
har nome [40;
f l o a t n1 , n2 , media ;
} ALUNO ;

int

main ( void ) {
ALUNO * maria ;
maria = ( ALUNO *) mallo ( s i z e o f ( ALUNO ) ) ;
i f (! maria ) exit (1) ;
gets ( maria - > nome ) ;
s anf ( " % f % f " , &( maria - > n1 ) , &( maria - > n2 ) ) ;
maria - > media = ( maria - > n1 + maria - > n2 ) / 2;
printf ( " A media de % s vale %0.2 f \ n " , maria - > nome ,
maria - > media ) ;
return 0;

O programa 10.8 mostra omo utilizar ponteiros para vetores de estruturas


e a forma mais segura de alo ar espao para os dados. Observar as notaes
usadas na funo que l os dados dos fun ionrios. Notar que ( adastro+i)
->salario o valor da salrio.
fgets (( adastro + i ) -> nome , 39 , stdin ) ;
ss anf ( linha , " % f " , &(( adastro + i ) -> salario ) ) ;

173

Listagem 10.8: Alo ao de espao para vetores de estruturas.

#in lude < stdio .h >


#in lude < stdlib .h >
typedef stru t _fun
har nome [40;
f l o a t salario ;

} Tfun ;

void

le ( Tfun * adastro , int fun ionarios ) {


int i ;
har linha [40;
for ( i =0; i < fun ionarios ; i ++) {
puts ( " Nome ? " );
fgets (( adastro + i ) -> nome , 39 , stdin ) ;
puts ( " Salario ? " ) ; fgets ( linha , 39 , stdin ) ;
ss anf ( linha , " % f " , &(( adastro + i ) -> salario ) ) ;
}

float

media ( Tfun * adastro ,

f l o a t media =0.0;
int i ;
for
}

int

int

fun ionarios ) {

( i =0; i < fun ionarios ; i ++) {


media += ( adastro + i ) -> salario ;

return

media /= fun ionarios ;

main ( void ) {
Tfun * adastro ;
int fun ionarios ;
har linha [40;
puts ( " Quantos fun ionarios ? " ) ; fgets ( linha , 39 , stdin )
;
ss anf ( linha , " % d " , & fun ionarios ) ;

if

(!( adastro = ( Tfun *) mallo ( fun ionarios *


s i z e o f ( Tfun ) ) ) ) {
exit (1) ;

}
le ( adastro , fun ionarios ) ;
printf ( " Salario medio = %.2 f \ n " ,
media ( adastro , fun ionarios ) ) ;
return 0;

174

10.7 Exer ios


Considere que uma empresa pre isa armazenar os seguintes dados de um
liente:

10.1:

Nome ompleto om no mximo 50 ara teres;


renda mensal do do liente;
ano de nas imento;
possui ou no arro.

Dena um tipo e uma estrutura para armazenarem estes dados e es reva um


programa que leia estes dados armazene-os em uma varivel e em seguida os
imprima.
10.2: Considerando a mesma estrutura do exer io anterior, es reva um programa que leia os dados de 100 lientes e imprima:

quantos lientes tm renda mensal a ima da mdia;


quantos lientes tm arro;
quantos lientes nas eram entre 1960 (in lusive) e 1980 (ex lusive).

Rees reva o programa 10.3 empregando funes para implementar as


diversas tarefas do programa. A funo main deve  ar da maneira indi ada na
Listagem 10.9.

10.3:

Listagem 10.9: Listagem do exer i io 3.

int

main ( void ) {
stru t aluno turma [ MAX ;
le ( turma ) ;
puts ( " Imprimindo dados lidos da turma . " ) ;
puts ( " Digite qualquer oisa para ontinuar . " ) ;
get har () ;
imprime ( turma ) ;

ordena_medias ( turma ) ;
puts ( " Imprimindo dados ordenados da turma . " ) ;
puts ( " Digite qualquer oisa para ontinuar . " ) ;
get har () ;
imprime ( turma ) ;
get har () ;

Es rever um programa que utilize stru ts e ponteiro para stru t e imprima o ontedo das variveis da stru t.

10.4:

175

Es rever um programa que utilize enumeradores om as matrias do seu


perodo. Ini ialize ada matria om um numero. Depois imprime os valores
das variveis enumeradas.

10.5:

10.6: Es rever um programa que utilize union. Ini ialize as variveis om


valores diferentes e imprima o ontedo delas.

Fazer um programa que simule as operaes de uma pilha push e pop,


usando stru ts. Um exemplo de entrada poderia ser o seguinte:

10.7:

empilha C
empilha B
empilha A
desempilha A
desempilha B
desempilha C
10.8: Es reva um programa que soli ite o nome e telefone de uma pessoa e grave
essas informaes num vetor de uma estrutura que ontem esses dados (nome e
telefone). O programa deve ter trs opes apenas: uma que adi iona um novo
dado, outra que lista todos os dados atualmente armazenados na memria e
outra que sai do programa. Esse vetor de estrutura deve ter apenas 10 elementos
e forne er uma mensagem de erro aso o usurio tente adi ionar mais pessoas
que este mximo permitido.
10.9: Es reva uma estrutura similar as strings do Delphi (possuem um ampo
armazenando o tamanho da string e um ponteiro para o primeiro ara tere da
string) e rie as funes str py e str at para strings nesse formato.

Es reva um programa fazendo o uso de estruturas. Vo dever riar


uma estrutura hamada Ponto, ontendo apenas a posio x e y (inteiros) do
ponto. De lare 2 pontos, leia a posio ( oordenadas x e y) de ada um e al ule
a distn ia entre eles. Apresente no nal a distn ia entre os dois pontos.

10.10:

Crie uma estrutura hamada retngulo, que possua duas estruturas


ponto (o ponto superior esquerdo e o ponto inferior direito). Faa um programa

10.11:

que re eba as informaes a er a de um retngulo (as oordenadas dos dois


pontos), e informe a rea, o omprimento da diagonal e o omprimento de ada
aresta

Es reva um programa que use as mesmas estruturas do exer io anterior


para des obrir se um ponto est dentro de um retngulo.
10.12:

10.13:

Considere que foi denida a seguinte estrutura:

typedef stru t _fra {


int numerador , denominador ;

} FRACAO ;

Es reva um programa em C que al ule as quatro operaes usando fraes


denidas om estruturas do tipo FRACAO. O programa deve ler duas fraes e
imprimir o resultado de ada uma das quatro operaes.
176

Captulo 11
Entrada e Sada por Arquivos

11.1 Introduo
Em C no existem instrues espe iais de entrada e sada omo em outras linguagens de programao. Estas tarefas, em C so exe utadas por funes espe ialmente riadas para esta nalidade e armazenadas em bibliote as espe  as.
Por esta razo todos programas em C que pre isam de entrada e/ou sada de
dados ne essitam in luir a diretiva #in lude<stdio.h> no in io do programa,
para permitir o uso da bibliote a padro stdio de funes de entrada e sada.

11.2 Fluxos de Dados


Para isolar os programadores dos problemas de manipular os vrios tipos de
dispositivos de armazenamento e seus diferentes formatos a linguagem C utiliza
o on eito de uxo de dados (stream). Todos os diferentes sistemas de arquivos
se omportam da mesma maneira que foi denida omo semelhante a um uxo
ontnuo de dados (stream). Dados podem ser manipulados em dois diferentes
tipos de uxos: uxos de texto e uxos binrios.

11.2.1 Fluxos de Texto


Um uxo de texto (text stream) omposto por uma seqn ia de ara teres,
que pode ou no ser dividida em linhas terminadas por um ara tere de nal de
linha. Um detalhe que deve ser onsiderado ao es rever um programa que na
ltima linha no obrigatrio o ara tere de m de linha.
Nem sempre a traduo entre a representao do ara tere no uxo de texto
e no sistema de arquivos do omputador hospedeiro um para um byte. Por
exemplo, entre UNIX e DOS h uma diferena na representao de nal de
linha (linefeed ) que ausa problemas na impresso de arquivos. Em UNIX um
nal de linha representado pelo ara tere de alimentao de linha (LF). Em
DOS um nal de linha representado pelo par retorno de arro/alimentao de
linha (CR/LF). Deste modo quando um arquivo gerado em UNIX vai para uma
177

impressora que espera nal de linha no modo DOS surge o que omumente
hamado de efeito es ada. A impresso ontinua na linha seguinte mas sem
voltar para o in io da linha porque em UNIX o ara tere de retorno de arro
no inserido no uxo de texto.
At agora temos trabalhado om os uxos de dados padro: stdin, para
entrada de dados e stdout para sada de dados. Ao ini iar todo programa em
C automati amente asso iado a estes dois uxos de dados sem ne essitar de
nenhuma interveno do programador. A denio de que perifri os estaro
asso iados a estes uxos depende do sistema opera ional. Normalmente o uxo
de entrada (stdin) est asso iado ao te lado e o uxo de sada (stdout) ao
monitor.

11.2.2 Fluxo Binrio


Um uxo binrio omposto por uma seqn ia de bytes lidos, sem traduo,
diretamente do dispositivo externo. Existe uma orrespondn ia um para um
entre os dados do dispositivo e os que esto no uxo que o programa manipula.
A Figura 11.1 ilustra estes dois tipos de uxos. No uxo de texto os dados so
armazenados omo ara teres sem onverso para representao binria. Cada
um dos ara teres o upa um byte. O numero 12 o upa dois bytes e o nmero
113 o upa 3. Um ara tere em bran o foi inserido entre ada um dos nmeros
para separ-los, de modo que a funo de entrada e sada possa des obrir que
so dois nmeros inteiros (12 e 113) e no o nmero 12113.
No uxo binrio ada nmero inteiro o upa 32 bits e armazenado na forma
binria. Os ara teres do exemplo esto armazenados seguindo a tabela ASCII.
Observe que, em arquivos binrios, no h ne essidade de separar os nmeros
j que eles sempre o upam 32 bits.
fluxo de texto
1 2 b 1 1 3 b a b

fluxo binrio
000...01100

32 bits
12

000...01110001 01100001 01100010

32 bits
113

8 bits 8 bits
a
b

Figura 11.1: Fluxos de dados.

11.2.3 Arquivos
Um arquivo pode estar asso iado qualquer dispositivo de entrada e sada
omo, por exemplo: impressora, te lado, disquete, dis o rgido et . No entanto,
178

os programas vem os arquivos atravs de uxos. Para que um determinado


arquivo em um perifri o seja asso iado a um uxo ne essrio que o arquivo
seja aberto e somente aps esta operao, o programa pode manipular os
dados. Normalmente a interao entre o programa e os arquivos feita por
meio de buers que intermediam a transfern ia dos dados entre os programas
e os perifri os. Isto serve para fa ilitar a operao do sistema opera ional.
Operaes omuns em arquivos so:
abertura e fe hamento de arquivos;
remover um arquivo;
leitura e es rita de um ara tere ou byte;
pro urar saber se o m do arquivo foi atingido;
posi ionar o arquivo em um ponto determinado.

Obviamente algumas dessas funes no se apli am a todos os tipos de dispositivos. Por exemplo, para uma impressora pode no ser possvel usar a
funo que reposi iona o arquivo no in io. Um arquivo em dis o permite a esso
aleatrio enquanto um te lado no.
Ao nal das operaes nos arquivos o programa deve fe h-los. Caso o
programador esquea de exe utar esta operao, ao nal do programa todos os
arquivos asso iados so fe hados automati amente e os ontedos dos buers
so des arregados para o dispositivo externo. Caso o arquivo seja de entrada o
ontedo do buer esvaziado.

11.3 Funes de Entrada e Sada


As funes de Entrada e Sada normalmente utilizadas pelos programadores
esto armazenadas na bibliote a stdio.h. As funes mais omuns esto mostradas na tabela 11.1.
Para ter a esso aos dados em um arquivo ne essrio a denio de um
ponteiro do tipo espe ial FILE. Este tipo tambm est denido na bibliote a
stdio.h. Um ponteiro deste tipo permite que o programa tenha a esso a uma
estrutura que armazena informaes importantes sobre o arquivo. Para denir
uma varivel deste tipo o programa deve onter a seguinte de larao
FILE *arq;

onde arq o ponteiro que ser usado para exe utar as operaes no arquivo.

11.4 In io e Fim
As operaes mostradas a seguir mostram operaes que devem ser realizadas
antes e depois de usar um arquivo (fopen() e f lose()). As outras duas funes
servem para que o usurio possa dete tar o m de um arquivo ou voltar para
seu in io.
179

Funo

Des rio

fopen()
f lose()
fput ()
get (), fget ()
fprintf()
ss anf()
fs anf()
fseek()
rewind()
feof()
ferror()
fflush()
fread()
fwrite()

Abre um arquivo
Fe ha um arquivo
Es reve um ara tere em um arquivo
L um ara tere de um arquivo
Equivalente a printf()
Equivalente a s anf(). L de uma adeia de ara teres
Equivalente a s anf()
Posi iona o arquivo em um ponto espe  o
Posi iona o arquivo no in io
Retorna verdade se hegou ao m do arquivo
Veri a a o orrn ia de um erro
Des arrega o buer asso iado ao arquivo
Leitura de dados no modo binrio
Es rita de dados no modo binrio

Tabela 11.1: Exemplos de funes de Entrada e Sada.

11.4.1 Abrindo um Arquivo


Antes de qualquer operao ser exe utada om o arquivo, ele deve ser aberto.
Esta operao asso ia um uxo de dados a um arquivo. Um arquivo pode ser
aberto de diversas maneiras, de a ordo om as operaes que devero ser exe utadas: leitura, es rita, leitura/es rita, adio de texto et . A funo utilizada
para abrir o arquivo hamada fopen() e tem o seguinte prottipo:
FILE *fopen ( onst

har

*parq,

onst har

*modo)

onde parq um ponteiro de arquivo para o arquivo a ser manipulado e modo


um ponteiro para uma adeia de ara teres que dene a maneira omo o arquivo
vai ser aberto. Este ponteiro no deve ser modi ado e a funo retorna um
ponteiro nulo (NULL) se o arquivo no puder ser aberto. A seguir listamos os
diversos modos que podem ser usados para abrir um arquivo.
r:
w:
a:

Abre um arquivo para leitura, o arquivo deve existir ou um erro o orre.


Cria um arquivo vazio para es rita, aso um arquivo om o mesmo nome
exista o seu ontedo apagado.
Adi iona ao nal de um arquivo. O arquivo riado aso ele no exista.
Abre um arquivo para leitura e es rita. O arquivo deve existir ou um
erro o orre.

r+:

Cria um arquivo vazio para leitura e es rita. Se um arquivo om o


mesmo nome existe o ontedo apagado.

w+:

Abre um arquivo para leitura e adio. Todas as operaes de es rita so


feitas no nal do arquivo. possvel reposi ionar o ponteiro do arquivo
para qualquer lugar em leituras, mas as es ritas movero o ponteiro para
o nal do arquivo. O arquivo riado aso no exista.

a+:

180

Observar que se um arquivo for aberto om permisso de es rita todo o seu


ontedo anterior ser apagado. Caso o arquivo no exista ele ser riado.
O tre ho de programa abaixo ilustra os passos ne essrios para abrir um
arquivo para es rita. Primeiro de larado o ponteiro pa para o arquivo. Em
seguida a funo fopen hamada para asso iar o nome externo do programa
(arquivo.txt) no modo es rita ao ponteiro pa. Um teste para ponteiro nulo
feito para veri ar se o orreu algum problema om a operao de abertura do
arquivo.

FILE * pa ; /* de lara ao do ponteiro para arquivo */


/* nome externo asso iado ao interno */
pa = fopen ( " arquivo . txt " , " w " ) ;
i f ( pa == NULL ) { /* verifi a erro na abertura */
printf ( " Arquivo nao pode ser aberto . " ) ;
return 1;
}

Lembrar que abrir, para es rita, um arquivo que j existe, impli a em apagar
todo o ontedo anterior e a preparao do arquivo para re eber dados a partir
de seu ponto ini ial. Se o programador deseja a res entar dados ao nal de um
arquivo j existente o modo de abertura deve ser a.

11.4.2 Fe hando um Arquivo


Um arquivo aberto por meio da funo fopen() deve ser fe hado om a funo
f lose() ujo prottipo

int

f lose (FILE *parq);

onde parq um ponteiro de arquivo para o arquivo que deve ser fe hado. Todos
os buers internos asso iados om o uxo de dados do arquivo so des arregados. O ontedo de qualquer buer no es rito es rito e dados no lidos
de buers so perdidos. Este ponto importante de ser onsiderado porque
em muitos sistemas opera ionais uma operao de es rita em um arquivo no
o orre imediatamente a emisso da ordem de es rita. O sistema opera ional
pode exe utar a ordem no momento que a har mais onveniente. Um valor zero
de retorno signi a que a operao foi exe utada om xito, qualquer outro valor
impli a em erro.

11.4.3 Fim de Arquivo


A funo feof() indi a que um arquivo hegou ao seu nal. A pergunta que
pode surgir a seguinte - Se j existe o valor EOF para indi ar o nal de arquivo,
por que pre isamos de uma funo extra do tipo feof()? O problema que EOF
um valor inteiro e ao ler arquivos binrios este valor pode ser lido omo parte
do arquivo e no por ser o nal do arquivo. A funo feof() serve para indi ar
181

que o nal de um arquivo binrio foi en ontrado. Naturalmente esta funo


pode ser apli ada tambm a arquivos texto. O prottipo da funo o seguinte:

int

feof(FILE *parq)

Um valor diferente de zero retornado no aso de ter sido atingido o nal


do arquivo. O valor zero indi a que ainda no se hegou ao nal do arquivo.
O exemplo 11.1 mostra um programa que l um ara tere do te lado e o
mostra na tela. Neste exemplo a leitura termina quando o usurio digita o
ara tere < tl>+D, que indi a nal de arquivo pelo te lado em Unix (no outro
sistema < tl>+Z).

Listagem 11.1: Uso da funo feof().

#in lude < stdio .h >


int main ( void ) {
har ;

= get har () ;
while ( != EOF ) {
put har ( ) ;
= get har () ;
}
return 0;

11.4.4 Volta ao In io
A funo rewind() re olo a o indi ador de posio de arquivo no in io do arquivo. Uma operao semelhante ao que fazemos em uma ta assete de msi a
ou vdeo. O prottipo da funo o seguinte:

void

rewind(FILE *parq)

importante observar que o arquivo deve estar aberto em um modo que


permita a exe uo das operaes desejadas. Por exemplo, um arquivo aberto
somente para es rita e em seguida reposi ionado para o in io, no ir permitir
outra operao que no seja es rita.

11.5 Lendo e Es revendo Cara teres


As operaes mais simples em arquivos so a leitura e es rita de ara teres.
Para ler um ara tere de um arquivo, que foi previamente aberto, pode-se usar
as funes get () e fget (), que so equivalentes. Os prottipos destas funes
so os seguintes:
182

int

fget (FILE *parq);

int

get (FILE *parq);

As funes get () e fget () so equivalentes e muitos ompiladores implementam get () omo uma ma ro do seguinte modo:

#dene

get (parq)fget (parq)

A funo l o ara tere omo um unsigned har mas retorna o valor omo
um inteiro, onde o byte mais signi ativo vale zero. O apontador do arquivo
avana um ara tere e passa a apontar para o prximo ara tere a ser lido.
A funo devolve o digo EOF ao hegar ao nal do arquivo ou aso um erro
o orra. O valor EOF tambm um inteiro vlido e portanto ao usar arquivos
binrios ne essrio que a funo feof() seja utilizada para veri ar o nal do
arquivo. A funo ferror() pode ser usada para determinar se um erro o orreu.
Para es rever ara teres h duas funes denidas put () e fput (). Os
prottipos das funes so os seguintes:

int

put (int h, FILE *parq);

int

fput (int h, FILE *parq)

onde parq um ponteiro de arquivo para o arquivo que foi previamente aberto
por meio da funo fopen() e h o ara tere a ser es rito.
O programa 11.2 mostra omo um arquivo pode ser riado para leitura e
es rita. Em seguida um onjunto de ara teres lido do te lado es rito no arquivo. O prximo passo a leitura do arquivo que ini iada aps uma hamada
a funo rewind(), fazendo om que o indi ador de posio do arquivo volte a
apontar para seu in io.
Uma outra alternativa mostrada em 11.3 mostra um exemplo onde o arquivo riado para es rita em seguida fe hado e reaberto para leitura  ando
automati amente posi ionado no in io para a leitura.

11.6 Testando Erros


A funo ferror(FILE *parq) serve para veri ar se o orreu um erro asso iado
ao uxo de dados sendo usado. Um valor diferente de zero a indi ao do
erro, que o orre geralmente quando a operao previamente exe utada no uxo
falhou. O parmetro parq um ponteiro para o uxo a ser testado. O programa
11.4 abre um arquivo para leitura, mas tenta es rever um ara tere o que provo a
um erro que testado pela funo ferror.
Listagem 11.4: Uso da funo ferror().

#in lude
int main

< stdio .h >


( void ) {
FILE * pArq ;
pArq = fopen ( " MeusDados . txt " ," r " ) ;

if

( pArq == NULL ) {

183

Listagem 11.2: Exemplo de leitura e es rita de ara teres.

#in lude < stdio .h >


#in lude < stdlib .h >
int main ( void ) {
int ;

FILE * pa ;
* nome = " texto . txt " ;

har

/* Abre o arquivo para leitura e es rita */


i f (( pa = fopen ( nome , " w + " ) ) == NULL ) {
printf ( " \ n \ nNao foi possivel abrir o arquivo .\ n " )
;
exit (1) ;
}
/* Cada ara tere digitado sera gravado no arquivo */
= get har () ;
while (! feof ( stdin ) ) {
fput ( , pa ) ;
= get har () ;
}
rewind ( pa ) ; /* volta ao ini io do arquivo */
printf ( " \ nTerminei de es rever , agora vou ler .\ n " ) ;
= fget ( pa ) ;
while (! feof ( pa ) ) {
put har ( ) ;
= fget ( pa ) ;
}
f lose ( pa ) ;
}

return

0;

184

Listagem 11.3: Exemplo de leitura e es rita de ara teres.

#in lude < stdio .h >


int main ( void )
int ;

FILE * pa ;
* nome = " texto . txt " ;

har
if

(( pa = fopen ( nome , " w " ) ) == NULL ) {


printf ( " \ n \ nErro ao abrir o arquivo - es rita .\ n "
);
return 1;

}
= get har () ;
while (! feof ( stdin ) ) {
fput ( , pa ) ;
= get har () ;
}
f lose ( pa ) ;
printf ( " \ nTerminei de es rever , agora vou ler .\ n " ) ;
i f (( pa = fopen ( nome , " r " ) ) == NULL ) {
printf ( " \ n \ nErro ao abrir o arquivo - leitura .\ n "
);
exit (1) ;
}
= fget ( pa ) ;
while (! feof ( pa ) ) {
put har ( ) ;
= fget ( pa ) ;
}
f lose ( pa ) ;
return 0;

185

printf ( " Erro abrindo arquivo . " );


1;

return

else

}
}

{
fput ( 'x ' , pArq ) ;
i f ( ferror ( pArq ) ) {
printf ( " Erro es revendo arquivo \ n " ) ;
f lose ( pArq ) ;
return 1;
}

return

0;

11.7 Lendo e Es revendo Cadeias de Cara teres


As funes fgets() e fputs() servem para ler e es rever adeias de ara teres
em arquivos. Os prottipos das funes so:

int
int

fputs( har *str, FILE *parq);

fgets( har *str,

int

omp, FILE *parq);

A funo fputs() es reve a adeia de ara teres apontada por str no uxo
apontado por parq. O digo nulo ao nal da adeia no opiado para o uxo.
O digo orrespondente EOF ser retornado se o orrer um erro e um valor no
negativo em aso de su esso.
A funo fgets() l uma adeia de ara teres do uxo espe i ado por parq
at que um ara tere de nova linha seja en ontrado ou omp-1 ara teres sejam
lidos. O ara tere de nova linha interrompe a leitura. Observar que diferentemente de gets() o ara tere de nova linha en ontrado passa a fazer parte da
adeia que re ebe um ara tere nulo ao seu nal. O ponteiro str retornado
aso a leitura o orra sem erro. No aso de erro o ponteiro str re ebe o valor
NULL. Se o m do arquivo for en ontrado e nenhum ara tere foi lido, o ontedo
de str mantido e um NULL retornado. O exemplo 11.5 mostra um exemplo
de uso destas funes para ler e es rever adeias de ara teres em um arquivo.
Listagem 11.5: Exemplo de leitura e es rita de adeias de ara teres.

#in lude < stdio .h >


#define MAX 80
int main ( void ) {
har linha [ MAX ;

FILE * pa ;
* nome = " texto . txt " ;

har
if

(( pa = fopen ( nome , " w + " ) ) == NULL ) {


printf ( " \ n \ nNao foi possivel abrir o arquivo .\ n " )
;

186

return 1;
}
fgets ( linha , MAX , stdin ) ;
while (! feof ( stdin ) ) {
fputs ( linha , pa ) ;
fgets ( linha , MAX , stdin ) ;
}
rewind ( pa ) ; /* volta ao ini io do arquivo */
printf ( " \ nTerminei de es rever , agora vou ler .\ n \ n " );
fgets ( linha , MAX , pa ) ;
while (! feof ( pa ) ) {
puts ( linha ) ;
fgets ( linha , MAX , pa ) ;
}
f lose ( pa ) ;
return 0;

11.8 Entrada e Sada Formatada


As funes fprintf() e fs anf() so equivalentes as funes printf() e s anf
() usadas at agora, sendo a ni a modi ao o fato de que elas trabalham om
uxos de dados (arquivos). Os prottipos das duas funes so os seguintes:

int fprintf(FILE *parq, onst har *formata ao, ...);


int fs anf(FILE *parq, onst har *formata ao, ...);
onde parq um ponteiro de arquivo re ebido aps uma hamada a fopen().
Em leituras, a funo retorna o nmero de itens lidos om su esso. Esta
ontagem pode igualar o nmero esperado de leituras ou ser menor no aso de
falha. Caso o orra uma falha antes de que uma leitura possa ser feita om
su esso, EOF retornado.
Em es ritas, aso a operao de es rita tenha su esso, o nmero total de
ara teres es rito retornado. Um nmero negativo retornado em aso de
falha.
Embora estas duas funes, por sua semelhana om printf() e s anf()
, sejam maneiras onvenientes de es rever e ler dados de arquivos, elas tm a
desvantagem de serem mais lentas do que uso de arquivos binrios. A perda
de tempo devido ao fato dos dados serem gravados em ASCII, o que obriga
a uma onverso dos dados a ada operao realizada. Em alguns asos o fato
dos dados serem gravados em ASCII pode ser onsiderado um vantagem que se
sobrepe a desvantagem da reduo de velo idade. Dados gravados em ASCII
podem ser fa ilmente veri ados pelos usurios, o que no a onte e om dados
em binrio. O exemplo 11.6 mostra o uso destas funes para ler e es rever
vrios tipos de dados em um arquivo.
Listagem 11.6: Exemplo de leitura e es rita de dados formatados.
187

#in lude < stdio .h >


int main ( void ) {
har palavra [20;
int i ; f l o a t f ;
FILE * pa ;

har * nome
i f (( pa =

= " format . txt " ;


fopen ( nome , " w + " ) ) == NULL ) {
printf ( " \ n \ nNao foi possivel abrir o arquivo .\ n " )
;
return 1;

}
puts ( " Entre om uma palavra . " ) ; s anf ( " % s " , palavra )
;
puts ( " Entre om um numero inteiro . " ) ; s anf ( " % d " , & i )
;
puts ( " Entre om um numero flutuante . " ) ; s anf ( " % f " , &
f);
/* Es reve os dados no arquivo */
fprintf ( pa , " % s % d % f " , palavra , i , f ) ;
rewind ( pa ) ; /* volta ao ini io do arquivo */
printf ( " \ nTerminei de es rever , agora vou ler .\ n " ) ;
fs anf ( pa , " % s % d % f " , palavra , &i , & f ) ;
printf ( " Palavra lida : % s \ n " , palavra ) ;
printf ( " Inteiro lido : % d \ n " , i ) ;
printf ( " Float
lido : % f \ n " , f ) ;
f lose ( pa ) ;
return 0;

11.9 Lendo e Es revendo Arquivos Binrios


As funes fread e fwrite so empregadas para leitura e es rita de dados em
modo binrio. Os prottipos das funes so:
size_t fread (void *ptr, size_t size, size_t nmemb, FILE *parq);
size_t fwrite( onst void *ptr, size_t size, size_t nmemb, FILE *parq);

A funo fread l nmemb objetos, ada um om size bytes de omprimento,


do uxo apontado por stream e os olo a na lo alizao apontada por ptr. A
funo retorna o nmero de itens que foram lidos om su esso. Caso o orra um
erro, ou o m do arquivo foi atingido o valor de retorno menor do que nmemb
ou zero. Esta funo no distingue entre um m de arquivo e erro, portanto
a onselhvel o uso de feof() ou ferror() para determinar que erro o orreu.
A funo fwrite es reve nmemb elementos de dados, ada um om size bytes
de omprimento, para o uxo apontado por stream obtendo-os da lo alizao
apontada por ptr. fwrite retorna o nmero de itens que foram lidos om su esso.
Caso o orra um erro, ou o m do arquivo foi atingido o valor de retorno menor
do que nmemb ou zero. O programa 11.7 ilustra omo podemos es rever e ler
dados binrios de diferentes tipos em arquivos. Como um dos parmetros da
funo o nmero de bytes do dado a ser lido, re omendado o uso de sizeof.
188

Listagem 11.7: Exemplo de leitura e es rita na forma binria.

#in lude < stdio .h >


int main ( void ) {
int inum =10; f l o a t fnum =2.5;
double pi =3.141516; har = 'Z ';
FILE * pa ; har * nome = " texto . bin " ;
if

(( pa = fopen ( nome , " w + " ) ) == NULL ) {


perror ( " fopen : " ) ;
return 1;

}
fwrite (& inum , s i z e o f ( int ) , 1 , pa ) ;
fwrite (& fnum , s i z e o f ( f l o a t ) , 1 , pa ) ;
fwrite (& pi , s i z e o f ( double ) , 1 , pa ) ;
fwrite (& , s i z e o f ( har ) , 1 , pa ) ;
rewind ( pa ) ;
fread (& inum , s i z e o f ( int ) , 1 , pa ) ;
fread (& fnum , s i z e o f ( f l o a t ) , 1 , pa ) ;
fread (& pi , s i z e o f ( double ) , 1 , pa ) ;
fread (& , s i z e o f ( har ) , 1 , pa ) ;
printf ( " %d , %f , %f , % \ n " , inum , fnum , pi , ) ;
f lose ( pa ) ;
return 0;

Uma das prin ipais apli aes destas funes a leitura e es rita de estruturas riadas pelos usurios. A gravao em binrio da estrutura permite que o
programador ao es rever ou ler do arquivo se preo upe somente om a estrutura
omo um todo e no om ada elemento que a ompe. O programa 11.8 mostra
um exemplo onde estruturas so gravadas e lidas de um arquivo. Neste exemplo
usado um lao para gravar uma estrutura de ada vez. No entanto, tambm
possvel gravar todas as estruturas de uma vez mudando o ter eiro parmetro
da funo fwrite(). O lao seria substitudo por
fwrite( &turma[i,

sizeof (stru t

pessoa), MAX, pa);

Para testar erro basta veri ar o valor retornado pela funo. Caso ela tenha
retornado um valor diferente de MAX o orreu um erro.

189

Listagem 11.8: Exemplo de leitura e es rita de estruturas.

#in lude < stdio .h >


#in lude < string .h >
typedef stru t _PESSOA {
har nome [40; int ano ;
} PESSOA ;

int

main () {
FILE * pa ;
har nome [40 , linha [80;
PESSOA turma [4 , ba k [4;
int i ;
for ( i =0; i <4; i ++) {
puts ( " Nome ? " );
fgets ( turma [ i . nome , 40 , stdin ) ;
turma [ i . nome [ strlen ( turma [ i . nome ) -1= ' \0 ';
puts ( " Ano ? " ); fgets ( linha , 80 , stdin ) ;
ss anf ( linha , " % d " , & turma [ i . ano ) ;
}
puts ( " \ nGravando \ n " );
puts ( " Qual o nome do arquivo ? " ) ; fgets ( nome , 40 , stdin
);
nome [ strlen ( nome ) -1= ' \0 ';
i f (( pa = fopen ( nome , " w + " ) ) == NULL ) {
puts ( " Arquivo nao pode ser aberto " ) ;
return 1;
}
for ( i =0; i <4; i ++) {
i f ( fwrite ( & turma [ i , s i z e o f ( PESSOA ) , 1 , pa ) !=
1)
puts ( " Erro na es rita . " ) ;
}
rewind ( pa ) ;
for ( i =0; i <4; i ++) {
i f ( fread ( & ba k [ i , s i z e o f ( PESSOA ) , 1 , pa ) !=
1) {
i f ( feof ( pa ) ) break ;
puts ( " Erro na leitura . " ) ;
}
}
for ( i =0; i <4; i ++) {
printf ( " Nome = % s \ n " , ba k [ i . nome ) ;
printf ( " Ano = % d \ n \ n " , ba k [ i . ano ) ;
}
return 0;

190

11.10 Exer ios


11.1: Es reva um programa que abra um arquivo texto e onte o nmero de
ara teres presentes nele. Imprima o nmero de ara teres na tela.
11.2:

Considere um arquivo de dados do tipo texto om o seguinte ontedo:

3
ZE SA
8.5
10.0
ANTONIO SANTOS
7.5
8.5
SEBASTIAO OLIVEIRA
5.0
6.0
O arquivo a ima um exemplo. Considere ento que nestes arquivos a
primeira linha ontm o nmero de alunos no arquivo. As linhas seguintes
ontm os seguintes dados:
nome do aluno om no mximo 50 ara teres;
nota da primeira prova;
nota da segunda prova.

Es reva um programa que imprima os nomes de todos os alunos que tm a mdia


das duas notas menor que 7.0
Es reva um programa que grave os dados lidos no exer io anterior em
um arquivo do tipo binrio de a esso aleatrio. O nmero que indi a quantos
alunos devem ser lidos (primeira linha do arquivo) no deve ser gravado no
arquivo binrio. Nesta questo o programa deve obrigatoriamente usar um
vetor de estruturas do seguinte tipo:

11.3:

typedef stru t _ALUNO


har nome [81;
f l o a t n1 , n2 ;

} ALUNO ;

Es reva um programa que leia de um arquivo, ujo nome sera forne ido
pelo usurio, um onjunto de nmeros reais e armazena em um vetor. O tamanho mximo do vetor e dado pela onstante TAM_MAX. A quantidade de nmeros
no arquivo varia entre 0 e TAM_MAX. O programa ao nal al ula a media dos
nmeros lidos.

11.4:

11.5: Faa um programa que leia 10 ara teres e armazene em um arquivo 10


pias de ada um. Exiba o ontedo

191

11.6: Crie uma funo que re eba duas strings omo parmetros, uma om um
endereo de arquivo e outra om um texto qualquer, e adi ione o texto no m
do arquivo.
11.7: Utilizando a funo do exer io anterior faa um programa que gere 10
arquivos om o nome "Teste"e extenses "01", ..., "10". Cada um ontendo o
texto "Texto do arquivo [NMERO DO ARQUIVO".
11.8: Es reva um programa para armazenar o telefone de 5 amigos. O programa
deve obrigatoriamente usar a estrutura

typedef stru t _PESSOA {


har nome [50;
int idade ;
f l o a t altura ;
har telefone [10;
} PESSOA ;

a ser preen hida pelo usurio antes do armazenamento de ada registro.


Faa um programa que leia os dados do arquivo gerado no exer io
anterior e salve-os num novo arquivo utilizando uma sada formatada omo
indi ado abaixo.
11.9:

FORMATO:
[nome tem [idade anos e [altura de altura
Tel.: [telefone
Es reva um programa que leia um arquivo texto ontendo linhas de
dados. Em ada linha do arquivo h o nome de um aluno e duas notas. Estes
dados esto separados por ponto e vrgula. Existe um ponto e vrgula ao nal
de ada linha. O formato dos dados e o seguinte:
ze sa; 10.0; 9.0;
antonio silva: 9.0; 7.0;

11.10:

O programa deve ler estes dados e imprimir os valores lidos, a mdia das
duas notas e se o aluno foi aprovado ou no (media 5). O formato de sada :
ze sa 10.0 8.0 9.0 aprovado
antonio silva 9.0 7.0 8.0 aprovado
11.11:

Faa um programa que re eba o nome de um arquivo e gere uma pia.

Es reva um programa que ompare dois arquivos espe i ados pelo


usurio e imprima sempre que os ara teres dos dois arquivos oin idirem. Por
exemplo:

11.12:

arquivo1.
Ol, pessoal!
arquivo2.
Oi, omo vai?
Neste aso, os ara teres na primeira e d ima primeira posio so iguais
nos dois arquivos. A sada do seu programa deve ser algo omo:
192

1 - O
11 - a
indi ando que os primeiros ara teres dos arquivos so iguais (O) bem omo o
d imo primeiro (a)
Um arquivo do tipo texto, hamado numeros.txt ontm uma quantidade des onhe ida de nmeros reais. Es reva um programa que leia estes nmeros, os oloque em ordem res ente e depois os grave em um arquivo binrio
hamado numeros.bin.

11.13:

Observaes:
(a) Neste exer io a quantidade de dados gravados no arquivo do tipo
texto des onhe ida, portanto, obrigatrio usar um vetor denido
om ponteiro. A denio de um vetor om um nmero onstante
de elementos, mesmo que seja um nmero grande, onsiderado um
erro.
(b) Para testar o programa rie o arquivo om um editor simples.
Um programador es reveu os tre hos de programas (I) e (II), mostrados
nas listagens 11.9 e 11.10, para ler dados inteiros de um arquivo. O nmero de
dados armazenados no arquivo des onhe ido.
11.14:

Listagem 11.9: (I) Tre ho de programa do problema 14.

while

(1)
fs anf (p , " % d " , & i ) ;
i f ( feof ( p ) ) break ;
printf ( " % d \ n " , i ) ;

Listagem 11.10: (II) Tre ho de programa do problema 14.


fs anf (p , " % d " , & i ) ;
(! feof ( p ) )
{
printf ( " % d \ n " , i ) ;
fs anf (p , " % d " , & i ) ;
}

while

Qual das opes abaixo verdadeira?


(a) Somente o tre ho I fun iona.
(b) Somente o tre ho II fun iona.
( ) Os dois tre hos fun ionam.
(d) Nenhum dos dois tre hos fun ionam.

193

Captulo 12
Problemas Extras

1a Problema:

Ser que Zeno hega l?


Zeno estava perdido em uma regio desrti a da Terra Mdia, ao norte de
Nrnia e a leste do famoso Castelo de Hogwarts. A idade mais prxima, Forks,
 ava a vrios dias de aminhada. Sedento e faminto ele j perdia as esperanas,
quando avistou, a 1000 metros de onde estava, uma fonte jorrando gua.
Zeno omeou a orrer, mas ho ou-se ontra uma barreira mgi a que
ir undava a fonte. No instante em que se ho ou ontra a barreira ouviu a
seguinte mensagem:
Forasteiro infeliz, para hegar at a fonte vo deve ter muita pa in ia e faa o seguinte: a ada 5 minutos aminhe metade da distn ia que ainda falta para hegar at a fonte. Desobedea qualquer
uma destas instrues e a morte ser o seu destino.
Tarefa

A sua tarefa des obrir em quantos minutos Zeno ir hegar a uma distn ia
da fonte menor do que 103 m.
Entrada

Este programa no tem entradas.


Sada

O seu programa deve imprimir em quantos minutos Zeno ir hegar na distn ia desejada.
2a Problema:

Estatsti a?

194

Uma medida importante em Estatsti a o desvio padro representado na


equao 12.2 por . Ele d a medida da variabilidade ou disperso de um
onjunto de dados. Alm de ser bastante til muito f il de ser al ulado.
Considere um onjunto de N nmeros S = {x0 , x1 , x2 , . . . , xN 1 } uja mdia
vale x. Para este onjunto de dados o desvio padro pode ser al ulado pela
equao 12.2.

PN 1

xi
N
v
u N 1
u1 X
(xi x)2
= t
N i=0

i=0

(12.1)
(12.2)

Tarefa

A sua tarefa ler um onjunto de dados armazenado em um arquivo do tipo


texto, hamado estatisti a.txt e al ular a mdia e depois o desvio padro
deste onjunto. Observe que o tamanho do onjunto des onhe ido e s pode
ser des oberto aps a leitura de todos os dados.
Neste exer io obrigatrio o uso de ponteiros para armazenar o
vetor.
Sada

A sada deve informar os valores obtidos para a mdia e o desvio padro.


Exemplo de Arquivo de Entrada e da sada
Arquivo estatisti a.txt:

1
2
3
4
5
6
7
8
9
10

Sada na tela:

A media vale 5.500000


O desvio padrao vale 2.872281

3a Problema:

Veri ando o CPF


Denies

O CPF o nmero usado pela Re eita Federal no Brasil para identi ar


os Contribuintes Pessoas Fsi as. O CPF omposto por 11 algarismos. Destes 11 algarismos os dois ltimos so usados para veri ar se os primeiros 9
foram digitados orretamente. Eles so hamados de algarismos veri adores.
Por exemplo, onsidere o CPF exemplo 12345678909. Este CPF na realidade
195

123456789, os algarismos 09 servem para que os programas da Re eita Federal


veriquem se os 9 primeiros esto orretos e so gerados automati amente pelos
omputadores da Re eita quando algum se ins reve. O algoritmo de gerao
dos dois ltimos algarismos des rito a seguir.
Para o primeiro dgito veri ador (v1 ), o 0, no nosso exemplo, o algoritmo
o seguinte: multiplique o primeiro algarismo por 10, o segundo por 9, e assim
su essivamente at o nono algarismo do digo e some todos estes resultados.
Neste exemplo teramos
soma1 = (1 10) + (2 9) + (3 8) + + (9 2)

Cal ule o valor do mdulo 11 de soma1 . Se este valor for 0 ou 1 ento o algarismo
v1 0, aso ontrrio o algarismo v1 o resultado da subtrao 11soma1 % 11.
Para o segundo dgito veri ador (v2 ), no nosso aso o 9, o algoritmo o
seguinte: multiplique o primeiro algarismo por 11, o segundo por 10, e assim
su essivamente at o nono algarismo do digo e some todos estes resultados.
Neste exemplo teramos
soma2 = (1 11) + (2 10) + (3 9) + + (9 3)

Some este resultado ao dobro do primeiro dgito veri ador (soma2 = soma2 +
2 v1 ). Cal ule o valor do mdulo 11 desta nova soma2 . Se este valor for 0
ou 1 ento o algarismo v2 0, aso ontrrio o algarismo v2 o resultado da
subtrao 11 soma2 % 11.
Tarefa

O programa mostrado na listagem 12.1 faz a veri ao de um CPF forne ido


pelo usurio. Complete as partes que faltam do programa. Observe que o
CPF lido omo um vetor de ara teres. Um exemplo de interao do
programa om um usurio o seguinte:

Entre om o pf.
12345678909
CPF lido: 12345678909
CPF valido.
4a Problema:

Mais perto, mais longe


Tarefa

Z S est planejando a sua prxima viagem por Pindorama. No momento


ele gostaria de saber qual so as idades mais distante e as mais perto da sua.
Para fazer estes l ulos ele dispe de um arquivo om as oordenadas de sua
idade e das vrias idades que ele ir visitar
Entrada

A entrada ser feita a partir de um arquivo texto hamado  idades.txt.


A primeira linha deste arquivo um nmero inteiro n dizendo quantas idades
h no arquivo. Considere que o nmero mximo de idades igual a 50. As n
196

Listagem 12.1: Pro essando o CPF.

#in lude
#in lude
#in lude
#define
#define
#define
int
int
int
int
int

< stdio .h >


< stdlib .h >
< string .h >
TAMCPF 11
CERTO 1
ERRADO 0

pfs ( har *) ;
verifi aCPF ( har *) ;
digito1 ( har *) ;
digito2 ( har * , int ) ;
leCPF ( har *) ;

int main ( int arg , har


har pfs [ TAMCPF +1;
int tam ;

* argv [) {

tam = leCPF ( pfs ) ;


i f ( tam != TAMCPF ) {
puts ( " CPF deve ter 11 digitos . " ) ;
return 1;
}
else {
i f ( verifi aCPF ( pfs ) ) {
puts ( " CPF valido . " ) ;
return 0;
}
else {
puts ( " CPF invalido . " ) ;
return 1;
}
}
return 0;

int

leCPF ( har * pfs ) {


puts ( " Entre om o pf . " ) ;
fgets ( pfs , TAMCPF +2 , stdin ) ;
pfs [ strlen ( pfs ) -1 = ' \0 ';
printf ( " CPF lido : % s \ n " , pfs ) ;
return strlen ( pfs ) ;

int

int

int

verifi aCPF ( har * pfs ) {


int dig1 , dig2 ;
dig1 = digito1 ( pfs ) ;
dig2 = digito2 ( pfs , dig1 ) ;
/* AQUI FALTA O FINAL */
digito1 ( har * pfs ) {
/* AQUI FALTA TODA A FUNCAO

*/

digito2 ( har * pfs , int dig1 ) {


/* AQUI TAMBEM FALTA TODA A197FUNCAO */

linhas seguintes ontm pares de nmeros om as oordenadas de ada uma das


idades que Z S ir visitar. O primeiro par de oordenadas perten e a idade
onde Z S vive.
Sada

A sada omposta de trs tipos de linhas e deve ser feita no vdeo. A


primeira linha informa as oordenadas da idade onde Z S vive. Em seguida
deve(m) vir as oordenadas da(s) idade(s) que  a(m) mais perto da idade
de Z S. Aps devem vir a(s) linha(s) que mostra(m) as oordenadas da(s)
idade(s) que  a(m) mais longe da idade de Z S. O exemplo abaixo mostra
o formato do arquivo de entrada e o formato da sada na tela.
Exemplo de entrada e sada
Arquivo :

8
2.0
0.0
1.0
3.0
4.0
0.0
4.0
7.0

2.0
0.0
1.0
3.0
4.0
4.0
0.0
7.0

5a Problema:

Sada na tela:

Origem: (2.000000, 2.000000)


Mais perto: (1.000000, 1.000000)
Mais perto: (3.000000, 3.000000)
Mais longe: (7.000000, 7.000000)

Produto Es alar

O produto es alar de dois vetores de n dimenses A = (a1 , a2 , . . . , an ) e

B = (b1 , b2 , . . . , bn ), onde (ai , bi ) dado pela equao 12.3


A B = a1 b 1 + a2 b 2 + + an b n

(12.3)

Tarefa

Es reva um programa que al ule o produto es alar de M pares de vetores,


todos em um espao de n dimenses. Neste problema no pre iso saber
vetores em C.
Entrada

A entrada onsiste das seguintes linhas de dados:


1. A primeira linha ontm um nmero inteiro M que informa o nmero de
pares de vetores a serem lidos.
2. A segunda linha ontm um nmero n que indi a a dimenso de ada um
dos vetores.
3. As linhas restantes ontm as oordenadas dos pares de vetores. Primeiro
n linhas om as oordenadas do primeiro par, em seguida n linhas om as
oordenadas do segundo par e assim su essivamente.

198

As oordenadas de ada par de vetores so forne idas da seguinte maneira.


Primeiro so forne idos dois nmeros a1 b1 depois a2 b2 e assim su essivamente
at an bn .
Sada

Imprimir os M produtos es alares al ulados.


Exemplo de entrada:

Exemplo de sada:

2
4
1 1.5
2 2
3 3.5
4 4
2.0 1.0
2.0 2.0
2.0 3.0
4.0 2.5

6a Problema:

32.000000
22.000000

Des onando do sorteio

H pessoas que des onam de tudo, omo h pessoas que a reditam em tudo.
Em Pindorama se joga em tudo, Ultrasena, Maxisena, Lotoesportiva et , desde
que seja o governo que re ebe todos os lu ros.
Um dos jogos a Ultrasena, onde os jogadores devem es olher nmeros entre
1 e 60. O jogador que a ertar os nmeros sorteados ganha uma frao mnima
do total que o governo arre adou. Um jogador des onado a ha que o sorteio
vi iado e ontratou vo para des obrir se isto verdade ou no.
Vo deve es rever um programa que leia os N ltimos nmeros inteiros
sorteados e onte a frequn ia om que ada um dos nmeros foi sorteado.
Entrada:

Primeiro o programa deve ler o valor de N . Em seguida o programa deve


ler a lista de N nmeros inteiros entre 1 e 60.
Sada:

Imprimir a frequn ia om que ada um dos nmeros apare eu. Nmeros


om frequn ia zero no devem ser impressos.
Exemplos de entrada e sada:

199

Exemplo de entrada

Sada para o exemplo de entrada

12
8
21
14
5
36
21
43
14
6
21
24
43

7a Problema:

5
6
8
14
21
24
36
43

=
=
=
=
=
=
=
=

1
1
1
2
3
1
1
2

Convertendo para base 2

Es reva um programa que leia uma sequn ia de nmeros inteiros na base


10 e imprima o nmero onvertido para base 2 e a maior sequn ia de bits 1
que o nmero binrio ontm.
Considere que o nmero na base 10 menor que 232 1.
Entrada:

A entrada ontm vrios asos de teste. Cada linha de um aso de teste


ontm um nmero inteiro menor que 232 1 O programa termina quando o
usurio forne er um nmero negativo.
Sada:

Para ada aso de teste da entrada seu programa deve produzir quatro linhas.
Na primeira linha o programa deve imprimir o aso de teste no formato Teste
n, onde n nmero do aso de teste omeando em 1. Na segunda linha o
nmero onvertido para base 2. Zeros esquerda no devem ser impressos. Na
ter eira linha o seu programa deve imprimir a maior sequn ia de 1's do nmero
em binrio. A quarta linha deve ser deixada em bran o.
Exemplos de entrada e sada:

200

Exemplo de entrada

Sada para o exemplo de entrada

6
25
123456
14
-1

Teste 1
110
2
Teste 2
11001
2

Teste 3
11110001001000000
4
Teste 4
1110
3

8a Problema:

Cal ulando reas


Vo foi ontratado para es rever um programa que al ula reas de r ulos.
O programa deve imprimir se um r ulo tem rea maior que a rea mdia ou
rea menor ou igual a mdia.
O seu programa deve usar a estrutura (12.2) para representar ada r ulo.
Listagem 12.2: Estrutura do problema 8.

typedef stru t

_CIRCULO

int x , y , raio ;
} CIRCULO ;
Entrada

Os dados estaro organizados da seguinte maneira. Primeiro, a quantidade


N de r ulos, em seguida os dados dos N r ulos, na seguinte ordem: oordenada x, oordenada y , raio raio.
Obs. No possvel assumir um valor mximo para N , aloque o espao de
memria ne essrio.
Sada

O programa de imprimir se um dado r ulo tem rea maior que a mdia


ou rea menor ou igual a mdia. Considerando que o primeiro r ulo re ebe o
nmero um, o segundo o nmero 2 e assim at o r ulo N , o formato de sada
o seguinte: a palavra Cir ulo seguida do nmero do r ulo e se ele tem rea
maior ou menor ou igual.
201

Exemplo de Entrada:

5
1
1
3
2
1

1
2
1
2
1

Exemplo de Sada:

Cir ulo
Cir ulo
Cir ulo
Cir ulo
Cir ulo

1
2
2
4
3

1
2
3
4
5

area
area
area
area
area

menor ou igual
menor ou igual
menor ou igual
maior
maior

9a Problema:

Lu rando om Aes
Vo foi ontratado, pela bolsa de valores de Pindorama, para es rever um
programa que imprima as aes om o melhor e o pior desempenho durante o
ano de 2325.
Entrada

A entrada ser lida de um arquivo texto om o nome de a oes.txt. O


arquivo onsiste de uma srie de linhas. Em ada linha h o nome da ao
seguido pelas otaes no dia 01 de janeiro de 2325 e no do dia 31 de dezembro
de 2325.
Nenhum nome de empresa ter mais de 20 ara teres. Observe que pode
haver mais de uma pior (melhor) ao.
Sada

A sada dever ser um arquivo do tipo texto, om o nome saida.txt. Neste


arquivo vo deve indi ar a melhor ao e seu rendimento e a pior ao om sua
perda. Observe que pode haver mais de uma melhor (pior) ao.
Exemplo de Entrada:

Exemplo Sada:

lixo 56.00 23.00


bb 100.00 125.00
etai 125.00 110.00
embrair 78.00 156.00
estavel 88.00 88.00
maislixo 56.00 23.00

Pior a ao = lixo, varia ao -0.59


Melhor a ao = embrair, varia ao 1.00
Pior a ao = maislixo, varia ao -0.59

10a Problema:

Somando Linhas
Es reva um programa que leia de um arquivo texto uma matriz quadrada de
nmeros reais. O tamanho mximo da matriz 10001000. O nome do arquivo
de entrada matrizin.txt. O seu programa deve al ular a soma de todos
os elementos de ada linha. Em seguida o seu programa deve des obrir qual a
maior soma e que linha tem soma igual a maior soma. O programa deve gravar
202

a maior soma e o(s) nmero(s) da(s) linha(s) om soma igual a maior em um


arquivo texto hamado matrizout.txt.
Entrada

Os dados no arquivo de entrada tem o seguinte formato. A primeira linha


do arquivo ontm o tamanho da matriz (1 N 1000). Em seguida o arquivo
ontm N N nmeros inteiros em um formato livre, ou seja quantidade de
nmeros por linha do arquivo varivel.
Sada

O arquivo de sada tem o seguinte formato. Primeiro o valor da maior soma


das linhas. Em seguida as linhas om soma igual a maior soma.
Exemplo de Entrada:

5
1.0
2.0
3.0
5.0
1.0

2.0
1.0
0.0
1.0
1.0

3.0
2.0
0.0
0.0
1.0

4.0
1.0
0.0
2.0
1.0

Exemplo de Sada:

14.000000
1
2
3

2.0
8.0
11.0
6.0
1.0

11a Problema:

Misturando Dados
Uma tarefa muito omum em omputao misturar dois vetores dados j
ordenados para riar um ter eiro tambm ordenado.
A sua tarefa es rever um programa que leia os dados de dois vetores e os
misture em um ter eiro.
Considere que o tamanho mximo de ada um dos dois vetores originais
des onhe ido.
Entrada

A leitura dos dados vai ser feita da seguinte maneira. Primeiro o programa
deve ler o tamanho do primeiro vetor (tam1). Em seguida o programa deve ler
tam1 nmeros reais. Aps estas leituras o programa l o tamanho do segundo
vetor (tam2). Finalmente, o programa l tam2 nmeros reais. Considerar que
os dados do primeiro e do segundo vetor esto em ordem res ente.
Sada

Aps misturar os dois vetores em um ter eiro o programa deve imprimir os


tam1 + tam2 nmeros reais armazenados no ter eiro vetor. Estes dados devem

203

estar em ordem res ente.


Exemplo de Entrada:

Exemplo de Sada:

5
1.0
4.0
7.0
10.0
12.0
3
1.0
2.0
9.0

1.0
1.0
2.0
4.0
7.0
9.0
10.0
12.0

204

Apndi e A
Tabela ASCII

A tabela ASCII (Ameri an Standard for Information Inter hange) usada por
grande parte da indstria de omputadores para a tro a de informaes e armazenamento de ara teres. Cada ara tere representado por um digo de
8 bits. A Tabela A.1 mostra os digos para a tabela ASCII de 7 bits. Existe
uma table estendida para 8 bits que in lui os ara teres a entuados.
Para saber qual o digo de um ara tere na base 10 junte o dgito da
primeira oluna da tabela om o dgito da primeira linha da tabela. Por exemplo,
o digo da letra a mins ula 97 na base 10.
0
1
2
3
4
5
6
7
8
9
10
11
12

0
nul
nl
d 4
rs
(
2
<
F
P
Z
d
n
x

1
soh
vt
nak
us
)
3
=
G
Q
[
e
o
y

2
stx

syn
sp
*
4
>
H
R
\
f
p
z

3
etx
r
etb
!
+
5
?
I
S

g
q
{

4
eot
so
an
"
,
6

J
T
^
h
r
|

5
enq
si
em
#
7
A
K
U
_
i
s
}

6
a k
dle
sub
$
.
8
B
L
V
'
j
t
~

7
bel
d 1
es
%
/
9
C
M
W
a
k
u
del

8
bs
d 2
fs
&
0
:
D
N
X
b
l
v

9
ht
d 3
gs
`
1
;
E
O
Y

m
w

Tabela A.1: Conjunto de ara teres ASCII


Os ara teres de ontrole listados a ima, servem para omuni ao om perifri os e ontrolar a tro a de dados entre omputadores. Eles tm o signi ado
mostrado na Tabela A.2.

205

Cara

nul
stx
eot
a k
bs
lf

so
dle
d 2
d 4
syn
an
sub
fs
rs
sp

Des rio

Cara

Cara tere nulo


Comeo de texto
Fim de transmisso
Conrmao
Volta um ara tere
Passa para prxima linha
Passa para prxima pgina
Shift-out
Data line es ape
Controle de dispositivo
Controle de dispositivo
Syn hronous idle
Can ela
Substitui
Separador de arquivo
Separador de registro
Espao em bran o

soh
etx
enq
bel
ht
vt
r
si
d 1
d 3
nak
etb
em
es
gs
us

Des rio

Comeo de abealho de transmisso


Fim de texto
Interroga
Sinal sonoro
Tabulao horizontal
Tabulao verti al
Passa para in io da linha
Shift-in
Controle de dispositivo
Controle de dispositivo
Negativa de onrmao
Fim de transmisso de um blo o
Fim de meio de transmisso
Es ape
Separador de grupo
Separador de unidade

Tabela A.2: Conjunto de digos espe iais ASCII e seus signi ados

206

Apndi e B
Palavras Reservadas

Palavras reservadas, tambm as vezes hamadas de palavra have, servem para


propsitos espe iais nas linguagens de programao. Servem para de larar tipos
de dados ou propriedades de um objeto da linguagem, indi ar um omando alm
de vrias outras funes. Palavras reservadas no podem ser usadas omo nomes
de variveis ou funes.
asm:

Indi a que digo es rito em assembly ser inserido junto omandos C.

auto:

Modi ador que dene a lasse de armazenamento padro.

Comando usado para sair in ondi ionalmente dos omandos for, while,
swit h, and do...while.

break:

ase:
har:

Comando usado dentro do omando swit h.


O tipo de dados mais simples em C, normalmente usado para armazenar
ara teres.
Modi ados de dados que impede que uma varivel seja modi ada.
Esta palavra no existia nas primeiras verses da linguagem C e foi introduzida pelo omit ANSI C. Veja volatile.

onst:

Comando que interrompe os omandos de repetio for , while ,


ou do...while e faz que eles passem para a prxima iterao.

ontinue:

usado dentro do omando swit h para a eitar qualquer valor no


denido previamente om um omando ase.

default:

do:

Comando de repetio usado em onjunto om o omando while . Pela


denio do omando o lao sempre exe utado pelo menos uma vez.
Tipo de dados usado para armazenar valores de ponto utuante em
pre iso dupla.

double:

else:

Comando que indi a um blo o de omandos alternativo que deve ser exe utado quando a ondio testada pelo omando if foi avaliada omo
FALSA.
207

Tipo denido pelo usurio que permite a denio de variveis que iro
a eitar somente ertos valores.

enum:

Modi ador de dados que indi a que uma varivel ir ser de larada em
outra rea do programa.

extern:

oat:
for:

Comando de repetio que ontm ini ializao de variveis, in remento e


sees ondi ionais. Em C o omando for um omando de repetio
extremamente exvel, permitindo inmeras possibilidades.

goto:

if:

Tipo usado para armazenar valores de ponto utuante.

Comando que ausa um pulo para uma posio do programa mar ada
om um rtulo.

Comando de testes usado para mudar o uxo do programa baseada em uma


de iso VERDADEIRO/FALSO.

int:

Tipo de dados usado para armazenar valores inteiros.

long:

Tipo de dados usado para armazenar valores inteiros om pre iso maior
do que o tipo int. Nos omputadores modernos o tipo long tem a mesma
pre iso que o tipo int e so usados 4 bytes.
Espe i ador de lasse de armazenamento que pede que, aso seja
possvel, uma varivel deve ser armazenada nos registradores do pro essador.

register:

Comando que ausa o uxo de instrues do programa abandonar a


funo em exe uo e retornar para a funo que hamou. Tambm pode
ser usado para retornar um ni o valor.

return:

Tipo de dados usado para armazenar valores inteiros em pre iso menor
do que o tipo int. Neste tipo 2 bytes so usados para armazenar os dados.

short:

Modi ador usado para indi ar que uma varivel pode armazenar tanto
valores positivos omo negativos.

signed:

sizeof:

Operador que retorna o tamanho em bytes do item forne ido.

Modi ador usado para signi ar que o ompilador deve preparar o


digo de forma a reter o valor da varivel.

stati :

Usado para ombinar C variveis de tipos diferentes na mesma estrutura.

stru t:

Comando de desvio usado para permitir que o uxo do programa possa


ser mudado para vrias direes diferentes. Usado em onjunto om o
omando ase.

swit h:

typedef:

Modi ador usado para riar novos nomes para tipos j existentes.

Palavra have usada para permitir mltiplas variveis partilharem o


mesmo espao na memria.

union:

208

Modi ador usado para signi ar que uma varivel onter somente
valores positivos.

unsigned:

void:

Palavra usada para signi ar que ou a funo no retorna nada ou que


um ponteiro deve ser onsiderado genri o ou ser apaz de apontar para
qualquer tipo de dados.

volatile:

Modi ador que signi a que uma varivel pode ser alterada.

Comando de teste que exe uta uma seo de digo enquanto uma ondio retorna VERDADEIRO.

while:

Em adio a estas as seguintes palavras so reservadas em C++:

at h, inline, template, lass, new, this, delete, operator, throw,


ex ept, private, try, finally, prote ted, virtual, friend, publi .
Caso queira es rever programas que possam ser onvertidas para a linguagem
C++ a onselhvel no us-las.

209