Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento...

261
Sum´ ario 1 Introdu¸c˜ ao 6 1.1 Hist´ orico ......................................... 6 1.2 Arquitetura de Computadores ............................. 8 1.2.1 Mem´ oria ..................................... 8 1.2.2 Processador ................................... 8 1.3 Algoritmos e Programas ................................ 9 1.4 ecnica de Desenvolvimento de Programas ..................... 11 1.5 Partes de um Programa ................................ 12 1.6 Tradu¸ ao de Programas ................................ 15 1.6.1 Compila¸c˜ ao ................................... 15 1.6.2 Interpreta¸ ao .................................. 15 1.7 Resumo ......................................... 16 1.8 Exerc´ ıcios Propostos .................................. 17 2 Conceitos B´ asicos 18 2.1 Vari´ aveis e C´ elulas de Mem´ oria ............................ 18 2.2 Identificadores ..................................... 21 2.3 Comando de Atribui¸ ao ................................ 23 2.4 Tipos de Dados ..................................... 25 2.4.1 Declara¸c˜ ao de Vari´ aveis ............................ 25 2.4.2 Tipo Inteiro ................................... 26 2.4.3 Tipo Ponto Flutuante ............................. 27 2.4.4 Tipo Booleano ................................. 28 2.4.5 Tipo Caractere ................................. 28 2.4.6 Convers˜ ao de Tipos .............................. 30 2.5 Constantes ....................................... 31 2.6 Express˜ oes ........................................ 32 2.6.1 Express˜ oes Aritm´ eticas ............................ 32 2.6.2 Express˜ oes Relacionais ............................. 34 2.6.3 Express˜ oes L´ ogicas ............................... 34 2.7 Comando de Entrada de Dados ............................ 35 1

Transcript of Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento...

Page 1: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

Sumario

1 Introducao 61.1 Historico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.2 Arquitetura de Computadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

1.2.1 Memoria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.2.2 Processador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

1.3 Algoritmos e Programas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.4 Tecnica de Desenvolvimento de Programas . . . . . . . . . . . . . . . . . . . . . 111.5 Partes de um Programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.6 Traducao de Programas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

1.6.1 Compilacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151.6.2 Interpretacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

1.7 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161.8 Exercıcios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

2 Conceitos Basicos 182.1 Variaveis e Celulas de Memoria . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.2 Identificadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.3 Comando de Atribuicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232.4 Tipos de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

2.4.1 Declaracao de Variaveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252.4.2 Tipo Inteiro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262.4.3 Tipo Ponto Flutuante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272.4.4 Tipo Booleano . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282.4.5 Tipo Caractere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282.4.6 Conversao de Tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

2.5 Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312.6 Expressoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

2.6.1 Expressoes Aritmeticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322.6.2 Expressoes Relacionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342.6.3 Expressoes Logicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

2.7 Comando de Entrada de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

1

Page 2: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2 SUMARIO

2.8 Comando de Saıda de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362.9 Comandos de Selecao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

2.9.1 Comando de selecao simples . . . . . . . . . . . . . . . . . . . . . . . . . . 392.9.2 Comando de selecao dupla . . . . . . . . . . . . . . . . . . . . . . . . . . . 412.9.3 Comando de selecao multipla . . . . . . . . . . . . . . . . . . . . . . . . . 46

2.10 Comandos de Repeticao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482.10.1 Comando de repeticao com pre-condicao . . . . . . . . . . . . . . . . . . . 492.10.2 Comando de repeticao com pos-condicao . . . . . . . . . . . . . . . . . . . 522.10.3 Comando de repeticao condensado . . . . . . . . . . . . . . . . . . . . . . 55

2.11 Problema dos Lotes Encaixantes . . . . . . . . . . . . . . . . . . . . . . . . . . . 582.12 Exercıcios Resolvidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642.13 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 672.14 Exercıcios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

3 Modularizacao 703.1 Introducao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703.2 Subprogramas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713.3 Partes de um Subprograma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

3.3.1 Cabecalho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723.3.2 Dicionario de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733.3.3 Corpo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743.3.4 Comentarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

3.4 Chamada de subprogramas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 763.5 Passagem de parametros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 773.6 Retorno de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

3.6.1 Encerramento antecipado de execucao . . . . . . . . . . . . . . . . . . . . 843.7 Funcoes sem lista de parametros . . . . . . . . . . . . . . . . . . . . . . . . . . . 863.8 Funcoes sem retorno de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 873.9 Recursividade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

3.9.1 Implementacao nao recursiva equivalente . . . . . . . . . . . . . . . . . . 903.10 Exercıcios Resolvidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913.11 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1043.12 Exercıcios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1053.13 Trabalhos Sugeridos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

4 Tipos Abstratos de Dados 1094.1 Tecnicas de Programacao Top-down e Bottom-up . . . . . . . . . . . . . . . . . . 1094.2 Tipos Compostos Heterogeneos (Estruturas) . . . . . . . . . . . . . . . . . . . . . 110

4.2.1 Definicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1114.2.2 Uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

4.3 Tipos Abstratos de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1164.3.1 Definicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116

Page 3: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

SUMARIO 3

4.3.2 Definicao de Atributos de um TAD . . . . . . . . . . . . . . . . . . . . . . 1204.3.3 Definicao de Operacoes de um TAD . . . . . . . . . . . . . . . . . . . . . 1204.3.4 Uso do TAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1224.3.5 Tipos de TADs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

4.4 Exercıcios Resolvidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1234.5 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1294.6 Lista de Exercıcios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1304.7 Trabalhos Sugeridos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

5 Vetores 1355.1 Vetores e sua importancia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1355.2 Representacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1375.3 Definicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

5.3.1 Definicao do Tamanho do Vetor . . . . . . . . . . . . . . . . . . . . . . . . 1395.4 Operacoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

5.4.1 Acesso indevido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1445.5 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1445.6 TAD Implementacional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

5.6.1 Atributos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1475.6.2 Operacoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

5.7 Exercıcios Resolvidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1585.8 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1585.9 Lista de Exercıcios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1595.10 Trabalhos Sugeridos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

6 Matrizes 1646.1 Introducao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1646.2 Definicao e Acesso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

6.2.1 Definicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1666.2.2 Acesso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167

6.3 O TAD implementacional tMatriz . . . . . . . . . . . . . . . . . . . . . . . . . . 1686.3.1 Atributos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1686.3.2 Operacoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

6.4 Exercıcios Resolvidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1746.5 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1816.6 Exercıcios Propostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1816.7 Trabalhos Sugeridos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1856.8 Topicos Avancados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186

Page 4: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4 SUMARIO

7 Apontadores 1877.1 Variaveis Apontadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1877.2 A Sintaxe dos Apontadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188

7.2.1 Operador Endereco de Memoria . . . . . . . . . . . . . . . . . . . . . . . 1907.2.2 O Operador Seta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190

7.3 Acesso a Variavel por Meio de Apontadores . . . . . . . . . . . . . . . . . . . . . 1917.4 Uso de Apontadores nas Passagens de Parametros . . . . . . . . . . . . . . . . . 1927.5 Alocacao Dinamica de Memoria . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1947.6 Problemas Gerados por Apontadores . . . . . . . . . . . . . . . . . . . . . . . . . 198

7.6.1 Apontadores Nao Inicializados . . . . . . . . . . . . . . . . . . . . . . . . 1987.6.2 Objetos Pendentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1987.6.3 Referencia Pendente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1997.6.4 Programacao Macarronica . . . . . . . . . . . . . . . . . . . . . . . . . . . 200

7.7 TAD Implementacional Lista Encadeada tLista . . . . . . . . . . . . . . . . . . . 2007.7.1 Definicao do Tipo tNo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2027.7.2 Atributos de tLista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2027.7.3 Operacoes de tLista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2037.7.4 Uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

7.8 Exercıcios Resolvidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2137.9 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2237.10 Lista de Exercıcios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2247.11 Trabalhos Sugeridos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228

8 Arquivos 2358.1 Variaveis Transientes X Variaveis Persistentes . . . . . . . . . . . . . . . . . . . . 2358.2 Tipos de Arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236

8.2.1 Tipos de Arquivos - Arquivos Texto . . . . . . . . . . . . . . . . . . . . . 2368.2.2 Tipos de Arquivos - Arquivos Binarios . . . . . . . . . . . . . . . . . . . . 237

8.3 Definicao de arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2388.4 Operacao sobre arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238

8.4.1 Abertura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2388.4.2 Fechamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240

8.5 Operacoes sobre arquivos texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2418.5.1 Leitura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2418.5.2 Escrita . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243

8.6 Operacoes sobre arquivos binarios . . . . . . . . . . . . . . . . . . . . . . . . . . 2448.6.1 Leitura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2448.6.2 Escrita . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245

8.7 Outras funcoes uteis para arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . 2468.7.1 feof() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2478.7.2 fseek() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249

8.8 Exercicios Resolvidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250

Page 5: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

SUMARIO 5

8.8.1 O Tipo Abstrato de Dados TDicionario . . . . . . . . . . . . . . . . . . . 2508.9 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2578.10 Exercıcios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2578.11 Trabalhos Sugeridos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260

Page 6: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

Capıtulo 1

IntroducaoCo-autor:

Andre Boechat

Objetivos:

• Apresentar um breve historico da Computacao;

• Apresentar nocoes sobre arquitetura de computadores, como funcionam o processador e amemoria;

• Definir o que sao algoritmos e programas, alem de apresentar algumas tecnicas para de-senvolve-los;

• Definir as partes de um programa e a importancia da documentacao;

• Introduzir o conceito de traducao de programas.

Basicamente, pode-se considerar a programacao de computadores como a forma que se dao relacionamento entre a maquina e o homem. Para programar de forma correta e eficiente,muitas vezes nao basta conhecer apenas os comandos de determinadas operacoes, e necessariosaber como a maquina, um ser nao pensante, faz para compreender e executa-los. Assim, estecapıtulo visa apresentar alguns conceitos fundamentais para o entendimento da programacao,desenvolvidos juntamente com a area mais recente da ciencia, a Computacao.

1.1 Historico

Dado o alto grau tecnologico dos computadores atuais, pode ser difıcil imaginar que os primeiroscomputadores eram totalmente mecanicos. Diversos tipos foram projetados e construıdos aolongo da evolucao, chegando aos modernos computadores digitais; porem, alguns se destacampela inovacao e complexidade que marcaram suas epocas.

6

Page 7: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

1.1. HISTORICO 7

A primeira maquina programavel que se tem notıcia foi construıda pelo professor de ma-tematica da Universidade de Cambridge, Charles Babbage (1792-1871). A “maquina analıtica”,como ficou conhecida, era totalmente mecanica, composta basicamente por engrenagens queformavam quatro componentes: a memoria, a unidade de calculo ou computacao, a unidadede entrada e a de saıda. A unidade de computacao recebia operandos da memoria para reali-zar sobre eles as operacoes de soma, subtracao, multiplicacao ou divisao, e depois armazenar oresultado na memoria.

Como a maquina analıtica executava as instrucoes lidas pela unidade de entrada, era possıvelexecutar diferentes sequencias de calculos, bastando para isso que um programa diferente fosseutilizado. Assim, a primeira pessoa no mundo a programar um computador foi a jovem AdaAugusta Lovelace, contratada pelo proprio Babbage a fim de produzir o software necessario parao funcionamento da maquina.

A procura por maquinas calculadoras cresceu com a Segunda Guerra Mundial, estimulandoo surgimento dos primeiros computadores eletronicos. O professor de fısica da Universidade daPensilvania, John Mauchley, junto com seu aluno de mestrado, J. Presper Eckert, construiuum computador chamado ENIAC (Electronic Numerical Integrator And Computer)[2], o qualdetinava-se ao computo de trajetorias taticas que exigissem conhecimento substancial em ma-tematica. O ENIAC tinha 18.000 valvulas e 1.500 reles, pesava 30 toneladas e consumia 140quilowatts de energia eletrica. Para programar o ENIAC, era necessario ajustar a posicao de6.000 chaves de varias posicoes e conectar um numero imenso de soquetes por meio de uma ver-dadeira floresta de cabos. Este gigantesco computador so ficou pronto em 1946, apos o terminoda guerra.

Um dos pesquisadores envolvidos no projeto do ENIAC, John von Neumann, construiu parao Instituto de Estudos Avancado de Princeton (Princeton Institute of Advanced Studies — IAS )a maquina IAS[3], a qual ainda e a base de praticamente todas as maquina atuais. Ele imaginouque os programas poderiam ser representados em formato digital na memoria, junto com osdados.

A invencao do transıstor e o desenvolvimento de circuitos integrados revolucionaram os pro-jetos de computadores do final da decada de 1950, tornando obsoletos os computadores valvula-dos. Nas decadas de 1960 e 1970, as famılias de computadores da IBM1 (International BusinessMachines), System/360, e da DEC2 (Digital Equipament Corporation), PDP-11, dominavam omercado.

Nesse perıodo surgiu uma das linguagens de programacao mais usadas para o desenvolvi-mento de softwares e tambem adotada neste livro, a linguagem C[1]. Ela e, ainda hoje, muito uti-lizada para a criacao de programas diversos, como processadores de texto, planilhas eletronicas,programas para a solucao de problemas de engenharia, e muitos outros.

Diversos fatores, como a criacao de linguagens de programacao mais semelhantes a linguagemhumana3, o que facilitava a vida dos programadores, e a integracao de circuitos em escala muitoalta, o que aumentou o desempenho e diminuıu o tamanho das maquinas, deram inıcio a era

1http://www.ibm.com2http://www.hp.com3Essas linguagens sao chamadas de “linguagens de alto nıvel”

Page 8: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8 CAPITULO 1. INTRODUCAO

dos computadores pessoais. E foi nesse contexto, na decada de 80, que a IBM construiu ocomputador mais vendido de toda a historia, o Personal Computer — o famoso PC.

O processador utilizado no PC foi construıdo por uma promissora empresa da epoca, a Intel4.E a versao inicial desse computador vinha com o sistema operacional MS-DOS fornecido poroutra empresa, a recem-criada Microsoft Corporation.

1.2 Arquitetura de Computadores

Para conhecer um pouco mais sobre o funcionamento dos computadores, e apresentada nestaSecao uma nocao basica sobre processadores e memorias.

1.2.1 Memoria

A memoria e a parte do computador onde as operacoes a serem executadas pelo computador(instrucoes) e as informacoes a serem processadas pelo mesmo (dados) sao armazenados.

Na memoria, o processador le e escreve informacoes ao executar as instrucoes de um pro-grama. Existem dois tipos de memoria: a memoria principal e a secundaria. A principal,conhecida tambem como RAM (Random Access Memory), possui as seguintes caracterısticas:

• Armazena dados e instrucoes do programa em execucao;

• Proporciona ao computador acesso rapido aos dados e instrucoes armazenados por ela;

• So mantem as informacoes armazenadas enquanto o computador estiver ligado.

A memoria secundaria geralmente possui maior capacidade de armazenamento de dados einstrucoes, porem o tempo necessario para acessa-los e bem maior quando comparado ao damemoria principal. As informacoes permanecem armazenadas mesmo apos o desligamento docomputador. Discos rıgidos e CD-ROMs sao exemplos de memorias secundarias.

A unidade basica da memoria e o digito binario, conhecido como “bit”. Um bit pode assumirapenas dois valores, normalmente 0 ou 1.

A memoria e formada por um conjunto de celulas, ou posicoes, sendo que cada uma podeguardar uma informacao e possui um numero de reconhecimento, conhecido como “enderecode memoria”. E por meio desse numero de endereco que os programas podem acessar umadeterminada celula. Se uma celula possuir k bits, ela podera armazenar qualquer uma das 2k

combinacoes possıveis para os bits. A Figura 1.1 mostra um exemplo de memoria com seiscelulas enderecaveis, onde cada celula possui dezesseis bits.

1.2.2 Processador

O processador e o “cerebro” do computador. Basicamente, o processador e responsavel porbuscar instrucoes na memoria, decodifica-las para determinar seus operandos (dados que serao

4http://www.intel.com

Page 9: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

1.3. ALGORITMOS E PROGRAMAS 9

Figura 1.1: Exemplo de uma memoria de 16 bits e 6 enderecos.

usados ao processar a instrucao) e quais operacoes devem ser realizadas com os mesmos, eexecutar tais operacoes. Essas tarefas compoem o processo de execucao de um programa.

1.3 Algoritmos e Programas

Apesar do nome pouco comum, diversos algoritmos sao executados por pessoas comuns todos osdias. Ao escovar os dentes, fazer um bolo ou trocar o pneu de um carro, diversos procedimentossao feitos em sequencia, seguindo, muitas vezes, uma certa ordem logica.

Para exemplificar a execucao de um algoritmo, descreve-se a seguir alguns passos necessariospara fazer algo simples, cotidiano, como o ato de escovar os dentes.

1. Pegar a escova e a pasta de dentes;

2. Colocar um pouco de pasta sobre as cerdas da escova;

3. Escovar os dentes do maxilar inferior;

4. Escovar os dentes do maxilar superior;

5. Expelir da boca o excesso de espuma;

6. Bochechar um pouco de agua;

7. Lavar a escova e guarda-la;

8. Enxugar o rosto.

Apos conhecer um exemplo comum de algoritmo, torna-se mais facil compreender a sua definicao:

Algoritmo e uma sequencia de operacoes que deve ser executada em umaordem definida e nao-ambıgua, com o proposito de solucionar um deter-minado problema.

Page 10: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

10 CAPITULO 1. INTRODUCAO

Apesar de conseguirem executar operacoes muito complexas, os computadores nao sao do-tados da mesma capacidade de compreensao que os humanos. Uma sequencia de tarefas consi-derada simples e obvia para uma pessoa qualquer pode ser incompreensıvel e pouco detalhadapara um computador.

Voltando ao exemplo da escovacao, um computador poderia considera-lo incompleto, poisha diversas questoes sobre como algum passo pode ser executado, por exemplo:

1. Onde esta a escova a ser usada?

2. Quanto, exatamente, se deve colocar de pasta sobre as cerdas?

3. O que fazer se nao houver pasta? Escovar mesmo sem a pasta ou interromper o processode escovacao?

Questoes como essas sao facilmente contornadas por um humano, decididas instantaneamentede acordo com o ambiente que o cerca. Entao, para que uma maquina tambem possa “decidir”o que fazer em situacoes semelhantes, e necessario que se estabelecam as condicoes iniciais(condicoes de entrada) e as finais (condicoes de saıda) do problema. Dessa forma, ela saberaquais ferramentas poderao ser usadas para atingir a condicao de saıda desejada.

Assim, o problema da escovacao seria mais bem definido da seguinte maneira:

Condicoes de Entrada: Dentes sujos com restos de alimentos, uma escova dental em condicoesde uso, 90 gramas de creme dental e 300 mililitros de agua tratada.

Condicoes de Saıda: Dentes limpos (sem restos de alimentos visıveis), uma escova dental emcondicoes de uso e 85 gramas de creme dental. Toda a quantidade de agua deve serutilizada.

Portanto, para um computador, os algoritmos definem o conjunto de atividades que ele devedesempenhar para solucionar um problema.

Contudo, tao importante quanto saber “o que” escrever para a maquina e saber “como”escrever. Para que um computador possa executar um algoritmo, e necessario que esse algoritmoseja traduzido para uma linguagem de programacao, geralmente incompreensıvel para a maioriadas pessoas. Ao se traduzir um algoritmo para uma linguagem de programacao, obtem-se umprograma.

“Embora os computadores modernos sejam capazes de executar operacoes difıceis ecomplexas, eles sao maquinas doceis e de uma inteligencia restrita. Eles devem serensinados exatamente o que fazer, e as instrucoes devem ser feitas em uma linguagemsimples, precisa e limitada que eles possam compreender. Estas instrucoes sao maisconhecidas como programa” (Darmell,1988).

Page 11: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

1.4. TECNICA DE DESENVOLVIMENTO DE PROGRAMAS 11

1.4 Tecnica de Desenvolvimento de Programas

Na maioria das vezes, o ato de programar nao e uma tarefa simples e facil. A sintaxe daslinguagens de programacao e bem rıgida e deve ser respeitada fielmente para que o computador acompreenda. Esquecer de um “;” no lugar onde e necessario, por exemplo, significa comprometera execucao de todo o programa (na verdade, o computador pode nem comecar a executa-lo). Oupior, um programa teoricamente correto, que nao apresente erros de sintaxe, pode fornecer umresultado incorreto. Encontrar o erro torna-se um enorme problema a medida que o programacresce em tamanho e complexidade.

Para contornar a complexidade dos programas, os construtores de software costumam fazeruso de uma poderosa tecnica de programacao, conhecida como “tecnica dos refinamentos suces-sivos”5. Ela consiste basicamente em dividir um processo complexo em processos-componentesmenores, especificando apenas a entrada e a saıda de cada um deles. E se, mesmo assim,alguns processos menores continuarem complexos, repete-se a divisao no interior dos processos-componentes, gerando processos cada vez mais simplificados.

Alem de facilitar a depuracao de erros, essa tecnica pode tornar um complexo programa emuma “uniao” de programas menores e mais simples. A divisao tambem possibilita outra grandevantagem, o reuso de codigo, ou seja, o uso de um mesmo trecho de programa para realizar omesmo tipo de tarefa em diferentes ocasioes dentro de um programa maior.

Um exemplo pratico do uso dos refinamentos sucessivos segue abaixo:

=⇒ Algoritmo “Escovacao dentaria”:

1. Pegar a escova e a pasta de dentes;

2. Colocar um pouco de pasta sobre as cerdas da escova;

3. Escovar os dentes do maxilar inferior;

4. Escovar os dentes do maxilar superior;

5. Expelir da boca o excesso de espuma;

6. Bochechar um pouco de agua;

7. Lavar a escova e guarda-la;

8. Enxugar o rosto.

=⇒ Processo-componente “pegar a escova e a pasta de dentes”:

1. Enquanto nao encontrar a escova e o tubo de pasta, continuar procurando por cada gavetado armario;

5Tambem conhecida como “dividir para conquistar”.

Page 12: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

12 CAPITULO 1. INTRODUCAO

2. Caso tenham acabado as gavetas e nao tenha encontrado a escova e o tubo, interromper atarefa.

=⇒ Processo-componente “escovar os dentes do maxilar inferior”:

1. Com as cerdas da escova na posicao vertical, fazer movimentos de vai-e-vem na regiaosuperior dos dentes;

2. Com as cerdas na posicao horizontal, escovar a regiao frontal dos dentes;

3. Com as cerdas na posicao horizontal, escovar a regiao detras dos dentes.

=⇒ Processo-componente “escovar a regiao detras dos dentes”:

1. Abrir bem a boca;

2. Afastar a lıngua da regiao a ser escovada;

3. Esfregar as cerdas da escova atras dos dentes.

O exemplo anterior mostra apenas parte do processo de refinamentos, que deve prosseguirate que cada atividade esteja suficientemente detalhada, possibilitando que o computador asreconheca e execute.

1.5 Partes de um Programa

Como dito anteriormente, os programas podem ser comparados a diversas atividades do dia-a-dia de qualquer pessoa. Um exemplo e o de receitas culinarias. Geralmente, essas seguem umadeterminada estrutura, como abaixo:

• Nome da receita;

• Ingredientes: descreve todo o material necessario para o preparo da receita;

• Modo de preparo: descreve a forma de trabalhar com os ingredientes para que se obtenhao resultado esperado;

• Comentarios sobre certos procedimentos ou ingredientes a fim de detalhar alguma peculi-aridade que o cozinheiro poderia nao conhecer previamente.

A estrutura de um bom programa segue um modelo semelhante. Basicamente, um programadeve conter quatro partes:

• Cabecalho: contem informacoes sobre o programa, como o seu nome;

Page 13: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

1.5. PARTES DE UM PROGRAMA 13

• Dicionario de dados: define quais sao os dados manipulados pelo programa;

• Corpo: define os procedimentos que o programa deve executar;

• Documentacao: explica certos aspectos nao muito claros do programa, tanto no corpo doprograma quanto no cabecalho ou no dicionario de dados.

Um dos principais objetivos deste tipo de estrutura e aumentar a legibilidade do programa, ouseja, facilitar o entendimento dos diversos processos que o programa executa. Um programa devevalorizar a formatacao, disposicao fısica das linhas de codigo, para facilitar seu entendimento.Colocar cada comando em uma linha e inserir uma linha em branco entre blocos de comandosde finalidade comum sao regras basicas para uma boa formatacao. Os programas devem serlidos e entendidos por quem os escreveu e por outras pessoas, uma vez que podem necessitar decorrecao, manutencao, modificacao ou apenas de serem compreendidos por um simples usuario.

Para ilustrar essa estrutura, apresenta-se a seguir um programa, Pseudocodigo 1.1, que efetuao calculo das raızes reais de uma equacao de segundo grau. Os dados de entrada do programasao os tres coeficientes da equacao e ele devera apresentar ao usuario as raızes reais da mesma,caso existam.

Pseudocodigo 1.1 Calculo das raızes reais de uma equacao de segundo grau.

Descricao: programa que calcula as raızes reais de uma equacao de segundo grau.Dados de Entrada: os tres coeficientes da equacao.Saıda do Programa: raızes reais da equacao.

Leitura dos coeficientes da equac~ao;Calculo do discriminante (delta);Calculo das raızes pelo processo componente "Calculo das Raızes";

Utilizando a tecnica dos refinamentos sucessivos, na ultima linha do Pseudocodigo 1.1 ocorrea execucao do processo componente Calculo das Raızes, que, a partir dos valores dos coeficien-tes lidos e do discriminante calculado, encontra os valores das raızes reais da equacao. No geral,o processo componente Calculo das Raızes deve conter os passos descritos no Pseudocodigo1.2.

Pseudocodigo 1.2 Processo componente para o calculo das raızes.

Processo-componente "Calculo das Raızes":Verificar a existencia de raızes reais

Se possui raızes reais:Exiba para o usuario os valores da raızes;

Sen~ao:Exiba um alerta sobre a n~ao existencia de raızes reais;

FIM-Processo componente "Calculo das Raızes"

Page 14: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

14 CAPITULO 1. INTRODUCAO

No Exemplo 1.1, o programa para o calculo das raızes esta transcrito para a linguagem deprogramacao C. Deve-se destacar que o texto escrito entre os sımbolos “/*” e “*/” e sempreignorado pelo computador, nao alterando em nada o funcionamento do programa. Porem, essetexto serve para comentar o codigo e deixa-lo mais claro. Pode-se faze-los tambem utilizando osımbolo “//”, que transforma em comentario tudo aquilo que estiver a sua direita, ate o finalda linha.

1 /*

2 Programa para calculo das raızes de segundo grau.

3 Dados de entrada: os coeficientes a, b e c de uma equac~ao

4 da forma ax^2 + bx + c = 0

5 Dados de saıda: imprime na tela as raızes reais da equac~ao , caso existam.

6 Restric~ao: N~ao se considera o zero como um possıvel valor de a.

7 */

8

9 #include <math.h>

10 #include <stdio.h>

11

12 main(){

13 float a; // Coeficiente angular.

14 float b; // Coeficiente linear.

15 float c; // Termo independente.

16 float delta; // Discriminante.

17 float raiz1; // A primeira raiz.

18 float raiz2; // A segunda raiz.

19

20 // Leitura dos coeficientes.

21 scanf("%f %f %f",&a, &b, &c);

22

23 // Calculo do discriminante (delta).

24 delta = b*b - 4 * a * c;

25

26 // Calculo das raızes.

27 if(delta < 0){

28 printf("A equac~ao n~ao possui raızes reais");

29 }else{

30 raiz1 = (-b + sqrt(delta)) / (2*a);

31 raiz2 = (-b - sqrt(delta)) / (2*a);

32 printf("As raızes da equac~ao s~ao: %f e %f",raiz1 , raiz2);

33 }

34 }

Exemplo 1.1: Programa para o calculo das raızes reais de uma equacao de segundo grau.

Na linguagem C, o cabecalho dos programas sempre tem o nome main() e o inıcio do corpodo programa e marcado pela chave “{”, assim como o final e marcado pela ultima chave “}”.As linhas 9 e 10 permitem o uso dos comandos sqrt e printf (o significado desses comandos eexplicado no proximo capıtulo).

Page 15: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

1.6. TRADUCAO DE PROGRAMAS 15

De acordo com a estrutura de programa apresentada no inıcio desta secao, as linhas 13 a18 compoem o dicionario de dados e o restante compoe o corpo do programa. A documentacaoesta inserida no programa em forma de comentarios, como as linhas 1 a 7, 20, 23 e 26.

Vale destacar a importancia da disposicao fısica das linhas de codigo para o facil entendimentodo programa. A hierarquizacao de elementos por meio de espacos em branco e chamada deindentacao. O trecho de programa relacionado ao calculo das raızes no Exemplo 1.1 demonstracomo a indentacao pode facilitar a visualizacao da mudanca do fluxo do programa.

Normalmente, linhas de codigo com mesma indentacao sao executadas de maneira contınua,uma apos a outra. Uma mudanca na indentacao indica uma mudanca nesse fluxo de execucaodo programa. No proximo capıtulo sao apresentadas diversas maneiras de mudar esse fluxo.

1.6 Traducao de Programas

Apesar do que foi dito na Secao 1.3, para ser executado pelo computador, um programa aindaprecisa ser traduzido para uma linguagem mais simples que as linguagens de alto nıvel: a lingua-gem de maquina. Chama-se de “codigo fonte” o arquivo que contem o conjunto de instrucoesescritas em uma determinada linguagem de programacao, normalmente familiares ao programa-dor. Ja o arquivo que as contem traduzidas para linguagem de maquina e chamado de “codigoobjeto”.

Para efetuar essa traducao, e necessario aplicar um programa, ou conjunto de programas,que receba o codigo fonte e gere o codigo objeto. A seguir, descrevem-se dois metodos basicospara um programa tradutor efetuar essa tarefa: a compilacao e a interpretacao de um codigofonte.

1.6.1 Compilacao

O processo de compilacao efetua a traducao integral do programa fonte para o codigo de maquina.Uma vez traduzido, o programa em linguagem de maquina pode ser executado diretamente. AFigura 1.2 ilustra esse processo.

A grande vantagem desse metodo de traducao e a rapidez na execucao dos programas, poisnao e necessario fazer qualquer traducao durante a execucao. Porem, o codigo objeto gerado pelacompilacao e, geralmente, especıfico para um determinado tipo de arquitetura de computador.Assim, e necessario uma nova compilacao do programa para cada tipo diferente de computador.

A linguagem C, adotada neste livro, e um exemplo de linguagem de programacao compilada.

1.6.2 Interpretacao

No processo de interpretacao, cada instrucao do codigo fonte e traduzida no instante imedia-tamente anterior a execucao dela. Desse modo, em contraste com a compilacao, a traducao eexecucao de programas interpretados podem ser vistas como um processo unico (veja as Figuras1.2 e 1.3).

Page 16: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

16 CAPITULO 1. INTRODUCAO

Figura 1.2: Metodo de compilacao. Figura 1.3: Metodo de interpretacao.

Apesar de ser um processo mais lento quando comparado ao metodo anterior, a interpretacaoapresenta maior flexibilidade na construcao de programas e facilidade de depuracao de codigo.A presenca do interpretador durante a execucao permite, por exemplo, a execucao de trechosde programas criados, alterados ou obtidos durante a propria execucao.

1.7 Resumo

• O processador e o componente do computador responsavel por executar os programasarmazenados na memoria.

• A memoria e responsavel por armazenar os programas e os dados. A unidade basica damemoria e o bit.

• Algoritmo e uma sequencia de operacoes que deve ser executada em uma ordem definidae nao-ambıgua, com o proposito de solucionar um determinado problema. Ao traduzir-seum algoritmo para uma linguagem de programacao, obtem-se um programa.

• A Tecnica de Refinamentos Sucessivos consiste, basicamente, em dividir sucessivamenteproblemas complexos em diversos problemas menores e mais simples.

• Um programa bem estruturado deve conter as seguintes partes bem definidas: cabecalho,dicionario de dados, corpo e documentacao.

Page 17: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

1.8. EXERCICIOS PROPOSTOS 17

• Basicamente, existem dois mecanismos de traducao de programas para linguagem demaquina: compilacao e interpretacao. Na compilacao, o codigo fonte e totalmente tradu-zido antes de ser executado. Ja na interpretacao, a traducao do codigo fonte e a execucaodo programa ocorrem quase simultaneamente, como um processo unico.

1.8 Exercıcios Propostos

1. Qual e o papel do processador?

2. Qual e o papel da memoria?

3. Considere uma memoria que possua celulas de 8 bits cada uma. Qual o numero de possıveisinformacoes diferentes cada celula pode armazenar?

4. Utilizando o conceito de algoritmo apresentado no capıtulo, descreva, atraves de um al-goritmo, o ato de trocar um pneu furado de um carro. Nao se esqueca de estabelecer ascondicoes iniciais do problema (por exemplo, carro com um pneu dianteiro furado, se achave de roda esta no carro, se o carro esta parado em uma ladeira, etc) e as condicoes desaıda (por exemplo, carro parado e frenado, etc).

5. Use a Tecnica de Refinamentos Sucessivos para detalhar as seguintes atividades:

(a) Montagem de uma barraca de camping;

(b) Preparacao de um bolo de aniversario;

(c) Calculo da distancia entre dois pontos no plano cartesiano.

Page 18: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

Capıtulo 2

Conceitos BasicosCo-autores:

Andre BoechatBruno Pandolfi

Objetivos:

• Apresentar o conceito de variavel;

• Estudar os principais tipos de dados basicos e expressoes validas;

• Mostrar como e feita a definicao de variaveis e constantes;

• Apresentar os comandos elementares usados em programas.

A ideia de resolver problemas formalizando a solucao atraves do emprego de algoritmos e aespinha dorsal da programacao procedural, na qual as tarefas sao prescritas ao computador pormeio de uma sequencia de operacoes basicas.

Este capıtulo trata do estudo dos conceitos e operacoes elementares da programacao, forne-cendo uma base solida que, mais adiante, serve para construir algoritmos progressivamente maiscomplexos e resolver problemas cada vez mais elaborados.

2.1 Variaveis e Celulas de Memoria

Qualquer algoritmo tem por finalidade produzir algum resultado util para compor a solucao deum problema. Os algoritmos computacionais, em sua maioria, operam sobre um conjunto dedados para produzir novos resultados de acordo com a necessidade da tarefa em questao.

Quando corretamente transcritos para uma linguagem de programacao, os algoritmos saochamados de programas e podem ser executados pelo computador. E necessario, todavia, arma-zenar as informacoes utilizadas pelos programas em um local organizado e seguro, para que asconsultas e alteracoes sejam efetuadas de maneira coerente e livre de erros. Os computadoresutilizam a memoria para armazenar os dados de um programa em execucao.

18

Page 19: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.1. VARIAVEIS E CELULAS DE MEMORIA 19

Como dito na Secao 1.2.1, a memoria pode ser entendida como uma sequencia de celulas,cada celula podendo armazenar uma porcao dos dados de um programa. Gracas a essa ordenacaosequencial, cada celula possui um numero identificador chamado endereco, que esta relacionadocom a posicao que a celula ocupa na sequencia. Por meio dos enderecos e possıvel acessarqualquer celula para ler ou alterar seu conteudo. A Figura 2.1 esboca essa ideia, porem, emcontraste com a Figura 1.1, omite a representacao dos bits.

Figura 2.1: Modelo para a estrutura da memoria do computador, mostrando uma fracao de seiscelulas, seus enderecos e conteudos.

As seis celulas de memoria da Figura 2.1 podem guardar valores numericos ou letras em seusinteriores. Cada celula e apontada por um endereco unico e sequencial.

A estrutura da memoria favorece a execucao de suas duas operacoes basicas: leitura e escrita.A leitura e o processo de consulta do conteudo da celula. Essa operacao nao altera o valorguardado na celula.

A escrita e o processo de armazenamento de um novo dado na celula indicada por umendereco conhecido. Apos a execucao da escrita, o valor que estava anteriormente armazenadona celula e perdido.

Um algoritmo para o calculo do valor da conta mensal de energia eletrica e um bom exemplopara compreender as operacoes basicas da memoria. Os dados de entrada desse algoritmo sao: aleitura atual do medidor, a leitura registrada no mes anterior e o preco do quilowatt-hora (kWh)— unidade comercial de energia eletrica.

Na pratica, o que se faz para calcular o valor da conta e encontrar a diferenca entre a leituraatual do medidor e a leitura do mes anterior e multiplicar esse valor pelo preco do quilowatt-hora.O algoritmo computacional, por sua vez, e descrito no Pseudocodigo 2.1.

No Pseudocodigo 2.1, o computador le os conteudos das celulas 43 e 46 (que guardam osvalores das leituras atual e anterior, respectivamente), realiza a subtracao e o resultado e guar-dado na celula 41. Posteriormente, essa diferenca e lida e seu valor multiplicado pelo conteudoda celula 44, que guarda o valor do preco unitario do kWh. Finalmente, o valor da conta eguardado na celula 42.

Acompanhando a descricao acima e possıvel chegar a situacao encontrada na Figura 2.2.Nos primordios da programacao, percebeu-se que acessar a memoria por meio de enderecos

era trabalhoso demais e causa constante de erros. Isso porque o programador deveria escolher osenderecos das celulas com as quais iria trabalhar, tanto das celulas que teriam valores a seremlidos quanto das que seriam usadas para a escrita de resultados.

Essa situacao confusa e observavel no exemplo da conta de energia eletrica. Sem o comentario

Page 20: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

20 CAPITULO 2. CONCEITOS BASICOS

Pseudocodigo 2.1 Calculo da conta de energia eletrica utilizando os enderecos das celulas dememoria.

Descricao: programa que calcula o valor da conta de energia eletrica.Dados de Entrada: celulas 43 e 46 contendo, respectivamente, a leitura atual e a anterior; e valorunitario do kWh na celula 44.Saıda do Programa: valor da conta, armazenada na celula 42.

Subtrair o conteudo da celula 43 do conteudo da celula 46 e guardar nacelula 41;

Multiplicar o conteudo da celula 41 pelo conteudo da celula 44 e guardar nacelula 42;

Figura 2.2: Conteudo da memoria apos execucao do algoritmo que calcula o valor de uma conta deenergia eletrica.

no inıcio do Pseudocodigo 2.1, seria impossıvel ter a mınima ideia do que o programa faz emcada passo. Isso torna difıcil nao so a escrita, mas tambem a correcao dos programas.

Para resolver essa questao, o conceito de variavel foi criado. Uma variavel nada mais e doque uma abstracao para o endereco de memoria. Com o emprego de variaveis, as celulas dememoria sao referenciadas nos programas por meio de rotulos, definidos com ajuda do bom-senso do programador. O compilador fica encarregado do trabalho de transformar rotulos emenderecos para que as operacoes de acesso a memoria sejam realizadas.

O Pseudocodigo 2.2 mostra como fica o programa que calcula o valor da conta de energiaeletrica, agora escrito utilizando variaveis.

Pseudocodigo 2.2 Calculo da conta de energia eletrica utilizando variaveis.

Descricao: programa que calcula o valor da conta de energia eletrica.Dados de Entrada: a leitura atual, a anterior e o preco unitario do kWh.Saıda do Programa: valor da conta.

Subtrair o conteudo da variavel ‘leituraAtual’ do conteudo da variavel‘leituraAnterior’ e guardar na variavel ‘diferenca’;

Multiplicar o conteudo da variavel ‘diferenca’ pelo conteudo da variavel‘valorUnitario’ e guardar na variavel ‘valorConta’;

A partir do Pseudocodigo 2.2, um compilador pode converter os rotulos para posicoes quais-quer na memoria, evitando que o programador tenha que se preocupar em manipula-las. Uma

Page 21: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.2. IDENTIFICADORES 21

Figura 2.3: Uma possıvel traducao para enderecos de memoria, a partir dos rotulos do codigo que utilizavariaveis.

possıvel traducao e exibida na Figura 2.3.Como visto nos exemplos desta secao, o uso de variaveis em um algoritmo reduz a quantidade

de comentarios explicativos, pois sua leitura e mais simples e seu entendimento e mais facil. Emcaso de erros, a correcao do programa e muito mais rapida e eficiente.

Apresentados os conceitos de variavel e celulas de memoria, e valido abordar um outrosignificado de programa. Trata-se de considerar os programas como sendo processos de mudancade estados.

Nessa abordagem, os dados de entrada, escritos em suas respectivas variaveis, sao conside-rados o estado inicial do programa. A partir daı, realiza-se uma sequencia de operacoes parachegar a um estado final. A cada operacao, diz-se que o programa esta em um novo estado in-termediario. O estado final e atingido quando a tarefa em questao e considerada como realizada.

A transicao do estado inicial para o estado final pode ser efetuada de diversas maneiras.Conforme pode ser visto mais adiante neste capıtulo, e possıvel escolher entre duas ou maissequencias de comandos, bem como repeti-las, de acordo com o estado intermediario em que oprograma se encontra.

2.2 Identificadores

Em geral, as linguagens de alto nıvel possuem dois tipos de elementos: os elementos definidospela propria linguagem — sımbolos para operadores, nome de comandos etc — e os elementosdefinidos pelo programador — identificadores, comentarios etc.

Um identificador e um sımbolo que pode representar alguma entidade criada pelo progra-mador, como uma variavel, por exemplo. Cada linguagem define uma regra para formacao deidentificadores. Em geral, sempre e possıvel utilizar uma sequencia de caracteres alfanumericos— letras ou dıgitos, sem acentos e sem cedilha — sendo que o primeiro caractere deve ser obri-gatoriamente alfabetico. Os Exemplos 2.1 e 2.2 apresentam, respectivamente, nomes corretos enomes invalidos de variaveis na linguagem C.

Algumas linguagens, como C, fazem diferenciacao entre letras maiusculas e minusculas.Desta forma, uma variavel de nome Saldo e considerada diferente de outra de nome saldo,ou, ainda, de nome SALDO. E importante ressalvar que nao e uma boa pratica de programacaocriar identificadores que apenas se diferenciem pelo formato das letras, como no exemplo dosaldo, pois isso tem impacto negativo na legibilidade dos programas.

Page 22: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

22 CAPITULO 2. CONCEITOS BASICOS

1 abc

2 x1

3 y2

4 letra

5 SOMA_TOTAL

6 B_32

Exemplo 2.1: Nomes validos de variaveis, concordando com as regras de nomenclatura.

1 fim? // ‘‘?’’ n~ao e um caractere alfanumerico

2 %percentual% // ‘‘%’’ n~ao e um caractere alfanumerico

3 123 quatro // Iniciado por numero

4 !hola! // ‘‘!’’ n~ao e um caracter alfanumerico

5 @ARROBA // ‘‘@’’ n~ao e um caractere alfanumerico

Exemplo 2.2: Nomes invalidos de variaveis.

Normalmente, em grandes projetos de software, sao adotados padroes para a escrita dosidentificadores a fim de que os programadores possam trocar seus codigos, entende-los e altera-los sem grande dificuldade. Neste texto, e adotado como regra na escrita:

• Nomes simples: comecados com letra minuscula e demais caracteres minusculos;

• Nomes compostos: primeira parte e iniciada por letra minuscula e as demais partes inici-adas por letra maiuscula. Os demais caracteres sao minusculos.

Como dito na Secao 1.5, um bom programa deve necessariamente ser legıvel e de facil com-preensao. A escolha dos nomes dos identificadores influenciam diretamente esses dois aspectos.Logo, e muito importante que os nomes sejam significativos, deixando bem clara a sua referencia.

A fim de contrastar com a declaracao de variaveis do Exemplo 2.1, o Exemplo 2.3 ilustraa convencao proposta, apresentando nomes significativos para variaveis. Neste, o rotulo dasvariaveis ja e suficiente para informar a funcionalidade das mesmas, tornando rapida a compre-ensao do programa que as utiliza e dispensando a necessidade de comentarios.

1 delta

2 raiz1

3 idade

4 letra

5 percentualDeLucro

6 primeiraLetra

7 indiceBovespa

Exemplo 2.3: Nomes significativos para variaveis.

Page 23: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.3. COMANDO DE ATRIBUICAO 23

2.3 Comando de Atribuicao

Os pseudocodigos da Secao 2.1 nao mostram como os conteudos das variaveis de entrada saoalterados para que o calculo seja efetuado coerentemente. Em outras palavras, nao se mostracomo as variaveis leituraAtual, leituraAnterior e valorUnitario sao inicializadas. O responsavelpela alteracao dessas variaveis, assim como de qualquer outra, e o comando de atribuicao.

O comando de atribuicao e muito importante e, com certeza, e o mais utilizado. E por meiodele que as variaveis podem ter seus valores (conteudos) alterados. Por isso, o comando deatribuicao esta diretamente ligado as operacoes de memoria.

No Exemplo 2.4 e transcrito o algoritmo do calculo da conta de energia eletrica para o codigode um programa na linguagem C.

1 main(){

2 leituraAtual = 125;

3 leituraAnterior = 25;

4 valorUnitario = 2;

5 diferenca = leituraAtual - leituraAnterior;

6 valorConta = diferenca * valorUnitario;

7 }

Exemplo 2.4: Calculo do valor da conta de energia eletrica.

No Exemplo 2.4, o sımbolo “=” representa o comando de atribuicao. Em seu lado esquerdosempre havera a variavel destino, na qual sera escrito o resultado da expressao do lado direitodo comando. As expressoes mais simples sao as que contem valores constantes, tais como as queocorrem nas linhas 1, 2 e 3 do Exemplo 2.4.

Essas tres linhas sao omitidas propositalmente do Pseudocodigo 2.2 para torna-lo mais sim-ples. Entretanto, elas nao sao difıceis de compreender, pois apenas informam ao computadorquais valores ele deve manipular para encontrar o resultado esperado: o valor da conta mensalde energia eletrica.

Dessa forma, o comando da linha 1 do Exemplo 2.4 simplesmente realiza a atribuicao do valor125 a variavel leituraAtual. A partir da efetivacao desse comando, o conteudo dessa variavelpode ser usado para os calculos. O mesmo vale para as demais variaveis.

As linhas 4 e 5 do Exemplo 2.4 sao transcricoes diretas dos dois passos do algoritmo daconta de energia. O que ocorre de diferente e que o valor a ser atribuıdo as variaveis do ladoesquerdo e primeiramente calculado na expressao para, em seguida, ser guardado na variavelcorrespondente. A Figura 2.4 representa graficamente essa passagem.

O comando de atribuicao e executado sempre da mesma maneira pelo computador. Emprimeiro lugar a expressao que esta do lado direito do comando e calculada e, para isso, todas asvariaveis que aparecem tem seus valores lidos e lancados na expressao. Apos o fim dos calculos naexpressao, o computador escreve o resultado na variavel destino, no lado esquerdo. Basicamente,a forma geral do comando de atribuicao e a seguinte:

<variavel> = <express~ao>;

Page 24: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

24 CAPITULO 2. CONCEITOS BASICOS

Figura 2.4: Representacao grafica da linha 4 do Exemplo 2.4.

E muito importante compreender a diferenca significativa existente entre o comando de atri-buicao e a igualdade matematica. Em muitas linguagens de programacao (C, por exemplo) aatribuicao e tambem representada pelo sımbolo “=”, o que pode provocar interpretacoes equi-vocadas. O Exemplo 2.5 mostra um trecho de programa que geralmente causa confusao para osprogramadores iniciantes.

1 contador = 10;

2 contador = contador + 1;

Exemplo 2.5: Incremento de uma variavel usando o comando de atribuicao.

No Exemplo 2.5 ocorrem duas atribuicoes. A primeira ocorre na linha 1, sendo mais umexemplo simples de inicializacao de uma variavel, como ja discutido anteriormente. Na linha 2,a variavel contador aparece em ambos os lados da expressao, o que pode parecer um absurdomatematico. Porem, e necessario lembrar que, nesse contexto, o sımbolo “=” atribui o valor daexpressao da direita a variavel que aparece a esquerda. Ou seja, avalia-se primeiro o resultadoda expressao a direita (10 + 1 = 11) e, posteriormente, atribui-se o valor a variavel a esquerda(contador = 11). Isso e representado graficamente na Figura 2.5.

Figura 2.5: Representacao grafica do incremento de uma variavel.

Mais uma observacao e necessaria: O programador deve ficar atento aos tipos de dadosmanipulados em um comando de atribuicao, pois o tipo da expressao a direita deve ser compatıvelcom o tipo da variavel a esquerda. A manipulacao dos tipos de dados e detalhada na Secao 2.4.

Page 25: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.4. TIPOS DE DADOS 25

2.4 Tipos de Dados

Um tipo de dados delimita o conjunto de valores possıveis que uma determinada variavel poderepresentar. Alem disso, define as operacoes basicas possıveis para suas variaveis.

Sua necessidade decorre do fato de que as celulas de memoria, sozinhas, conseguem represen-tar apenas conjuntos de dados muito limitados. Entretanto, a maioria dos valores de interessepertence a conjuntos extensos, os quais nao podem ser representados com o uso de apenas umacelula de memoria.

Os programadores, entao, passaram a utilizar multiplas celulas para representar um unicovalor. Essa atitude resolveu a dificuldade de armazenar dados complexos, mas criou um outraquestao: os processos de leitura e escrita para valores de multiplas celulas, bem como as de-mais operacoes sobre tais valores, exigiam codigos que, alem de nao-triviais, fugiam do foco doproblema principal.

Nao demorou para que as linguagens de programacao incorporassem a definicao dos tiposde dados e suas operacoes essenciais, poupando os programadores da tarefa de defini-los em seucodigo e tornando-o mais enxuto e legıvel.

Tipos de dados, portanto, abstraem a forma de implementacao e disponibilizam operacoessobre os elementos do conjunto para que o programador possa utiliza-las sem ter que implementa-las.

Os tipos basicos mais importantes sao o tipo inteiro, o ponto flutuante, o booleano e o tipocaractere. Cada linguagem de programacao possui certas particularidades em relacao aos tiposde dados.

Primeiramente, e preciso abordar um conceito imprescindıvel da escrita de programas emlinguagem C: a declaracao de variaveis. Em seguida, sao descritas as caracterısticas mais comunsdos tipos basicos principais.

2.4.1 Declaracao de Variaveis

De acordo com o problema abordado, diferentes conjuntos de dados sao necessarios. Conformevisto, os tipos de dados representam os conjuntos de valores possıveis para suas variaveis, assimcomo as operacoes validas sobre elas. Tambem ja foram abordadas a necessidade e as vantagensdo uso de variaveis em um programa. Entretanto, ainda nao foi mencionado como as variaveissao criadas, ou seja, como o programador declara formalmente uma variavel em seu codigo.

Na linguagem C, o ato de declarar uma variavel e simples e imprescindıvel. Afinal, semesse procedimento, nao e possıvel usa-la. Quando a declaracao de variaveis e esquecida, umamensagem de erro e apresentada ao programador, e a compilacao do codigo e interrompida. Porisso, toda variavel deve ser declarada antes de ser utilizada.

A declaracao de variaveis tem uma estrutura simples e algumas regras basicas. Em primeirolugar, escreve-se o nome do tipo de dados ao qual a variavel pertence. Em seguida, separadopor um espaco em branco, escreve-se o identificador da variavel.

<tipo> <identificador>;

Page 26: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

26 CAPITULO 2. CONCEITOS BASICOS

E possıvel declarar mais de uma variavel em uma mesma linha, desde que todas sejam do mesmotipo, conforme o Exemplo 2.6.

1 float valorFracionado , saldo , salarioMinimo;

2 char letra , ultimaLetra;

3 int entrada1 , entrada2 , entrada3;

Exemplo 2.6: Declaracao multipla de variaveis em uma mesma linha de codigo.

2.4.2 Tipo Inteiro

O tipo inteiro, como o proprio nome sugere, representa um intervalo finito do conjunto ma-tematico dos numeros inteiros.

De fato, uma linguagem de programacao pode definir varios tipos inteiros, cada um comintervalo diferente. Na linguagem C, por exemplo, existem varios tipos inteiros, tais como o int,long int, unsigned int, short int. Neste livro, para bem da simplicidade, usa-se apenas o tipoint.

O intervalo de valores para o tipo int depende do compilador que esta sendo empregado.Assumimos aqui que o intervalo do tipo int sempre varia de entre −32768 a 32767.

Em C, como na maioria das linguagens, as operacoes sobre as variaveis do tipo inteiro jaestao implementadas e a disposicao do programador. As operacoes disponıveis sao as de soma,subtracao, multiplicacao, divisao e resto de divisao, conforme o Exemplo 2.7.

O uso dessas funcoes e bastante simples e intuitivo, pois ha ate certa relacao com os sımbolosda escrita matematica. No Exemplo 2.7, as variaveis x e y sao relacionadas entre si e os resultadossao armazenados nas variaveis de a a f.

Os operadores de soma e subtracao funcionam tal qual na aritmetica. O operador de sub-tracao pode ser aplicado para um unico valor quando se deseja inverter seu sinal. A linha 12 doExemplo 2.7 mostra essa situacao.

Um destaque deve ser dado ao operador de multiplicacao. Seu unico sımbolo e “*” (nao hao sımbolo “×” ou o “·”). Alem disso, em oposicao ao que ocorre na aritmetica, a escrita do “*”nao pode ser omitida. Logo, a operacao da linha 13 do Exemplo 2.7 geraria erro se nao estivessecomentada, pois o compilador trataria xy como uma variavel nao declarada.

1 main(){

2 int x, y, a, b, c, d, e, f;

3

4 x = 10;

5 y = 3;

6

7 a = x + y; // a armazena 13

8 b = x - y; // b armazena 7

9 c = x * y; // c armazena 30

10 d = x / y; // d armazena 3

11 e = x % y; // e armazena 1

Page 27: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.4. TIPOS DE DADOS 27

12 f = -a; // f armazena -13

13 // c = xy;

14 }

Exemplo 2.7: Operacoes basicas com o tipo inteiro int.

Tambem e importante destacar o resultado da operacao de divisao. No caso do Exemplo2.7, o resultado correto da divisao de x — que armazena o valor 10 — por y — cujo valor e 3— e a dızima periodica 3, 333 . . . Entretanto, como as variaveis envolvidas na linha 10 sao todasdo tipo inteiro, o compilador trata de truncar o resultado, desconsiderando a parte decimal efornecendo 3 como resultado da operacao.

Ainda no Exemplo 2.7, deve-se notar o uso do operador de resto de divisao inteira. Seusımbolo — “%” — deve ficar entre os valores do dividendo e do divisor. A linha 11 mostra aobtencao do resto da divisao de x por y. Apos a execucao dessa operacao, a variavel e guardarao valor 1, que e o resto da divisao de 10 por 3.

2.4.3 Tipo Ponto Flutuante

Esse tipo de dados representa um intervalo dos numeros racionais. Assim como o tipo inteiro,ha mais do que um intervalo possıvel, dependendo da precisao escolhida.

Na linguagem C, os tipos de ponto flutuante sao o float e o double. Neste livro, apenas otipo float e empregado.

Dependendo do compilador utilizado, os tipos de dados de ponto flutuante apresentam dife-rentes precisoes. Aqui se considera que o tipo float prove seis casas decimais de precisao.

As operacoes pre-definidas sao as mesmas que as disponıveis para o tipo int, exceto, e claro,pela inexistencia do operador de resto de divisao. O Exemplo 2.8 mostra o uso de variaveis dotipo float em um programa.

1 main(){

2 float p, q, x, z;

3 int y;

4

5 x = 10;

6 y = 4;

7

8 p = 50 / 30; // p guardara 1

9 q = 10.0 / 4; // q guardara 2.5

10

11 z = x / y; // z guardara 2.5

12 }

Exemplo 2.8: Operacoes com variaveis do tipo float.

As operacoes entre variaveis do tipo float sao escritas com os mesmos sımbolos das operacoesdo tipo int. O Exemplo 2.8 mostra particularidades do processo de compilacao que podem gerarerros nos programas.

Page 28: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

28 CAPITULO 2. CONCEITOS BASICOS

A linha 8 do Exemplo 2.8 possui um comentario explicando que a variavel p recebe 1 comoresultado da operacao de divisao. Tal erro nao ocorre para a divisao da linha seguinte. Ajustificativa para essa situacao e que, conforme e mostrado na Secao 2.3, o computador primeirocalcula o resultado da expressao do lado direito do comando de atribuicao para, em seguida,escrever esse valor na correspondente variavel de destino.

Durante a compilacao, o compilador checa os tipos das variaveis envolvidas nos calculospara realizar as operacoes correspondentes. Entretanto, quando ha apenas valores numericosenvolvidos, o compilador considera os numeros escritos sem ponto decimal como sendo do tipointeiro. E por isso que a divisao realizada na linha 8 do Exemplo 2.8 resulta em 1. O computadorentende a operacao 50/30 como uma divisao inteira, descartando a parte decimal do resultado.Ja na linha 9, o compilador enxerga o valor 10.0 como sendo do tipo float devido a presencaexplıcita do ponto decimal, e realiza a divisao, resultando no valor esperado.

No caso da ultima linha do Exemplo 2.8, nenhum resultado inesperado ocorre porque otipo mais abrangente — tipo float da variavel x — encontrado na expressao e considerado nasoperacoes, garantindo o resultado esperado. Caso a variavel x tambem fosse do tipo int, entaoo mesmo incoveniente da linha 8 ocorreria.

2.4.4 Tipo Booleano

O tipo booleano e o tipo de dados mais simples. Ele contem apenas dois valores possıveis:verdadeiro e falso. E usado principalmente quando se precisa verificar condicoes no programa,em expressoes logicas (Secao 2.6.3) e relacionais (Secao 2.6.2).

Na linguagem C nao ha uma representacao especıfica para esse tipo de dados e sao utilizadosvalores inteiros para codifica-lo. Desta forma, todo valor inteiro diferente de zero e consideradovalor “verdadeiro”. O valor zero e considerado “falso”.

2.4.5 Tipo Caractere

Como o proprio nome indica, o tipo caractere registra os codigos para letras, numeros e caracteresespeciais ($, &, #, @ etc). Normalmente, esses codigos e caracteres variam para as diversasregioes do planeta, conforme suas particularidades linguısticas. Um padrao largamente utilizadoatualmente, pricipalmente no Ocidente, e o ASCII (American Standard Code of InformationInterchange — Padrao Americano para Intercambio de Informacoes), especificado pelo ANSI(American National Standars Institute — Instituto Americano Nacional de Padroes).

O padrao ASCII e uma tabela. Cada posicao da tabela simboliza um caractere. Na linguagemC, o tipo char e empregado para conter o ındice para a posicao da tabela que codifica umdeterminado caractere.

Originalmente, essa tabela era composta por apenas 128 sımbolos, os quais incluıam todos oscaracteres alfanumericos do Ingles, sinais de pontuacao e alguns outros sımbolos. Os primeiros 32caracteres eram utilizados para controle de fluxo de dados (em comunicacoes entre o computadore seus perifericos) e nao imprimıveis. Atualmente, esses caracteres caıram em desuso. A Tabela2.1 mostra os 128 caracteres da tabela ASCII original.

Page 29: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.4. TIPOS DE DADOS 29

Codigo Caractere Codigo Caractere Codigo Caractere Codigo Caractere

0 NUL (null) 32 SPACE 64 @ 96 `

1 SOH (start of heading) 33 ! 65 A 97 a

2 STX (start of text) 34 ” 66 B 98 b

3 ETX (end of text) 35 # 67 C 99 c

4 EOT (end of transmission) 36 $ 68 D 100 d

5 ENQ (enquiry) 37 % 69 E 101 e

6 ACK (acknowledge) 38 & 70 F 102 f

7 BEL (bell) 39 ’ 71 G 103 g

8 BS (backspace) 40 ( 72 H 104 h

9 HT (horizontal tab) 41 ) 73 I 105 i

10 LF (NL line feed,new line) 42 * 74 J 106 j

11 VT (vertical tab) 43 + 75 K 107 k

12 FF (NP from feed,new page) 44 , 76 L 108 l

13 CR (carriage return) 45 - 77 M 109 m

14 SO (shift out) 46 . 78 N 110 n

15 SI (shift in) 47 / 79 O 111 o

16 DLE (data link escape) 48 0 80 P 112 p

17 DC1 (device control 1) 49 1 81 Q 113 q

18 DC2 (device control 2) 50 2 82 R 114 r

19 DC3 (device control 3) 51 3 83 S 115 s

20 DC4 (device control 4) 52 4 84 T 116 t

21 NAK (negative acknowledge) 53 5 85 U 117 u

22 SYN (synchronous idle) 54 6 86 V 118 v

23 ETB (end of trans. block) 55 7 87 W 119 w

24 CAN (cancel) 56 8 88 X 120 x

25 EM (end of medium) 57 9 89 Y 121 y

26 SUB (substitute) 58 : 90 Z 122 z

27 ESC (escape) 59 ; 91 [ 123 {28 FS (file separator) 60 < 92 \ 124 |29 GS (group separator) 61 = 93 ] 125 }30 RS (record separator) 62 > 94 ˆ 126 ˜

31 US (unit separator) 63 ? 95 127 DEL

Tabela 2.1: Os 128 caracteres da tabela ASCII original.

Com o passar do tempo, a tabela ASCII sofreu modificacoes. Ela foi atualizada e incorporoumais 128 novos sımbolos, os quais incluem, por exemplo, os caracteres acentuados e o cedilha,do Portugues. Essa nova versao e conhecida como tabela ASCII estendida.

Para fazer com que uma variavel do tipo char aponte para um sımbolo de interesse, oprogramador precisa apenas atribuir a essa variavel o caractere desejado, colocando-o entreaspas simples. O Exemplo 2.9 exibe essa situacao.

1 main(){

2 char letraA , letraFMaiuscula , simboloSoma;

3

4 letraA = ‘a’;

Page 30: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

30 CAPITULO 2. CONCEITOS BASICOS

5 letraFMaiuscula = ‘F’;

6 simboloSoma = ‘+’;

7 }

Exemplo 2.9: Uso de variaveis do tipo caractere.

2.4.6 Conversao de Tipos

Agora, conhecidas algumas informacoes sobre os tipos de dados basicos, torna-se mais simplescompreender o problema existente na atribuicao entre tipos diferentes, mencionada na Secao2.3.

Considera-se que os tipos int, float e char ocupam a quantidade de memoria representadana Figura 2.6.

Figura 2.6: Tamanho da memoria utilizada pelos tipos de dados basicos.

As diferencas nos tamanhos sao justificaveis, uma vez que, quanto maior o conjunto a serrepresentado, mais celulas de memoria sao necessarias para acomodar uma variavel. Destaforma, sendo o conjunto dos caracteres o menor, e preciso apenas um byte (uma celula) pararepresenta-lo. Ja o conjunto do tipo float, que e o maior dos tres, precisa de 4 bytes (4 celulas)para uma representacao coerente de seus valores.

E preciso ter em mente que, devido a essas restricoes de implementacao, nao se deve utili-zar operacoes de atribuicao entre variaveis sem tomar algum cuidado. Se elas forem de tiposdiferentes, problemas podem acontecer.

Nao ha problemas em atribuir uma variavel do tipo int a outra do tipo float. Tal qual ocorrena matematica, toda variavel do tipo int e possıvel de ser representada por outra do tipo float,pois o conjunto dos numeros racionais contem o conjunto dos inteiros. Um raciocınio similarpode ser empregado para justificar as atribuicoes de variaveis char a variaveis de tipo int oufloat, que tambem ocorrem sem erros.

O problema e quando se tenta atribuir uma variavel de um conjunto mais amplo a uma deum conjunto mais restrito. Veja o Exemplo 2.10.

Observando o Exemplo 2.10, um programador distraıdo pode pensar que houve uma atri-buicao correta. Entretanto, o valor armazenado pela variavel teste e 125. Nao havendo condicoesde armazenar corretamente (um codigo de 4 bytes nao pode ser escrito num espaco de apenas2 bytes), o compilador simplesmente descarta a parte decimal do numero, armazenando apenas

Page 31: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.5. CONSTANTES 31

sua parte inteira na variavel. Logo, e preciso permanecer atento as atribuicoes desse tipo paranao se equivocar sobre o valor armazenado por uma variavel.

1 main(){

2 int teste;

3

4 teste = 125.568;

5 }

Exemplo 2.10: Atribuicao entre tipos diferentes com perda de informacao.

2.5 Constantes

Em algumas situacoes surge a necessidade de se utilizar um determinado valor constante emdiversas partes do codigo. Para simplificar a alteracao dessas constantes e facilitar a leitura docodigo, e possıvel definir um nome signicativo para elas de maneira simples, por meio de umaestrutura especıfica.

Essa estrutura e iniciada pela diretiva #define, seguida pelo identificador da constante epelo seu respectivo valor, todos separados por um espaco em branco.

#define <identificador> <valor>

Na linguagem C, a declaracao de constantes deve ser feita no inıcio do codigo, antes da funcaomain . O Exemplo 2.11 apresenta declaracoes validas de constantes.

1 #define PI 3.141593

2 #define FALSO 0

3 #define VERDADEIRO 1

4 #define RAIZDEDOIS 1.414214

5

6 main(){

7 float raio , comprimento , area;

8

9 raio = 10;

10 area = PI * raio * raio;

11 comprimento = 2 * PI * raio;

12 }

Exemplo 2.11: Definicao de constantes.

Na declaracao de constantes, a escolha dos nomes segue as mesmas regras para a escrita dosnomes de variaveis. Geralmente, para diferenciar as constantes no codigo, opta-se por escreverseus nomes com todas as letras maiusculas.

O Exemplo 2.11 mostra um exemplo simples onde diversas constantes sao declaradas deacordo com a convencao proposta. Durante a compilacao do codigo, o compilador troca tocasas ocorrencias da constante PI por seu respectivo valor, definido na linha 1.

Page 32: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

32 CAPITULO 2. CONCEITOS BASICOS

2.6 Expressoes

As variaveis e constantes podem ser combinadas com os operadores associados a cada tipo dedados, gerando expressoes.

2.6.1 Expressoes Aritmeticas

A expressao aritmetica e aquela cujos operadores e operandos sao de tipos numericos (int oufloat, por exemplo).

Nas operacoes aritmeticas, e guardada sempre a seguinte relacao de prioridade:

1. Multiplicacao, divisao e resto de divisao;

2. Adicao e subtracao.

Para se obter uma sequencia diferente de calculos, varios nıveis de parenteses podem serusados para quebrar as prioridades definidas. Nao e permitido o uso de colchetes e chaves, umavez que estes sımbolos ja sao utilizados com outras finalidades. O Exemplo 2.12 exibe uma seriede expressoes aritmeticas validas.

1 main(){

2 int x, y, z;

3

4 x = 10 * 10 + 25; // x = 125

5 y = 5 * (7 + 3); // y = 50

6 z = 10 * ((x - 25) / y + (x - 25) * 2); // z = 2020

7 }

Exemplo 2.12: Expressoes aritmeticas e o uso de parenteses para determinar a precedencia dasoperacoes.

No Exemplo 2.12, e importante notar que, no comando de atribuicao a variavel x, a multi-plicacao 10 × 10 e executada primeiro. Na linha seguinte, a soma 7 + 3 e executada primeiroe seu valor e, em seguida, multiplicado por 5 e atribuıdo a variavel y. A analise da linha 6 edeixada para o leitor.

Alem das operacoes basicas ja citadas, e possıvel usar, nas expressoes aritmeticas, outrasoperacoes bastante comuns na matematica, definidas dentro da linguagem na forma de funcoes.A sintaxe geral para o uso dessas funcoes e a seguinte:

<nome da func~ao>(<valor>)

Algumas funcoes matematicas sao mostradas na Tabela 2.2.O Exemplo 2.13 exibe varios usos de funcoes matematicas e expressoes aritmeticas.

Page 33: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.6. EXPRESSOES 33

Nome Descricaoabs Modulo ou valor absoluto de um valor inteirofabs Modulo ou valor absoluto de um valor racionalsin Seno de um angulo em radianoscos Cosseno de um angulo em radianossqrt Raiz quadrada de um numeropow Potenciacaofloor Maior inteiro nao maior que o numero de entradaceil Menor inteiro nao menor que o numero de entradalog Logaritmo neperianoexp Exponencial

Tabela 2.2: Principais funcoes matematicas ja definidas na linguagem C.

1 #include <math.h>

2

3 #define PI 3.1415

4

5 main(){

6 float a, b, c, delta , raiz1 , raiz2;

7 float x, y, z;

8

9 a = 10;

10 b = 50;

11 c = 30;

12

13 delta = b * b - 4 * a * c;

14 raiz1 = -b + sqrt(delta) / (2 * a);

15 raiz2 = -b - sqrt(delta) / (2 * a);

16

17 x = sin(-PI / 2);

18 y = fabs(x);

19 z = pow(y,2); // y elevado a potencia 2

20 }

Exemplo 2.13: Uso de funcoes matematicas pre-definidas.

Para o uso das funcoes matematicas apresentadas no Exemplo 2.13 e necessario a inclusaoda biblioteca math.h, como na linha 1. Os mesmos calculos para a procura das raızes de umaequacao de segundo grau sao executados nas linhas 13 a 15, onde a funcao sqrt calcula a raizquadrada do seu operando — a variavel delta. Ja as linhas 15 a 17 apresentam calculos avulsos:a linha 17 executa o calculo do seno de −π/2 e armazena o resultado na variavel x; a linha18 armazena, na variavel y, o modulo do valor armazenado em x; e a linha 19 calcula o valorarmazenado em y elevado a potencia de 2 e armazena o resultado na variavel z.

Page 34: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

34 CAPITULO 2. CONCEITOS BASICOS

2.6.2 Expressoes Relacionais

As expressoes relacionais comparam valores entre si. Tal qual se faz na pratica, o operadorrelacional trabalha com dois valores: o da expressao que esta a sua direita e o da expressao queesta a sua esquerda. E importante destacar que uma variavel ou uma constante isolada, por siso, pode ser considerada uma expressao.

A Tabela 2.3 mostra exemplos de operadores relacionais da linguagem C e alguns casos deuso.

Sımbolo Nome Exemplo< menor que a < 10<= menor ou igual a x <= y== igual a 4 == 2*2> maior que t > 0>= maior ou igual a delta >= 0!= diferente de x != 9+8*8

Tabela 2.3: Operadores relacionais.

As expressoes relacionais resultam sempre em 0 (zero) para uma comparacao falsa ou 1 parauma comparacao verdadeira.

As variaveis do tipo char tambem podem ser comparadas entre si, respeitando a ordenacaodo padrao de codificacao utilizado.

E importante atentar que, embora sejam escritos de maneira parecida, ha uma grande dife-renca entre o operador de comparacao “==” e o comando de atribuicao “=”. Essa semelhanca euma fonte comum de erros de programacao, geralmente difıceis de detectar.

2.6.3 Expressoes Logicas

As expressoes logicas sao utilizadas para relacionar os resultados de um conjunto de operacoesrelacionais. Elas realizam as principais operacoes da logica booleana e, na linguagem C, temcomo operadores:

• “&&” (AND): Realiza o “E” logico;

• “||” (OR): Realiza o “OU” logico;

• “!” (NOT): Realiza a negacao.

Os resultados obtidos das expressoes logicas tambem sao valores do tipo inteiro: 0 para falsoe 1 para verdadeiro.

Para melhor entender o que cada operador realiza, sao levados em conta dois valores P e Qde entrada, que podem ser verdadeiros (V) ou falsos (F). A Tabela 2.4 resume todos os casospossıveis.

Page 35: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.7. COMANDO DE ENTRADA DE DADOS 35

P Q P && Q P || Q !P !QV V V V F FV F F V F VF V F V V FF F F F V V

Tabela 2.4: Todas as combinacoes possıveis para os operadores logicos.

O uso dos operadores relacionais e logicos fica bem mais claro adiante, neste capıtulo, quandoos comandos de selecao e repeticao sao estudados.

2.7 Comando de Entrada de Dados

O comando de entrada de dados serve para captar do usuario do programa um ou mais valoresnecessarios para a execucao das tarefas. Na verdade, o que se faz e ler os dados de uma fonteexterna, normalmente do teclado, para depois usa-los de alguma maneira dentro do programa.

Por meio desse comando de leitura de dados, uma ou mais variaveis podem ter seus valoreslidos durante a execucao do programa. Essa caracterıstica permite criar programas mais flexıveis.

Na linguagem C, a sintaxe para o uso do comando e a seguinte:

scanf("<formato1> <formato2> ... <formatoN>", &var1, &var2, ..., &varN);

Essa estrutura e dividida em duas partes distintas. A primeira, colocada entre aspas duplas,contem os formatos, os quais sao relacionados diretamente com os tipos das variaveis a seremlidas. A segunda parte e uma lista dos nomes dessas variaveis, com uma relacao direta entrea posicao nessa lista e o respectivo formato descrito na primeira parte do comando. Conformemostra a descricao da sintaxe, os nomes das variaveis devem ser precedidos pelo caractere “&”.

A Tabela 2.5 mostra alguns dos possıveis formatos.

Codigo Significado%c Le um unico caracter%d Le um inteiro decimal%f Le um numero em ponto flutuante

Tabela 2.5: Codigos para formatos de dados do comando de entrada scanf .

Um exemplo claro da utilidade do comando de entrada de dados e o calculo da conta deenergia eletrica. O exemplo apresentado ate agora tinha os valores de consumo e do preco doquilowatt-hora escritos diretamente no codigo. Isso e bastante incomodo, pois, quando se quercalcular o valor de uma conta diferente, o codigo deve ser alterado e recompilado.

Uma maneira de tornar o programa mais flexıvel e utilizar o comando de entrada de dados.Com ele, e possıvel digitar os valores desejados para as variaveis e efetuar os calculos para

Page 36: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

36 CAPITULO 2. CONCEITOS BASICOS

diferentes contas, bastando, para isso, executar novamente o programa. O codigo modificado eexibido no Exemplo 2.14.

De acordo com o formato descrito no comando de leitura, os valores das variaveis leituraA-tual, leituraAnterior e valorUnitario devem ser digitados pelo usuario, nesta ordem, separadospor espacos em branco.

1 #include <stdio.h>

2 main(){

3 int leituraAtual , leituraAnterior , diferenca;

4 float valorUnitario , valorConta;

5

6 scanf("%d %d %f", &leituraAtual , &leituraAnterior , &valorUnitario);

7 diferenca = leituraAtual - leituraAnterior;

8 valorConta = diferenca * valorUnitario;

9 }

Exemplo 2.14: Emprego do comando de entrada de dados para o algoritmo do Exemplo 2.4.

Observando o codigo do Exemplo 2.14, e importante ressaltar que nao ha mais a parte deinicializacao das variaveis. Essa tarefa foi substituıda pelo comando de entrada de dados e osvalores sao, agora, passados pelo usuario do programa. Esses valores podem ser alterados a cadaexecucao do programa para que varias contas diferentes possam ser calculadas.

2.8 Comando de Saıda de Dados

Ate agora, os exemplos de codigos e os conceitos estudados nao mostravam como os programascomunicavam seus resultados ao usuario ou ate mesmo a outros programas. Esse e o papel docomando de saıda de dados.

O comando de saıda de dados serve para escrever mensagens e exibir valores de variaveis,proporcionando mais informacao e legibilidade tanto para o usuario quanto para o proprio pro-gramador.

Na linguagem C, a sintaxe para o uso do comando de saıda e mostrada a seguir.

printf("<formato1> <formato2> ... <formatoN>", var1, var2, ..., varN);

A estrutura do comando de saıda de dados e bastante semelhante a do comando de entrada.A principal diferenca e sobre o uso do caractere “&”. No comando de saıda, o caractere “&”nao deve ser escrito a frente dos identificadores das variaveis. A segunda parte do comando eopcional, conforme e mostrado logo adiante nesta secao.

A Tabela 2.6 mostra alguns dos possıveis formatos a serem usados.Conforme ja mencionado, o comando de saıda e muito utilizado para exibir mensagens para

o usuario. Nao e obrigatorio que as mensagens contenham apenas valores ou caracteres armaze-nados em variaveis, sendo possıvel escrever textos como mensagem. O Exemplo 2.15 demonstraessa possibilidade.

Page 37: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.8. COMANDO DE SAIDA DE DADOS 37

Codigo Significado%c Caracter%d Inteiros decimais com sinal%e Notacao cientıfica%f Ponto flutuante decimal%% Escreve o sımbolo “%”

Tabela 2.6: Codigos para formatos de dados para o comando de saıda printf .

1 #include <stdio.h>

2

3 main(){

4 printf("Bom dia a todos!");

5 printf("Outra mensagem");

6 }

Exemplo 2.15: Escrevendo mensagens para o usuario do programa.

Pode-se, ainda, mesclar uma mensagem de texto com valores de variaveis. O Exemplo 2.16ilustra essa ideia. Nele, e possıvel notar que, para cada especificador de formato na primeiraparte do comando, deve existir uma variavel de tipo correspondente posicionada adequadamentena segunda parte.

1 printf("Valor do saldo: %f", saldo);

2 printf("A metade de %d vale %d", numero , metade);

3 printf("O menor numero digitado foi %d", menor);

Exemplo 2.16: Escrevendo mensagens que incluem valores de variaveis.

Uma versao mais completa do codigo para o calculo da conta de energia eletrica e exibida noExemplo 2.17. Nele, o comando de saıda e usado antes de cada comando de entrada de dados(linhas 5, 8 e 11), escrevendo mensagens para indicar ao usuario do programa qual valor eledevera informar. A ultima linha de codigo utiliza o comando de saıda para exibir o valor docalculo da conta. Trata-se de uma mensagem mista, em que o especificador %f sera substituıdopelo valor da variavel valorConta. Supondo que, apos os calculos, essa variavel armazene o valor187, a ultima mensagem exibida na tela seria:

Valor da conta: R$ 187.000000

1 #include <stdio.h>

2

3 main(){

4 int leituraAtual , leituraAnterior , diferenca;

5 float valorUnitario , valorConta;

Page 38: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

38 CAPITULO 2. CONCEITOS BASICOS

6

7 printf("Digite o valor da leitura ATUAL: ");

8 scanf("%d", &leituraAtual);

9

10 printf("Digite o valor da leitura ANTERIOR: ");

11 scanf("%d", &leituraAnterior);

12

13 printf("Digite o preco do Quilowatt -hora: ");

14 scanf("%f", &valorUnitario);

15

16 diferenca = leituraAtual - leituraAnterior;

17 valorConta = diferenca * valorUnitario;

18

19 printf("Valor da conta R$: %f", valorConta);

20 }

Exemplo 2.17: Algoritmo mais interativo para o exemplo de calculo da conta de energia eletrica.

Quando se usa o comando printf , o caractere especial “\n” e bastante util. Ele serve paraquebrar a linha exatamente na posicao onde for inserido no texto. A Tabela 2.7 explica melhoro funcionameto desse caractere.

Codigo Resultadoprintf("OI.\nComo vai?"); OI.

Como vai?int x; O valor de x eh:x = 10; 10printf("O valor de x eh:\n%d", x);int a; Primeira linha.a = 20; Segunda linha (a = 20).printf("Primeira linha.\nSegunda linha (a = %d). \n\nFIM.", a);

FIM.

Tabela 2.7: Exemplos de uso do caractere especial “\n”.

2.9 Comandos de Selecao

O comando de selecao permite que um programa possa realizar diferentes alternativas de sequenciasde instrucoes durante sua execucao. Dependendo do valor de uma expressao ou de uma variavel,o programa segue executando uma ou outra sequencia de comandos.

Existem tres categorias distintas: selecao simples, selecao dupla e selecao multipla, as quaissao abordadas a seguir.

Page 39: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.9. COMANDOS DE SELECAO 39

2.9.1 Comando de selecao simples

E possıvel imaginar diversas situacoes cotidianas que se assemelham ao comportamento docomando de selecao simples. Uma comparacao classica leva em conta a tomada de um desviodurante uma viagem.

Quando se vai de carro para algum lugar, e normal se conhecer uma rota sequenciada delugares intermediarios pelos quais se passa antes de chegar ao destino. Entretanto, e possıvelque ocorra algum imprevisto e seja necessario tomar um desvio.

Ha tarefas computacionais que tambem se deparam com tais cenarios. Antes de exemplificar,e melhor apresentar a estrutura do comando de selecao simplificado. Ela pode ser observada aseguir.

if(<express~ao logica>){<sequencia de comandos>

}

Nao e difıcil entende-la. Quando o computador executa esse comando, o que e realizado emprimeiro lugar e o teste da expressao logica. Se ela resultar “verdadeiro”, entao a sequencia decomandos e executada. Caso contrario, o programa segue executando normalmente as instrucoesposteriores.

Desta forma, a decisao de desviar a execucao normal do programa e condicionada ao resultadoda expressao logica escrita no inıcio do comando.

O uso do comando de selecao simples e exibido no Pseudocodigo 2.3, o qual descreve umalgoritmo que faz a leitura de dois numeros inteiros e os imprime como foram digitados e,tambem, em ordem crescente.

Pseudocodigo 2.3 Ordena dois numeros inteiros digitados pelo usuario.

Descricao: Algoritmo para imprimir, em ordem crescente, dois numeros inteiros digitados pelo usuario.Dados de Entrada: dois numeros inteiros.Saıda do Programa: numeros inteiros impressos na ordem em que foram digitados e em ordem cres-cente.

Func~ao Principal:Leia dois valores inteiros.Imprima os valores coletados.SE o primeiro numero lido for maior que o segundo ENT~AO

Ordene os valores.FIM-SEImprima os valores ordenados.

FIM-Func~ao Principal

No Pseudocodigo 2.3, a operacao SE-ENTAO e executada tal qual o comando de selecaosimples if. O Exemplo 2.18 apresenta um codigo em linguagem C para o algoritmo do referidopseudocodigo.

Page 40: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

40 CAPITULO 2. CONCEITOS BASICOS

1 #include <stdio.h>

2 main(){

3 int num1 , num2 , aux;

4

5 printf("Digite dois numeros inteiros separados por espacos: ");

6 scanf("%d %d", &num1 , &num2);

7 printf("Valores digitados: %d %d.\n", num1 , num2);

8

9 if(num1 > num2){

10 aux = num1;

11 num1 = num2;

12 num2 = aux;

13 }

14 printf("Valores ordenados: %d %d.\n", num1 , num2);

15 }

Exemplo 2.18: Comando if simplificado.

O Exemplo 2.18 inicia exibindo uma mensagem ao usuario (linha 5), solicitando que sejamdigitados dois numeros. Esses valores sao armazenados em variaveis correspondentes (linha 6)e, em seguida, sao mostrados ao usuario por meio de uma mensagem (linha 7). A expressaologica do comando de selecao da linha 9 determina se ha necessidade de inverter os numerosantes de exibi-los ordenadamente. E importante ressaltar que nao ha necessidade de ordenar osnumeros caso o usuario ja os tenha digitado na sequencia correta. Nesse caso, o programa podeseguir normalmente e exibir na tela os valores das variaveis. Por ultimo, os valores sao exibidosem ordem crescente (linha 14).

Ainda no Exemplo 2.18, as linhas 10, 11 e 12 sao importantes o bastante para serem destaca-das. Elas tratam da operacao de troca de valores entre duas variaveis, a qual e muito utilizadae deve ser bem entendida.

O comando de atribuicao e ideal para copiar o valor de uma variavel para outra. A questao eque a variavel de destino tem seu valor alterado permanentemente apos a realizacao do comando.Ou seja, o valor que estava escrito nessa variavel antes da execucao da atribuicao e apagado e onovo valor e escrito em seu lugar.

No caso da operacao de troca de valores, se fossem usadas apenas as duas variaveis envolvidas,uma delas teria seu valor perdido quando a primeira atribuicao fosse realizada. Esse problemaocorre no Exemplo 2.19, no qual o valor inicial da variavel var1 e perdido.

1 main(){

2 int var1 , var2;

3

4 var1 = 100;

5 var2 = 200;

6

7 var1 = var2; // var1 guarda 200

8 var2 = var1; // var2 guarda 200

9 }

Page 41: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.9. COMANDOS DE SELECAO 41

Exemplo 2.19: Tentativa equivocada de trocar os valores de duas variaveis.

A solucao para o problema da perda de valores e simples e pode ser encontrada nas linhas10, 11 e 12 do Exemplo 2.18. Basta usar uma variavel auxiliar e copiar para ela o valor daprimeira variavel de destino usada nas atribuicoes. Naquele exemplo, o valor da variavel num1foi salvo na variavel aux para nao ser perdido na atribuicao da linha 11. Em seguida, esse valorpode ser copiado corretamente para a variavel num2 na linha 12.

2.9.2 Comando de selecao dupla

O comando de selecao dupla pode ser comparado com a bifurcacao de um caminho. E precisoescolher uma das alternativas e segui-la.

Em programacao, o comando de selecao dupla serve para executar sempre uma de duasalternativas de sequencias de instrucoes, de acordo com a verificacao de uma condicao. Aestrutura do comando na linguagem C e mostrada a seguir.

if (<express~ao logica>){<Sequencia de comandos 1>

}else{<Sequencia de comandos 2>

}

Primeiramente, o computador testa a expressao logica. Caso resulte “verdadeiro”, entao asequencia de comandos 1 e executada. Caso contrario, a sequencia de comandos 2 e realizada.Assim, apenas uma e sempre uma das sequencias de comandos e executada durante uma mesmarealizacao do comando de selecao dupla.

Apos a operacao de uma das sequencias de comando, o programa continua sua execucao naprimeira linha de codigo apos o conjunto de instrucoes do comando de selecao.

Para exemplificar o uso do comando de selecao dupla, o algoritmo do Pseudocodigo 2.4mostra como se faz para decidir se um aluno esta aprovado em uma disciplina, com base namedia de suas notas semestrais.

O comando SE-ENTAO-SENAO do Pseudocodigo 2.4 deve ser interpretado da mesma ma-neira que e o comando de selecao dupla if. No Exemplo 2.20, e listado o codigo em C para oalgoritmo do pseudocodigo recem-mencionado.

1 #include <stdio.h>

2 main(){

3 int matricula;

4 float n1 , n2 , n3 , mediaParcial;

5

6 printf("Digite a matricula e as notas parciais do aluno: ");

7 scanf("%d %f %f %f", &matricula , &n1 , &n2 , &n3);

8 mediaParcial = (n1 + n2 + n3) / 3.0;

Page 42: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

42 CAPITULO 2. CONCEITOS BASICOS

Pseudocodigo 2.4 Informa se um aluno esta aprovado ou nao, de acordo com a media dasnotas obtidas no semestre.

Descricao: Algoritmo para decidir se um aluno esta aprovado ou nao, com base na media das notassemestrais.Dados de Entrada: matrıcula do aluno, notas.Saıda do Programa: mensagem dizendo se o aluno esta aprovado ou nao.

Func~ao Principal:Leia a matrıcula e as notas do aluno.Calcule a media parcial.SE a media parcial for menor que 7 ENT~AO

Imprima uma mensagem dizendo que o aluno deve fazer prova final.SEN~AO

Imprima uma mensagem dizendo que o aluno esta aprovado.FIM-SE.

FIM-Func~ao Principal

9

10 if(mediaParcial < 7.0){

11 printf("\nO aluno %d deve fazer prova final.", matricula);

12 } else {

13 printf("\nO aluno %d foi aprovado com media %f", matricula , media);

14 }

15 }

Exemplo 2.20: Uso do comando de selecao if para a verificacao da media parcial de um aluno.

No Exemplo 2.20, as linhas 3 e 4 correspondem a declaracao das variaveis; a linha 7, ainicializacao delas. Apos o calculo da media parcial das notas (linha 8), o comando de selecaoverifica se tal media e menor que 7, 0 e, assim, executa a instrucao da linha 11 ou da linha 13.

Como pode ser visto no Exemplo 2.21, e possıvel usar comandos de selecao de forma ani-nhada, ou seja, pode-se colocar um comando de selecao dentro de uma das sequencias de co-mandos de outro. Nesse programa, compara-se dois numeros inteiros digitados pelo usuario,informando se foram digitados em ordem crescente, decrescente ou se sao iguais. Antes, entre-tanto, e bom observar o Pseudocodigo 2.5, que corresponde ao codigo do Exemplo 2.21.

1 #include <stdio.h>

2 main(){

3 int num1 , num2;

4

5 printf("Digite dois numeros inteiros quaisquer: ");

6 scanf("%d %d", &num1 , &num2);

7

8 if(num1 > num2){

9 printf("\nOrdem decrescente.");

Page 43: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.9. COMANDOS DE SELECAO 43

Pseudocodigo 2.5 Compara dois numeros e informa se foram digitados em ordem crescente,decrescente ou se sao iguais.

Descricao: Algoritmo para decidir se dois numeros digitados estao em ordem crescente, decrescente ouse sao iguais.Dados de Entrada: matrıcula do aluno, notas.Saıda do Programa: mensagem dizendo se o aluno esta aprovado ou nao.

Func~ao Principal:Leia dois numeros inteiros.SE o primeiros for maior que o segundo ENT~AO

Imprima uma mensagem dizendo que e ordem crescente.SEN~AO

SE o segundo for maior que o primeiro ENT~AOImprima uma mensagem dizendo que e ordem decrescente.

SEN~AOImprima uma mensagem dizendo que os numeros s~ao iguais.

FIM-SE.FIM-SE.

FIM-Func~ao Principal

10

11 }else{

12 if(num2 > num1){

13 printf("\nOrdem crescente.");

14

15 }else{

16 printf("\nNumeros iguais.");

17 }

18 }

19 }

Exemplo 2.21: Comando de selecao if aninhado em outro comando if.

A estrutura dos comandos de selecao do Exemplo 2.21 permite testar todos os casos. Observeque nao ha uma verificacao explıcita para a igualdade dos numeros. Isso acontece porque todosos demais casos possıveis sao testados antes e, se nao se tratar de nenhum desses, entao osnumeros certamente sao iguais. Nesse caso, basta apenas exibir a mensagem correspondente.

Em muitos casos, alem de ser elegante, o uso da estrutura de selecao aninhada pode sermais eficiente. Verifica-se esse fato nos Exemplos 2.22 e 2.23. Ambos os programas leem tresnumeros digitados pelo usuario e identificam o maior deles, porem, um dos programas faz menosverificacoes que o outro, ganhando eficiencia.

1 #include <stdio.h>

2 main(){

Page 44: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

44 CAPITULO 2. CONCEITOS BASICOS

3 int n1 , n2 , n3;

4

5 printf("Entre com os tres numeros: ");

6 scanf("%d %d %d", &n1 , &n2 , &n3);

7

8 if((n1 > n2) && (n1 > n3)){

9 printf("O maior numero digitado foi: %d.", n1);

10 }

11

12 if((n2 > n1) && (n2 > n3)){

13 printf("O maior numero digitado foi: %d.", n2);

14 }

15

16 if((n3 > n1) && (n3 > n2)){

17 printf("O maior numero digitado foi: %d.", n3);

18 }

19 }

Exemplo 2.22: Programa que identifica o maior de tres numeros sem o uso do comando deselecao aninhado.

1 #include <stdio.h>

2 main(){

3 int n1 , n2 , n3;

4

5 printf("Entre com os tres numeros separados por espacos: ");

6 scanf("%d %d %d", &n1 , &n2 , &n3);

7

8 if (n1 > n2){

9 if (n1 > n3){

10 printf("O maior numero digitado foi: %d.", n1);

11 } else {

12 printf("O maior numero digitado foi: %d.", n3);

13 }

14 }else{

15 if (n2 > n3) {

16 printf("O maior numero digitado foi: %d.", n2);

17 } else {

18 printf("O maior numero digitado foi: %d.", n3);

19 }

20 }

21 }

Exemplo 2.23: Programa que identifica o maior de tres numeros, usando o uso do comando deselecao aninhado.

No caso do Exemplo 2.22, o uso de varios comandos if isolados acarreta em perda deeficiencia. Quando o primeiro numero digitado pelo usuario for o maior, o programa realizadois testes desnecessarios (linhas 12 e 16). E quando o segundo numero for o maior, o programa

Page 45: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.9. COMANDOS DE SELECAO 45

realiza um teste desnecessario (linha 16).No Exemplo 2.23, apenas dois testes sao executados (linhas 8 e 9 ou linhas 8 e 15), diminuindo

significativamente o numero de comparacoes em relacao ao Exemplo 2.22.O programa do Exemplo 2.24 recebe do usuario tres numeros inteiros e verifica se eles podem

ser tamanhos dos lados de um triangulo. Caso verdadeiro, o programa ainda indica a classificacaodo triangulo. O Pseudocodigo 2.6 lista o algoritmo para esse exemplo.

Pseudocodigo 2.6 Informa se tres numeros podem constituir os lados de um triangulo e o tipodo triangulo que pode ser formado.

Descricao: Algoritmo para calcular se tres numeros podem representar os lados de um triangulo e,caso seja possıvel, o tipo do triangulo.Dados de Entrada: tres valores inteiros.Saıda do Programa: mensagem dizendo o tipo do triangulo ou se nao pode ser formado um triangulo.

Func~ao Principal:Leia tres numeros inteiros.SE os tres valores forem iguais ENT~AO

Imprima uma mensagem dizendo que e triangulo equilatero.SEN~AO

SE cada valor e menor do que a soma dos outros dois ENT~AOSE os tres valores forem diferentes ENT~AO

Imprima uma mensagem dizendo que e triangulo escaleno.SEN~AO

Imprima uma mensagem dizendo que e triangulo isosceles.FIM-SE.

SEN~AOImprima uma mensagem dizendo que os valores n~ao podem ser lados de um triangulo.

FIM-SE.FIM-SE.

FIM-Func~ao Principal

1 #include <stdio.h>

2 main(){

3 int lado1 , lado2 , lado3;

4 int soma1 , soma2 , soma3;

5

6 printf("Entre com tres numeros inteiros: ");

7 scanf("%d %d %d", &lado1 , &lado2 , &lado3);

8

9 soma1 = lado1 + lado2;

10 soma2 = lado1 + lado3;

11 soma3 = lado2 + lado3;

12

Page 46: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

46 CAPITULO 2. CONCEITOS BASICOS

13 if((lado1 == lado2) && (lado2 == lado3)){

14 printf("Triangulo equilatero\n");

15 }else{

16

17 if((soma1 > lado3) && (soma2 > lado2) && (soma3 > lado1)){

18

19 if(( lado1 != lado2) && (lado1 != lado3) && (lado2 != lado3)){

20 printf("Triangulo escaleno\n");

21 }else{

22 printf("Triangulo isosceles\n");

23 }

24 }else{

25 printf("Os tres lados nao formam um triangulo\n");

26 }

27 }

28 }

Exemplo 2.24: Programa que indica se tres numeros formam um triangulo.

No Exemplo 2.24, o comando if mais externo (linha 13) confere se os numeros formam umtriangulo equilatero, verificando se os tres sao iguais. Caso nao formem um triangulo equilatero,na linha 17 e verificado se os tres numeros formam realmente um triangulo, comparando a somade dois lados com a medida do terceiro (para todas as possibilidades). Caso verdadeiro, o if maisinterno confere se os tres lados sao diferentes um do outro, formando um triangulo escaleno; oresultado “falso”para esse ultimo teste implica necessariamente na formacao de um trianguloisosceles.

2.9.3 Comando de selecao multipla

O comando de selecao if e bastante poderoso e largamente utilizado. Entretanto, ele nao e ounico comando de selecao existente. Ha um comando que, embora seja menos abrangente que ocomando if, resolve muitas situacoes de forma clara e elegante. Trata-se do comando de selecaomultipla.

O comando de selecao multipla sempre pode ser substituıdo por um ou mais comandos ifaninhados, mas ele torna o codigo muito mais claro quando se quer executar varias sequenciasde comandos diferentes, sendo que cada sequencia deva corresponder a um determinado valorde uma expressao. A estrutura seguinte facilita a compreensao do comando.

switch (<express~ao>){case <valor1>:

<sequencia de comandos 1>break;

case <valor2>:<sequencia de comandos 2>break;

.

Page 47: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.9. COMANDOS DE SELECAO 47

.

.case <valorN>:

<sequencia de comandos N>break;

default :<sequencia de comandos>

}

Na estrutura do comando de selecao multipla, a expressao normalmente e uma expressaoaritmetica ou uma variavel de tipo numerica, e associa-se o valor da expressao ao valor de umdeterminado case. Assim, apenas a sequencia de comandos do bloco case correspondente seraexecutada. E importante observar que cada sequencia de comandos e encerrada pelo comandobreak.

A clausula default e opcional. Ela marca a sequencia de comandos padrao, que deve serexecutada quando nenhuma comparacao obtiver sucesso. Se nao estiver presente, nada seraexecutado nesse caso.

Na linguagem C, cada case deve servir para comparar o resultado da expressao com umvalor especıfico. Nao se permite comparacoes com o resultado de outras expressoes.

No Exemplo 2.25 usa-se o comando switch na construcao de um programa que simula ofuncionamento de uma urna eletronica. O Pseudocodigo 2.7 exibe o algoritmo desse exemplo.

Pseudocodigo 2.7 Algoritmo de uma urna eletronica simplificada.

Descricao: Algoritmo para simular uma urna eletronica simplificada. Nao ha a opcao para voto embranco.Dados de Entrada: o numero do candidato.Saıda do Programa: mensagem dizendo o nome do candidato escolhido ou se o voto foi anulado.

Func~ao Principal:Leia o numero do candidato.CASO o numero do candidato SEJA:

1, ENT~AO imprima uma mensagem dizendo que Hortensia da Silva foi escolhida.2, ENT~AO imprima uma mensagem dizendo que Jose dos Cravos foi escolhido.3, ENT~AO imprima uma mensagem dizendo que Margarida S. Pereira foi escolhida.OUTRO VALOR, ENT~AO imprima uma mensagem dizendo que o voto foi anulado.

FIM-CASOFIM-Func~ao Principal

O comportamento do comando CASO-SEJA do Pseudocodigo 2.7 deve ser pensado da mesmamaneira que o do comando de selecao multipla switch.

1 #include <stdio.h>

2 main(){

Page 48: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

48 CAPITULO 2. CONCEITOS BASICOS

3 int numero;

4

5 printf("URNA ELETRONICA - SEU VOTO PARA PREFEITO: ");

6 scanf("%d", &numero);

7

8 switch(numero){

9 case 1:

10 printf("Candidato escolhido: Hortencia da Silva");

11 break;

12 case 2:

13 printf("Candidato escolhido: Jose dos Cravos");

14 break;

15 case 3:

16 printf("Candidato escolhido: Margarida S. Pereira");

17 break;

18 default:

19 printf("Numero digitado invalido. Voto anulado.");

20 }

21 }

Exemplo 2.25: Uso do comando switch para simular uma urna eletronica de eleicao.

No programa do Exemplo 2.25, os numeros de 1 a 3 estao associados a determinados candi-datos e, para qualquer outro numero, a clausula default e associada.

Apos a inicializacao da variavel numero com o comando de entrada de dados (linha 6), ocomando de selecao compara o numero digitado com os numeros dos tres candidatos inscritos.Em cada caso, se o numero digitado coincide com a constante, a sequencia de comandos corres-pondente ao candidato escolhido e executada. Se nenhuma comparacao obtiver sucesso, entaoo usuario digitou um numero de candidato que nao existe. Nesse caso, o programa exibe umamensagem de alerta para o usuario, avisando-lhe que o numero digitado e invalido para a eleicao(linha 19).

Quando o comando break nao termina uma sequencia de comandos cuja comparacao resultouverdadeira, a sequencia de comandos seguinte e executada sem que o teste correspondente sejaefetuado. Na pratica, o que acontece e que quando uma comparacao do switch resultar emverdadeiro, todas as sequencias de comando seguintes sao executadas ate que o primeiro comandobreak seja encontrado.

E preciso, portanto, ficar atento e finalizar cada sequencia de comandos com o comandobreak evitando, assim, erros de programacao muitas vezes difıceis de detectar.

2.10 Comandos de Repeticao

A capacidade que as maquinas possuem de repetir tarefas exaustivamente com a mesma quali-dade e uma das principais razoes do sucesso de sua invencao. Os computadores podem repetiruma ou mais sequencia de comandos quantas vezes for necessario, e e o programador quemdecide o criterio de parada das repeticoes.

Page 49: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.10. COMANDOS DE REPETICAO 49

As aplicacoes para os comandos de repeticao sao praticamente infinitas porque quase todasas tarefas contem partes que devem ser executadas mais de uma vez.

Na linguagem C, existem tres principais estruturas de repeticao. A opcao pelo uso de umaou outra depende normalmente da preferencia do programador e do problema em questao,normalmente buscando-se o maximo de clareza ou facilidade de escrita do codigo. Essas tresestruturas sao abordadas a seguir.

2.10.1 Comando de repeticao com pre-condicao

A estrutura do comando while e a mais simples das tres e seu funcionamento e igualmentesimples de compreender. A estrutura e a seguinte:

while (<express~ao logica>){<Sequencia de comandos>

}

O computador inicia o comando testando a validade da expressao logica. Se for verdadeira,entao ele executa a sequencia de comandos e retorna ao teste de validacao da expressao logica,reiniciando o ciclo. O computador repete esse processo ate que o resultado da expressao logicaseja falso.

No caso em que o primeiro teste de validacao da expressao logica resulte em falso, a sequenciade comandos nao e executada nenhuma vez.

O Pseudocodigo 2.8 representa um algoritmo que recebe um numero inteiro positivo n eimprime na tela os n primeiros inteiros positivos.

Pseudocodigo 2.8 Imprimir os n primeiros numeros positivos.

Descricao: programa para imprimir na tela os n primeiros numeros positivos.Dados de Entrada: n (quantidade de inteiros a serem impressos).Saıda do Programa: os numeros inteiros de 1 a n.

Func~ao Principal:Leia n.Valor recebe 1.ENQUANTO Valor for menor ou igual a n FACA:

Imprima Valor.Incremente Valor.

FIM-ENQUANTOFIM-Func~ao Principal

O comando ENQUANTO do Pseudocodigo 2.8 funciona da mesma maneira que o comandode repeticao com pre-condicao while. O programa do Exemplo 2.26 mostra um codigo em Cque realiza as operacoes do referido pseudocodigo.

Page 50: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

50 CAPITULO 2. CONCEITOS BASICOS

1 #include <stdio.h>

2 main(){

3 int n, valor;

4

5 printf("Digite um numero inteiro positivo: ");

6 scanf("%d", &n);

7 valor = 1;

8

9 while (valor <= n){

10 printf("%d ", valor);

11 valor = valor + 1;

12 }

13 }

Exemplo 2.26: Comando de repeticao while para imprimir os n primeiros numeros inteiros.

As variaveis n e valor do Exemplo 2.26 representam a quantidade de numeros impressos e oproprio numero, respectivamente. A variavel n e inicializada pelo usuario atraves do comandode entrada de dados; valor e inicializada com o numero 1, para posteriormente ser incrementadaa cada iteracao.

Pela expressao logica do while, nota-se que a condicao de parada de iteracoes ocorre quandoa variavel valor atingir um numero maior que o numero n, ou seja, o bloco de comandos dowhile (linhas 10 e 11) e executado enquanto o numero armazenado em valor for menor ou igualao numero armazenado em n.

A condicao de parada em qualquer comando de repeticao e um fator muito importante quese deve escolher com bastante cuidado. E preciso garantir que o computador efetue um numerofinito de repeticoes para que, em algum momento, o programa possa seguir seu fluxo normalde execucao. Alem de resultados incorretos, uma condicao de parada erronea pode acarretaruma execucao de programa sem termino (nessa situacao, diz-se que o programa esta em “loopinfinito”).

A Tabela 2.8 apresenta o resultado da execucao do programa do Exemplo 2.26, quando ousuario informa o valor 4 para a variavel n.

n valor valor <= n Tela4 1 Sim 14 2 Sim 1 24 3 Sim 1 2 34 4 Sim 1 2 3 44 5 Nao 1 2 3 4

Tabela 2.8: Detalhes da execucao do comando while do Exemplo 2.26.

O proximo programa, Exemplo 2.27, imprime os n primeiros numeros ımpares. Essa quan-tidade n e definida pelo usuario.

Page 51: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.10. COMANDOS DE REPETICAO 51

1 #include <stdio.h>

2 main(){

3 int iterador , valor , n;

4

5 printf("Imprimir numeros impares. Entre com a quantidade de termos: ");

6 scanf("%d", &n);

7

8 iterador = 1;

9 valor = 1;

10

11 while(iterador <= n){

12 printf("\n %d",valor);

13 valor = valor + 2;

14 iterador = iterador + 1;

15 }

16 }

Exemplo 2.27: Programa que imprime os n primeiros numeros ımpares, utilizando o comandode repeticao while.

No programa do Exemplo 2.27, a quantidade de numeros ımpares a ser impresso e fornecidopelo usuario atraves do comando scanf. A variavel iterador e usada para armazenar o numero aser impresso em cada iteracao do comando while. O bloco de instrucoes do comando de repeticao(linhas 11 e 12) e executado enquanto o numero armazenado em iterador for menor ou igual aonumero fornecido pelo usuario.

Com os comandos de repeticao e possıvel melhorar o programa da urna eletronica propostono Exemplo 2.25, da secao anterior. Naquele exemplo, o programa nao confirma o voto dousuario, impossibilitando que um erro de digitacao pudesse ser corrigido durante a execucao doprograma. O Pseudocodigo 2.9 lista o algoritmo melhorado.

Pseudocodigo 2.9 Urna eletronica com opcao de corrigir voto.

Descricao: programa para imprimir na tela os n primeiros numeros positivos.Dados de Entrada: numero do candidato, resposta da confirmacao.Saıda do Programa: mensagem indicando o candidato escolhido.

Func~ao Principal:Resposta recebe zero.ENQUANTO resposta for igual a zero FACA:

Leia o numero do candidato.Imprima o nome do candidato escolhido.Leia a resposta da confirmac~ao.

FIM-ENQUANTO.FIM-Func~ao Principal

Page 52: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

52 CAPITULO 2. CONCEITOS BASICOS

No codigo do Exemplo 2.28, o usuario tem a possibilidade de corrigir o seu voto sem que oprograma termine.

1 #include <stdio.h>

2 main(){

3 int numero , resposta;

4

5 resposta = 0;

6

7 while (resposta == 0){

8 printf("URNA ELETRONICA - SEU VOTO PARA PREFEITO: ");

9 scanf("%d", &numero);

10

11 switch(numero){

12 case 1:

13 printf("Candidato escolhido: Hortencia da Silva");

14 break;

15 case 2:

16 printf("Candidato escolhido: Jose dos Cravos");

17 break;

18 case 3:

19 printf("Candidato escolhido: Margarida S. Pereira");

20 break;

21 default:

22 printf("Numero digitado invalido. Voto NULO.");

23 }

24

25 printf("\nDigite 1 para CONFIRMAR ou 0 para CORRIGIR ");

26 scanf("%d", &resposta);

27 }

28 }

Exemplo 2.28: Comando de repeticao while utilizado para melhorar o codigo do Exemplo 2.25.

O criterio de parada escolhido no Exemplo 2.28 e a alteracao do valor da variavel resposta.Enquanto essa variavel armazena o valor zero, o programa repetira o processo de votacao eperguntara ao usuario se confirma o voto ou se gostaria de corrigi-lo. Quando o valor davariavel resposta e alterado, a expressao logica da linha 7 retorna falso, encerrando o comandode repeticao.

2.10.2 Comando de repeticao com pos-condicao

Em contraste com o comando de pre-condicao, o comando de repeticao com pos-condicao soefetua o teste da expressao logica (condicao de parada) apos a primeira execucao da sequenciade comandos. Logo, o bloco de comandos e executado pelo menos uma vez, independente daexpressao logica. A propria sintaxe do comando sugere essa diferenca:

do{

Page 53: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.10. COMANDOS DE REPETICAO 53

<Sequencia de comandos>} while(<express~ao logica>);

O Pseudocodigo 2.9 pode ser modificado para melhorar sua legibilidade. Com o emprego docomando FACA-ENQUANTO, o algoritmo fica mais simples.

Pseudocodigo 2.10 Urna eletronica com opcao de corrigir voto (versao melhorada).

Descricao: programa para imprimir na tela os n primeiros numeros positivos.Dados de Entrada: numero do candidato, resposta da confirmacao.Saıda do Programa: mensagem indicando o candidato escolhido.

Func~ao Principal:FACA:

Leia o numero do candidato.Imprima o nome do candidato escolhido.Leia a resposta da confirmac~ao.

ENQUANTO resposta for igual a zero.FIM-Func~ao Principal

O programa do Exemplo 2.28 pode ser reescrito utilizando-se o comando do-while. Nessecaso, o uso do do-while permite ao programador ter a opcao de nao inicializar a variavel respostaantes da execucao da sequencia de comandos, responsabilizando o usuario pela inicializacao(conforme se nota no Exemplo 2.29).

1 #include <stdio.h>

2 main(){

3 int numero , resposta;

4 /* A variavel resposta n~ao e mais inicializada pelo programador */

5 do

6 {

7 printf("URNA ELETRONICA - SEU VOTO PARA PREFEITO: ");

8 scanf("%d", &numero);

9 switch(numero)

10 {

11 case 1:

12 printf("Candidato escolhido: Hortencia da Silva");

13 break;

14 case 2:

15 printf("Candidato escolhido: Jose dos Cravos");

16 break;

17 case 3:

18 printf("Candidato escolhido: Margarida S. Pereira");

19 break;

20 default:

21 printf("Numero digitado invalido. Voto NULO.");

22 }

Page 54: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

54 CAPITULO 2. CONCEITOS BASICOS

23 printf("\nDigite 1 para CONFIRMAR ou 0 para CORRIGIR ");

24 scanf("%d", &resposta);

25 } while (! resposta);

26 }

Exemplo 2.29: Aplicacao para o comando do-while, modificando o codigo do Exemplo 2.28.

No Exemplo 2.29, nota-se que nao ha mais a inicializacao explıcita da variavel resposta.Com o comando do-while, garante-se que a variavel sera inicializada pelo usuario antes de seuvalor ser testado na expressao logica da linha 25, utilizada como criterio de parada.

Pode parecer estranho, a primeira vista, como a expressao logica !resposta funciona. Naverdade essa espressao e equivalente ao teste resposta == 0.

Para entender essa equivalencia, basta lembrar que o operador logico de negacao inverte ovalor logico da variavel ao qual ele e aplicado. E bom recordar tambem que, para os numerosinteiros, o valor zero equivale a falso enquanto que qualquer numero diferente de zero e tomadocomo valor logico verdadeiro. Assim sendo, sempre que o programador desejar testar se umvalor inteiro e igual a zero, basta testar o resultado do operador de negacao, pois o unico casoem que ele retornara verdadeiro sera quando o valor numerico testado for zero.

Um outro exemplo simples para o uso do comando do-while e um algoritmo no qual o usuarioinforma uma sequencia de valores positivos e, em seguida, a media desses valores e apresentada.O usuario devera digitar zero quando quiser finalizar a sequencia e saber a media. O algoritmodesse programa esta listado no Pseudocodigo 2.11.

Pseudocodigo 2.11 Calculo da media de numeros positivos digitados pelo usuario.

Descricao: Algoritmo para calculo da media de numeros positivos digitados pelo usuario.Dados de Entrada: numeros nao negativos.Saıda do Programa: media dos valores digitados.

Func~ao Principal:FACA:

Leia um valor.SE valor e positivo ENT~AO

Atualize a soma dos numeros digitados.Incremente a quantidade de numeros digitados.

FIM-SE.ENQUANTO valor digitado for positivo.SE o usuario digitou algum valor positivo ENT~AO

Calcule a media dos valores digitados.Imprima essa media.

FIM-SE.FIM-Func~ao Principal

O Exemplo 2.30 exibe o programa para o Pseudocodigo 2.11.

Page 55: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.10. COMANDOS DE REPETICAO 55

1 #include <stdio.h>

2 main(){

3 float valor , soma , media;

4 int quantidade;

5

6 soma = 0;

7 quantidade = 0;

8 do {

9 printf("Informe um valor positivo ou zero para encerrar o programa: ");

10 scanf("%f",&valor);

11 if (valor > 0) {

12 soma = soma + valor;

13 quantidade = quantidade + 1;

14 }

15 } while(valor > 0);

16 if (quantidade > 0) {

17 media = soma/quantidade;

18 printf("Media dos valores digitados: %f\n", media);

19 }

20 }

Exemplo 2.30: Programa que calcula a media dos valores de uma sequencia digitada pelo usuario.

O funcionamento do programa do Exemplo 2.30 e simples. A variavel soma guarda a somados valores digitados pelo usuario e deve ser inicializada com zero. A cada novo valor positivodigitado, seu valor deve ser atualizado. Essa atualizacao ocorre na linha 12. Observa-se que ocomando de selecao da linha 11 impede que haja atualizacao das variaveis soma e quantidadequando o usuario quer encerrar o programa e digita zero.

A variavel valor e a condicao de parada do comando de repeticao. Sempre que o usuariodigita zero (ou ate mesmo um numero negativo), o comando de repeticao e encerrado.

Para saber quantos numeros foram digitados, a variavel quantidade e empregada. Ela einicializada com zero e, sempre que o usuario digita um numero positivo, ela e incrementada(linha 13).

Quando o comando de repeticao e encerrado, e preciso verificar se o usuario digitou algumvalor. Essa verificacao se deve ao fato de que o primeiro valor digitado pode ser zero, indicandoque o usuario saiu do programa e nao quis calcular nada. No caso de algum valor valido tersido informado (expressao logica da linha 16), entao a media e calculada e uma mensagem como resultado e exibida ao usuario (linhas 17 e 18).

2.10.3 Comando de repeticao condensado

O comando de repeticao condensado permite agrupar, em um unico comando, a inicializacaode uma variavel, o incremento desta variavel e o teste de parada. Seu uso e adequado parasituacoes em que o numero de repeticoes da sequencia de comandos ja e conhecido.

A estrutura do comando e exibida a seguir:

Page 56: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

56 CAPITULO 2. CONCEITOS BASICOS

for (<inicializac~ao>; <express~ao logica>; <incremento>){<Sequencia de comandos>

}

Inicializacao e um comando de atribuicao usado para colocar um valor na variavel de controleutilizada na expressao logica. Assim como os demais comandos de repeticao, a expressao logicarepresenta a condicao de parada das iteracoes. Incremento define como a variavel de controleque sera modificada a cada iteracao.

Um exemplo de como utilizar o comando for esta listado no codigo do Exemplo 2.31. Esseprograma serve para imprimir os n primeiros termos de uma PG (progressao geometrica). Ousuario deve informar os valores do primeiro termo, da razao e da quantidade de termos a seremexibidos.

1 main(){

2 float primeiroTermo , razao , n, i, termo;

3

4 printf("Informe o valor do primeiro termo da PG: ");

5 scanf("%f",&primeiroTermo);

6 printf("Informe o valor da razao da PG: ");

7 scanf("%f",&razao);

8 printf("Informe quantos termos devem ser impressos: ");

9 scanf("%f",&n);

10 termo = primeiroTermo;

11 for (i=0; i<n; i=i+1) {

12 printf("%f ", termo);

13 termo = termo*razao;

14 }

15 }

Exemplo 2.31: Programa para exibir os n primeiros termos de uma progressao geometrica utilizando ocomando de repeticao for.

No Exemplo 2.31, as variaveis primeiroTermo, razao e n sao inicializadas pelo usuario,usando o comando de entrada de dados. A linha 10 trata da inicializacao da variavel termo,que guarda o valor do termo da PG a ser impresso a cada repeticao (iteracao) do comando for.

O comando de repeticao, em primeiro lugar, inicializa a variavel de controle i com o valorzero. Em seguida, ocorre a verificacao da expressao logica. Caso o usuario tenha digitadozero, o comando nao executa sua sequencia de instrucoes nenhuma vez, pois tanto i quanto narmazenam zero e tornam falso o resultado da expressao logica. Nesse caso, nada e impresso natela.

Mas se o usuario digitou um valor maior que zero, a sequencia de comandos sera repetida ateque a quantidade solicitada de termos seja impressa. Para isso, o comando de saıda de dados echamado logo no inıcio da sequencia de comandos (linha 12). No caso em que i e igual a zero(primeira iteracao), o primeiro termo e exibido. A linha 13 conclui a sequencia de comandosatualizando a variavel termo para guardar o proximo termo da sequencia.

Page 57: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.10. COMANDOS DE REPETICAO 57

Um passo implıcito e que o comando realiza o incremento da variavel i no momento aposa execucao da ultima instrucao da sequencia de comandos. Feita essa atualizacao, a condicaode parada e novamente verificada e, caso seja verdadeira, uma nova repeticao e comecada paraimprimir outro termo da PG.

A Tabela 2.9 mostra passo a passo a execucao completa do comando de repeticao para oprograma do Exemplo 2.31. Os valores informados sao para uma PG de razao igual a 2, primeirotermo igual a 2 e quantidade de termos a serem impressos igual a 4. As colunas mostram asvariaveis principais do comando de repeticao (i, termo e n), o resultado da expressao logica acada iteracao e o que foi impresso na tela. Os valores sao referentes ao momento posterior aexecucao da sequencia de instrucoes, antes do incremento da variavel de controle.

i termo n i < n Tela0 4 4 Verdadeiro 21 8 4 Verdadeiro 2 42 16 4 Verdadeiro 2 4 83 32 4 Verdadeiro 2 4 8 164 32 4 Falso 2 4 8 16

Tabela 2.9: Detalhes da execucao do comando for do Exemplo 2.31.

O programa do Exemplo 2.32 realiza a operacao de exponenciacao de um numero, utilizandoo comando de repeticao for.

1 #include <stdio.h>

2 main(){

3 int base , expoente , resultado , i;

4

5 printf("Informe os valores para base e expoente: ");

6 scanf("%d %d", &base , &expoente);

7

8 resultado = 1;

9 for (i = 0; i < expoente; i = i + 1){

10 resultado = resultado * base;

11 }

12

13 printf("%d elevado a %d = %d\n", base , expoente , resultado);

14 }

Exemplo 2.32: Programa para realizar a operacao de exponenciacao utilizando o comando de repeticaofor.

No Exemplo 2.32, os valores da base e do expoente sao fornecidos pelo usuario via comandode entrada de dados (linha 6). A variavel de controle i e inicializada com o valor zero dentrodo comando for e, a cada iteracao, e incrementada de 1. Quando o valor de i atinge valor igualao valor da variavel expoente, as iteracoes sao terminadas e o programa segue para a linha 13,

Page 58: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

58 CAPITULO 2. CONCEITOS BASICOS

imprimindo os valores da base, do expoente e do resultado da exponenciacao.Assim como o comando while, o comando for efetua primeiramente o teste da condicao de

parada antes de executar a sequencia de comandos pela primeira vez.

2.11 Problema dos Lotes Encaixantes

Com o conhecimendo dos conceitos basicos da programacao, uma primeira classe de problemaspode ser estudada. Trata-se do Problema dos Lotes Encaixantes, que corresponde a situacoesem que se precisa executar uma varredura em uma massa de dados e extrair dela algumasinformacoes estatısticas.

O termo lotes encaixantes refere-se ao fato de que, na maioria das vezes, problemas como esseenvolvem entidades complexas compostas por outras mais simples. As entidades mais simplesse encaixam para formar outras com um grau de complexidade ainda maior. Assim sendo, epossıvel visualizar varios nıveis que variam desde os mais simples e com muitos elementos ateos mais complexos e com algumas dezenas de integrantes.

A Figura 2.7 ajuda a explicar a ideia. Nela, os quadrados de bordas contınuas e finas repre-sentam o nıvel mais simples. Eles se agrupam para formar os quadrados de bordas pontilhadas,que representam um nıvel intermediario de complexidade. Juntos, os quadrados pontilhadoscompoem o nıvel mais complexo, representado pelo grande quadrado de borda grossa. Napratica, podem existir nao apenas tres, mas quantos nıveis forem necessarios para caracterizaros dados de um programa.

Figura 2.7: Uma representacao grafica para os lotes encaixantes

Considera-se, como exemplo, o problema de um professor que ministra uma disciplina paradiversas turmas. Nesse caso, e interessante saber qual turma obteve melhor rendimento, o aluno

Page 59: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.11. PROBLEMA DOS LOTES ENCAIXANTES 59

que mais se destacou em cada turma e os que menos renderam nos estudos. Os dados, nessecaso, podem ser observados em quatro nıveis.

O nıvel de notas e o mais simples. Ele e indivisıvel e e caracterizado pelas notas dos trabalhose provas realizados no semestre. O nıvel seguinte e o das medias semestrais em que as notas saoagrupadas por aluno. O terceiro agrupamento e o das turmas. Os alunos sao reunidos de acordocom as turmas a que pertencem. Por ultimo, o nıvel mais complexo, e a propria disciplina. Ela ea entidade mais abrangente, que e composta diretamente pelas turmas existentes no determinadosemestre.

Problemas de lotes encaixantes, normalmente, sao resolvidos por meio do emprego de coman-dos de repeticao aninhados. Quanto mais externo for o comando de repeticao, maior o nıvel decomplexidade das entidades que estao sendo examinadas. A Figura 2.8 exibe essa ideia, usandocomo exemplo o problema das notas escolares.

Figura 2.8: Comandos de repeticao aninhados, utilizados para resolver um problema de lotesencaixantes.

O Pseudocodigo 2.12 descreve um algoritmo para realizar um levantamento estatıstico dodesempenho de alunos e turmas de uma disciplina hipotetica num determinado semestre.

O Exemplo 2.33 ilustra o codigo para um programa que le os dados das notas dos alunos eexibe a media de cada um. Para cada turma, sera exibida a melhor e a pior media. Ao final,exibe a turma com maior percentual de aprovacoes da disciplina.

Page 60: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

60 CAPITULO 2. CONCEITOS BASICOS

Pseudocodigo 2.12 Problema dos Lotes Encaixantes para o problema das notas escolares

Descricao: programa para analisar as notas de uma disciplina escolar.Dados de Entrada: codigo da turma, matrıculas dos alunos, notas dos alunos.Saıda do Programa: media de cada aluno, matrıculas dos alunos de melhor e de pior medias de cadaturma, codigo da turma com melhor rendimento.

Func~ao Principal:Leia o codigo de uma turma.ENQUANTO codigo for diferente de -1 FACA:Leia o numero de matrıcula de um aluno.ENQUANTO o numero de matrıcula for diferente de -1 FACA:Leia uma nota do aluno.ENQUANTO a nota digitada n~ao for negativa FACA:Leia outra nota do aluno.Atualize os dados do aluno.FIM-ENQUANTOAtualize os dados da turma.Imprima a media das notas do aluno.Leia o numero de matrıcula de um aluno.FIM-ENQUANTOAtualize os dados da disciplina.Imprima os numeros de matrıcula e as medias dos alunos com maiore menor medias da turma.Leia o codigo de uma turma.FIM-ENQUANTOImpria o codigo da turma com melhor aproveitamento.FIM-Func~ao Principal

1 #include <stdio.h>

2 #define MEDIAMINIMA 7.0

3

4 main(){

5 int codTurma , matricula , numNotasAluno , numAlunosTurma , alunoMaiorMedia ,

alunoMenorMedia , melhorTurma;

6 float nota , mediaAluno , numAprovadosTurma , somaNotasAluno , maiorMediaTurma ,

menorMediaTurma , aproveitamentoTurma , melhorAproveitamento;

7

8 melhorAproveitamento = 0;

9

10 printf("Informe o codigo da turma: ");

11 scanf("%d", &codTurma);

12 while (codTurma != -1) {

13 maiorMediaTurma = 0;

14 menorMediaTurma = 10;

Page 61: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.11. PROBLEMA DOS LOTES ENCAIXANTES 61

15 numAprovadosTurma = 0;

16 numAlunosTurma = 0;

17

18 printf("Informe o numero de matricula do aluno: ");

19 scanf("%d", &matricula);

20 while (matricula != -1) {

21 numNotasAluno = 0;

22 somaNotasAluno = 0;

23 numAlunosTurma = numAlunosTurma + 1;

24

25 printf("Informe a nota do aluno: ");

26 scanf("%f", &nota);

27 while (nota != -1) {

28 somaNotasAluno = somaNotasAluno + nota;

29 numNotasAluno = numNotasAluno + 1;

30 printf("Informe a nota do aluno ou ’-1’ para encerrar: ");

31 scanf("%f", &nota);

32 }

33

34 mediaAluno = somaNotasAluno / numNotasAluno;

35

36 if (mediaAluno >= MEDIAMINIMA) {

37 numAprovadosTurma = numAprovadosTurma + 1;

38 }

39

40 if (mediaAluno >= maiorMediaTurma) {

41 maiorMediaTurma = mediaAluno;

42 alunoMaiorMedia = matricula;

43 }

44

45 if (mediaAluno <= menorMediaTurma) {

46 menorMediaTurma = mediaAluno;

47 alunoMenorMedia = matricula;

48 }

49 printf("Media do aluno: %f\n", mediaAluno);

50 printf("Informe o numero de matricula do aluno ou ’-1’ para encerrar: "

);

51 scanf("%d", &matricula);

52 }

53

54 aproveitamentoTurma = (numAprovadosTurma/numAlunosTurma) * 100;

55 if (melhorAproveitamento < aproveitamentoTurma) {

56 melhorAproveitamento = aproveitamentoTurma;

57 melhorTurma = codTurma;

58 }

59 printf("O aluno %d obteve a melhor media da turma (%f)\n", alunoMaiorMedia

, maiorMediaTurma);

60 printf("O aluno %d obteve a pior media da turma (%f)\n", alunoMenorMedia ,

menorMediaTurma);

61 printf("Informe o codigo da turma ou ’-1’ para encerrar: ");

62 scanf("%d", &codTurma);

Page 62: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

62 CAPITULO 2. CONCEITOS BASICOS

63 }

64 printf("A turma %d obteve o melhor aproveitamento (%f %%)", melhorTurma ,

melhorAproveitamento);

65 }

Exemplo 2.33: Problema dos lotes encaixantes aplicado a notas de uma disciplina

Fazendo uma comparacao com a Figura 2.8 e com o Pseudocodigo 2.12, nao fica complicadoentender o funcionamento do codigo do Exemplo 2.33. Apos a declaracao das variaveis, oprograma inicializa a variavel melhorAproveitamento (linha 8), que armazena o percentual deaprovacoes da turma de melhor aproveitamento. O valor ajustado e o menor valor possıvel (zero)e sua escolha sera justificada adiante. Em seguida, o programa solicita ao usuario que digite umcodigo para identificar a primeira turma que sera analisada (linhas 10 e 11).

O primeiro comando de repeticao, na linha 12, serve para percorrer todas as turmas, umaa uma. Sempre que sua expressao logica resultar verdadeiro, e sinal que uma nova turma teraseus dados digitados.

Aqui vale destacar um artifıcio util que e empregado nesse codigo. Todos os comandos derepeticao fazem a verificacao de suas variaveis de controle comparando-as com o mesmo valor−1. Ocorre que, para evitar que o usuario seja obrigado a saber, a priori, da quantidade deelementos de um conjunto de dados que sera passado ao programa, utiliza-se um valor absurdo(qualquer valor que nao pertenca ao conjunto em questao) para servir de sinalizacao para oprograma de que o cunjunto de dados foi inteiramente percorrido. Esse valor e, comumente,chamado de flag.

No Exemplo 2.33, considera-se que os codigos das turmas e das matrıculas sao inteirospositivos e que as notas sao valores racionais nao negativos. Assim sendo, o valor −1 foi utilizadopara indicar ao programa quando todas as notas de um aluno foram ja digitadas. Ou que todosos dados dos alunos de uma determinada turma foram digitados. Ou ainda, que todas as turmastiveram seus dados informados.

A sequencia de comandos comeca, entao, com a inicializacao das variaveis da turma emquestao (linhas 13 a 16). As variaveis maiorMediaTurma e menorMediaTurma guardam, res-pectivamente, a melhor e a pior media obtidas na turma. Ja numAprovadosTurma e nu-mAlunosTurma armazenam, respectivamente, a quantidade de alunos aprovados na turma e aquantidade total de alunos da turma. Os valores dessas duas variaveis servem para calcular oaproveitamento da turma.

Nas linhas 18 e 19, o programa solicita ao usuario que informe a matrıcula do primeiro alunoda turma que tera lidas suas notas. Na linha seguinte aparece o segundo comando de repeticao,o qual interage com os dados dos alunos de uma turma.

Assim como no comando de repeticao mais externo, o comando da linha 21 inicia suasequencia de comandos realizando a inicializacao das variaveis pertinentes. As variaveis num-NotasAluno e somaNotasAluno servem para calcular a media aritmetica simples das notas doaluno em questao armazenando, respectivamente, a quantidade de notas do aluno e a somadelas. Na linha 23, a variavel numAlunosTurma e incrementada, indicando a adicao dos dadosde mais um aluno.

Page 63: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.11. PROBLEMA DOS LOTES ENCAIXANTES 63

As linhas 25 e 26 requerem ao usuario que ele digite o valor da primeira nota do aluno emquestao. Em seguida, o programa executa o comando de repeticao mais interno, que serve pararegistrar todas as notas de um determinado aluno.

Esse comando coleta os dados das notas, solicitando ao usuario que digite o valor da nota(linhas 30 e 31) e atualizando os valores das variaveis que calculam a media do aluno no semestre.

Encerrada a digitacao das notas, o usuario deve digitar −1 para encerrar e, quando o faz, oprograma passa para a rotina de calculo da media (linha 34).

Com o valor da media, algumas verificacoes sao feitas para atualizar as estatısticas da turmaem questao. Em primeiro lugar, e verificado se a media alcancada pelo aluno e suficiente paraaprovacao. Em caso afirmativo, a variavel numAprovadosTurma e incrementada.

E verificado, em seguida (linha 40), se a media do aluno e maior que a maior media encontradaate entao. Em caso verdadeiro, a variavel maiorMediaTurma e atualizada, assim como a variavelalunoMaiorMediaTurma, que guardara a matrıcula desse aluno.

O comando de selecao da linha 45 e equivalente ao da linha 40. Desta vez, a intencao eatualizar os dados do aluno com pior rendimento.

Vale um comentario sobre os valores de inicializacao das variaveis maiorMediaTurma e me-norMediaTurma. E preciso ter em mente que, para a primeira verificacao de melhor e pioraluno de cada turma, os respectivos comandos de selecao devem comparar o valor da mediacalculada com os valores ja armazenados. O problema e que, para o primeiro aluno de cadaturma, essas variaveis ainda nao contem valores validos. Sendo assim, para evitar erros, avariavel maiorMediaTurma e inicializada com o menor valor possıvel para a media e a variavelmenorMediaTurma, ao contrario, e inicializada com o maior valor possıvel. Essa inicilizacaogarante que os dados do primeiro aluno serao corretamente assimilados como o melhor e o piorresultado encontrado. Essa condicao e correta no inıcio, pois os dados do primeiro aluno sao osunicos passados ao sistema ate entao.

O comando da linha 49 imprime os dados do aluno, informando sua matrıcula e a mediaalcancada. Em seguida o usuario deve informar o codigo da matrıcula do proximo aluno ouencerrar o cadastro dos dados da turma em analise, digitando −1.

Caso tenha encerrado as digitacoes de uma turma, o programa executa o calculo do respectivoaproveitamento (linha 54).

Feito isso, um comando de selecao verifica se o aproveitamento calculado e melhor que omelhor ja encontrado. Em caso afirmativo, as variaveis melhorAproveitamento e melhorTurmasao atualizadas para apontar para a turma recem analisada (linhas 56 e 57, respectivamente).

Terminando a sequencia de instrucoes do segundo comando de repeticao, os dados do melhore do pior aluno da turma sao exibidos (linhas 59 e 60). Por ultimo, e perguntado ao usuariose ele deseja incluir os dados de uma outra turma, bastando, para isso, digitar seu codigo. Sedigitar a flag −1, o comando de repeticao e encerrado e o programa exibira, em sua ultima linha,os dados da melhor turma (linha 64).

Page 64: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

64 CAPITULO 2. CONCEITOS BASICOS

2.12 Exercıcios Resolvidos

1. Faca um programa que calcule as raızes reais da equacao do segundo grau ax2 + bx+ c.

Pseudocodigo 2.13 Calculo das raızes da equacao do segundo grau ax2 + bx+ c.

Descricao: Algoritmo para calculo das raızes de uma equacao do segundo grau ax2 + bx+ c.Dados de Entrada: coeficientes a, b e c.Saıda do Programa: raızes da equacao.

Func~ao Principal:Leia os coeficientes a, b e c.Calcule delta igual a b*b-4*a*c.SE delta for maior ou igual a zero ENT~AO

SE delta for igual a zero ENT~AOCalcule a unica raiz igual a -b/(2*a).Imprima o valor da raiz.

SEN~AOCalcule a raiz1 igual a (-b + raiz quadrada de delta)/(2*a).Calcule a raiz2 igual a (-b - raiz quadrada de delta)/(2*a).Imprima os valores das raızes.

FIM-SESEN~AO

Imprima uma mensagem dizendo que n~ao ha raızes reais.FIM-SE

FIM-Func~ao Principal

1 main(){

2

3 float a, b, c, delta , raizDelta , raiz1 , raiz2;

4

5 printf("Informe os valores das constantes ’a’, ’b’ e ’c’ (separados por

espacos): ");

6 scanf("%f %f %f", &a, &b, &c);

7

8 delta = b*b - 4*a*c;

9

10 if (delta >= 0){

11 if (delta == 0) {

12 raiz1 = -b / (2*a);

13 printf("As duas raizes sao iguais a: %f.", raiz1);

14 } else {

15 raizDelta = sqrt(delta);

16 raiz1 = (-b + raizDelta) / (2 * a);

17 raiz2 = (-b - raizDelta) / (2 * a);

18 printf("As duas raizes s~ao: %f e %f", raiz1 , raiz2);

Page 65: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.12. EXERCICIOS RESOLVIDOS 65

19 }

20 } else {

21 printf("Nao existem raizes reais desta equacao!");

22 }

23 }

Exemplo 2.34: Programa para calcular as raızes reais de uma equacao do segundo grau.

2. Escreva um programa que escreva os n primeiros termos da sequencia de Fibonacci. Essasequencia tem zero como primeiro termo e 1 como segundo. Do terceiro termo em diante,a formula para obtencao e a soma dos dois anteriores.

1 main(){

2 int n, termoAtual , penultimoTermo , antePenultimoTermo , i;

3

4 printf("Informe o numero de termos a serem impressos: ");

5 scanf("%d", &n);

6

7 if (n >= 1) {

8 printf("0 ");

9 }

10 if (n >= 2) {

11 printf("1 ");

12 }

13

14 antePenultimoTermo = 0;

15 penultimoTermo = 1;

16 termoAtual = 2;

17 for (i=0; i < n-2; i=i+1) {

18 printf("%d ", termoAtual);

19 antePenultimoTermo = penultimoTermo;

20 penultimoTermo = termoAtual;

21 termoAtual = penultimoTermo + antePenultimoTermo;

22 }

23 }

Exemplo 2.35: Programa para calcular as raızes reais de uma equacao do segundo grau.

3. Fazer um programa para imprimir a tabuada de 1 a 9.

1 main(){

2 int n1 ,n2 ,r;

3

4 printf("\nTABUADA de 1 a 9\n\n");

5 n1=1;

6 n2=1;

7 while (n1 <10){

8 while (n2 <10){

Page 66: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

66 CAPITULO 2. CONCEITOS BASICOS

9 r=n1*n2;

10 printf("%d * %d = %d\n",n2,n1,r);

11 n2=n2+1;

12 }

13 printf("\n");

14 n2=1;

15 n1=n1+1;

16 }

17 }

Exemplo 2.36: Programa para exibir a tabuada de 1 a 9.

4. Calcular o Maximo Divisor Comum (MDC) de dois numeros. O MDC de dois numerospode ser obtido escolhendo o maior deles e subtraindo-lhe o valor do menor. Esta operacaoe repetida ate que os dois sejam iguais, cujo valor sera o MDC dos numeros iniciais:

33 15 45 1818 15 27 1803 15 09 1803 12 09 0903 09 MDC = 0903 0603 03MDC = 03

1 main(){

2 int numero1 , numero2 , auxiliar1 , auxiliar2;

3

4 printf("Digite dois numeros para calcular seu MDC: ");

5 scanf("%d %d", &numero1 , &numero2);

6

7 auxiliar1 = numero1;

8 auxiliar2 = numero2;

9

10 while (auxiliar1 != auxiliar2) {

11 if (auxiliar1 > auxiliar2) {

12 auxiliar1 = auxiliar1 - auxiliar2;

13 } else {

14 auxiliar2 = auxiliar2 - auxiliar1;

15 }

16 }

17 printf("O MDC vale %d\n", auxiliar1);

18 }

Exemplo 2.37: Programa para exibir o MDC de dois numeros.

Page 67: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.13. RESUMO 67

5. Faca um programa que converta um valor em base binaria para base decimal.

1 main(){

2 int binario , aux1 , aux2 , aux3 , decimal;

3

4 printf("Digite um valor em base binaria: ");

5 scanf("%d", &binario);

6

7 aux1 = binario;

8 aux2 = 1;

9 decimal = 0;

10 while (aux1 > 0) {

11 aux3 = aux1 % 10;

12 decimal = decimal + aux3*aux2;

13 aux2 = aux2 *2;

14 aux1 = aux1 /10;

15 }

16 printf("O valor %d em base binaria equivale a %d em base decimal\n",

binario , decimal);

17 }

Exemplo 2.38: Programa para converter numeros de binario para decimal.

2.13 Resumo

• O computador guarda as informacoes dos programas na memoria. A memoria pode serentendida como uma sequencia de celulas, cada uma identificada por um numero conhecidocomo endereco de memoria. Nas linguagens de programacao, as variaveis permitem oacesso as celulas de memoria sem a necessidade de manipular seus enderecos diretamente.

• Na linguagem C, para a declaracao de uma variavel, o programador deve informar qual otipo de dados que ela ira manipular.

• O comando de atribuicao permite atribuir uma determinada informacao (ou valor) a umavariavel do programa.

• Os identificadores sao nomes que identificam uma variavel ou constante. Eles sao formadospor caracteres alfanumericos, sendo que o primeiro deve ser obrigatoriamente alfabetico.

• Na programacao, os quatro tipos de dados mais comuns sao: tipo inteiro, tipo pontoflutuante, tipo booleano e tipo caractere.

• Variaveis e constantes podem ser combinadas com operadores para formarem expressoes.No comando de atribuicao, o valor da expressao (termos a direita do comando) e atribuıdoa variavel (a esquerda do comando).

• Os principais tipos de expressoes sao aritmetica, relacional e logica.

Page 68: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

68 CAPITULO 2. CONCEITOS BASICOS

• Na maioria dos problemas de computacao, os comandos de entrada de dados, saıda dedados, selecao e repeticao, sao imprescindıveis.

• Diversos problemas computacionais encaixam-se na modelagem do Problema dos LotesEncaixantes. Essa classe de problemas e facilmente resovida com o aninhamento de co-mandos de repeticao, os quais destinam-se a examinar um nıvel especıfico da massa dedados.

2.14 Exercıcios Propostos

1. Escreva um programa, em C, que recebe um valor de angulo em graus e informa os valoresdo seno, do cosseno e da tangente desse angulo.

2. Faca um programa, em C, que converta valores de temperatura de Fahrenheit para Celsius.A proporcao utilizada e:

TemperaturaCelsius

5=

(TemperaturaFahrenheit − 32)9

3. Faca um programa que calcule a soma

S =11

+32

+53

+ . . .+9950

4. Faca um programa que calcule a soma

S =37× 38

1− 36× 37

2+

35× 363

− . . .+ 1× 237

5. Um comerciante deseja aumentar suas vendas fazendo uma promocao. Os produtos queele trabalha e seus respectivos precos e codigos sao: a - anel - R$ 3,00, p - pulseira - R$5,00, b - brinco - R$ 5,00 e c - cinto - R$ 10,00. As promocoes oferecidas sao:

• comprar 1 unidade de cada produto, ganha-se um desconto de 10% no total da com-pra.

• comprar mais de 1 unidade de algum produto, ganha-se 5% de desconto no valortotal da compra. Faca um programa para simular a venda na loja do comerciante,recebendo como dado de entrada o codigo do produto e o codigo da promocao que ofregues quiser. Imprimir o valor original da compra e o valor com desconto. Utilize ocomando de selecao multipla (switch).

6. Fazer um programa que calcule e escreva uma tabela de graus centıgrados em funcao degraus farenheit que variam de 50 a 150 de 1 em 1.

7. Faca um programa para ler uma sequencia de n numeros inteiros positivos (um por vez),e verificar se eles sao pares ou ımpares.

Page 69: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

2.14. EXERCICIOS PROPOSTOS 69

8. Suponha que a populacao de um paıs A seja de 9.000 habitantes com uma taxa anual decrescimento de 3% e que a populacao de um paıs B seja, aproximadamente, de 20.000 dehabitantes com uma taxa anual de crescimento de 1,5%, fazer um programa que calculee escreva o numero de anos necessarios para que a populacao de paıs A ultrapasse ou seiguale a populacao do paıs B, mantidas estas taxas de crescimento.

9. Uma certa firma fez uma pesquisa de mercado para saber se as pessoas gostaram ou nao deum novo produto lancado no mercado. Para isso, obteve, para cada pessoa entrevistada,informacoes a respeito do sexo do entrevistado e sua resposta (S = Sim ou N = Nao).Sabe-se que foram entrevistados 2000 pessoas, fazer um programa que calcule e escreva:

• O numero de pessoas que responderam sim

• O numero de pessoas que responderam nao

• A porcentagem de pessoas do sexo feminino que responderam sim

• A porcentagem de pessoas do sexo masculino que responderam nao

10. A fabrica de chocolates ”MENINO” esta com problemas financeiros e pretende fazer umcorte na folha de pagamento. Para isso, o setor de financas adotou o seguinte criterio parareduzir a despesa com pessoal:

• funcionarios com tempo de servico menor que 2 anos (24 meses) serao demitidos;

• funcionarios com tempo de servico superior (ou igual) a 2 anos (24 meses) e menorque 10 anos (120 meses) terao seus salarios reduzidos em 10%;

• funcionarios com tempo de servico superior (ou igual) a 10 anos (120 meses) nao seraodemitidos e nem terao seus salarios reduzidos. Eles poderao optar por um plano dedemissao voluntaria com a seguinte proposta de indenizacao: 2 salarios atuais paracada ano de servico.

Faca um programa para:

(a) ler mes e ano correntes;

(b) ler os dados dos funcionarios que sao: matrıcula do funcionario, salario atual, mes eano de ingresso na fabrica. (obs: nao se sabe, a priori, o numero de funcionarios dafabrica).

(c) aplicar o criterio acima descrito;

(d) imprimir para cada funcionario: a matrıcula, o caso em que ele se enquadra no criterio.Se o funcionario se enquadrar na reducao do salario, imprimir o salario novo. Se ele seenquadrar no plano de demissao voluntaria, imprimir a indenizacao que o funcionariorecebera.

Page 70: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

Capıtulo 3

ModularizacaoCo-autor:

Gilberto Segundo

Objetivos:

• Definir o que e modularizacao;

• Apresentar as vantagens de um programa modularizado;

• Apresentar metodos de como criar e adaptar programas modularizados;

• Introduzir o conceito de recursividade e como usa-la

Os programas sao escritos a fim de resolverem varios tipos de problemas. Alguns dessesproblemas exigem mais tempo e maiores esforcos do programador. Por isso, e indispensavel queo programador utilize de tecnicas que visam uma maior organizacao e consequente entendimentofacilitado do programa. Uma das tecnicas mais utilizadas e a modularizacao.

Este capıtulo trata sobre o conceito e a pratica de programas modularizados.

3.1 Introducao

Quando se trabalha em qualquer problema complexo, seja em programacao, seja em outra area,o ser humano sente a necessidade de dividir esse problema maior em problemas menores. Cadaproblema menor e entao trabalhado de forma a solucionar as questoes que lhe cabem e, juntando-se cada uma dessas solucoes, tem-se a solucao do problema maior. Esse processo e chamado demodularizacao e baseia-se na conhecida tecnica de “dividir para conquistar”.

Pode-se aplicar a modularizacao em diversas areas na vida cotidiana. Para a fabricacao deum automovel, por exemplo, sao necessarios diversos servicos: funilaria, montagem, estofamento,pintura, soldagem, etc. A princıpio, poderia existir apenas um robo que fizesse todas as etapasda fabricacao do carro, mas isso acarretaria em alguns problemas, tais como: complexidade

70

Page 71: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.2. SUBPROGRAMAS 71

do robo, que deveria fazer todos os servicos de forma completa e eficiente; alto prejuızo emeventuais servicos de manutencao, que teria que parar todo o processo de montagem; falta declareza no entendimento do processo de fabricacao, o que prejudicaria a expansao do processode montagem; entre outras.

Uma otima alternativa para esse problema e fazer varios robos, cada um com sua funcaoespecıfica. O que se estaria fazendo na verdade e uma modularizacao.

Pode-se facilmente mover as ideias contidas no problema apresentado para a elaboracao deum programa. O programa pode ser dividido em varias partes, sendo que cada parte trata deuma determinada funcionalidade.

Dessa forma, o programa tem a sua legibilidade melhorada, uma vez que fica mais facilentender o que o programa faz por completo ou como o programa faz determinada subtarefa. Amodificabilidade do programa tambem e melhorada, uma vez que para se alterar determinadafuncionalidade, e necessario apenas alterar um pequena parte do codigo, nao sendo necessariomodificar varios pontos do codigo.

Como as funcionalidades do programa estando separadas logicamente, o programador tem aoportunidade de reutilizar uma parte do programa para escrever um outro programa que utilize,em uma de suas tarefas, o mesmo bloco de instrucoes. A confiabilidade do programa tambem eaumentada pelo fato dele ser mais facil de ser entendido e corrigido.

Por fim, a produtividade para a elaboracao de um programa tambem e aumentada, uma vezque cada parte do programa pode ser trabalhada por uma equipe diferente, alem de que cadaequipe so precisa saber o que as partes da outra equipe fazem e nao como fazem.

Nas secoes seguintes serao mostradas tecnicas de como fazer um programa modularizadoutilizando a linguagem C.

3.2 Subprogramas

Um subprograma e um trecho de um programa que realiza qualquer operacao computacional.Ele efetua parte de uma tarefa que um algoritmo maior deveria executar, ou seja, ele e umaparte do programa, especializado em alguma funcionalidade. Na linguagem C, o uso de funcoese a principal forma de modularizacao.

Uma funcao matematica f(x) e uma relacao que mapeia um dado valor x de um domınio emum unico valor y de um conjunto imagem. Em programacao, a ideia e semelhante: uma funcaoe um conjunto de instrucoes que recebe alguns valores como dados de entrada e, a partir deles,produz um valor como saıda. A Figura 3.1 ilustra o funcionamento de uma funcao matematica.

Figura 3.1: Funcao simples.

Page 72: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

72 CAPITULO 3. MODULARIZACAO

Em programacao, os dados de entrada sao chamados de parametros e o valor da saıda echamado de retorno. Durante a execucao da funcao, os dados de entrada sao manipulados demaneira a produzir o resultado esperado. Durante essa manipulacao de dados a funcao podechamar outras funcoes, que contem rotinas que auxiliam na elaboracao do resultado final. AFigura 3.2 ilustra esse processo.

Figura 3.2: Funcao usando outras funcoes.

Na fabricacao de um automovel, algum processo realizado por um determinado robo podesolicitar servicos de outros robos. Por exemplo, o robo que faz a colocacao das pecas no carropode solicitar por diversas vezes o servico do robo de soldagem de pecas. Apos a finalizacao dasoldagem da peca, o robo de montagem podera colocar outra peca no carro.

3.3 Partes de um Subprograma

As partes de um subprograma sao as mesmas de um programa, ou seja: cabecalho, dicionariode dados, corpo e comentario.

A seguir serao comentadas cada uma dessas partes, enfocando sua importancia nos subpro-gramas.

3.3.1 Cabecalho

O cabecalho do subprograma e onde estao definidos o nome do subprograma, os tipos dos seusparametros de entrada e o tipo de dado de retorno.

Os parametros da funcao sao os ingredientes que ela precisa para executar as suas instrucoese seus tipos devem ser fielmente respeitados. Ja o tipo de retorno da funcao simboliza o tipo deproduto gerado por ela. Se a funcao diz retornar um numero float, quer dizer que o programadordeve esperar receber apenas esse tipo de dado e tomar as medidas necessarias para manipula-loposteriormente.

O nome do subprograma serve para identifica-lo. O programador deve escolher nomes auto-explicativos sobre a funcionalidade da funcao, ou seja, para que ela serve. Isso torna o codigomais legıvel e menos susceptıvel a erros por parte do programador.

Page 73: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.3. PARTES DE UM SUBPROGRAMA 73

No Exemplo 3.1, a funcao calculaMedia possui dois parametros de entrada do tipo floate retorna um valor tambem do tipo float. O primeiro parametro recebe o nome a e o segundorecebe o nome b. A funcao retorna um dado do tipo float, ou seja, retornara um numero quecontem casas decimais. Mais detalhes sobre passagem de parametros, assim como o retorno defuncoes serao mostrados posteriormente.

1 float calculaMedia (float a, float b);

Exemplo 3.1: Cabecalho de um subprograma na linguagem C.

Percebe-se que o nome da funcao ja nos da a ideia do que que ela faz: calcula a media de doisnumeros. Porem, maiores explicacoes sobre essa media, se e aritmetica, geometrica ou outra,devem ser explicadas nos comentarios da funcao.

Quando a quantidade de parametros de uma funcao nao e respeitada, a funcao nao tem todosos dados necessarios para a realizacao de suas instrucoes. Na funcao do Exemplo 3.1, quandoo programador chama a funcao calculaMedia passando apenas um numero, ao inves de dois,o compilador avisa o programador sobre tal erro, nao deixando que o programa seja gerado.Assim, evita-se erros de execucao.

Tambem podem ocorrer erros quando a ordem ou tipo dos parametros nao sao respeitadas.No cotidiano, tambem ocorrem esses tipos de erros. Por exemplo, para que um carro funcione,ele precisa, entre outras coisas, de agua e oleo lubrificante. Caso a agua seja colocada no lugar dooleo lubrificante, ou o contrario, e previsıvel que o carro, em algum momento, apresente falhasna execucao de suas operacoes, nao se locomovendo. Assim, fica facil perceber que um bomprogramador deve sempre verificar se esta respeitando os tipos dos parametros das funcoes.

3.3.2 Dicionario de dados

O dicionario de dados e onde se faz a declaracao de variaveis e constantes usadas no subprogramae nao declaradas no cabecalho da funcao.

Quando se declara variaveis em subprogramas, estas so podem ser utilizadas naquele sub-programa. Qualquer outro subprograma, mesmo aquele que chamou a funcao, nao tem acessoa essas variaveis. Assim, por existirem e serem acessıveis apenas naquele subprograma, saochamadas de variaveis locais.

Considere novamente o exemplo do funcionamento da fabrica de automoveis. Enquantoo subprograma “Robo de solda” estiver fazendo seu trabalho (soldagem de pecas), algumasinformacoes usadas em alguns procedimentos necessitam ser criadas, tais como: quantidade desolda, qualidade da solda, metodo de soldagem, etc. Quando o “Robo de solda” termina seutrabalho, essas informacoes nao sao mais necessarias. Note que os outros robos nao precisamsaber dessas informacoes para poderem executar seus trabalhos.

Para representar em um programa o funcionamento de uma fabrica de automoveis, cadarobo poderia ser representado por um subprograma. As informacoes seriam representadas porvariaveis locais. A Figura 3.3 ilustra essa correspondencia. O “Robo de pintura” tem duas

Page 74: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

74 CAPITULO 3. MODULARIZACAO

variaveis: quantidade de tinta e cor da tinta. Essa variaveis nao sao visıveis para os outrosrobos; em particular, para o robo de solda.

Figura 3.3: Dicionario de dados.

3.3.3 Corpo

O corpo do subprograma e onde estao contidas as instrucoes a serem executadas pelo subpro-grama. Nele, podem ser realizadas operacoes, tais como: atribuicoes de valores as variaveis,chamadas de outras funcoes, calculos de expressoes, leitura de dados e apresentacao de resulta-dos.

O Pseudocodigo 3.1 descreve uma funcao que calcula a distancia entre dois pontos no planocartesiano.

Pseudocodigo 3.1 Passos a serem relizados pela funcao

Processo componente "distancia":

Usar o teorema de Pitagoras para calcular a distancia dos pontos dados

Retornar o valor da distancia

FIM -Processo componente "distancia"

O Exemplo 3.2 mostra a implementacao na linguagem C do Pseudocodigo 3.1. O corpo ecomposto de atribuicao de valores as variaveis dx, dy e dist atraves de calculos matematicos epelo retorno do valor contido em dist. O retorno de dados e estudado na Secao 3.6.

Essa funcao recebe como parametro as coordenadas de dois ponto no plano cartesiano eretorna a distancia entre esses pontos. Para fazer o calculo dessa distancia, primeiramentecalcula-se a distancia entre as coordenadas x (armazenando esse valor em dx) e a distanciaentre as coordenadas y (armazenando esse valor em dy). Posteriormente, usa-se o teorema dePitagoras para calcular a distancia entre os pontos dados.

Page 75: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.3. PARTES DE UM SUBPROGRAMA 75

1 float distancia (float x1 , float y1 , float x2 , float y2){

2

3 float dx , dy , dist;

4

5 dx = x2 - x1;

6

7 dy = y2 - y1;

8

9 dist = sqrt (dx*dx + dy*dy);

10

11 return dist;

12 }

Exemplo 3.2: O corpo do subprograma sao as instrucoes contidas nele.

3.3.4 Comentarios

Para melhor legibilidade e entendimento do codigo do subprograma, e recomendavel fazer co-mentarios.

Acima de cada subprograma pode-se colocar comentarios com as seguintes finalidades: dizerpara que essa funcao serve, quais os parametros que ela recebe, explicitando como devem seresses parametros (unidade de medida, relevancia para a funcao, etc), restricoes para aplicacoes,entre outras.

No dicionario de dados, os comentarios podem ser usados para explicar o significado de al-guma variavel cujo nome nao e suficientemente significativo. No corpo da funcao, os comentariospodem ser usados para explicar o que foi feito em determinado conjunto de instrucoes cujo en-tendimento nao e facil ou que nao tem utilidade aparente.

Na linguagem C, os comentarios dos subprogramas devem ser feitos da mesma maneira usadapara comentar o programa, entre “/*” e “*/” ou apos “//”, como explicado no Capıtulo 1.

O Exemplo 3.3 mostra um comentario geral da funcao distancia , explicando os parametrosda funcao e como e feito o calculo.

1 /*

2 Func~ao para calcular a distancia entre dois pontos no plano cartesiano.

3 Dados de entrada:

4 float x1: a coordenada x do primeiro ponto.

5 float y1: a coordenada y do primeiro ponto.

6 float x2: a coordenada x do segundo ponto.

7 float y2: a coordenada y do segundo ponto.

8

9 Dados de saıda:

10 dist: retorna a distancia entre os pontos passados

11 */

12

13 float distancia (float x1 , float y1 , float x2 , float y2){

14

Page 76: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

76 CAPITULO 3. MODULARIZACAO

15 float dx , dy , dist;

16

17 dx = x2 - x1;

18

19 dy = y2 - y1;

20

21 dist = sqrt (dx*dx + dy*dy);

22

23 return dist;

24 }

Exemplo 3.3: Comentarios em um subprograma.

3.4 Chamada de subprogramas

Em programacao, quando um subprograma solicita servicos de um outro subprograma dizemosque foi feita uma chamada ao subprograma. Durante a execucao de um programa, podem serfeitas diversas chamadas a um mesmo subprograma.

Considere o exemplo do funcionamento da fabrica de automoveis. O “Robo de Solda” podeser chamado diversas vezes durante o processo de fabricacao de um carro e, e claro, em pon-tos de montagem diferentes. Toda vez que ele e chamado, executa novamente o seu servico,considerando as particularidades de cada caso.

Em programacao acontece o mesmo. Um mesmo subprograma pode ser chamado em diversospontos do codigo. A funcao distancia , descrita no Exemplo 3.2, pode ser usada para fazervarios calculos de distancias entre pontos diferentes e em varios lugares diferentes de um mesmoprograma.

A chamada de um subprograma na linguagem C e feita digitando o nome da funcao e, em se-guida, digitando os dados de entrada necessarios entre parenteses, para que assim o subprogramaexecute suas instrucoes.

No Exemplo 3.4, a funcao distancia e chamada duas vezes. Na primeira vez, ela e cha-mada para calcular a distancia entre duas cidades, sendo fornecidas as coordenadas x e y emquilometros de distancia das cidades. A segunda chamada da funcao e feita para calcular adistancia entre dois moveis de um escritorio.

Note que as coordenadas passadas para o subprograma em cada momento podem ser di-ferentes, fazendo com que o programa calcule distancias diferentes. A interpretacao fısica dascoordenadas passadas tambem pode ser diferente, nao alterando a funcionalidade do subpro-grama.

1 #include <stdio.h>

2 #include <math.h>

3

4 float distancia (float x1 , float y1 , float x2 , float y2){

5

6 float dx , dy , dist;

Page 77: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.5. PASSAGEM DE PARAMETROS 77

7

8 dx = x2 - x1;

9

10 dy = y2 - y1;

11

12 dist = sqrt (dx*dx + dy*dy);

13

14 return dist;

15 }

16

17

18 main (){

19 float xa , xb , ya , yb , dist;

20

21 printf ("Forneca as coordenadas x e y (em quilometros) das cidades A e B,

respectivamente: ");

22

23 scanf ("%f%f%f%f", &xa ,&ya ,&xb ,&yb);

24

25 dist = distancia (xa,ya,xb,yb);

26

27 printf ("Distancia em quilometros entre as cidades A e B: %f\n", dist);

28

29 printf ("Forneca as coordenadas x e y (em metros) da cadeira e da mesa do seu

escritorio: ");

30 scanf ("%f%f%f%f", &xa ,&ya ,&xb ,&yb);

31

32 dist = distancia (xa,ya,xb,yb);

33

34 printf ("Distancia em metros entre a cadeira e a mesa do seu escritorio: %f\n

", dist);

35 }

Exemplo 3.4: Chamadas de um mesmo subprograma

3.5 Passagem de parametros

Os parametros de uma funcao sao os dados iniciais necessarios que ela possa realizar o seutrabalho. Por exemplo, a funcao matematica: y(x) = x2 calcula o quadrado do numero x, quefoi passado como parametro para a funcao. Voltando ao exemplo da fabricacao de um carro,pode-se dizer que a fabrica e o programa principal. Ao final do processo, ela deve fornecer umcarro pronto para o uso. Mas a fabrica, como ja foi dito, nao conta apenas com um robo parafazer todo o processo e sim com varios robos, cada um com sua funcao especıfica.

Cada robo deve receber uma entrada e fornecer uma saıda. Para o “Robo de Pintura”,as entradas sao: a carroceria do carro, feita por outro robo, e a cor usada para pinta-la. Apartir dessas entradas, o “Robo de Pintura” executa as instrucoes estabelecidas para pintar acarroceria. Ao final da pintura, o robo esta pronto para fornecer a saıda: a carroceria pintada.

Page 78: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

78 CAPITULO 3. MODULARIZACAO

Essa saıda pode servir como entrada para outro robo.Cada parametro de uma funcao possui um tipo, declarado no cabecalho da funcao, como

mostrado no Exemplo 3.1, onde os parametros a e b sao do tipo float. Quando e feita uma cha-mada ao subprograma, podem ser passados como parametro os valores de variaveis do programaprincipal, que obrigatoriamente devem ser do mesmo tipo dos parametros da funcao chamada.

No Exemplo 3.4, sao feitas varias chamadas ao subprograma distancia . Em cada uma dessaschamadas sao passadas entradas distintas, nesse caso, pontos diferentes no plano cartesiano.Considere que na primeira chamada os pontos passados sao: xa = 10, ya = 30, xb = 20, yb =60. Ja na segunda chamada foram passados os pontos: xa = 15, ya = 18, xb = 5, yb = 53. AFigura 3.4 ilustra esse processo.

Figura 3.4: Passagem de parametro.

Quando o programa principal chama o subprograma distancia , os valores que estao contidosnas variaveis xa, ya, xb e yb sao passados para as variaveis x1, y1, x2 e y2 do subprograma.

E importante perceber que, quando e feita uma passagem de parametros, apenas os valoresdas variaveis sao passados para o subprograma chamado e nao as variaveis em si. Esse metodode passagem de parametro e chamado de passagem por copia, ou entao, passagem por valor.

A primeira implicacao dessa regra e a a nao necessidade de se usar variaveis como entradapara outra funcao, podendo-se usar diretamente um valor. O Exemplo 3.5 ilustra essa ideia. Noprograma principal e feita a chamada ao subprograma distancia passando-se os valores 10 ,−15 , 26 e −23 como parametros. Na funcao distancia , as variaveis x1, y1, x2 e y2 recebemesses valores, para so entao a funcao iniciar suas instrucoes.

Page 79: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.5. PASSAGEM DE PARAMETROS 79

1 #include <stdio.h>

2

3 float distancia (float x1 , float y1 , float x2 , float y2){

4

5 float dx , dy , dist;

6

7 dx = x2 - x1;

8

9 dy = y2 - y1;

10

11 dist = sqrt (dx*dx + dy*dy);

12

13 return dist;

14 }

15

16 main (){

17 int dist;

18

19 dist = distancia (10, -15, 26, -23);

20

21

22 }

Exemplo 3.5: Passagem de parametros.

Outra implicacao do fato de que apenas valores sao passados como parametro para umafuncao e a impossibilidade de mudar o conteudo das variaveis que sao usadas como entradapara a funcao. No Exemplo 3.6, a variavel a, da funcao dobraValor , recebe apenas o valorda variavel x da funcao principal. Com isso, a variavel x permanece com o seu valor anterior achamada da funcao dobraValor , apesar da variavel a dessa funcao ter o seu valor alterado.

1 #include <stdio.h>

2

3 int dobraValor (int a){

4 printf ("Numero original: %d \n", a);

5

6 a = 2*a;

7

8 printf ("O seu dobro e: %d \n", a);

9

10 return a;

11 }

12

13 main (){

14 int x = 10;

15

16 dobraValor (x);

17

18 printf ("O valor de x e: %d \n", x);

Page 80: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

80 CAPITULO 3. MODULARIZACAO

19 }

Exemplo 3.6: Passagem de valor na chamada de subprogramas.

A saıda da execucao do programa do Exemplo 3.6 e mostrada no Exemplo 3.7. Note que,como esperado, a variavel x permaneceu com o seu valor original.

1 Numero original: 10

2 O seu dobro e: 20

3 O valor de x e: 10

Exemplo 3.7: Saıda da execucao do programa do Exemplo 3.6.

Uma outra implicacao do metodo de passagem de valores e a nao visibilidade das variaveisdo programa principal no subprograma chamado, ou seja, o subprograma nao pode utilizar asvariaveis do programa principal ou de algum outro subprograma. No Exemplo 3.8, as variaveisx e y nao podem ser acessadas dentro da funcao alteraValor . Com isso, o compilador emiteum erro quando o programa e compilado, dizendo que as variaveis x e y nao foram declaradasanteriormente e a compilacao do programa e interrompida.

1 void alteraValor (void){

2 x = 20;

3 y = x*5;

4 }

5

6 main (){

7 int x = 10, y = 15;

8

9 alteraValor ();

10 }

Exemplo 3.8: Visibilidade das variaveis.

O que ocorre no Exemplo 3.8 tambem pode ser comparado com os robos da fabrica deautomoveis. O “Robo de Solda” nao pode usar a variavel local cor do automovel do “Robo dePintura”. O “Robo de Solda” nao sabe o que e essa variavel, nem que ela existe, assim, naopode usa-la.

3.6 Retorno de dados

Esta secao trata da forma como os dados sao retornados em cada subprograma, isto e, como seproduz uma saıda da funcao.

Um subprograma produz, no decorrer das suas instrucoes, um valor final (uma saıda), quedevera ser passado para o programa ou mesmo subprograma que o chamou. O valor retornadopelo subprograma sera atribuıdo a alguma variavel do programa que chamou essa funcao, ouentao usado em alguma expressao.

Page 81: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.6. RETORNO DE DADOS 81

Na linguagem C, deve-se declarar o tipo de dado retornado pela funcao em seu cabecalhoe usa-se o comando return para especificar a variavel ou valor que deve ser retornado. Apos asua execucao, a execucao da funcao corrente termina, mesmo que existam mais instrucoes aposo return. Na implementacao da funcao distancia , feita no Exemplo 3.2, o valor contido navariavel dist e retornado.

Como a main tambem e uma funcao, tambem temos que especificar o tipo de dado retornadopor ela. Por padrao, na linguagem C, a funcao main retorna um valor tipo int. Quando oprogramador nao coloca nenhum valor para ser retornado pela main (como no Exemplo 3.9),alguns compiladores fazem com que o valor 0 seja retornado por padrao. O valor 0 tambem eusado para simbolizar que nada aconteceu de errado na execucao do programa.

Neste livro, optou-se por nao explicitar o valor retornado pela funcao main, ja que este valornao sera usado no programa. Contudo, vale lembrar que alguns compiladores exigem que oretorno da main esteja escrito no codigo fonte, ficando a cargo do programador a percepcao daobrigatoriedade de escreve-lo.

Considere um programa que calcula a media de um aluno e diz se ele foi aprovado ou nao.O Pseudocodigo 3.2 mostra os passos a serem realizados pelo programa.

Pseudocodigo 3.2 Programa para calcular a media de um aluno.

Func~ao Principal:

Usar o processo componente "calculaMedia" passando -se as 2 notas de provas

do aluno como parametros.

Verificar se a media retornada e maior ou igual a sete.

Caso afirmativo:

O aluno esta aprovado.

Caso negativo:

Usar o processo componente "calculaMedia" passando -se a media

anterior e a nota da prova final do aluno como parametros.

Verificar se a nova media retornada e maior ou igual a cinco.

Caso Afirmativo;

O aluno esta aprovado.

Caso negativo:

O aluno esta reprovado.

FIM -Func~ao Principal

Processo componente "calculaMedia":

Somar os dois numeros passados como parametros e dividir o resultado por

dois.

Retornar o resultado acima.

FIM -Processo componente "calculaMedia"

Uma possıvel implementacao do Pseudocodigo 3.2 esta transcrita no Exemplo 3.9. Primei-ramente, o programa pede que o usuario digite os valores das notas das duas provas realizadaspelo aluno. Essas notas sao armazenadas nas variaveis nota1 e nota2 respectivamente e, logoem seguida, sao passadas como parametros para a funcao calculaMedia . A funcao calcula-Media recebe dois valores do tipo float e faz a media aritmetica deles, retornando, ao final da

Page 82: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

82 CAPITULO 3. MODULARIZACAO

sua execucao, o valor dessa media. O valor retornado e armazenado na variavel resultado dafuncao principal, que por sua vez serve de condicao para a aprovacao do aluno. Caso o valorarmazenado em resultado seja maior ou igual a sete, o aluno esta aprovado; caso contrario, oprograma pede a nota da prova final do aluno, que e armazenada na variavel notaFinal. Asvariaveis notaFinal e resultado sao entao usadas como parametros da funcao calculaMedia .Caso o resultado retornado seja maior ou igual a cinco, o aluno esta aprovado.

1 #include <stdio.h>

2

3 float calculaMedia (float a, float b){

4 float media;

5

6 media = (a+b)/2;

7

8 return media;

9 }

10

11 main (){

12 float nota1 , nota2 , notaFinal , resultado;

13

14 printf ("Forneca as notas das duas provas do aluno: ");

15 scanf ("%f%f", &nota1 , &nota2);

16

17 resultado = calculaMedia (nota1 , nota2);

18

19 printf ("A media do aluno foi: %f\n", resultado);

20

21 if (resultado >= 7){

22 printf ("O aluno passou de semestre .\n");

23 }

24 else{

25 printf ("O aluno teve que fazer prova final. Forneca a nota da prova final

do aluno: ");

26 scanf ("%f", &notaFinal);

27

28 if (calculaMedia (resultado , notaFinal) >= 5){

29 printf ("O aluno passou de semestre .\n");

30 }

31 else{

32 printf ("O aluno n~ao obteve o rendimento mınimo para passar de semestre

. Esta reprovado .\n");

33 }

34 }

35 }

Exemplo 3.9: Retorno de dados.

Note que, na primeira chamada da funcao calculaMedia , o valor retornado foi armazenadoem uma variavel, pois precisa ser usado posteriormente. Ja na segunda chamada da funcao, o

Page 83: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.6. RETORNO DE DADOS 83

valor retornado e usado diretamente na condicional de aprovacao ou nao do aluno, nao sendonecessario seu armazenamento em alguma variavel. Mas atencao: caso fosse necessario usar essevalor posteriormente, deverıamos guarda-lo em alguma variavel, ao inves de chamar outra veza funcao calculaMedia usando os mesmos parametros. Essa chamada sendo feita novamenteacarretaria em perda de desempenho do programa, ja que a funcao teria que recalcular valores,o que levaria um certo tempo para ser feito.

Em muitos casos e interessante, ou ate necessario, que o subprograma altere as variaveiscriadas no programa que o chamou. No exemplo da fabrica de automoveis e isso que deveacontecer. A Figura 3.5 ilustra esse processo.

Figura 3.5: Passagem de parametro por referencia.

Nesse exemplo, o carro que e passado para o robo de solda esta com varias pecas soltas.Entao, o robo solda essas pecas e passa o carro para o robo de pintura. Nesse caso, percebe-se que deve-se passar o mesmo carro para o proximo robo e nao apenas um copia das suascaracterısticas, que simbolizam os valores das variaveis em programas. Entao, o carro recebe apintura e e passado como parametro para uma proxima funcao, ou seja, para um outro robo.

Como discutido na Secao 3.5, nao e possıvel para um subprograma que recebe o valor deuma variavel de um outro subprograma, alterar diretamente o valor da variavel do subprogramaque o chamou. Nesse caso, pode-se retornar o valor calculado e entao armazena-lo na variaveldesejada. A expressao geral e x = f(x).

Por exemplo, pode-se fazer uma variacao do uso da funcao dobraValor usada no Exemplo3.6 para alterar o valor da variavel do programa que a chamou. Essa alteracao esta descrita noExemplo 3.10. Nesse exemplo, o valor retornado pela funcao dobraValor agora e armazenadona variavel x.

1 #include <stdio.h>

2

3 int dobraValor (int a){

4 printf ("Numero original: %d \n", a);

Page 84: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

84 CAPITULO 3. MODULARIZACAO

5

6 a = 2*a;

7

8 printf ("O seu dobro e: %d \n", a);

9

10 return a;

11 }

12

13 main (){

14 int x = 10;

15

16 x = dobraValor (x);

17

18 printf ("O valor de x e: %d \n", x);

19 }

Exemplo 3.10: Atualizacao da variavel de outra funcao.

A saıda da execucao do programa do Exemplo 3.10 e mostrada no Exemplo 3.11. Note quea variavel x passou a ter o valor 20.

1 Numero original: 10

2 O seu dobro e: 20

3 O valor de x e: 20

Exemplo 3.11: Saıda da execucao do programa do Exemplo 3.6.

3.6.1 Encerramento antecipado de execucao

Observando a definicao de calculaMedia , implementada no Exemplo 3.9, nota-se que o valorso e retornado ao final da funcao, quando todas as outras instrucoes foram executadas. Noentanto, e possıvel ocorrer de um subprograma ter varios pontos de retorno distintos.

No Pseudocodigo 3.3 sao mostrados os passos realizados pela funcao ehDivisor , que verificase um numero e divisor do outro. Para evitar um erro matematico, tem-se que verificar se odivisor e diferente de zero. Se for igual a zero, entao a execucao da funcao deve ser interrompidae o erro devera ser indicado de alguma forma. Nesse caso, escolheu-se retornar o valor 0.

No Exemplo 3.12 e apresentada a implementacao, na linguagem C, do Pseudocodigo 3.3.Note que a funcao apresenta tres pontos distintos de retorno. No primeiro, e verificado se odivisor e zero e caso isso seja verdade e retornado o valor 0, caso contrario, a funcao continuaexecutando suas instrucoes. No segundo, e verificado se o resto da divisao inteira de x por y ezero, ou seja, e verificado se y e divisor de x. Caso isso seja verdade e retornado o valor 1, casocontrario, e retornado o valor −1, simbolizando que y nao e divisor de x. Aqui, o valor 1 foiusado para simbolizar sucesso na verificacao.

Note ainda que esse recurso torna a funcao mais eficiente e legıvel.

Page 85: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.6. RETORNO DE DADOS 85

Pseudocodigo 3.3 Funcao que determina se um numero e divisor do outro

Processo componente "ehDivisor":

Verificar se o divisor e igual a zero

Caso afirmativo:

Retornar o valor zero

Verificar se o resto da divis~ao do dividendo pelo divisor e igual a zero

Caso afirmativo:

Retornar o valor 1

Caso contrario:

Retornar o valor -1

FIM -Processo componente "ehDivisor"

1 int ehDivisor (int x, int y){

2 if (y == 0){

3 return 0;

4 }

5

6 if (x%y == 0){

7 return 1;

8 }else{

9 return -1;

10 }

11 }

Exemplo 3.12: Encerramento antecipado para evitar erros

Ainda no Exemplo 3.12, o encerramento antecipado de execucao foi feito para evitar umerro na execucao do programa. Porem, o encerramento antecipado de execucao pode ser feitonaturalmente, sem o objetivo de evitar erros de execucao.

Considere o caso do Exemplo 3.9. O programa principal poderia ser na verdade um sub-programa que retorna 1 caso o aluno esteja aprovado e −1 caso contrario. Se o aluno obtivermedia 7 apenas com as duas primeiras notas, a execucao do programa e interrompida e o valor1 e retornado. Essa alteracao esta descrita no Exemplo 3.13. Note que nao e necessario o usodo else na linha 20, pois caso a o resultado da media seja maior ou igual a sete, a funcao irainterromper sua execucao, nao acarretando o calculo invalido da media considerando a nota daprova final do aluno, que nao foi feita.

1 #include <stdio.h>

2

3 float calculaMedia (float a, float b){

4 float media;

5

6 media = (a+b)/2;

7

8 return media;

Page 86: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

86 CAPITULO 3. MODULARIZACAO

9 }

10

11 int aprovado (float nota1 , float nota2 , float notaPF){

12 float resultado;

13

14 resultado = calculaMedia (nota1 , nota2);

15

16 if (resultado >= 7){

17 return 1;

18 }

19

20 if (calculaMedia (resultado , notaPF) >= 5){

21 return 1;

22 }

23 else{

24 return 0;

25 }

26 }

27

28 main(){

29 float nota1 , nota2 , notaPF;

30 int passou;

31

32 printf ("Forneca as notas das duas provas do aluno e a nota da prova final.

Caso o aluno n~ao tenha feito prova final , digite zero: ");

33 scanf ("%f%f%f", &nota1 , &nota2 , &notaPF);

34

35 passou = aprovado(nota1 ,nota2 ,notaPF);

36

37 if (passou == 1){

38 printf ("O aluno passou de semestre .\n");

39 }

40 else{

41 printf ("O aluno n~ao obteve o rendimento mınimo para passar de semestre.

Esta reprovado .\n");

42 }

43 }

Exemplo 3.13: Encerramento antecipado natural.

3.7 Funcoes sem lista de parametros

Ate agora as funcoes mostradas continham dados de entrada, ou seja, uma lista de parametros.Mas ha casos em que isso nao e necessario, pois a funcao executa suas instrucoes sem precisarde dados de entrada. Alguns leitores podem achar que isso faz com que o subprograma retornesempre o mesmo dado, afinal, a ausencia de dados de entrada tornaria a funcao uma funcaoconstante.

Esse pensamento estaria correto se o subprograma nao pudesse coletar dados externos,

Page 87: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.8. FUNCOES SEM RETORNO DE DADOS 87

usando por exemplo a funcao scanf.No Exemplo 3.14 a funcao lerNumeros nao tem nenhum parametro de entrada. Isso foi feito

pois ela sempre executara a mesma rotina: lera 5 numeros digitados pelo usuario e fara a somadeles. E facil perceber que o resultado retornado pode variar a cada chamada da funcao. Issoacontece pois essa funcao usa os dados retornados por scanf para completar suas instrucoes.Note que em C usa-se void na lista de parametros para simbolizar que a funcao nao possuiparametros de entrada.

1 int lerNumeros (void){

2 int x=0, temp , i;

3

4 for (i=0 ; i<5 ; i++){

5 printf ("digite um numero: ");

6 scanf ("%d", &temp);

7 x += temp;

8 }

9

10 return x;

11 }

Exemplo 3.14: Lista de parametros vazia

3.8 Funcoes sem retorno de dados

Assim como ha funcoes que nao tem nenhum parametro, tambem ha funcoes que nao retornamnenhum tipo de dado. Na linguagem C, para simbolizar essa situacao usa-se void como tipo dedado retornado.

O Exemplo 3.15 exibe uma funcao que nao retorna dados para a funcao que a chamou. Afuncao multiplica recebe tres numeros e exibe o resultado da multiplicacao destes. Nota-se quenenhum dado e retornado, nem mesmo o valor da multiplicacao. O programador pode decidirpor este tratamento caso o resultado da multiplicacao nao seja usado posteriormente.

1 void multiplica (float a, float b, float c){

2

3 printf ("Resultado = %f", a*b*c);

4

5 }

Exemplo 3.15: Funcao sem retorno.

Funcoes sem retorno de dados podem guardar os valores gerados em algum arquivo. Caso issoseja feito, os dados podem ser recuperados lendo-se esses arquivos. A manipulacao de arquivos,tanto para leitura, tanto para escrita, e discutida na capıtulo 8.

Ha tambem a opcao da funcao nao ter nenhum parametro de entrada e nenhum dado retor-

Page 88: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

88 CAPITULO 3. MODULARIZACAO

nado. O Exemplo 3.16 mostra uma funcao para exibir uma saudacao ao usuario. Note que afuncao nao possui parametros de entradas nem valor de retorno.

1 void saudacao (void){

2 printf ("Bem -vindo ao programa Calculo Eletronico , onde seus calculos

s~ao resolvidos rapidamente\nPara mais informac~oes e atualizac~oes

acesse o site: www.programaemc.com.br");

3

4 }

Exemplo 3.16: Funcao sem parametro e sem retorno.

3.9 Recursividade

A recursividade ocorre quando algo e definido a partir de si mesmo. Uma recursao sempre edefinida a partir de uma ou mais relacoes recursivas (quando o proximo elemento e definido apartir do anterior), e uma ou mais bases de recursao (pontos de parada).

Em programacao, o metodo recursivo pode ser usado para definir uma funcao. Por exemplo,pode-se definir uma lista como sendo a uniao de um elemento com uma lista. Essa lista poderiaser mais um elemento com mais uma lista ou apenas uma lista vazia. Pode-se simplificar essadefinicao por:

lista = lista vazia ⇒ base da recursaolista = elemento + lista ⇒ relacao recursiva

Por exemplo, o calculo do fatorial de um numero inteiro nao negativo pode ser implementadoatraves de uma funcao recursiva. Pode-se definir o fatorial de um numero n como sendo o proprionumero n multiplicado pelo fatorial do numero n-1. A definicao de fatorial pode ser representadapor:

fatorial (0) = 1 ⇒ base da recursaofatorial (n) = n * fatorial (n-1) ⇒ relacao recursiva

Nas definicoes recursivas anteriores sao usados criterios de parada a fim de que o processorecursivo tivesse um limite. Imagine se uma lista fosse definida somente como um elementoconcatenado com uma lista. Por essa definicao nunca se teria uma lista finita, pois sempre novoselementos teriam que ser adicionados. Para evitar isso usa-se um criterio de parada, chamadode base da recursao. No exemplo da definicao da lista, a base da recursao e uma lista vazia. Noexemplo do fatorial de um numero, a base da recursao pode ser o numero 0, ou seja, e como sedissesse: “quando chegar ao numero 0 pare”.

O Pseudocodigo 3.4 mostra os passos a serem seguidos para o calculo do fatorial de umnumero de forma recursiva.

Page 89: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.9. RECURSIVIDADE 89

Pseudocodigo 3.4 Fatorial de um numero de forma recursiva.

Processo componente "fatorial":

Verificar se o numero passado como parametro e igual a zero

Caso Afirmativo:

Retornar o valor 1.

Caso Negativo:

Retornar o numero passado como parametro multiplicado pelo valor do

fatorial do seu antecessor.

FIM -Processo componente "fatorial"

A implementacao recursiva do fatorial na linguagem C e mostrada no Exemplo 3.17. Oprograma chama ele mesmo quantas vezes forem necessarias ate que o parametro n seja 0.Quando isso acontece, a funcao retorna 1 e a execucao prossegue a partir da ultima chamada dafuncao, multiplicando o valor retornado (1) pelo valor 1 da chamada anterior da funcao e assimsucessivamente, ate se obter o fatorial do numero n inicial.

1 int fatorial (int n){

2 if (n == 0){

3 return 1;

4 }else{

5 return n * fatorial (n-1);

6 }

7 }

Exemplo 3.17: Implementacao recursiva do fatorial.

E importante o compreender que a cada chamada do programa fatorial e reservado umnovo espaco de memoria, ou seja, os dados do programa fatorial anterior sao preservados ecaso a funcao recursiva tivesse variaveis locais, novas instancias dessas variaveis seriam criadasa cada chamada, sem qualquer relacao com as variaveis da outra chamada do subprograma. Porisso, funcoes recursivas tendem a necessitar de mais memoria do computador.

Chamando a funcao fatorial passando-se como argumento o numero 5, tem-se o esquemailustrado na Figura 3.6. As setas direcionadas para baixo significam a chamada do programaapontado, exibindo o valor passado para como parametro. As setas direcionadas para cimasignificam o retorno do dado do programa chamado, mostrando o valor retornado pela funcao.

Page 90: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

90 CAPITULO 3. MODULARIZACAO

Figura 3.6: Fatorial utilizando recursao.

3.9.1 Implementacao nao recursiva equivalente

Em geral, toda funcao recursiva pode ser implementada sem recursao, atraves do uso de coman-dos de repeticao. A vantagem da versao nao recursiva e a eficiencia. Ja a vantagem da recursivae a elegancia, legibilidade e redigibilidade.

O Exemplo 3.18 mostra uma forma nao recursiva da implementacao da funcao fatorial. Ocomando for e utilizado para multiplicar o f por i a cada valor de i, ate que i assuma o valor den, passado como parametro.

1 int fatorial2 (int n){

2 int i, f;

3

4 f = 1;

5

6 for (i=2, i <= n; i++){

7 f= f*i;

8 }

9 return f;

10 }

Exemplo 3.18: Implementacao nao recursiva do fatorial.

Page 91: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.10. EXERCICIOS RESOLVIDOS 91

3.10 Exercıcios Resolvidos

Exercıcio Resolvido 3.1 - Soma de inteiros

Faca uma funcao que receba um numero inteiro positivo n, calcule a soma dos n primeirosnumeros naturais e retorne esse valor. Considere os numeros naturais comecando do 1. Nao usea formula de P.A. (Progessao aritmetica).

Solucao Possıvel:

Para produzir a soma dos n primeiros inteiros deve-se gerar a serie dos n primeiros valoresinteiros e acumula-los em uma variavel soma.

Na Figura 3.7 e mostrado um exemplo de solucao para n = 4. Note que a medida que osvalores de i sao gerados eles sao acumulados em soma. Fica claro que e necessaria a realizacaode uma repeticao para produzir os valores de i e atualizar soma.

i soma1 12 33 64 10

Figura 3.7: Solucao para n = 4.

O Pseudocodigo 3.5 mostra o algoritmo que descreve os passos a serem realizados pela funcao.

Pseudocodigo 3.5 Passos a serem realizados pela funcao soma .

Processo componente "soma":

Inicializar soma com o valor zero

Para um loop de 1 a n:

Acumular em soma o valor corrente de i

Retornar o valor soma

FIM -Processo componente "soma"

O Exemplo 3.19 mostra a implementacao desse algoritmo. Note que o pseudocodigo foiseguido fielmente, acrescentado-se apenas instrucoes necessarias e especıficas da linguagem C.

Page 92: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

92 CAPITULO 3. MODULARIZACAO

1 int soma (int n){

2 int i, soma;

3

4 soma = 0;

5

6 for (i = 1; i<= n; i = i + 1){

7 soma = soma + i;

8 }

9

10 return soma;

11 }

Exemplo 3.19: Exercıcio Resolvido - Soma de inteiros.

Exercıcio Resolvido 3.2 - Multiplos

Faca um programa que leia um numero natural n e dois numeros naturais i e j diferentes de0 e imprima em ordem crescente os n primeiros naturais que sao multiplos de i ou de j. Resolvao problema utilizando uma funcao que verifique se um numero e multiplo do outro. Exemplo:Para n = 6 , i = 2 e j = 3 a saıda devera ser : 0,2,3,4,6,8.

Solucao Possıvel:

Para exibir os n primeiros naturais multiplos de i e j deve-se testar os numeros naturais uma um, comecando de zero e verificando se sao multiplos de i ou de j. Caso o numero naturalcorrente, contido na variavel natural, seja multiplo da variavel i ou j, uma variavel contadoracont devera ser incrementada e a verificacao continuara com o proximo numero natural. Averificacao devera acabar quando n numeros naturais multiplos de i ou de j forem encontrados.Essa condicao sera alcancada quando a variavel cont for igual a variavel n, que contem o numerode multiplos a serem impressos.

A Figura 3.8 mostra os passos realizados pelo programa para n = 6, i = 2 e j = 3.

Para saber se um numero x e multiplo de um numero y basta verificar se o resto da divisaointeira de x por y e zero.

O Pseudocodigo 3.6 mostra um algoritmo que descreve os passos a serem realizados pelafuncao.

Page 93: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.10. EXERCICIOS RESOLVIDOS 93

No Natural Multiplo de j ? Multiplo de i ? No de multiplos de i ou j0 sim sim 11 nao nao 12 nao sim 23 sim nao 34 nao sim 45 nao nao 46 sim sim 57 nao nao 58 nao sim 6

Figura 3.8: Solucao para n = 6, i = 2 e j = 3.

Pseudocodigo 3.6 Passos a serem relizados pela funcao.

Func~ao Principal:

Ler os valores de n, i e j

Chamar o processo componente multiplos passando -se como parametros n, i e j

.

FIM -Func~ao Principal

Processo componente "multiplos":

Inicializar a variavel do numero atual e a variavel indicando o npumero de

m´ultiplos com o valor zero.

Enquanto o numero de multiplos for menor que n:

Verificar se o numero atual e multiplo de i ou de j atraves do processo

componente ehMultiplo

Caso afirmativo:

Incrementar a variavel contadora de multiplos e exibir o valor do

numero atual.

Incrementar a variavel do numero atual

FIM -Processo componente "multiplos"

Processo componente "ehMultiplo":

Verificar se o resto da divis~ao de x por y e zero.

Caso afirmativo:

Retornar o valor 1, indicando sucesso.

Caso negativo:

Retornar o valor 0.

FIM -Processo componente "ehMultiplo"

O Exemplo 3.20 mostra a implementacao do algoritmo do Pseudocodigo 3.6. Na funcaoehMultiplo usou-se como convencao o valor 1 para indicar sucesso na verificacao de x sermultiplo de y e 0 caso contrario. Note tambem que no comando de repeticao for da funcaomultiplos foi omitido o terceiro parametro. Isso foi necessario pois a variavel cont so devera

Page 94: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

94 CAPITULO 3. MODULARIZACAO

ser incrementada se natural for multiplo de i ou j, o que nem sempre e verdade.

1 #include <stdio.h>

2

3 int ehMultiplo (int x, int y){

4

5 if (x%y == 0){

6 return 1;

7 }

8 else{

9 return 0;

10 }

11 }

12

13 void multiplos(int i, int j, int n){

14 int natural , cont;

15

16 natural = 0;

17

18 printf("Os %d primeiros multiplos de %d ou de %d s~ao:", n, i, j);

19

20 cont = 0;

21 while (cont < n){

22

23 if (ehMultiplo (natural , i) == 1 || ehMultiplo (natural , j) == 1){

24 printf(" %d", natural);

25 cont ++;

26 }

27

28 natural ++;

29 }

30 printf("\n");

31

32 }

33

34 int main(){

35 int n, i, j;

36

37 printf ("Digite 3 numeros naturais , o primeiro sendo a quantidade n de

multiplos que ser~ao impressos e os dois ultimos sendo os numeros i e j

que servir~ao como base para a gerac~ao dos multiplos: ");

38

39 scanf ("%d%d%d", &n, &i, &j);

40

41 multiplos (i, j, n);

42

43 return 0;

44 }

Exemplo 3.20: Exercıcio Resolvido - Multiplos.

Page 95: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.10. EXERCICIOS RESOLVIDOS 95

Exercıcio Resolvido 3.3 - Triangulo Retangulo

Faca uma funcao que dados tres numeros naturais, verifique se eles formam os lados de umtriangulo retangulo. Os numeros dados simbolizam o comprimento de cada lado do triangulo.

Solucao Possıvel:Na geometria, o Triangulo Retangulo e um triangulo que possui um angulo reto e outros

dois angulos agudos. Sabe-se ainda que o quadrado da hipotenusa (o maior lado do retangulo)e igual a soma dos quadrados dos catetos.

Sendo assim, para resolver esse exercıcio, precisamos primeiro saber qual dos tres ladosdados, a, b ou c, corresponde a hipotenusa. Para tanto, compara-se todos os lados, dois a dois,colocando-se o maior lado na variavel a.

Como o maior lado estara guardado em a e certo dizer que os lados dados correspondem aum triangulo retangulo se, e somente se, a2 = b2 + c2.

O Pseudocodigo 3.7 mostra um algoritmo que descreve os passos a serem realizados pelafuncao.

Pseudocodigo 3.7 Passos a serem relizados pela funcao.

Processo componente "trianguloRetangulo":

Comparar se o lado b e maior do que o lado a

Caso afirmativo , trocar os valores de a e b.

Comparar se o lado c e maior do que o lado a

Caso afirmativo , trocar os valores de a e c.

Verificar se a*a = b*b + c*c

Caso afirmativo:

Retornar o valor 1

Caso negativo:

Retornar o valor 0

FIM -Processo componente "trianguloRetangulo"

O Exemplo 3.21 mostra a implementacao desse algoritmo. Note que para trocar os valoresdas variaveis a e b teve-se que ter uma variavel auxiliar, chamada aux, para guardar o valor dea para so depois atribuir o valor da variavel b para a variavel a e posteriormente atribuir o valorantigo da variavel a (que esta guardado na variavel aux) para a variavel b.

1 int trianguloRetangulo(int a, int b, int c) {

2 int aux;

3

4 if (b > a){

5 aux = a;

6 a = b;

7 b = aux;

8 }

9

10 if (c > a){

Page 96: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

96 CAPITULO 3. MODULARIZACAO

11 aux = a;

12 a = c;

13 c = aux;

14 }

15

16 if (a * a == b * b + c * c){

17 return 1;

18 }

19 else{

20 return 0;

21 }

22 }

Exemplo 3.21: Exercıcio Resolvido - Triangulo Retangulo.

Exercıcio Resolvido 3.4 - Tabuada

Faca um programa que dado dois numeros inteiros, m e n, gere uma tabuada conforme aFigura 3.9, sendo que para esse exemplo os numeros fornecidos foram: 22 e 37.

0 x 1 = 0 1 x 1 = 1 ... 37 x 1 = 370 x 2 = 0 1 x 2 = 2 ... 37 x 2 = 74

. . ... .

. . ... .0 x 22 = 0 1 x 22 = 22 ... 37 x 22 = 814

Figura 3.9: Solucao para m = 22 e n = 37.

Solucao Possıvel:

Para gerar a tabuada proposta, e preciso perceber onde sao usados os numeros dados. Noteque a tabuada representa o resultado da multiplicacao de um numero x por um numero y. Onumero x assume valores desde 0 ate o segundo numero dado como argumento, enquanto onumero y assume valores desde 1 ate o primeiro numero dado como argumento.

E facil perceber que e necessario o uso de comandos de repeticao para solucionar o problema.Pode-se usar 2 comandos de repeticao, um contido no outro, diretamente ou indiretamente, viauma funcao externa.

O Pseudocodigo 3.8 mostra um algoritmo que descreve os passos a serem realizados pelafuncao.

Page 97: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.10. EXERCICIOS RESOLVIDOS 97

Pseudocodigo 3.8 Passos a serem relizados pela funcao.

Processo componente "mult":

Para um loop variando de 1 a n:

Guardar o resultado de cont vezes x em r e exibir o resultado

FIM -Processo componente "mult"

Func~ao Principal:

Coletar os valores das duas variaveis (n e m)

Para um loop com x variando de 0 a m:

Chamar processo componente "mult", passando como parametro n e x

FIM -Func~ao Principal

O Exemplo 3.22 mostra a implementacao desse algoritmo. Note que a variavel a da funcaomult contem o valor da variavel n da funcao main , enquanto a variavel b da funcao multcontem o valor da variavel x da funcao main .

1 #include <stdio.h>

2

3 void mult (int a, int b){

4 int r, cont;

5

6 for (cont =1; cont <= a; cont ++){

7 r = b*cont;

8

9 printf ("%dx%d=%d\n", b, cont , r);

10 }

11

12 printf ("\n");

13 }

14

15 int main (void){

16 int m, n, x;

17

18 printf ("Entre com dois numeros inteiros: ");

19 scanf ("%d %d", &n,&m);

20

21 for (x=0; x <=m ; x++){

22 mult (n,x);

23 }

24

25 return 0;

26 }

Exemplo 3.22: Exercıcio Resolvido - Tabuada.

Exercıcio Resolvido 3.5 - N primeiros numeros primos

Seja n inteiro positivo diferente de zero. Faca um programa para exibir os n primeiros

Page 98: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

98 CAPITULO 3. MODULARIZACAO

numeros primos.

Solucao Possıvel:

Para exibir os n primeiros numeros primos e necessario fazer primeiro uma funcao que verifi-que se um dado numero x e primo ou nao. Por definicao: “Numero primo e um numero naturalque pode ser dividido (o resto da sua divisao e zero) apenas por dois numeros naturais, o 1 (um)e ele mesmo, com excessao do numero 1, que nao e tido como primo”.

Sabe-se tambem que o unico numero que e primo e par ao mesmo tempo e o numero 2. Logo,qualquer numero que seja par (resto da divisao por 2 igual a zero) que nao seja o dois, nao eprimo.

Entao, o que se tem a fazer para saber se determinado numero e primo e verificar se ele e onumero dois ou se ele tem apenas 2 divisores. Mas, caso o numero em questao seja o numero1, multiplo de 2 (com excessao do zero e do dois), ou tiver mais de 2 divisores, entao ele nao eprimo.

Todos os numeros inteiros positivos diferentes de zero tem ao menos 2 divisores: o 1 e elemesmo, com excessao do numero 1. Logo, se for encontrado mais algum divisor, o numeroestudado nao e primo. Entao, apos feitas as verificacoes anteriores, para encontrar algum outrodivisor do numero, basta ir dividindo-o por todos os numeros ımpares maiores ou iguais a 3 emenores ou iguais a raiz quadrada do numero em questao. Caso nao encontremos divisores nesseintervalo, entao nao existem outros divisores alem do 1 e o proprio numero.

O Pseudocodigo 3.9 mostra um algoritmo que descreve os passos a serem realizados pelafuncao.

O Exemplo 3.23 mostra a implementacao desse algoritmo. Note que o valor retornado pelafuncao ehPrimo foi convencionado. Caso o numero passado seja primo, a funcao retornara ovalor um, caso contrario retornara o valor zero. O programador tem a liberdade de convencionaro valor retornado, mas devera indicar isso no comentario do programa.

Page 99: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.10. EXERCICIOS RESOLVIDOS 99

Pseudocodigo 3.9 Passos a serem relizados pela funcao.

Processo componente "ehPrimo":

Verificar se x e igual a um

Caso afirmativo:

Retornar o valor zero

Verificar se x e igual a 2

Caso afirmativo:

Retornar o valor um

Verificar se x e divisıvel por 2

Caso afirmativo:

Retornar o valor zero

Para um loop com i variando de 3 a raiz quadrada de x:

Verificar se x e divisıvel por i

Caso afirmativo:

Retornar o valor zero

Incrementar o valor de i em 2 unidades

Retornar o valor um

FIM -Processo componente "ehPrimo"

Func~ao Principal:

Coletar o valor da variavel quant que representa o numero de primos a serem

impressos

Iniciar numero com valor 1.

Para um loop com cont variando de zero a quant:

Usar a func~ao ehPrimo para verificar se cont e primo

Caso afirmativo;

Imprimir cont

Incrementar cont

FIM -Func~ao Principal

1 #include <stdio.h>

2 #include <math.h>

3

4 /*

5 Verifica se o numero passado como parametro e primo.

6 Entrada: um numero inteiro positivo diferente de zero

7 Saıda: retorna 1 para o caso do numero informado for primo e zero caso contrario

8 */

9 int ehPrimo(int x){

10

11 int i;

12

13 if (x == 1){

14 return 0;

15 }

16

17 if (x == 2){

18 return 1;

Page 100: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

100 CAPITULO 3. MODULARIZACAO

19 }

20

21 if (x % 2 == 0){

22 return 0;

23 }

24

25 for (i = 3; i<= sqrt (x) ;i= i +2){

26 if (x%i == 0){

27 return 0;

28 }

29 }

30

31 return 1;

32 }

33

34 int main (){

35

36 int quant , numero , cont;

37

38 printf ("Digite a quantidade de numeros primos a serem impressos:");

39

40 scanf ("%d", &quant);

41

42 printf ("Os numeros primos s~ao:");

43

44 for (numero = 1, cont = 0; cont < quant; numero ++){

45 if (ehPrimo(numero) == 1){

46 printf (" %d", numero);

47

48 cont ++;

49 }

50 }

51

52 printf ("\n");

53

54 return 0;

55 }

Exemplo 3.23: Exercıcio resolvido - N primeiros numeros primos.

Exercıcio Resolvido 3.6 - Palındromo

Um palındromo e uma palavra, frase ou qualquer outra sequencia de unidades (como umacadeia de ADN) que tenha a propriedade de poder ser lida tanto da direita para a esquerdacomo da esquerda para a direita.

Sabendo-se disso, faca uma funcao que verifique se um numero inteiro e palındromo.Exemplo:101 e palındromo1012 nao e palındromo

Page 101: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.10. EXERCICIOS RESOLVIDOS 101

Solucao Possıvel:

Para fazer essa funcao e necessario ler o numero de tras para frente. Para ler o ultimoalgarismo de um numero guardado numa variavel x basta guardamos numa variavel m o restoda divisao inteira desse numero por 10. Apos isso, guarda-se em x a parte inteira da divisao dex por 10, excluindo-se assim o ultimo algarismo do numero. Nesse momento a variavel m possuio ultimo algarismo original de x, enquanto esta possui agora apenas os primeiros algarismosoriginais, excluindo-se apenas o ultimo.

Entao, multiplicando-se m por 10 e somando-se a esse resultado o resto da divisao inteira donovo valor de x por 10, teremos em m os ultimos dois algarismo de x na ordem inversa.

E facil perceber que basta fazer os passos acima recursivamente para obter em m o numerox original, mas na ordem inversa. Tendo-se esse numero, basta compara-lo com o valor original,guardado anteriormente em uma outra variavel.

A Figura 3.10 ilustra o comportamento das variaveis x e m com o decorrer das iteracoespara um x inicial igual a 52325. A coluna x /10 mostra a parte inteira da divisao de x por 10,enquanto a coluna x % 10 mostra o resto dessa divisao. Percebe-se que o processo iterativo deveacabar quando o x final for igual a zero. Note que no final desse exemplo a variavel m contemo numero inicial x do processo, mostrando que 52325 e palındromo.

Iteracao x inicial x / 10 x % 10 m final x final1 52325 5232 5 5 52322 5232 523 2 52 5233 523 52 3 523 524 52 5 2 5232 55 5 0 5 52325 0

Figura 3.10: Solucao para x = 52325.

O Pseudocodigo 3.10 mostra o algoritmo que descreve os passos a serem realizados pelafuncao.

Page 102: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

102 CAPITULO 3. MODULARIZACAO

Pseudocodigo 3.10 Passos a serem relizados pela funcao.

Processo componente "palindromo":

Guardar em c o valor de x

Iniciar m com zero

Enquanto x for diferente de zero:

Fazer m igual a multiplicac~ao de m por 10 com a soma da divis~ao inteira

de x por 10.

Fazer x igual a divis~ao inteira de x por 10

Verificar se m e igual a c

Caso positivo:

Retornar o valor um

Caso negativo:

Retornar o valor zero.

FIM -Processo componente "palindromo"

O Exemplo 3.24 mostra a implementacao desse algoritmo. Note que a variavel c guarda ovalor inicial de x e que esta variavel e comparada com o valor de m ao final do processo. Aquitambem usou-se a convencao de usar o valor de retorno 1 para indicar sucesso na verificacao ezero caso contrario.

1 int palindromo (int x){

2 int c, m;

3

4 c = x;

5

6 m = 0;

7

8 while (x != 0){

9 m = m*10 + (x % 10);

10 x = x / 10;

11 }

12

13 if (m == c){

14 return 1;

15 }else{

16 return 0;

17 }

18 }

Exemplo 3.24: Exercıcio resolvido - Palındromo.

Exercıcio Resolvido 3.7 - Maximo Divisor Comum

Faca uma funcao que calcule o maximo divisor comum entre dois numeros naturais passadoscomo parametros da funcao. Faca a funcao na forma recursiva e na forma iterativa.

Solucao Possıvel:

Page 103: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.10. EXERCICIOS RESOLVIDOS 103

A apresentacao mais simples consiste em comparar-se os numeros e colocar a diferenca entreos dois (o menor subtraıdo do maior). Agora compara-se o resultado dessa subtracao com omenor numero anterior, repetindo-se o processo ate que se obtenha igualdade entre os numerosnas duas colunas, que e o resultado procurado.

Para melhor compreender o funcionamento do metodo, basta recorrer a um raciocınio muitosimples. Com efeito, se observarmos com atencao a tabuada da multiplicacao de um numeroqualquer, podemos ver que a diferenca entre dois produtos e sempre um produto que figurana mesma tabuada. Portanto, se dois numeros forem multiplos de um terceiro, entao a suadiferenca tambem e, o que nos permite substituir o maior deles por essa diferenca, para efeitosde calculo do MDC; e tudo isso tantas vezes quantas forem necessarias, ate que se chegue a umponto em que os dois numeros se identificam no mesmo, o que nos remete para a questao maissimples: qual e o MDC de dois numeros iguais? O que e precisamente a situacao a que se chegouno nosso metodo.

O Pseudocodigo 3.11 mostra o algoritmo que descreve os passos a serem realizados pelafuncao iterativa.

Pseudocodigo 3.11 Passos a serem relizados pela funcao.

Processo componente "mdc_Recursivo":

Verificar se a e igual a b

Caso positivo:

Retornar o valor de a

Verificar se a e maior que b

Caso positivo:

Chamar a func~ao mdc_Recursivo passando -se como primeiro parametro o

valor da subtrac~ao de a - b e como segundo parametro o b

Caso negativo:

Chamar a func~ao mdc_Recursivo passando -se como primeiro parametro o

valor da subtrac~ao de b - a e como segundo parametro o a

FIM -Processo componente "mdc_Recursivo"

O Exemplo 3.25 mostra a implementacao desse algoritmo.

1 int mdc_Recursivo (int a, int b){

2 if (a == b){

3 return a;

4 }

5

6 if (a > b){

7 return mdc (a-b, a);

8 }else{

9 return mdc (a, b-a);

10 }

11 }

Exemplo 3.25: Exercıcio resolvido - M.D.C. (modo recursivo).

Page 104: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

104 CAPITULO 3. MODULARIZACAO

O Pseudocodigo 3.12 mostra o algoritmo que descreve os passos a serem realizados pelafuncao iterativa.

Pseudocodigo 3.12 Passos a serem relizados pela funcao.

Processo componente "mdc_Iterativo":

Enquanto a for diferente de b faca:

Verificar se a e maior que b:

Caso positivo:

Colocar em a o resultado da subtrac~ao a - b

Caso contrario:

Colocar em b o resultado da subtrac~ao b - a

Retornar o valor de a

FIM -Processo componente "mdc_Iterativo"

O Exemplo 3.26 mostra a implementacao desse algoritmo. Note que nesse caso a imple-mentacao na forma iterativa e obtida facilmente a partir da forma recursiva.

1 int mdc_Iterativo (int a, int b){

2

3 while (a != b){

4 if (a > b){

5 a = a-b;

6 }else{

7 b = b-a;

8 }

9 }

10

11 return a;

12 }

Exemplo 3.26: Exercıcio resolvido - M.D.C. (modo iterativo).

3.11 Resumo

• A modularizacao baseia-se na conhecida tecnica de “dividir para conquistar”e pode serdefinida como a divisao de um problema em varias partes. Cada uma dessas partes podeser desenvolvida independentemente das outras.

• As partes principais de um subprograma sao: cabecalho, dicionario de dados, corpo ecomentarios.

• Os parametros de um subprograma sao os dados iniciais necessarios para a funcao poderrealizar o seu trabalho. O subprograma pode tambem nao receber nenhum parametro pararealizar suas funcoes. Na linguagem C, quando a funcao nao tem parametros usa-se voidna declaracao da funcao, em sua lista de parametros.

Page 105: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.12. EXERCICIOS PROPOSTOS 105

• Um subprograma podera produzir no decorrer das suas instrucoes um valor que sera retor-nado, chamado de valor de retorno. Na linguagem C, quando a funcao nao produz nenhumvalor de retorno usa-se void para simbolizar o tipo de dado retornado.

• Algumas vezes e interessante antecipar o encerramento da execucao de programas.

• A programacao recursiva e uma tecnica muito utilizada na implementacao de funcoes.

• Geralmente e possıvel criar versoes recursivas e nao recursivas de uma mesma funcao.

As vantagens encontradas em um programa modularizado sao:

• Legibilidade: facilidade de leitura e entendimento do codigo fonte;

• Manutenibilidade: facilidade de modificar o codigo fonte;

• Reusabilidade: facilidade de reutilizar total ou parcialmente o codigo fonte;

• Confiabilidade: como o programa e facil de ser entendido e corrigido, torna-se maisconfiavel;

• Produtividade: o programa pode ser dividido em modulos e cada modulo pode ser traba-lhado por uma equipe diferente. Alem disso, uma equipe so precisa saber o que determi-nado modulo de outra equipe faz e nao como faz;

3.12 Exercıcios Propostos

1. (a) Construa uma funcao encaixa que, dados dois inteiros positivos a e b, verifica se bcorresponde aos ultimos dıgitos de a.

Ex.:

a b567890 890 =>encaixa1243 1243 =>encaixa2457 245 =>nao encaixa457 2457 =>nao encaixa

(b) Usando a funcao do item anterior, faca um programa que le dois inteiros positivos a eb e verifica se o menor deles e segmento do outro.

Exemplo:

a b567890 678 => b e segmento de a1243 2212435 => a e segmento de b235 236 => um nao e segmento do outro

Page 106: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

106 CAPITULO 3. MODULARIZACAO

2. Faca uma funcao que receba como argumento os lados de um triangulo e calcule o seuperımetro e em seguida o valor da area.

3. Considere o valor de π = 3.141592. Construa uma funcao para calcular a area de umcırculo tendo como dado de entrada, o valor do raio. Em seguida, fazer outra funcao paracalcular o raio do cırculo que possui como area, a metade da area calculada anteriormente.

4. Faca uma funcao que receba como parametro uma quantia em reais (valor inteiro). Calculeo numero de cedulas de cada tipo (1, 2, 5, 10, 20, 50, 100), necessario para pagar a quantia.Exiba apenas o numero nao nulo de cedulas de cada tipo.

5. Faca uma funcao que receba como entrada dois valores inteiros, a e b, e exiba a sequenciade numeros pares do intervalo (a, b), com a < b.

6. Uma loja de material de construcao precisa de um programa para saber a quantidade demetros quadrados (m2) que devem ser usados para colocar piso nas casas dos clientes. Efornecido o numero de comodos, os lados dos quadrilateros de cada comodo e o preco dopiso que o cliente escolheu. Faca uma funcao que receba essas informacoes como dados deentrada e imprima a quantidade de piso (em m2 ) e o valor da compra. Obs: Todos oscomodos da casa tem a forma de quadrilateros.

7. Faca uma funcao que calcule e retorne o n-esimo termo de uma PA (progressao aritmetica)sendo fornecidos como entrada o numero de termos, o primeiro termo e a razao.

8. Elabore uma funcao em C que calcule o valor aproximado de π com precisao de cincodecimos atraves da serie:

π = 113 − 1

33 + 153 . . .

Considere que a precisao de cinco decimos requer que a soma dos elementos da serie sodeve ser interrompida quando o valor do termo e inferior a 0,00001. Para implementar afuncao, use uma subfuncao que, dados x e y, calcule xy.

Page 107: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

3.13. TRABALHOS SUGERIDOS 107

3.13 Trabalhos Sugeridos

1. Aplicando Conhecimentos de Calculo

Em um belo dia, um preguicoso monitor de Calculo teve uma simples ideia para facilitarseu trabalho. Percebendo que varios alunos tinham duvidas sobre derivadas e integraisde polinomios, ele resolveu pedir a um programador (nesse caso, voce) um algoritmo quefizesse esse “trabalho”.

Por experiencia, o monitor restringiu o programa a polinomios de ate grau nove e passouas seguintes especificacoes ao programador:

Exemplos de Dados de Entrada

Uma funcao seria digitada da seguinte maneira: (Opcao 1)

+2x4+0x3-25x2+1x1-5x0=

ou seja, a leitura devera ser pelo teclado e sempre na mesma ordem: <operador><coeficiente><variavel> <potencia>. Observacao: a leitura do teclado deve ser feita termo a termo,por exemplo, “+2x4 [enter] +0x3 [enter]”. Apenas o caractere “=” podera ser lido sepa-radamente.

Uma funcao f(x) = 2x4 − 25x2 + x− 5 seria digitada da seguinte maneira: (Opcao 2)

+2x4-25x2+1x-5=

Ou seja, a leitura devera ser pelo teclado, porem com algumas diferencas em relacao aopcao anterior. Serao omitidos a potencia “1”, a variavel com potencia “0” e os termoscom coeficiente “0”. Observacao: nesse caso a leitura tambem deve ser feita termo a termo,porem, deve-se lembrar que alguns termos podem ser menores que outros (“+2x4” e “1x”,por exemplo).

Em ambos os casos, a flag de final de leitura sera o caracter “=” e os coeficientes seraonumero reais (float). A ideia e que, se o programador optar pela segunda opcao, o algoritmodevera ser generico ao ponto de receber as duas formas de entrada.

Armazenada a funcao de entrada, o programa devera imprimir, no mesmo formato deentrada, a derivada e a integral da funcao. Como se nao bastasse a folga do monitor, eleainda deseja que o programa imprima tambem as raızes das funcoes quando estas foremdo primeiro ou do segundo grau.

Exemplos de Saıda

Usando a funcao de entrada: f(x) = x2 − 5x+ 6

• Derivada 2.00x1-5.00x0= (Opcao 1) 2.00x-5.00= (Opcao 2)

Page 108: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

108 CAPITULO 3. MODULARIZACAO

• Integral 0.33x3-2.50x2+6.00x1+C= (Opcao 1) 0.33x3-2.50x2+6.00x+C= (Opcao 2)

• Raızes (apenas para funcoes de primeiro e segundo grau) x1=2.00 x2=3.00 Os coefi-cientes e as raızes deverao ser impressos com 2 casas decimais.

Page 109: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

Capıtulo 4

Tipos Abstratos de DadosCo-Autores:

Bruna Vello Colnago

Rodrigo Lopes Batista

Objetivos:

• Introduzir o conceito de Tipos Compostos Heterogeneos;

• Explicar as vantagens da utilizacao de Tipos Abstratos de dados;

• Tornar o codigo do programa mais compreensıvel;

• Simplificar a confeccao de aplicacoes mais complexas.

Este capıtulo busca esclarecer como a criacao e manipulacao de novos tipos de dados permitefacilitar o entendimento, a confeccao e o reaproveitamento de codigo.

4.1 Tecnicas de Programacao Top-down e Bottom-up

Para escrever um programa, os programadores podem adotar duas tecnicas: a Top-down e aBottom-up. A tecnica Bottom-up consiste em considerar o programa como um conjunto demodulos correlacionados, implementar cada um desses modulos e depois junta-los por meio deuma estrutura global. Ja a tecnica Top-down consiste em primeiramente definir a estruturaglobal do programa e posteriormente definir cada uma das partes que detalham as suas tarefas.

Analogamente, um projetista de automoveis pode inicialmente definir como sera o carro,velocidade, rapidez, rotacoes maximas, etc , e posteriormente confeccionar seus componentes(motor, rodas, freios, suspensao...), conforme a necessidade - Top-down - ou confeccionar cadaum dos componentes separadamente, garantir seu funcionamento e depois junta-los em um carrocujas metas sejam compatıveis com as possibilidades dos componentes - Bottom-up.

109

Page 110: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

110 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

Na abordagem Bottom-up, cada modulo e implementado segundo suas funcionalidades eobjetivos, independentemente do restante do programa, assim torna-se mais simples redigir ocodigo do programa, facilitando o trabalho do programador. Alem do mais, a separacao doprograma em modulos permite a realizacao de testes especıficos, facilitando a depuracao deerros. Outra importancia dessa abordagem e a facilidade de alterar partes do programa, sendonecessario alterar apenas alguns modulos sem se importar com os demais.

Por fim, o programa torna-se muito mais facil de ser entendido, ao passo que o leitor naoprecisa ler todo o codigo do programa, bastando saber as funcionalidades de cada modulo. Aimplementacao dos mesmos importa somente ao programador. Assim, a abordagem Bottom-upe mais vantajosa em relacao a Top-down, ao passo que e muito mais intuitiva ao programador.

4.2 Tipos Compostos Heterogeneos (Estruturas)

As formas de representacao de dados fornecidas pelo computador sao insuficientes para que oprogramador possa representar em sua totalidade as possıveis colecoes de dados existentes. Pro-gramadores ha muito tempo reconhecem o valor de se organizar itens de dados correlacionadosem uma unica entidade computacional. As Estruturas sao entidades que representam tipos dedados e que permitem o agrupamento de varias variaveis de diversos tipos.

Suponha um programa que faca o cadastro de estudantes de uma universidade, cada umpossuindo um conjunto de atributos correlacionados, como por exemplo: matrıcula, idade, co-eficiente de rendimento e perıodo. Utilizando as entidades de programacao ja conhecidas, nocadastro de um unico aluno seriam necessarias quatro variaveis para representar todos os seusatributos; para dois estudantes, seriam necessarias oito variaveis; ja para diversos estudantesseria necessario um conjunto de variaveis consideravelmente grande.

A utilizacao de muitas variaveis aumenta o trabalho do programador e dificulta que outrapessoa entenda a aplicacao. Para solucionar esse problema, muitas linguagens de programacao,entre elas a linguagem C, possibilitam ao programador criar tipos compostos heterogeneos. Nalinguagem C, os tipos compostos heterogeneos sao chamados struct (estruturas). As estruturassao conjuntos de dados correlacionados, que podem ser representados em sua totalidade por umaunica variavel. No exemplo mencionado, cada estudante poderia ser representado por uma unicavariavel, dessa forma, seria necessario adicionar apenas uma variavel para cada novo estudantea ser cadastrado.

Dada a impossibilidade de se antecipar todos os tipos de dados utilizados por um programa,uma linguagem de programacao apenas implementa tipos de dados simples. Desse modo, fica acargo do programador usar desses dados para a definicao de novos tipos de dados.

Alem de facilitar e tornar mais clara a implementacao, os tipos compostos heterogeneos temcomo finalidades principais a possibilidade de retorno de mais de um valor por funcao e a criacaode tipos abstratos de dados. Essas caracterısticas sao discutidas mais adiante neste capıtulo.

Page 111: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.2. TIPOS COMPOSTOS HETEROGENEOS (ESTRUTURAS) 111

4.2.1 Definicao

Uma estrutura e uma colecao de variaveis, que podem ou nao ser de tipos diferentes, colocadassob um unico nome para manipula-las. As estruturas ajudam na organizacao do codigo e fa-cilitam a vida do programador, pois juntam variaveis relacionadas e permitem que elas sejamtratadas como uma unidade maior.

Na pratica, uma estrutura e uma “caixa” onde podem ser agrupados diversos dados correla-cionados. Essa caixa, na verdade, e o conjunto de alguns bytes de memoria correspondente aosomatorio dos tamanhos dos dados que se pretende agrupar.

A Figura 4.1 ilustra uma estrutura que representa um estudante, tEstudante. Note que aestrutura tEstudante ocupa um espaco equivalente ao espaco necessario para guardar todos osseus atributos.

Figura 4.1: Estrutura tEstudante

Sintaxe

Para criar uma estrutura com n atributos, deve-se obdecer a sintaxe exposta abaixo.

struct <nome da estrutura>{<tipo do atributo 1> <nome do atributo 1>;<tipo do atributo 2> <nome do atributo 2>;...<tipo do atributo n> <nome do atributo n>;};

A palavra struct indica que a entidade criada e uma estrutura e as chaves delimitam o trechoonde os atributos da estrutura sao definidos. Cada atributo e definido por seu tipo seguido deum identificador.

O Exemplo 4.1 apresenta a sintaxe de uma estrutura para o caso do estudante.

1 struct tEstudante{

2 int idade;

3 int matricula;

Page 112: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

112 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

4 float coeficiente;

5 int periodo;

6 };

Exemplo 4.1: Sintaxe da estrutura tEstudante

4.2.2 Uso

Como as estruturas sao conjuntos de dados, existem duas formas basicas de manipula-las, se-lecionando um unico elemento de dado de forma seletiva, ou manipulando toda a estrutura deforma integral.

Seletivo

Para manipular cada um dos atributos da estrutura se utiliza o mecanismo de selecao conformea sintaxe apresentada a seguir.

<nome da variavel>.<nome do atributo>

O Exemplo 4.2 ilustra o uso seletivo da estrutura estudante. Nesse Exemplo, a leitura dedados e feita atribuindo-se cada valor lido a um atributo da estrutura.

1 #include <stdio.h>

2 #include <stdlib.h>

3

4 struct tEstudante{

5 int idade;

6 int matricula;

7 float coeficiente;

8 int periodo;

9 };

10

11 main(){

12 struct tEstudante aluno;

13 printf("Digite os dados do estudante");

14 scanf("%d %d %f %d",&aluno.idade ,& aluno.matricula ,& aluno.coeficiente ,& aluno.

periodo);

15 }

Exemplo 4.2: Acesso seletivo a atributos da estrutura.

Integral

Quando se deseja manipular a estrutura como um todo, se utiliza simplesmente o nome davariavel onde a mesma esta armazenada. O uso integral em atribuicoes e descrito pela sintaxea seguir.

Page 113: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.2. TIPOS COMPOSTOS HETEROGENEOS (ESTRUTURAS) 113

<nome da variavel 1> = <nome da variavel 2>

O Exemplo 4.3 ilustra o uso integral da estrutura estudante.

1 #include <stdio.h>

2 #include <stdlib.h>

3

4 struct tEstudante{

5 int idade , matricula , periodo;

6 float coeficiente;

7 };

8

9 main(){

10 struct tEstudante aluno ,outro;

11 printf("Digite os dados do estudante");

12 scanf("%d %d %f %d",&aluno.idade ,& aluno.matricula ,& aluno.coeficiente ,& aluno.

periodo);

13 outro = aluno;

14 }

Exemplo 4.3: Acesso integral a estrutura

No Exemplo 4.3, ao final da execucao do programa os valores dos atributos de outro saoiguais aos valores dos atributos de aluno.

O comando typedef pode ser utilizado para renomear tipos simples ou compostos. Parautilizar o comando typedef, deve-se obdecer a sintaxe exposta abaixo.

typedef <nome do tipo simples ou composto> <novo nome>;

Na pratica, a renomeacao de tipos facilita o entendimento e a escrita de codigo.O Exemplo 4.4 apresenta a utilizacao do typedef.

1 typedef struct tEstudante tEstudante;

2

3 typedef float distancia;

Exemplo 4.4: Uso do comando typedef

O Exemplo 4.5 apresenta a adaptacao do Exemplo 4.3 para a utilizacao do comando typedef,permitindo que o tipo composto heterogeneo struct tEstudante seja utilizado atraves da palavrastruct tEstudante.

1 #include <stdio.h>

2 #include <stdlib.h>

3

4 struct tEstudante{

5 int idade;

Page 114: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

114 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

6 int matricula;

7 float coeficiente;

8 int periodo;

9 };

10

11 typedef struct tEstudante tEstudante;

12

13 main(){

14 tEstudante aluno ,outro;

15 printf("Digite os dados do estudante");

16 scanf("%d %d %f %d",&aluno.idade ,& aluno.matricula ,& aluno.coeficiente ,& aluno.

periodo);

17 outro=aluno;

18 }

Exemplo 4.5: Acesso integral a estrutura utilizando o comando typedef

Simplificacao na Passagem de Parametros e Retorno de Funcao

Conforme comentou-se anteriormente, as estruturas sao conjuntos de dados inter-relacionados,dessa forma a passagem de parametros de funcao e simplificada, pois ao inves de cada um dosatributos ser um parametro da funcao, apenas a estrutura e passada. Note a diferenca entre alista de parametros das duas funcoes representadas no Exemplo 4.6.

1 void funcao1(int idade , int matricula , float coeficiente , int periodo){ ... }

2

3 void funcao2(tEstudante aluno){ ... }

Exemplo 4.6: Passagem de estrutura por parametro.

A mesma funcao pode ser escrita dos dois modos apresentados no Exemplo 4.6 na funcao1quatro variaveis relacionadas ao estudante sao passadas como parametro; na funcao2 , o proprioestudante e passado como parametro. A funcao2 e mais compreensıvel que a funcao1 , pois apessoa que ler o codigo da funcao1 tera que inferir que aquelas quatro variaveis referem-se aum mesmo estudante.

Da mesma forma, o retorno de funcoes pode ser simplificado pelo uso de estruturas. Suponhaque se deseje fazer a leitura de dados de um estudante. O Exemplo 4.7 mostra duas maneiras defazer isso: utilizando funcoes que retornam estruturas ou funcoes que retornam tipos simples.

1 #include <stdio.h>

2 #include <stdlib.h>

3

4 struct tEstudante{

5 int idade;

6 int matricula;

7 float coeficiente;

Page 115: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.2. TIPOS COMPOSTOS HETEROGENEOS (ESTRUTURAS) 115

8 int periodo;

9 };

10

11 typedef struct tEstudante tEstudante;

12

13 int lePeriodo (){

14 int periodo;

15 scanf("%d",&periodo);

16 return periodo;

17 }

18

19 int leMatricula (){

20 int matricula;

21 scanf("%d",&matricula);

22 return matricula;

23 }

24

25 float leCoeficiente (){

26 float coeficiente;

27 scanf("%f",&coeficiente);

28 return coeficiente;

29 }

30

31 int leIdade (){

32 int idade;

33 scanf("%d",&idade);

34 return idade;

35 }

36

37 tEstudante leEstudante (){

38 tEstudante aluno;

39 scanf("%d %d %f %d",&aluno.idade ,& aluno.matricula ,& aluno.coeficiente ,& aluno.

periodo);

40 return aluno;

41 }

42

43 main(){

44 tEstudante aluno1 ,aluno2;

45 aluno1.periodo=lePeriodo ();

46 aluno1.matricula=leMatricula ();

47 aluno1.coeficiente=leCoeficiente ();

48 aluno1.idade=leIdade ();

49 aluno2=leEstudante ();

50 }

Exemplo 4.7: Estrutura como retorno de funcao.

No Exemplo 4.7 e realizada a leitura de dados de aluno1 sem utilizar o retorno de estruturas,e de aluno2, utilizando-o. Para realizar a leitura de aluno1 foram necessarias a declaracao dequatro funcoes diferentes, uma para cada atributo, e quatro chamadas de funcao no programaprincipal. Para realizar a leitura de aluno2 foi necessario apenas a declaracao de uma funcao

Page 116: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

116 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

e uma chamada de funcao no programa principal. Assim, pode-se perceber que o retorno deestruturas torna o codigo mais compacto, legivel e eficiente, por ter menos chamadas de funcao.

4.3 Tipos Abstratos de Dados

Tipos abstratos de dados (TADs) sao novos tipos de dados implementados pelo programador,nos quais ele define tanto as estruturas de dados quanto as operacoes a elas aplicaveis, conformesuas necessidades para a resolucao de um determinado problema.

Os TADs podem ser considerados generalizacoes de tipos primitivos de dados, assim comofuncoes sao generalizacoes de operacoes primitivas, tais como adicao, subtracao e multiplicacao.Da mesma forma que funcoes podem ser usadas para encapsular partes de algoritmos, o TADpode ser usado para encapsular tipos de dados.

O TAD pode ser discutido pela perspectiva do implementador e do usuario do tipo. O im-plementador cria as estruturas de dados, implementa as funcoes para manipula-las. Ja o usuarioutiliza esse TAD como se fosse um tipo de dados fornecido pela linguagem de programacao.Deste modo, o usuario so deve manipular os atributos do TAD atraves das funcoes definidaspelo implementador do tipo.

4.3.1 Definicao

Um tipo abstrato de dados e um tipo de dado definido em termos do seu comportamento enao em termos de sua representacao. A ideia de tipo abstrato de dados e desvincular o tipo dedado (valores e operacoes) de sua implementacao, ou seja, quando definimos um tipo abstratode dados estamos preocupados com o que ele faz e nao como ele faz.

Os programas que usam um determinado tipo abstrato de dados sao chamados clientes; eo programa que define sua estrutura e comportamento e conhecido como implementacao. UmTAD pode ser definido como a composicao de uma estrutura de dados e das operacoes definidassobre estes dados.

Exemplo da Definicao de um Tipo Composto com Operacoes Pre-definidas

Suponha que se deseja definir um tipo abstrato de dados tData, considerando os atributos dia,mes e ano. Primeiramente, deve-se decidir as operacoes a serem definidos para o TAD, quepodem ser as seguintes:

• inicializaData : funcao que inicializa uma data a partir de valores passados como parametro.

• leData : funcao que inicializa uma data a partir de valores lidos do teclado.

• alteraData : funcao que altera uma data a partir de valores passados como parametro.

• eBissexto: funcao que indica se um ano e bissexto ou nao.

• diasNoMes: funcao que indica a quantidade de dias do mes em questao.

Page 117: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.3. TIPOS ABSTRATOS DE DADOS 117

• diaSeguinte : funcao que altera a data para o dia seguinte.

Pode-se entao implementar o TAD na linguagem desejada. No Exemplo 4.8, observa-se aimplementacao do TAD tData na linguagem C.

1 #include <stdio.h>

2

3 typedef struct data{

4 int dia;

5 int mes;

6 int ano;

7 }tData;

8

9 tData inicializarValores(int d,int m,int a){

10 tData dt;

11

12 dt.dia=d;

13 dt.mes=m;

14 dt.ano=a;

15 return dt;

16 }

17

18 tData leData (){

19 tData d;

20

21 printf("Entre com a data");

22 scanf("%d %d %d",&d.dia ,&d.mes ,&d.ano);

23 return d;

24 }

25

26 tData alteraData(int d,int m,int a){

27 tData dt;

28

29 dt.dia=d;

30 dt.mes=m;

31 dt.ano=a;

32 return dt;

33 }

34

35 int eBissexto(tData d){

36 if(d.ano %400==0){

37 return 1;

38 }else if(d.ano %100==0){

39 return 0;

40 }else if(d.ano %4==0){

41 return 1;

42 }else{

43 return 0;

44 }

45 }

46

Page 118: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

118 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

47 int diasNoMes(tData d){

48 if(d.mes ==4||d.mes ==6||d.mes ==9||d.mes ==11){

49 return 30;

50 }else{

51 if(d.mes =2){

52 if(eBissexto(d)){

53 return 29;

54 }else{

55 return 28;

56 }

57 }else{

58 return 31;

59 }

60 }

61 }

62

63 tData diaSeguinte(tData d){

64 if(d.dia <diasNoMes(d)){

65 d.dia++;

66 }else{

67 d.dia=1;

68 if (d.mes <12){

69 d.mes++;

70 }else{

71 d.mes=1;

72 d.ano++;

73 }

74 }

75 return d;

76 }

77

78 main(){

79 }

Exemplo 4.8: Definicao do TAD tData.

O codigo do Exemplo 4.8 ilustra a definicao de um Tipo Composto com Operacoes Pre-definidas. O tipo tData contem os atributos de uma data. Uma variavel desse tipo e inicializadaatraves da funcao inicializarValores, essa funcao permite inicializacao dos atributos sem queestes sejam acessados. A funcao de leitura leData obtem uma data do teclado e retorna umavariavel do tipo tData contendo os valores lidos. A funcao alteraData apresenta o mesmocodigo que a funcao de inicializacao, contudo sua utilizacao destina-se a datas ja inicializadas.A funcao eBissexto verifica se uma dada data esta em um ano bissexto, o algoritmo considera aseguinte regra: Sao bissextos todos os anos multiplos de 400, nao sao bissextos todos os multiplosde 100 e nao de 400, sao bissextos todos os multiplos de 4 e nao multiplos de 100, por fim, naosao bissextos todos os demais anos. A funcao diasNoMes determina o numero de dias de umdo mes de uma determinada data. Os meses de abril, junho, setembro e novembro possuem 30dias. Caso a data seja do mes de fevereiro, verifica-se se o ano e bissexto, se for bissexto o mes

Page 119: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.3. TIPOS ABSTRATOS DE DADOS 119

tem 29 dias, se nao for bissexto o mes tem 28 dias. Caso a data nao esteja em nenhum dosmeses citados, o mes apresenta 31 dias.

Importancia de Definir Tipos com Operacoes Proprias

A criacao de um conjunto de operacoes proprias de um TAD tem como finalidade torna-lo,aos olhos do usuario, um tipo de dados da propria linguagem, ou seja, o usuario nao deve sepreocupar em como sao implementados os TADs. Alem do mais, utilizar as operacoes do TADtorna o codigo mais confiavel. Suponha uma aplicacao que utilize o TAD tData conforme oExemplo 4.9.

1 #include <stdio.h>

2

3 // A definic~ao do TAD , bem como suas operac~oes , esta no Exemplo 4.6

4

5 main(){

6 tData d;

7

8 d=leData ();

9 printf("Passou um dia!\n");

10 d.dia++;

11 printf("Hoje e %d/%d/%d.\n",d.dia ,d.mes ,d.ano);

12 }

Exemplo 4.9: Problema de Confiabilidade no uso do TAD tData.

Observe que, no Exemplo 4.9, a intencao do programador foi adicionar um dia a data lida,entretanto, este nao utilizou a funcao do tipo diaSeguinte . Para grande parte dos valores dedata, o programa funcionaria corretamente, entretanto, para datas que sao o ultimo dia do mes,esse programa gera inconsistencia, pois a data obtida nao sera uma data valida. No decorrer daaplicacao, um valor invalido de data sera repassado para outras partes do programa. Assim essainconsistencia pode ter um efeito colateral que acarrete em problemas no codigo. Sendo assim,e altamente recomendavel que se utilizem apenas as operacoes ja definidas para manipular asestruturas do TAD e que nao ocorra a manipulacao de atributos.

Vantagens de Usar TADs

As vantagens de utilizar um TAD sao:

• Facilidade de Manutencao: Pode-se alterar o tipo usado sem alterar a aplicacao. Porexemplo, pode-se incluir novos atributos ou operacoes sem que o codigo que utilize o tiposeja alterado.

• Reutilizacao: Um TAD bem generalizado pode ser utilizado em diversas aplicacoes.

• Abstracao: A abstracao de informacoes atraves do TAD permite a melhor compreensaodos algoritmos e maior facilidade de programacao.

Page 120: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

120 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

• Ocultamento: Separa o codigo de implementacao do codigo de uso do TAD, que funcionacomo um tipo de dados fornecido pela linguagem.

• Integridade: A manipulacao dos atribuitos por operacoes definidas sobre o tipo impedema ocorrencia de inconsistencias.

Na pratica, essas vantagens tornam o codigo mais facil de se escrever, mais compreensıvelpara quem le e mais facil de se modificar.

Problema do uso de TADs em C

A ideia do TAD e esconder o codigo da implementacao do usuario, que nao deve ter acessoindiscriminado aos atributos do TAD. A linguagem C, entretanto, nao oferece a funcionalidadede protecao ao acesso aos atributos e operacoes. Na verdade, C nao implementa TAD, o que sefaz e apenas uma simulacao, visto que apesar de se definir as operacoes sobre o tipo, o usuariotem a liberdade para acessar diretamente os atributos sem nenhuma protecao, tornando o codigonao confiavel.

4.3.2 Definicao de Atributos de um TAD

Os atributos de um TAD sao os dados que se relacionam a ele. Por exemplo, no caso doestudante, seus atributos sao: idade, matrıcula, coeficiente de rendimento e perıodo. Conformedefinido na Secao 4.2.1.

4.3.3 Definicao de Operacoes de um TAD

As operacoes de um TAD sao funcoes que utilizadas para acesso dos dados. Estas operacoesvisam impedir o acesso direto aos dados, assim, o usuario so deve acessar os dados atraves dessasoperacoes.

Tipos de Operacoes de um TAD

Um TAD nao e definido por seus atributos, mas sim por suas operacoes. As operacoes saoa interface do programador usuario com a propria representacao interna. Existem cinco tiposdiferentes de operacoes que podem ser realizadas sobre um TAD:

Construtoras

Operacoes construtoras sao aquelas que inicializam variaveis, logo devem ser utilizadas antes dequalquer outra para garantir que o TAD foi inicializado corretamente. Observe no Exemplo 4.10diferentes implementacoes de funcoes construtoras para o TAD estudante.

1 tEstudante inicializar (){

2 tEstudante novo;

Page 121: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.3. TIPOS ABSTRATOS DE DADOS 121

3

4 novo.idade =0;

5 novo.matricula =0;

6 novo.coeficiente =0;

7 novo.periodo =0;

8 return novo;

9 }

10

11 tEstudante inicializarValores(int idade ,int matricula ,float coeficiente , int

periodo){

12 tEstudante novo;

13

14 novo.idade=idade;

15 novo.matricula=matricula;

16 novo.coeficiente=coeficiente;

17 novo.periodo=periodo;

18 return novo;

19 }

Exemplo 4.10: Diferentes formas de Implementacao da funcao construtora para o TADtEstudante.

A funcao inicializar inicia com zero todos os atributos de uma variavel do tipo tEstudante,esta variavel e retornada pela funcao de inicializacao. A funcao inicializarValores exerce omesmo papel de inicializar que a funcao inicializar . Contudo, esta recebe os valores a seremincializados como parametros da funcao.

Analisadoras

As operacoes analisadoras ou consultoras analisam o conteudo de um TAD e retornam proprie-dades, ou seja, essas operacoes obtem informacoes do TAD. O Exemplo 4.11 mostra uma funcaoanasiladora.

1 int bomAluno(tEstudante aluno){

2 if (aluno.coeficiente >7.0){

3 return 1;

4 }else{

5 return 0;

6 }

7 }

Exemplo 4.11: Funcao analisadora.

Observa-se, no Exemplo 4.11, que a funcao bomAluno e um exemplo de funcao analisadorapara o TAD tEstudante, pois retorna uma propriedade do mesmo (se e um bom aluno).

Page 122: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

122 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

Modificadoras

As operacoes modificadoras, ou atualizadoras, permitem alteracoes de atributos do TAD. OExemplo 4.12 mostra uma funcao modificadora para o TAD tEstudante.

1 tEstudante alteraIdade(tEstudante aluno ,int novaIdade){

2 aluno.idade=novaIdade;

3 return aluno;

4 }

Exemplo 4.12: Funcao modificadora.

Produtoras

As operacoes produtoras sao aquelas que, a partir dos dados de um TAD, produzem uma novainformacao. A funcao maiorIdade , do Exemplo 4.13, produz um resultado (a maior idade) apartir de dois estudantes dados.

1 int maiorIdade(tEstudante est1 ,tEstudante est2){

2 if (est1.idade >est2.idade){

3 return est1.idade;

4 }

5 return est2.idade;

6 }

Exemplo 4.13: Exemplo de funcao produtora.

Destrutoras

As operacoes destrutoras sao utilizadas para liberar recursos de memoria quando o TAD nao emais necessario. Exemplos e explicacoes sobre essa funcao sao dados no Capıtulo 7.

4.3.4 Uso do TAD

Considere o Exemplo 4.14 que faz uso do TAD tData. Note que o TAD e acessado apenas pelasoperacoes pre-definidas.

1 #include <stdio.h>

2

3 // A definic~ao do TAD , bem como suas operac~oes , esta no Exemplo 4.6

4

5 main(){

6 tData data;

7 int anoBissexto;

8 int nDias;

Page 123: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.4. EXERCICIOS RESOLVIDOS 123

9

10 data=leData ();

11 anoBissexto=eBissexto(data);

12

13 if(anoBissexto == 1){

14 printf("Ano Bissexto");

15 }else{

16 printf("Ano n~ao Bissexto");

17 }

18

19 nDias=diasNoMes(data);

20 printf("Numero de dias no mes:",nDias);

21 }

Exemplo 4.14: Uso do TAD tData.

O Exemplo 4.14 determina se uma data digitada pelo teclado e de um ano bissexto e onumero de dias no mes da data digitada. Pode-se afirmar que o programa usuario manipula oTAD somente atraves das operacoes pre-definidas pelo implementador, assim o codigo usuariofica mais legıvel. Pode-se observar que as operacoes separam o codigo usuario do codigo deimplementacao do TAD. A redigibilidade tambem aumenta, visto que o acesso aos dados erealizado apenas por simples operacoes. O codigo tambem fica mais confiavel, pois o usuarionao altera livremente os dados, isso so pode ser feito atraves das operacoes do TAD. E, por fim,caso a implementacao do TAD precise ser alterada, o codigo usuario nao sofrera mudancas, amenos que os cabecalhos das funcoes sejam alterados.

4.3.5 Tipos de TADs

Os TADs podem se dividir em TADs de Domınio e TADs Implementacionais, conforme suarelacao com o problema ou com sua solucao .

TADs de Domınio

Sao aqueles que definem um tipo de dados que esta no domınio do problema. Como por exemplo,os TADs tEstudante e tData.

TADs Implementacionais

Sao de objetos de programacao que nao tem relacao direta com o problema, mas sim com suaimplementacao. Podemos tomar como exemplos as listas, as arvores, os grafos e as filas. Algunsdesses conceitos sao apresentados nos proximos capıtulos.

4.4 Exercıcios Resolvidos

Exercıcio Resolvido4.1 - Leitura da Estrutura tData

Page 124: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

124 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

Faca um programa que imprima de uma estrutura do tipo data, a data de nascimento30/01/1984.

Solucao Possıvel:Nao existem dados de entrada, a data de nascimento a ser informada e armazenada direta-

mente em uma estrutura data. A impressao da data e realizada no formato abreviado utilizandoo comando printf . A saıda do programa e a impressao da data 30/01/1984.

1 #include <stdio.h>

2

3 struct data{ // estrutura do tipo data

4 int dia;

5 int mes;

6 int ano;

7 };

8

9 int main(){

10 struct data dataNascimento;

11

12 // inicializa a estrutura data de nascimento

13 dataNascimento.dia = 30;

14 dataNascimento.mes = 01;

15 dataNascimento.ano = 1984;

16 printf("Data: %d/%d/%d\n", dataNascimento.dia , dataNascimento.mes ,

dataNascimento.ano);

17 return 0;

18 }

Exercıcio Resolvido 4.2 - Operacoes sobre a Estrutura Data

Defina, agora, a estrutura do exemplo anterior como um tipo e realize operacoes (sobre estetipo) de edicao e consulta.

Solucao Possıvel:Este programa utiliza operacoes de alteracao e consulta sobre o TAD para datas. A estrutura

para datas e declara como um tipo utilizando o comando typedef. A operacao alteraDatarecebe como parametros o dia, mes e ano de uma determinada data e passa, como retorno defuncao, a data informada. A operacao consultaData realiza a impressao de uma data. Assim,pode-se observar as vantangens da utilizacao de TADs, atraves destas duas operacoes e necessarioescrever menos, visto que as operacoes podem ser aproveitadas. A data e inicializada no corpodo programa em 30/01/1984, em seguida e alterada. A saıda do programa e a impressao dadata 16/05/2007.

1 #include <stdio.h>

2

Page 125: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.4. EXERCICIOS RESOLVIDOS 125

3 typedef struct data{

4 int dia;

5 int mes;

6 int ano;

7 }tData;

8

9 tData alteraData(int d,int m,int a){

10 tData dt;

11

12 dt.dia=d;

13 dt.mes=m;

14 dt.ano=a;

15 return dt;

16 }

17

18 void consultaData(tData data) {

19 printf("Data: %d/%d/%d\n", data.dia , data.mes , data.ano);

20 }

21

22 int main() {

23 tData dataNascimento;

24

25 dataNascimento = alteraData (30 ,01 ,1984);

26 dataNascimento = alteraData (16 ,05 ,2007);

27

28 consultaData(dataNascimento);

29 return 0;

30 }

Exercıcio Resolvido 4.3 - Menor Data

Escreva um programa em C que leia duas datas e retorne a menor data cronologicamente.Observacao: As datas devem ser armazenadas em estruturas.

Solucao Possıvel:O programa que determina qual e a menor data entre duas. Agora, a inicializacao das

datas e realizada por leitura do teclado. O retorno da operacao menorData e a menor entreduas datas, a primeira verificacao e realizada quanto ao ano, caso o ano das datas sejam iguaisverifica-se o mes, se os meses sao iguais verifica-se os dias.

1 #include <stdio.h>

2

3 struct data{ // estrutura do tipo data

4 int dia;

5 int mes;

6 int ano;

7 };

8

Page 126: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

126 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

9 struct data menorData(struct data data0 , struct data data1){

10 if (data0.ano < data1.ano){

11 return data0;

12 }else if (data1.ano < data0.ano){

13 return data1;

14 }else if (data0.mes < data1.mes){

15 return data0;

16 }else if (data1.mes < data0.mes){

17 return data1;

18 }else if (data0.dia < data1.dia){

19 return data0;

20 }else{

21 return data1;

22 }

23 }

24

25 struct data leData (){

26 struct data d;

27

28 printf("Entre com a data");

29 scanf("%d %d %d",&d.dia ,&d.mes ,&d.ano);

30 return d;

31 }

32

33 main(){

34 // declarac~ao de variaveis

35 struct data data0 , data1 , menor;

36

37 // entrada das datas

38 printf("Primeira data:\n");

39 data0 = leData ();

40 printf("\nSegunda data:\n");

41 data1 = leData ();

42

43 // determina a menor data

44 menor = menorData(data0 , data1);

45

46 printf("\nA menor data eh: %d/ %d/ %d.\n", menor.dia , menor.mes , menor.ano);

47 }

Exercıcio Resolvido 4.4 - TAD Tponto

Defina o tipo Tponto para representar os pontos do plano cartesiano de duas dimensoes.

Solucao Possıvel:Para representar um ponto, e criada uma estrutura com dois atributos, as coordenadas x e

y.

Page 127: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.4. EXERCICIOS RESOLVIDOS 127

1 typedef struct {

2 int x;

3 int y;

4 } Tponto;

Exercıcio Resolvido 4.5 - Operacao Tponto simetricoOrigem (Tponto ponto)

Agora, implemente a operacao Tponto simetricoOrigem (Tponto ponto), para deter-minar o ponto simetrico de um ponto em relacao a origem.

Solucao Possıvel:A operacao simetricoOrigem tem como retorno uma variavel do tipo Tponto. Para obter

um ponto simetrico a outro em relacao a origem, basta inverter as coordenadas do ponto dado.

1 Tponto simetricoOrigem (Tponto ponto){

2 ponto.x = -ponto.x;

3 ponto.y = -ponto.y;

4

5 return ponto;

6 }

Exercıcio Resolvido 4.6 - Operacao int qualQuadrante (Tponto ponto)

Agora, implemente a operacao int qualQuadrante (Tponto ponto) que determina emqual quadrante pertence um ponto.

Solucao Possıvel:Dado um ponto, a operacao qualQuadrante retorna a qual quadrante esse ponto pertence.

A funcao retorna 0 quando o ponto for parte do limite de quadrantes, 1 quando o ponto pertencerao 1o quadrante, 2 quando pertencer ao 2o quadrante, 3 se pertencer ao 3o quadrante e 4 caso sejado 4o quadrante. Para determinar a que quadrante o ponto pertence, e utilizado um conjuntode if e else aninhados que verificam os sinais das coordenadas.

1 int qualQuadrante (Tponto ponto){

2 if (ponto.x == 0 || ponto.y == 0){

3 return 0;

4 }else{

5 if (ponto.x > 0) {

6 if (ponto.y > 0){

7 return 1;

8 }else{

9 return 4;

10 }

11 } else {

Page 128: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

128 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

12 if (ponto.y > 0){

13 return 2;

14 }else{

15 return 3;

16 }

17 }

18 }

Exercıcio Resolvido 4.8 - Operacao float distanciaPontos (Tponto a, Tponto b)

Defina um programa que calcule a distancia entre dois pontos, implemente e use operacoesconstrutoras e destrutoras, implemente tambem a operacao float distanciaPontos (Tpontoa, Tponto b), de calculo de distancia entre dois pontos.

Solucao Possıvel:Inicialmente, sao definidas a estrutura Tponto e as operacoes aplicaveis a ela. Alem das

funcoes relacionadas ao problema, deve-se sempre definir as funcoes inicializadora e destrutora.A funcao ler() inicializa o Tponto a partir de valores fornecidos pelo usuario, a funcao zera()zera as coodernadas do ponto e a funcao distanciaPontos calcula a distancia entre pontos, dadapela raiz quadrada da soma do quadrado da diferenca entre as abscissas e entre as ordenadas.A funcao principal utiliza os metodos declarados de forma a corresponder a funcionalidadedesejada.

1 #include <stdio.h>

2

3 struct ponto{

4 int x, y;

5 }

6

7 typedef struct ponto Tponto;

8

9 // Operac~ao construtora:

10 Tponto ler(){

11 Tponto ponto;

12

13 printf("Entre com as coordenadas\n");

14 printf("X: ");

15 scanf("%d", &ponto.x);

16 printf("Y: ");

17 scanf("%d", &ponto.y);

18

19 return ponto;

20 }

21

22 // Operac~ao destrutora:

23 Tponto zera(){

24 Tponto origem = {0, 0};

Page 129: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.5. RESUMO 129

25

26 return origem;

27 }

28

29 // Operac~ao Produtora:

30 float distanciaPontos (Tponto a, Tponto b){

31 float distancia , deltaX , deltaY;

32

33 deltaX = a.x - b.x;

34 deltaY = a.y - b.y;

35

36 distancia = sqrt(deltaX ^2 + deltaY ^2);

37 return distancia;

38 }

39

40 main (){

41 Tponto a, b;

42 float distancia;

43

44 a = ler ();

45 b = ler ();

46

47 distancia = distanciaPontos(a, b);

48 printf("Distancia entre pontos: %f\n", distancia);

49

50 a = zera();

51 b = zera();

52 }

4.5 Resumo

• Inicialmente foram abordadas as seguintes abordagens na programacao:

– bottom-up: que e uma tecnica que propoe considerar o programa como um conjuntode modulos correlacionados, implementar cada um desses modulos e depois junta-lospor meio de uma estrutura global.

– top-down: que e uma tecnica que proporciona que um programa seja visto comouma descricao de um processo. O processo e dividido em subprogramas, os quais saoresponsaveis por cumprir partes da funcionalidade geral do processo. Por sua vez,cada subprograma ainda pode ser dividido em novos subprogramas.

• Utilizou-se a tecnica ”dividir para conquistar”nas duas abordagens, onde cada abordagemdeve ser utilizada de acordo com as informacoes conhecidas do sistema. Aqui enfatizou-sea abordagem bottom-up porque ela permite que o programador usuario nao se preocupecom a implementacao de cada modulo, bastando saber a funcionalidade de cada modulopara que os mesmos possam ser integrados.

Page 130: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

130 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

• Uma estrutura agrupa varias variaveis numa so. Funciona como uma ficha pessoal quetenha nome, telefone e endereco. A ficha seria uma estrutura. A estrutura, entao, servepara agrupar um conjunto de dados nao similares, formando um novo tipo de dados.Estas proveem uma grande facilidade para o armazenamento de tipos nao definidos pelalinguagem. O uso de estruturas e considerado uma otima pratica de programacao, vistoque, alem de permitirem uma organizacao melhor, possibilitam realizar atribuicoes oupassagem de parametros em uma unica vez. Uma estrutura pode ser manipulada de formaseletiva (acesso a um unico atributo) ou de forma integral (acesso a estrutura como umtodo).

• Os TADS sao generalizacoes das estruturas, pois associamos varias operacoes sobre aestrutura, estas podem ser dos seguintes tipos: construtoras, analisadoras, modificadoras,produtoras e destrutoras. Assim, os TADS sao definidos como uma estrutura de dados e asoperacoes sobre os dados. A importancia de um TAD esta na transparencia que ele oferece,o usuario do tipo nao precisa se preocupar em como o TAD e implementado. O uso deTADs permite inumeras vantagens como abstracao, facilidade de alteracao, reutilizacao,ocultamento e integridade. Os Tipos Abstratos de Dados sao classificados em TADs deDomınio e TADs Implementacionais. TADs de domınio sao aqueles que descrevem um tipodo problema, enquanto TADs Implementacionais descrevem uma estrutura que ira ajudara resolver o problema, mas nao se refere ao problema. Exemplos de TADs de domınio saoos registros de alunos, funcionarios, datas, etc. Exemplos de TADs implementacionais saoas pilhas, listas, etc.

• Contudo, e importante dizer que a ideia do TAD e que o codigo da implementacao do tipode dado, fique invisıvel para o programador que for usar o tipo. Assim, na verdade, C naoimplementa TAD, o que se faz e uma simulacao de TDAs. No entanto, a simulacao deTADs em C se torna uma boa pratica de programacao, pois torna o codigo do programamais compreensıvel e simplifica a definicao das estruturas de dados. Em linguagens quepermitam Programacao Orientada a Objetos (POO), os TADs podem ser implementadoscom a confiabilidade que C nao permite.

4.6 Lista de Exercıcios

Exercıcio 4.1 - TAD tCilindro

Implemente um TAD para o armazenamento dos dados de um cilindro. A entrada dos dadosreferentes ao cilindro sera realizada via console(teclado). As possıveis operacoes sobre o tiposao:

• leitura dos dados;

Page 131: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.6. LISTA DE EXERCICIOS 131

• Inicializa Cilindro;

• Altera Altura;

• Altera Raio;

• Calcula Volume;

• Imprime Dimensoes;

• Imprime Volume;

Exercıcio 4.2 - Determinando a Idade

Modifique o TAD tData incluindo uma operacoes que determine a idade de uma pessoa, equantos dias faltam para seu aniverario tendo como entradas a data de nascimento e a dataatual. Deve-se considerar anos bissextos e meses com o numero de dias conforme o calendarioocidental.

Exercıcio 4.3 - TAD tPonto

Implemente um TAD Ponto para representar um ponto no plano com as seguintes operacoes:

• leitura: leitura via console;

• desloca x: realiza um deslocamento horizontal;

• desloca y: realiza um deslocamento vertical;

• atribui x y: atribui novos valores as coordenadas de um ponto;

• distancia: calcula a distancia entre dois pontos;

• imprime: imprime as coordenadas do ponto.

Exercıcio 4.4 - TAD tCirculo

Implemente um TAD Circulo para representar um cırculo (Observe que o centro e um ponto)com as seguintes operacoes:

• leitura: leitura via console;

Page 132: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

132 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

• atribui raio: atribui um valor r ao raio do circulo;

• atribui centro: atribui novo valor ao centro do circulo;

• area: calcula a area do cırculo;

• interior: verifica se um dado ponto esta dentro do cırculo.

Exercıcio 4.5 - TAD tTrapezio

Implemente um TAD Trapezio para representar um trapezio com as seguintes operacoes:

• leitura: funcao leitura para cada lado do trapezio;

• atribuicao: atribui individualmente cada lado;

• area: calcula a area do trapezio;

• interior: verifica se um dado ponto esta dentro do trapezio.

Exercıcio 4.6 - Imobiliaria

Voce foi contratado para fazer algumas pesquisas no cadastro de uma imobiliaria. Considereque cada imovel possui um codigo de identificacao, uma area total e o preco por metro quadradodo imovel. Implemente um programa que leia os dados dos imoveis, armazene e imprima oimovel mais caro e o de maior area em um TAD imovel.

4.7 Trabalhos Sugeridos

Trabalho 4.1 - Estacionamento

Considere o sistema responsavel pelo controle de entrada e saıda de veıculos de um estaci-onamento que funciona 24 h por dia. Um motorista ao entrar no estacionamento recebe umticket indicando o horario e a data de entrada, na saıda do estacionamento o atendente realizaa cobranca pelo uso do servico.

O preco do uso do estacionamento por hora e de R$ 1,00 nos dias uteis e R$ 2,00 em sabados,domingos e feriados.

Page 133: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

4.7. TRABALHOS SUGERIDOS 133

O sistema deve ler do ticket do usuario o horario e a data de entrada, deve identificar ohorario atual e a respectiva data, calcular o tempo de uso do estacionamento e o valor a serpago.

Caso o motorista permaneca no estacionamento por menos de 15 minutos ele nao deverapagar pelo uso do estacionamento. Caso o motorista permaneca por menos de uma hora eledevera pagar pelo preco de uma hora completa.

Implemente um TAD horario que armazene os horarios e as datas de entrada e saıda paracada veıculo e que tenha operacoes como:

• ler horario de entrada;

• ler data de entrada;

• obter horario do sistema;

• obter data do sistema;

• calculo de tempo no estacionamento;

• calculo de custo;

• determinacao do horario e data de saıda para um determinado custo de uso do estaciona-mento considerando um determinado horario de entrada.

Trabalho 4.2 - Banco

O gerente de uma agencia bancaria te contratou para fazer um programa em C para extrairalgumas informacoes das contas dos correntistas de sua agencia. Para tanto leia sucessivamenteos dados do numero da conta (um valor inteiro positivo) e valor da operacao (um valor pontoflutuante positivo para as operacoes de credito e negativo para as operacoes de debito) realizadasno ultimo mes. Seu programa deve usar os dados da listagem para informar:

1. As operacoes suspeitas, isto e, aquelas que movimentaram acima de 20.000 reais

2. Os dois correntistas que produziram o maior saldo nas suas operacoes.

3. O saldo total das operacoes na agencia .

Nos ıtens 1, 2, e 3 tambem devem ser apresentados os numeros das contas dos correntistas.Considere que os dados de cada conta sao fornecidos contiguamente, isto e, sao fornecidostodos os dados das operacoes de uma conta, depois todos os dados de outra conta e assimsucessivamente. O processamento deve ser encerrado quando for lido um numero de conta iguala zero.

Page 134: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

134 CAPITULO 4. TIPOS ABSTRATOS DE DADOS

Trabalho 4.3 - NPD UFES

O diretor do NPD da UFES te contratou para fazer um programa em C para extrair algumasinformacoes a respeito dos cursos e dos alunos da UFES. Para tanto leia sucessivamente os dadoscodigo do curso (um valor inteiro positivo), a matrıcula do aluno (um valor inteiro positivo), acarga horaria da disciplina (um valor inteiro positivo) e a media final obtida em uma disciplinacursada pelo aluno (um valor ponto flutuante). Seu programa deve esses dados para informar:

1. O coeficiente de rendimento de cada aluno .

2. O melhor aluno de cada curso, isto e, o aluno de melhor coeficiente de rendimento nocurso.

3. O curso mais difıcil, isto e, aquele que tem o menor coeficiente de rendimento medio.

4. Os tres alunos com maior numero de reprovacoes na UFES.

Nos ıtens 1 e 2 devem ser apresentados o curso, a matrıcula e o coeficiente do aluno. Noitem 3 devem ser apresentados o curso e o coeficiente de rendimento medio. No item 4, devemser apresentados o curso, a matrıcula e o numero total de reprovacoes. Considere que os dadosde cada aluno e curso sao fornecidos contiguamente, isto e, sao fornecidos todos os dados dasdisciplinas cursadas por um aluno em um curso, depois todos os dados de outro aluno destecurso e assim sucessivamente ate terminar todos os dados de alunos do curso. Esse processo serepete para todos os cursos da UFES. O processamento deve ser encerrado quando for lido umcodigo de curso igual a zero.

Page 135: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

Capıtulo 5

VetoresAutores:

AndrezinhoThiago Paris Salviato

Objetivos:

• Introduzir a estrutura de dados vetor e mostrar sua importancia;

• Apresentar suas operacoes basicas e discutir os cuidados a serem tomados ao utiliza-las;

• Definir um TAD Implementacional tVetorInt;

• Apresentar aplicacoes para o TAD.

5.1 Vetores e sua importancia

Imagine que se queira fazer um programa para manusear dados de um mesmo tipo - as idadesdas pessoas de uma famılia, ou os salarios dos funcionarios de uma empresa, por exemplo.Uma alternativa seria a utilizacao de varias variaveis ou entao a leitura de valores sempre quenecessarios. Mas sera que essas seriam as melhores solucoes? E se o programa for grande ehaja necessidade de que ele seja modularizado? Nao ficaria ruim na hora de passar todas essasvariaveis como parametros? Ao se refletir sobre essas perguntas, outra ideia pode vir a tona:a utilizacao de um TAD, ja que, dessa forma, as variaveis podem ser encapsuladas numa soestrutura e apenas ela poderia ser passada como parametro! Boa ideia! Mas e se fossem 100valores diferentes? Ou se houvesse a necessidade de mante-los ordenados, por exemplo? Comoja se pode perceber, nem sempre os tipos basicos de dados (int, float, char) sao suficientes paraexprimir estruturas de dados em algoritmos.

Para ilustrar melhor o problema considere que um professor tenha uma turma de 50 alunose deseja saber quantos deles tiveram nota acima da media da turma. Com os instrumentosapresentados ate o capıtulo anterior, seria necessaria a leitura das notas dos alunos por duas

135

Page 136: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

136 CAPITULO 5. VETORES

vezes (ou a utilizacao de 50 variaveis - nao tente isso em casa!): uma para calcular a media eoutra para verificar quais alunos tiveram notas superiores a media. O Exemplo 5.1 mostra umamaneira de resolver o problema do professor utilizando a Linguagem C, fazendo a dupla leituracitada acima.

1 #include <stdio.h>

2

3 main(){

4 int i;

5 int quant;

6 float nota;

7 float soma;

8 float media;

9

10 nota = 0.0;

11 soma = 0.0;

12 media = 0.0;

13

14 for(i = 0; i < 50 ; i++){

15 printf("Digite uma nota");

16 scanf("%f",&nota);

17 soma=soma+nota;

18 }

19

20 media=soma /50;

21

22 quant = 0;

23

24 for(i = 0; i < 50 ; i++){

25 printf("Digite uma nota\n");

26 scanf("%f",&nota);

27 if(nota > media) quant ++;

28 }

29

30 printf("\n%d alunos obtiveram nota acima da media\n",quant);

31 }

Exemplo 5.1: Resolucao do exemplo do professor sem a utilizacao de vetores

Todos os problemas citados ate agora no capıtulo poderiam ser resolvidos com a utilizacaode vetores.

Um vetor e uma estrutura de dados composta homogenea, isto e, ele possui, em geral, maisde um elemento - por isso, composta - sendo que estes elementos sao sempre de um mesmo tipo- por isso, homogenea.

Resumindo, a utilizacao de um vetor se faz necessaria sempre que for preciso armazenaruma quantidade finita de dados de um mesmo tipo, para ser manuseado durante a execucao doprograma. No Exemplo 5.1, por exemplo, as notas de todos os alunos da turma poderiam tersido armazenadas num unico vetor com apenas uma leitura e a partir de entao eles estariam

Page 137: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.2. REPRESENTACAO 137

disponıveis para serem utilizados durante todos os calculos.

5.2 Representacao

A Figura 5.1 mostra a maneira mais comum de se representar um vetor graficamente.

Figura 5.1: Representacao de um vetor

A Figura 5.1 representa um vetor de inteiros chamado vet com os nove primeiros numerosprimos, onde o terceiro elemento (elemento de ındice igual a 2) e o numero 5 e o de ındice 4 e onumero 11, por exemplo. E importante lembrar que todo o primeiro elemento de um vetor nalinguagem C possui o ındice zero.

Analizando a Figura 5.1 fica evidente outras importantes caracterısticas dessa estrutura: aseqencializacao e a indexacao de seus elementos e a sua dimensao.

Quando se declara um vetor num programa, significa que durante a sua execucao sera re-servado um espaco de memoria sequencial com o tamanho necessario para que seja possıvelarmazenar todos os elementos do vetor. Portanto os elementos serao armazenados sequencial-mente na memoria.

Essa propriedade facilita bastante o acesso do programa ao elemento desejado dentro dovetor, pois, para que o dado seja recuperado, fica sendo necessario apenas o nome do vetor, quelocaliza o primeiro elemento, e um ındice, que indicara ao programa a que distancia do inıcioesta o dado desejado.

Mas para que seja feita a reserva do espaco de memoria, deve ser informado no codigo qualo tamanho do vetor, isto e, o numero maximo de elementos que ele pode armazenar. A Figura5.2 mostra uma ilustracao de como um vetor e armazenado na memoria do computador.

Dados os conceitos teoricos do vetor, chega a hora de discutir como essa estrutura pode serutilizada na pratica, abordando assuntos como a sua definicao, as operacoes definidas sobre elae outros. Isso sera feito a partir de agora.

5.3 Definicao

O primeiro passo para uma utilizacao clara e efetiva dos vetores e uma declaracao que deixe claropara que a estrutura esta sendo usada. Isso ajuda a dar legibilidade ao codigo, logo, facilida aimplementacao.

Na linguagem C, o vetor e declarado da seguinte maneira:

<tipo_dados> <nome_vetor>[<tam_vetor>];

Page 138: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

138 CAPITULO 5. VETORES

Figura 5.2: Vetores na memoria do computador

onde tipo dados representa o tipo dos dados dos elementos que serao armazenados no vetor,nome vetor o nome pelo qual o vetor sera referenciado e tam vetor o numero de elementos quecabem la dentro. O Exemplo 5.2 mostra alguns exemplos de declaracao de vetores.

1 int vet [9];

2

3 char nome [9];

4

5 float notas [6];

6

7 float notasAlunos [50];

Exemplo 5.2: Algumas declaracoes de vetores

No Exemplo 5.2, o primeiro vetor declarado pode ser representado graficamente pela Figura5.1 mostrada na secao anterior, ou seja, seu nome e vet e ele pode armazenar ate nove elementos

Page 139: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.3. DEFINICAO 139

do tipo int. O segundo e o terceiro foram os representados pela Figura 5.2. Aquele, chamadonome, armazena no maximo 6 elementos do tipo char, e este, chamado notas, ate seis do tipofloat. Ja o ultimo poderia ser utilizado no problema do professor citado anteriormente, porexemplo. Neste vetor, chamado notasAlunos, podem ser armazenados cinquenta valores do tipofloat, que poderiam representar as notas dos cinquenta alunos.

5.3.1 Definicao do Tamanho do Vetor

Na linguagem C, o tamanho do vetor pode ser definido em dois momentos diferentes: emtempo de compilacao e em tempo de execucao; lembrando sempre que, em ambos os casos,uma vez que ele for definido e que a memoria for alocada, o tamanho nao podera ser alterado.Alguns fatores devem ser considerados na hora de escolher entre essas duas abordagens, como oconsumo de memoria e o tipo de aplicacao.

Definicao em tempo de compilacao

A definicao em tempo de compilacao e caracterizada pelo numero inteiro entre colchetes nadeclaracao do vetor. Todas as declaracoes mostradas no Exemplo 5.2 sao exemplos de vetoresdefinidos em tempo de compilacao, antes da execucao do programa.

Entao, para armazenar dados nesse tipo de vetor, e necessario que se tenha conhecimentoprevio da quantidade maxima de elementos que nele sera armazenado.

Suponha que se queira fazer um programa para cadastrar os alunos de uma escola de ensinomedio com cinco turmas por ano e fazer um acompanhamento de suas notas. Considere tambemque cada aluno pode cursar, no maximo, oito materias por ano, duas delas optativas. O Exemplo5.3 mostra uma estrutura que poderia ser utilizada para representar um aluno na linguagem C.

1 typedef struct aluno{

2 char nome [50];

3 int rg;

4 int ano;

5 char turma;

6 float notas [8];

7 }tAluno;

Exemplo 5.3: Definicao da Estrutura Aluno

A estrutura proposta no Exemplo 5.3 possui um vetor chamado nome, do tipo char e detamanho igual a 50 para armazenar o nome completo de um aluno; duas variaveis do tipo intchamadas rg e ano, para armazenar, respectivamente, o numero do RG do aluno e seu ano(serie); uma variavel do tipo char chamada turma, para armazenar sua turma; e um vetor dotipo float chamado notas e de tamanho igual a 8, para armazenar as notas desse aluno nasdiferentes disciplinas que ele pode cursar.

Page 140: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

140 CAPITULO 5. VETORES

Repare que as notas e o nome do aluno podem ocupar um espaco menor que o tamanhomaximo do vetor. Essa caracterıstica dos vetores definidos em tempo de compilacao pode acar-retar em desperdıcio de memoria, pois os espacos armazenados para eles podem nao ser utilizadostotalmente.

Definicao em tempo de execucao

A definicao do tamanho em tempo de execucao, pode ser implementada substituindo onumero inteiro que e colocado entre colchetes na declaracao do vetor por uma variavel que soganhara um valor durante a execucao do programa. O Exemplo 5.4 mostra como isso pode serfeito na linguagem C.

1 #include <stdio.h>

2

3 main(){

4

5 int num;

6

7 ...

8

9 printf("Quantas notas deseja armazenar no vetor?");

10 scanf("%d" ,&num);

11

12 float notas[num];

13

14 ...

15

16 }

Exemplo 5.4: Definicao de um vetor em tempo de execucao

Repare que declarando o vetor dessa forma, o desperdıcio de memoria pode ser eliminado,ja que o vetor e utilizado por completo, desde que se tenha conhecimento previo do numero deelementos que serao armazenados e que se possa informa-lo a aplicacao.

E importante ressalvar que essa forma dinamica de definicao de tamanho nao funciona nocaso de vetores dentro de estruturas, como o vetor nota da estrutura tAluno do Exemplo 5.3,por exemplo.

5.4 Operacoes

Na linguagem C nao existem operacoes pre-definidas para a manipulacao de um vetor como umtodo. Por exemplo, nao e permitida a leitura de um vetor por inteiro com o comando scanf. Asoperacoes so podem ser feitas para cada elemento do vetor, individualmente.

Page 141: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.4. OPERACOES 141

Como ja mencionado na Secao 5.2, para acessar um elemento de um vetor, sao necessariosapenas seu nome e o ındice que informa sua localizacao. Na linguagem C a sintaxe de acesso aum elemento de um vetor e dada por:

<nome_vetor> [<ındice>]

onde o ındice pode ser tanto um numero inteiro maior ou igual a zero quanto uma expressaointeira composta por variaveis e numeros.

Sabendo acessar o elemento ele pode ser manipulado como uma variavel qualquer e serutilizado em operacoes das mais diversas como atribuicao, operacoes aritmeticas, etc. O Exemplo5.5 mostra algumas dessas operacoes em Linguagem C.

1 #include <stdio.h>

2

3 main(){

4 int i;

5 int vet1 [10];

6 int vet2 [10];

7 float notas [8];

8 float soma;

9 float media;

10

11 vet1 [0] = 43;

12

13 for(i=0;i<5;i++){

14 vet1 [2*i+1] = 10;

15 }

16

17 for(i=0;i<10;i++){

18 vet2[i] = 0;

19 }

20

21 for(i=0;i<8;i++){

22 scanf("%f",&notas[i]);

23 }

24

25 for(i=0;i<10;i++){

26 vet2[i] = vet1[i];

27 }

28

29 for(i=0;i<8;i++){

30 soma += notas[i];

31 }

32 media = soma /8;

33 }

Exemplo 5.5: Operacoes sobre elementos de um vetor

Page 142: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

142 CAPITULO 5. VETORES

No Exemplo 5.5, primeiramente sao declarados a variavel i, do tipo int; os vetores vet1 evet2, ambos do tipo int e de tamanho igual a 10; o vetor notas do tipo float e de tamanhoigual a 8; e as variaveis soma e media. Em seguida, o primeiro elemento do vetor vet1, ou seja,o elemento de ındice 0 (zero), recebe o valor 43 (linha 11); todos os elementos de vet1 de ındiceımpar recebem o valor 10 (linhas 13 a 15); todos os elementos de vet2 recebem o valor zero(linhas 17 a 19); cada uma das 8 posicoes do vetor notas e preenchido por um valor lido doteclado (linhas 21 a 23); os elementos do vetor vet1 sao copiados para vet2 (linhas 25 a 27); e,por ultimo, e calculada a media dos valores contidos no vetor notas e armazenada na variavelmedia (linhas 29 a 32).

E importante ressaltar a grande importancia da utilizacao de expressoes como ındice, poisela e essencial para o acesso rapido a todos os elementos do vetor.

Um outro exemplo interessante para ilustrar as operacoes sobre os vetores e a resolucao doproblema do professor citado na secao 5.1. Ja foi proposta uma solucao fazendo uma duplaleitura das notas dos alunos (Exemplo 5.1). O Exemplo 5.6 mostra uma solucao utilizandovetores.

1 #include <stdio.h>

2

3 main(){

4 int i;

5 int quant;

6 float notas [50];

7 float soma;

8 float media;

9

10 nota = 0.0;

11 soma = 0.0;

12 media = 0.0;

13

14 for(i = 0; i < 50 ; i++){

15 printf("Digite uma nota");

16 scanf("%f",&notas[i]);

17 soma=soma+nota[i];

18 }

19

20 media=soma /50;

21

22 quant = 0;

23

24 for(i = 0; i < 50 ; i++){

25 if(notas[i] > media) quant ++;

26 }

27

28 printf("\n%d alunos obtiveram nota acima da media\n",quant);

29 }

Exemplo 5.6: Resolucao do exemplo do professor com a utilizacao de vetores

Page 143: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.4. OPERACOES 143

Repare que, dessa vez, os valores referentes as notas sao lidos do teclado apenas uma vez esao, entao, armazenados no vetor notas e imediatamente somados para o calculo da media daturma, valor este armazenado na variavel media. Para a contagem de alunos com nota acima damedia, nao e necessaria uma nova leitura do teclado, apenas uma consulta ao vetor notas queja possui todos os valores armazenados.

Os vetores tambem podem ser passados como parametro de funcoes, mas nunca como retorno.O Exemplo 5.7 mostra um codigo em linguagem C que resolve o problema anterior, mas com autilizacao de funcoes que recebem um vetor como parametro.

1 #include <stdio.h>

2

3 float calculaMedia(float vetor [50]){

4 int i;

5 float soma;

6 float media;

7

8 soma = 0.0;

9

10 for(i = 0 ; i < 50 ; i++)

11 soma = soma + vetor[i];

12 }

13

14 media = soma /50;

15

16 return(media);

17 }

18

19 int alunosAcimaMedia(float vetor [50], float media){

20 int i;

21 int quant;

22

23 quant = 0;

24 for(i = 0 ; i < 50 ; i++)

25 if(vetor[i] > media) quant ++;

26 }

27

28 return(quant);

29 }

30

31 main(){

32 int i;

33 int quant;

34 float notas [50];

35 float soma;

36 float media;

37

38 nota = 0.0;

39 soma = 0.0;

40 media = 0.0;

Page 144: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

144 CAPITULO 5. VETORES

41

42 for(i = 0 ; i < 50 ; i++){

43 printf("Digite uma nota");

44 scanf("%f",&notas[i]);

45 }

46

47 media = calculaMedia{notas};

48

49 quant = alunosAcimaMedia(notas ,media);

50

51 printf("\n%d alunos obtiveram nota acima da media\n",quant);

52 }

Exemplo 5.7: Passagem de vetores para funcao

Algumas caracterısticas da linguagem C tornam a utilizacao de vetores passados comoparametro perigosa quando nao tomados os devidos cuidados. Por isso essa tecnica nao serausada agora.

5.4.1 Acesso indevido

A Figura 5.2 da secao 5.2 tambem pode ser utilizada para ilustrar um exemplo de um problemaque ocorre com certa frequencia em programas na linguagem C, ja que ela nao faz nenhumarestricao ao acesso de elementos fora dos limites do vetor. Portanto, se, por acidente, umprogramador tentasse acessar em seu programa o ındice 14 do vetor nome representado nafigura, por exemplo, nenhum erro seria acusado em tempo de compilacao, ou de execucao. Oerro so poderia ser percebido em tempo de execucao, quando o computador retornasse um valorinesperado no programa.

Mas isso e o mınimo que pode acontecer. Se o programador utilizasse um ındice diferente,ele poderia acessar e apagar alguma faixa de memoria de outro programa e acabar causandodanos irreversıveis. Logo, a solucao mais adequada e sempre avaliar os limites de um vetor antesde manipula-lo.

5.5 Strings

O vetor de elementos do tipo char do Exemplo 5.2, chamado nome, assim como todos os vetoresdo tipo char, podem ser considerados de um novo tipo, o tipo string. Strings correspondem auma sequencia de caracteres. Geralmente, sao usadas para realizar a entrada e saıda de dadosem um programa e para armazenar dados nao numericos.

E comum representar uma string como um vetor de caracteres (tipo char), dispondo dasmesmas operacoes comuns a essa estrutura de dados. A Figura 5.3 exemplifica a representacaode uma string como um vetor de caracteres.

Toda string armazenada em um vetor e terminada por um caracter especial, conhecido comocaracter nulo ‘\0’ (“barra-zero”). A principal funcao desse caracter e alertar o fim de uma string,

Page 145: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.5. STRINGS 145

Figura 5.3: Vetor de caracteres.

evitando um acesso indesejado a uma posicao do vetor que se encontra “vazia”. O programado Exemplo 5.8 demonstra uma forma nao usual de imprimir strings, mas aplica o conceito decaracter nulo.

1 void imprime_string(char palavra []){

2 int i;

3

4 for(i=0; palavra[i] != ‘\0’;i++){

5 printf ("%c",palavra[i]);

6 }

7 printf ("\n");

8 }

Exemplo 5.8: Subprograma para impressao de strings, utilizando diretamente o “barra-zero”.

No Exemplo 5.8, a condicao de parada do laco for e encontrar o caracter ‘\0’, e, durante cadaiteracao, cada caracter do vetor e impresso separadamente. A forma mais comum (e simples)de imprimir uma string e a apresentada no Exemplo 5.9.

1 void imprime_string(char palavra []){

2

3 printf("%s\n",palavra);

4 }

Exemplo 5.9: Impressao de uma string sem a utilizacao direta do caracter “barra-zero”.

O programa do Exemplo 5.9 produz o mesmo resultado do Exemplo 5.8, porem, naquele ocaracter ‘\0’ e verificado implicitamente pela funcao printf.

A biblioteca padrao de C ainda oferece algumas funcoes muito uteis para a manipulacao destrings, como a strcpy (copia), a strlen (tamanho) e a strcmp (comparacao). O Exemplo 5.10demonstra o uso dessas funcoes.

1 #include <stdio.h>

2 #include <string.h>

3

4 main(){

5 char vet1 [20] = "ola enfermeira";

6 char vet2 [20];

7 char vet3 [20];

8

9 printf("Tamanho da string: %d \n\n",strlen(vet1));

10

Page 146: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

146 CAPITULO 5. VETORES

11 strcpy(vet2 ,vet1);

12 printf("%s \n %s \n\n",vet1 ,vet2);

13

14 strcpy(vet3 ,"sim senhor");

15 printf("%s \n\n",vet3);

16

17 if(strcmp(vet1 ,vet2) == 0){

18 printf("As strings sao iguais");

19 }else{

20 printf("As strings sao diferentes");

21 }

22

23 if(strcmp(vet1 ,vet3) == 0){

24 printf("As strings sao iguais");

25 }else{

26 printf("As strings sao diferentes");

27 }

28 }

Exemplo 5.10: Programa demonstrativo de algumas funcoes da biblioteca padrao de C paramanipulacao de strings.

A primeira linha dentro da funcao main mostra uma maneira de inicializar um vetor, nocaso do exemplo o vetor chamado vet1, e ja preenche-lo com valores, no mesmo caso com o textoola enfermeira (linha 5). Em seguida sao declarados mais dois vetores de caracteres: vet1 evet2, ambos de tamanho igual a 20. Depois disso as funcoes da biblioteca padrao string.h saoutilizadas para, respectivamente: imprimir o tamanho da string em vet1, com a funcao strlen(linha 9); copiar o conteudo de vet1 em vet2, com a funcao strcpy e em seguida imprimı-los natela com a funcao printf da biblioteca stdio.h (linhas 11 e 12); copiar a string sim senhor paradentro do vetor vet3 e em seguida imprimir seu conteudo na tela (linhas 14 e 15); e, finalmente,comparar o conteudo das strings contidas em vet1 e vet2 (linhas 17 a 21), e vet1 e vet3 (linhas23 a 27) com a funcao strcmp.

Para o uso da funcao strcpy, a ordem dos parametros e de suma importancia; o primeiroparametro e o vetor de destino da string que se deseja copiar, enquanto o segundo e o vetor deorigem da string. Em relacao a funcao strcmp, ela retorna o valor zero se as strings armazenadasem ambos os vetores forem iguais (letras em caixa alta sao consideradas diferentes das em caixabaixa).

5.6 TAD Implementacional

Como dito na secao 5.4, na linguagem C nao existem operacoes basicas para a manipulacaode vetores como um todo. Porem a manipulacao individual de todos os seus elementos podeser muito trabalhosa e muitas vezes operacoes comuns devem ser repetidas ao longo do codigodo programa comprometendo sua legibilidade, confiabilidade e modificabilidade. Por isso, asoperacoes basicas sobre um vetor devem ser modularizadas pela utilizacao de subprogramas e,

Page 147: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.6. TAD IMPLEMENTACIONAL 147

para isso, a utilizacao de um TAD se mostra oportuna.Nessa secao sera apresentado na linguagem C um TAD de natureza implementacional, cha-

mado tVetorInt, que podera ser usado em aplicacoes que necessitam manipular vetores de intei-ros. Para isso sera definida uma estrutura contendo um vetor e o numero de elementos correntesdo vetor.

5.6.1 Atributos

O Exemplo 5.11 mostra os atributos da estrutura utilizada no TAD Implementacional tVetorInt.

1 #define TAM 100

2

3 typedef struct vetor{

4 int vet[TAM];

5 int n;

6 }tVetorInt;

Exemplo 5.11: Definicao da Estrutura tVetorInt

O Exemplo 5.11 mostra a definicao da estrutura tVetorInt. Ela possui um vetor de inteiroschamado vet, de tamanho definido por TAM e um atributo n do tipo int que representa onumero corrente de elementos em vet, ou seja, o numero de elementos armazenados no vetornum determinado momento da execucao do programa. Esse valor deve ser zero quando o vetorestiver vazio e deve ser incrementado ou decrementado sempre que se adicionar ou excluir umelemento do vetor, respectiviamente.

A primeira linha do codigo do Exemplo 5.11 faz com que toda a palavra TAM existenteno codigo do programa seja substituıda pelo valor 100 na hora da compilacao. Esse artifıcio ebastante utilizado quando se trabalha com vetores com tamanho maximo, ja que permite queuma alteracao no valor de TAM no inıcio do codigo modifique os tamanhos de todos os vetoresdo codigo que possuem TAM como definicao de tamanho.

A Figura 5.4 mostra uma maneira simples de representar graficamente a estrutura propostano Exemplo 5.11.

A figura mostra duas estruturas do tipo. Como pode ser observado, apesar de vet possuirtamanho igual a 100, ele possui apenas 9 elementos na primeira estrutura e 5 na segunda, valoresrepresentados pelo atributo n.

5.6.2 Operacoes

Agora serao ilustradas as funcoes que devem ser utilizadas como operacoes para manipular aestrutura tVetorInt. Tal como visto no capıtulo anterior, essas operacoes se dividem em quatrocategorias diferentes: contrutoras, analizadoras, produtoras e modificadoras.

Page 148: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

148 CAPITULO 5. VETORES

Figura 5.4: Representacao grafica da estrutura tVetorInt.

Construtoras

Para o caso do TAD tVetorInt, podem ser criadas duas funcoes dessa natureza, uma que inicializaa estrutura com um vetor vazio e outra que a inicializa ja lendo para dentro do vetor umdeterminado numero de elementos ignorando o que havia antes. Para efeito de comparacao,essas duas funcoes sao semelhantes a operacao ” = ” utilizada sobre as variaveis dos tiposprimitivos (int, float, char, etc). Uma dessas duas funcoes deve ser utilizada antes de qualqueroutra operacao sobre a estrutura.

A funcao do Exemplo 5.12 e uma maneira de se implementar uma funcao que inicializa aestrutura tVetorInt sem nunhum elemento dentro do vetor.

1 tVetorInt iniciaVazioVetorInt(tVetorInt v){

2 v.n = 0;

3 return(v);

4 }

Exemplo 5.12: Inicializacao de um tVetorInt vazio

Repare que a funcao tem como parametro de entrada uma estrutura do tipo tVetorInt, ouseja, antes de ser utilizada, uma variavel do tipo deve ser declarada no corpo principal doprograma, a funcao main da linguagem C.

O Exemplo 5.13 mostra o codigo da outra funcao construtora citada.

1 tVetorInt leituraVetorInt(tVetorInt v,int num){

2 int i;

3 for(i = 0 ; i < num ; i++) scanf("%d",&v.vet[i]);

4 v.n = num;

5 return(v);

6 }

Exemplo 5.13: Inicializacao de um tVetorInt com leitura de elementos

Page 149: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.6. TAD IMPLEMENTACIONAL 149

A funcao do Exemplo 5.13 recebe como parametro de entrada a estrutura do tipo tVetorIntque se quer inicializar e o numero de elementos que se quer ler para dentro do vetor. Ela, entao,le do teclado os elementos desejados e armazena-os dentro do vetor da estrutura.

Analisadoras

As operacoes analizadoras sao utilizadas para que se possa obter informacoes relacionadas comos valores do TAD. Serao mostradas aqui tres funcoes desse tipo.

A primeira funcao, que pode ser visualizada no Exemplo 5.14 e para que possam ser visua-lizados em tela os valores de todos os elementos armazenados no vetor da estrutura.

1 void escritaVetorInt(tVetorInt v){

2 int i;

3

4 printf("\n\n");

5 printf("Os elementos que estao atualmente no vetor sao:");

6 printf("\n");

7 for(i = 0 ; i < v.n ; i++) printf("%d ",v.vet[i]);

8 printf("\n\n");

9 }

Exemplo 5.14: Escrita em tela

A funcao simplesmente acessa todos os elementos do vetor e imprime seus valores na tela(linha 7).

As outras duas funcoes citadas como analizadoras sao ambas utilizadas para determinar aexistencia de um determinado elemento dentro do vetor. Essas funcoes, alem de funcionaremcomo uma simples consulta dentro de um vetor, podem ser utilizadas dentro de outras funcoescomo, por exemplo, para achar um determinado elemento que se queira apagar.

A funcao do Exemplo 5.15 varre o vetor sequencialmente a procura de um elemento e retornaseu ındice se encontra-lo. Caso contrario, ela retorna -1.

1 int pesquisaSequencialInt(tVetorInt v,int elem){

2 int i;

3

4 for(i = 0 ; i < v.n ; i++){

5 if(v.vet[i]== elem) return(i);

6 }

7 return (-1);

8 }

Exemplo 5.15: Pesquisa Sequencial

A funcao do Exemplo 5.15 recebe como parametro de entrada a estrutura do tipo tVetorIntque possui o vetor que se deseja pesquisar e o elemento a ser encontrado. Ela, entao, compara,a partir do primeiro, o valor de todos os elementos com o valor procurado. Se achar um igual,

Page 150: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

150 CAPITULO 5. VETORES

retorna o valor de seu ıncide. Se chegar ao final do vetor e nao tiver encontrado nenhum valorigual ao que se procura, a funcao retorna o valor -1.

Repare que se existir no vetor dois elementos iguais, a funcao obtem apenas o ındice doprimeiro. Isso acontece, porque ela retorna quando o primeiro valor e encontrado. Outra carac-terıstica dessa funcao que deve ser evidenciada e sua ineficiencia quando o valor procurado estanas ultimas posicoes ou quando ele nao existe no vetor.

Para resolver o problema da ineficiencia citada, outras funcoes foram desenvolvidas paraotimizar o processo de localizacao de elementos. O Exemplo 5.16 mostra uma delas: a PesquisaBinaria. Essa funcao deve ser utilizada apenas em vetores ordenados de forma crescente. Elapercorre o vetor partindo-o ao meio a procura do elemento e retorna seu ındice se encontra-lo e-1 caso contrario.

1 int pesquisaBinariaInt(tVetorInt v,int elem){

2 int inicio;

3 int fim;

4 int meio;

5

6 inicio = 0;

7 fim = v.n - 1;

8

9 while(inicio <= fim){

10 meio = (inicio + fim)/2;

11 if(elem < v.vet[meio]) fim = meio - 1;

12 else if(elem > v.vet[meio]) inicio = meio + 1;

13 else return(meio);

14 }

15 return (-1);

16 }

Exemplo 5.16: Pesquisa Binaria

A funcao do Exemplo 5.16 recebe como parametro de entrada a estrutura do tipo tVetorIntque possui o vetor que se deseja pesquisar e o elemento a ser encontrado. Sao declaradas,entao, tres variaveis: inicio, fim e meio. A variavel inicio recebe, o valor do ındice do menorelemento do vetor, ou seja, zero, e fim recebe o valor do ındice do maior elemento, ou seja,v.n− 1. Enquanto o valor de inicio for menor ou igual ao valor de fim, meio recebe o ındice doelemento central da regiao por eles delimitada. E exatamente esse elemento central que sempresera comparado ao elemento que se esta procurando. Se aquele for maior que este, fim recebe ovalor do ındice anterior a meio. Caso contrario, inicio recebe o valor do ındice posterior a meio.Se nenhuma das duas alternativa acontecerem, quer dizer que o elemento foi encontrado e seuındice e igual a meio. Se em algum momento inicio passar a ser maior que fim, o elemento naoexiste na lista e a funcao retorna -1.

As Figuras 5.5 e 5.6 mostram o funcionamento do algoritmo do Exemplo 5.16 para duaspesquisas diferentes.

A Figura 5.5 ilustra as etapas da busca do elemento 4 dentro do vetor vet da estrutura

Page 151: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.6. TAD IMPLEMENTACIONAL 151

Figura 5.5: Etapas da pesquisa binaria com o elemento procurado no inıcio do vetor.

do tipo tVetorInt mostrada na figura. Primeiramente inicio e fim adquirem os valores 0 e 10,respectivamente. Como inicio e menor que fim, meio recebe o ındice 5, e o elemento apontadopor ele, o valor 10, e comparado ao valor procurado. Como 10 e maior que 4, fim recebe o ındice4. Como inicio continua menor que fim, meio recebe o ındice 2. Dessa vez, o elemento apontadopor meio e igual ao elemento procurado. A funcao retorna, entao, o valor de seu ındice: 2.

Ja a Figura 5.6 mostra a busca do elemento 23 dentro do mesmo vetor apresentado na Figura5.5. Primeiramente inicio e fim adquirem os valores 0 e 10, respectivamente. Como inicio emenor que fim, meio recebe o ındice 5, e o elemento apontado por ele, o valor 10, e comparadoao valor procurado. Como 10 e menor que 23, inicio recebe o ındice 6. Como inicio continuamenor que fim, meio recebe o ındice 8, e o elemento apontado por ele, o valor 19, e comparadoao valor procurado. Novamente 19 e menor que 23 e inicio recebe o ındice 9. Como iniciocontinua menor que fim, meio recebe o ındice 9 tambem. Dessa vez, o elemento apontado pormeio e igual ao elemento procurado. A funcao retorna, entao, o valor de seu ındice: 9.

E importante observar que, para esta ultima busca, o algoritmo de pesquisa binaria fazapenas tres comparacoes enquanto que o algoritmo de pesquisa sequencial teria de fazer dez.

Produtoras

As funcoes dessa natureza geram algum tipo de produto como resultado de operacoes feitassobre dois ou mais vetores. Dentre elas podem ser citadas a Adicao e o Produto Escalar.

A Adicao, Exemplo 5.17, soma cada elemento de mesmo ındice de um vetor com outrocom o mesmo numero de elementos correntes e armazena o resultado em um terceiro vetor. Seos vetores a serem somados nao possuirem o mesmo numero de elementos correntes, a funcaoretorna uma mensagem de erro.

Page 152: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

152 CAPITULO 5. VETORES

Figura 5.6: Etapas da pesquisa binaria com o elemento procurado no final do vetor.

1 tVetorInt somaVetorInt(tVetorInt v1 ,tVetorInt v2 ,tVetorInt soma){

2 int i;

3

4 if(v1.n != v2.n){

5 printf("\n\n");

6 printf("Vetores com tamanhos diferentes");

7 printf("\n\n");

8 soma.n = 0;

9 }else{

10 soma.n = v1.n;

11 for(i = 0 ; i < soma.n ; i++){

12 soma.vet[i] = v1.vet[i] + v2.vet[i];

13 }

14 }

15 return(soma);

16 }

Exemplo 5.17: Adicao de dois vetores

A funcao somaVetorInt recebe como parametros de entrada tres estruturas do tipo tVetorInt.Duas delas, v1 e v2, devem possuir os vetores que se deseja somar, e a outra, soma, o vetor ondea soma sera armazenada. Primeiramente verifica-se se os vetores de v1 e v2 possuem o mesmonumero de elementos correntes. Se nao possuırem, uma mensagem de erro e exibida na tela.

Page 153: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.6. TAD IMPLEMENTACIONAL 153

Caso contrario, cada elemento de mesmo ındice de v1 e v2 sao somados e armazenados com omesmo ındice no vetor de soma e este e retornado pela funcao.

Ja a funcao Produto Escalar, cujo codigo pode ser encontrado no Exemplo 5.18 calcula, comoo proprio nome ja diz, o produto escalar entre dois vetores. Para isso, os vetores devem possuir omesmo numero de elementos correntes. Caso contrario a funcao tambem retorna uma mensagemde erro.

1 int escalaVetorInt(tVetorInt v1 ,tVetorInt v2){

2 int i;

3 int prod;

4

5 prod = 0;

6 if(v1.n != v2.n){

7 printf("\n\n");

8 printf("Vetores com tamanhos diferentes");

9 printf("\n\n");

10 }else{

11 for(i = 0 ; i < v1.n ; i++){

12 prod = prod + v1.vet[i] * v2.vet[i];

13 }

14 }

15 return(prod);

16 }

Exemplo 5.18: Produto Escalar

A funcao Produto Escalar recebe como parametros de entrada duas estruturas tVetorInt :v1 e v2. Primeiro o numero de elementos correntes de seus vetores sao verificados. Caso sejadiferente, uma mensagem de erro e exibida na tela. Se forem iguais, o produto escalar de seusvetores, que vem a ser a soma dos produtos dos elementos de mesmo ındice, sao calculados.

Modificadoras

As operacoes a seguir sao responsaveis por realizar alteracoes no vetor do TAD de forma agarantir a coerencia da estrutura. Para excluir um elemento no meio de um vetor, por exemplo,a funcao de exclusao deve, alem de apaga-lo, cuidar para que o numero de elementos correntesdo vetor seja atualizado e que todos os elementos com ındice maior que o dele sejam transferidosuma posicao para a esquerda. Alem da operacao de exclusao, serao apresentadas a seguir funcoesde insercao e ordenacao.

A funcao do Exemplo 5.19 mostra um algoritmo para insercao de um elemento numa posicaopre-determinada. Ela insere o elemento na posicao desejada considerando a posicao zero comoa primeira do vetor.

1 tVetorInt insereVetorInt(tVetorInt v,int elem ,int pos){

2 int i;

3

Page 154: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

154 CAPITULO 5. VETORES

4 if((pos < 0) || (pos > v.n)){

5 printf("\n\n");

6 printf("Entrada de Dados Incorreta");

7 printf("\n\n");

8 }else{

9 v.n++;

10 for(i = v.n - 2 ; i > pos - 1 ; i--){

11 v.vet[i+1] = v.vet[i];

12 }

13 v.vet[i] = elem;

14 }

15 return(v);

16 }

Exemplo 5.19: Insercao em Posicao Pre-determinada

A funcao insereVetorInt recebe como parametros de entrada uma estrutura tVetorInt, oelemento a ser inserido e a posicao em que ele deve ser inserido. Se a posicao for invalida, ouseja, menor que 0 ou maior que v.n, uma mensagem de erro e impressa na tela e o elemento naoe inserido. Caso contrario os elementos de dentro do vetor vao sendo movidos para a direita demodo a deixar a posicao desejada para a insercao livre. Finalmente, o vetor recebe o valor doelemento na posicao desejada e a estrutura e retornada.

A funcao do Exemplo 5.20 mostra um algoritmo de exclusao de um elemento. Ela percorreo vetor da estrutura sequencialmente procurando o elemento a ser excluıdo. Se encontra-lo,retira-o e continua procurando outros iguais para excluir ate nao achar mais.

1 tVetorInt excluiVetorInt(tVetorInt v,int elem){

2 int i;

3 int pos;

4 int quant;

5

6 pos = 0;

7 quant = 0;

8 while(pos < v.n){

9 if(v.vet[pos] == elem){

10 for(i = pos ; i < v.n - 1 ; i++){

11 v.vet[i] = v.vet[i+1];

12 }

13 v.n--;

14 }

15 pos ++;

16 }

17 return(v);

18 }

Exemplo 5.20: Exclusao de Elemento

A funcao excluiVetorInt recebe como parametros de entrada uma estrutura tVetorInt e oelemento que se quer excluir. Ela, entao, varre o vetor da estrutura da primeira a ultima posicao

Page 155: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.6. TAD IMPLEMENTACIONAL 155

comparando os elementos nele contidos com o valor do elemento a ser excluıdo. Se for igual, elemove todos os elementos seguintes para a esquerda apagando, assim, o elemento alvo. Depoisdisso ele continua a procura por outros elementos a que tambem devem ser excluıdos. Quandochega ao final do vetor, ela retorna a estrutura modificada.

As duas proximas funcoes a serem apresentadas sao de ordenacao. Ambas colocam em ordemcrescente os elementos de um vetor, mas utilizando metodos diferentes. A funcao do Exemplo5.21 mostra a ordenacao pelo metodo do menor.

1 tVetorInt ordenaMenorInt(tVetorInt v){

2 int pos;

3 int i;

4 int indice_menor;

5 int menor;

6

7 for(pos = 0 ; pos < v.n - 1 ; pos ++){

8 menor = v.vet[pos];

9 for(i = pos + 1 ; i < v.n ; i++){

10 if(v.vet[i] < menor){

11 menor = v.vet[i];

12 indice_menor = i;

13 }

14 }

15 v.vet[indice_menor] = v.vet[pos];

16 v.vet[pos] = menor;

17 }

18 return(v);

19 }

Exemplo 5.21: Ordenacao pelo metodo do menor

A funcao ordenaMenosInt recebe a estrutura tVetorInt cujo vetor se deseja ordenar. Pri-meiramente ela varre o vetor procurando o elemento de menor valor e o troca de posicao como primeiro elemente do vetor. Feito isso, ela procura o menor elemento no restante do vetor eo troca de posicao com o segundo elemento e assim sucessivamente com o terceiro, quarto, . . .,v.n− 1 elementos. A Figura 5.7 ilustra o funcionamento desse algoritmo.

Ja a funcao ordenaBolhaInt, Exemplo 5.22, utiliza o metodo da bolha.

1 tVetorInt ordenaBolhaInt(tVetorInt v){

2 int a;

3 int b;

4 int temp;

5

6 for(a = 1 ; a < v.n ; a++){

7 for(b = v.n - 1 ; b >= a ; --b){

8 if(v.vet[b-1] > v.vet[b]){

9 temp = v.vet[b-1];

10 v.vet[b-1] = v.vet[b];

Page 156: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

156 CAPITULO 5. VETORES

11 v.vet[b] = temp;

12 }

13 }

14 }

15 return(v);

16 }

Exemplo 5.22: Ordenacao pelo metodo da bolha

A funcao ordenaBolhaInt tambem recebe como parametro de entrada apenas a estruturatVetorInt. Entao ela percorre o vetor inteiro, do maior para o menor ındice, fazendo comparacoesentre seus elementos e trocando-os quando o elemento de maior ındice possui seu valor menorque o elemento de menor ındice. Feito isso uma vez, o elemento de menor valor ja fica naprimeira posicao do vetor. Entao o algoritmo ignora esse elemento e repete o procedimento parao resto do vetor. Esse procedimento e repetido v.n − 1 vezes. Finalmente, a funcao retorna aestrutura com o vetor ordenado. A Figura 5.8 ilustra o funcionamento desse algoritmo.

Exemplo de Utilizacao do TAD tVetorInt

Sera apresentado agora um exemplo de utilizacao do TAD tVetorInt. Vale lembrar que o Exemplo5.23 apresenta apenas o programa principal contendo a chamada das funcoes definidas ate aqui.Para seu funcionamento correto, todas as funcoes dever estar contidas no arquivo do programa.

1 int main(){

2 tVetorInt vet1;

3 tVetorInt vet2;

4 tVetorInt vet3;

5 int elem;

6 int pos;

7 int prodEscalar;

8 int enter;

9

10 vet1 = leituraVetorInt(vet1 ,10);

11 vet2 = leituraVetorInt(vet2 ,10);

12 vet3 = iniciaVazioVetorInt(vet3);

13

14 printf("\n\n");

15 printf("Vet1:");

16 escritaVetorInt(vet1);

17 printf("Vet2:");

18 escritaVetorInt(vet2);

19

20 printf("\n\nQual elemento deseja localizar utilizando a pesquisa sequencial ?\n\n

");

21 scanf("%d" ,&elem);

22

23 pos = pesquisaSequencialInt(vet1 ,elem);

24 if(pos >= 0) printf("\n\nElemento encontrado na posicao %d\n\n",pos);

Page 157: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.6. TAD IMPLEMENTACIONAL 157

25 else printf("\n\nElemento nao encontrado\n\n");

26

27 printf("\n\nQual elemento deseja localizar utilizando a pesquisa binaria ?\n\n");

28 scanf("%d",&elem);

29

30 pos = pesquisaBinariaInt(vet1 ,3);

31 if(pos >= 0) printf("\n\nElemento encontrado na posicao %d\n\n",pos);

32 else printf("\n\nElemento nao encontrado\n\n");

33

34 vet3 = somaVetorInt(vet1 ,vet2 ,vet3);

35

36 printf("\n\n");

37 printf("Vet1:");

38 escritaVetorInt(vet1);

39 printf("Vet2:");

40 escritaVetorInt(vet2);

41 printf("Vet3:");

42 escritaVetorInt(vet3);

43

44 prodEscalar = escalaVetorInt(vet1 ,vet2);

45

46 printf("\n\n");

47 printf("Vet1:");

48 escritaVetorInt(vet1);

49 printf("Vet2:");

50 escritaVetorInt(vet2);

51

52 printf("\n\nProduto escalar = %d\n\n",prodEscalar);

53

54 vet3 = leituraVetorInt(vet3 ,0);

55

56 vet3 = insereVetorInt(vet3 ,5,0);

57 printf("Vet3:");

58 escritaVetorInt(vet3);

59

60 vet3 = insereVetorInt(vet3 ,3,0);

61 printf("Vet3:");

62 escritaVetorInt(vet3);

63

64 vet3 = insereVetorInt(vet3 ,7,1);

65 printf("Vet3:");

66 escritaVetorInt(vet3);

67

68 vet3 = insereVetorInt(vet3 ,10 ,3);

69 printf("Vet3:");

70 escritaVetorInt(vet3);

71

72 vet3 = excluiVetorInt(vet3 ,3);

73 printf("Vet3:");

74 escritaVetorInt(vet3);

75 vet3 = excluiVetorInt(vet3 ,7);

Page 158: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

158 CAPITULO 5. VETORES

76 printf("Vet3:");

77 escritaVetorInt(vet3);

78 vet3 = excluiVetorInt(vet3 ,10);

79 printf("Vet3:");

80 escritaVetorInt(vet3);

81 vet3 = excluiVetorInt(vet3 ,5);

82 printf("Vet3:");

83 escritaVetorInt(vet3);

84

85 vet1 = ordenaMenorInt(vet1);

86 printf("Vet1:");

87 escritaVetorInt(vet1);

88

89 vet2 = ordenaBolhaInt(vet2);

90 printf("Vet2:");

91 escritaVetorInt(vet2);

92

93 }

Exemplo 5.23: Exemplo de Utilizacao do TAD tVetorInt

5.7 Exercıcios Resolvidos

5.8 Resumo

• Um vetor e uma estrutura de dados composta homogenea, isto e, ele possui, em geral,mais de um elemento de um mesmo tipo.

• Sao caracterısticas importantes dos vetores a seqencializacao, a indexacao e a suadimensao.

• Deve-se tomar cuidado para nao se acessar um vetor indevidamente, como, por exemploutilizando um ındice maior que seu tamanho.

• A dimensao de um vetor pode ser definida, em C, tanto em tempo de compilacao, quantoem tempo de execucao.

• Na linguagem C nao existem operacoes basicas para a manipulacao de um vetor como umtodo. Seus elementos devem ser manipulado separadamente.

• Quando acessado individualmente, cada elemento de um vetor pode ser encarado comouma variavel basica.

• A utilizacao de expressoes como ındice no acesso a elementos de um vetor e uma ferramentapoderosa e deve ser usada.

Page 159: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.9. LISTA DE EXERCICIOS 159

• A utilizacao de funcoes para a manipulacao de vetores como um todo e importante paraa legibilidade e reusabilidade do programa e deve ser usada.

• A utilizacao de TAD’s Implementacionais e um artifıcio para facilitar a manipulacao devetores e aumentar a legibilidade e reusabilidade do programa.

• O TAD Implementacional tVetorInt, implementado aqui na linguagem C, pode ser utili-zado, sempre que necessario, para a manipulacao de vetores de numeros inteiros.

5.9 Lista de Exercıcios

1. Faca um programa em linguagem C que leia 100 numeros reais e os imprima na ordeminversa em que foram lidos.

2. Crie uma funcao em linguagem C que some os elementos de um vetor com 100 elementosinteiros.

3. Faca um programa em linguagem C que leia as notas e as matrıculas dos alunos de umaturma de no maximo 50 alunos numa prova e obtenha:

(a) a melhor nota e o aluno que a obteve;(b) a pior nota e o aluno que a obteve;(c) a media da turma;(d) os alunos que obtiveram nota superior a media da turma.

4. Faca um programa em linguagem C que determine os 100 primeiros numeros primos.Considere que:

(a) um numero e primo quando so e divisıvel por si mesmo;(b) e suficiente testar a divisibilidade de um numero X por numeros primos que o ante-

cedem ate um limite igual a raiz de X.

5. Faca um programa em linguagem C que leia duas listas de caracteres com ate 100 elementose coloque cada um num vetor respectivo. Apos ter sido realizado a leitura das duas listas,deve ser lida a ordem a partir da qual deve ser inserida a segunda lista na primeira listade caracteres. Considere o seguinte exemplo:

Primeira lista:abcdjklmSegunda lista:efghiOrdem:5Resultado:abcdefghijklm

Page 160: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

160 CAPITULO 5. VETORES

6. Faca um programa em linguagem C que leia dois vetores ordenados em M e N elementosrespectivamente e os intercale gerando um novo vetor U, tambem ordenado. Considere oexemplo:

M: 5N: 4Primeiro vetor:1 7 13 14 30Segundo vetor:2 3 7 16Resultado:1 2 3 7 7 13 14 16 30

Obs.: O terceiro vetor nao pode ser gerado copiando-se primeiramente os dois vetores efazendo a ordenacao posteriormente.

7. Faca um programa em linguagem C que leia N (N < 1000) numeros de matrıculas de alunosque fazem PD1 e os coloque em ordem crescente num vetor a medida que vao sendo lidasas matrıculas. Posteriormente escreva uma funcao que identifique se um certo conjuntode M alunos fazem PD1. Deve-se utilizar o algoritmo de pesquisa binaria para fazer estaverificacao.

8. Faca um programa em linguagem C que:

(a) leia N numeros reais colocando-os num vetor de 100 elementos (considerar N < 1000);

(b) ordene crescentemente os elementos de ındices ımpares utilizando o metodo da bolhapara tal(considerar apenas os N elementos);

(c) escreva os N numeros apos o ajuste do ıtem (b);

9. Crie um procedimento em linguagem C que cumpra a seguinte especificacao:

(a) Dados de entrada:

i. um vetor de caracteres com um maximo de 100 elementos;ii. o tamanho corrente do vetor (suponha que o vetor inicie na primeira posicao);iii. um caracter a ser inserido;iv. a posicao do vetor onde o caracter deve ser inserido.

(b) Dados de saıda:

i. o vetor com o caracter inserido na posicao;ii. o vetor deve ser mantido inalterado se a posicao onde deveria ser inserido o carcter

superior ao tamanho corrente do vetor ou se o vetor ja estiver completo.

Page 161: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.10. TRABALHOS SUGERIDOS 161

10. Um armazem trabalha com 100 mercadorias diferentes identificadas pelos numeros de 1 a100. O dono anota as quantidades de cada mercadoria vendida no mes. Ele tem uma tabelaque indica para cada mercadoria o preco de venda. Escreva um algoritmo em linguagemC que calcule o faturamento mensal do armazem, onde:

Faturamento = Σ(quantidadei ∗ precoi), i = 1, 2, . . . , 100.

11. Escreva um algoritmo em linguagem C que:

(a) leia um conjunto A de 100 elementos reais;

(b) construa e imprima um outro conjunto B formado da seguinte maneira:

i. os elementos de ordem par sao os correspondentes de A divididos por 2;ii. os elementos de ordem ımpar sao os correspondentes de A multiplicados por 3.

12. Dado um vetor contendo uma frase com 80 caracteres (incluindo brancos), escreva umalgoritmo em linguagem C para:

(a) contar quantos brancos existem na frase;

(b) contar quantas vezes aparece a letra ’A’;

(c) contar quantas vezes aparece um mesmo par de letras na frase e quais sao eles.

13. Faca um algoritmo em linguagem C para ler um vetor de comprimento N (par menor ouigual a 50) e imprimir seu conteudo depois de feita a troca dos elementos das posicoespares com os elementos das posicoes ımpares.

14. Faca um programa em linguagem C que, dado um nome terminado por ponto, devolva onumero de vogais nele presentes.

15. Faca um programa em linguagem C que, dada uma frase terminada por ponto, retire todosos espacos em branco da mesma e retorne a frase modificada.

16. Faca um programa em linguagem C que, dada duas listas de nomes, compare-as e retorneo numero de vezes que cada palavra da segunda lista aparece na primeira lista. Assumaque cada nome seja composto de no maximo 15 caracteres.

5.10 Trabalhos Sugeridos

Page 162: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

162 CAPITULO 5. VETORES

Figura 5.7: Metodo do Menor

Page 163: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

5.10. TRABALHOS SUGERIDOS 163

Figura 5.8: Metodo da Bolha

Page 164: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

Capıtulo 6

MatrizesAutores:

Clebson OliveiraJulio Dalfior

Objetivos:

• Mostrar a importancia de se utilizar a estrutura implementacional de dados matrizes pararesolver problemas

• Introduzir o conceito do tipo abstrato de dado matriz (tMatriz)

• Mostrar como modelar um problema atraves do TAD tMatriz

6.1 Introducao

Uma matriz e um tipo de dado composto homogeneo na qual seus elementos sao organizadosem uma estrutura multidimensional. Por exemplo, uma matriz bidimensional e formada pelacombinacao de linhas horizontais e verticais. A figura 6.1 mostra uma matriz 5 por 3. Note quea matriz possui 5 linhas e 3 colunas. Embora matrizes possam ter mais que 2 dimensoes, nestelivro serao abordadas apenas matrizes bidimensionais. Uma matriz com m linhas e n colunas echamada matriz m por n.

Para mostrar que matrizes bidimensionais sao muito comuns no nosso dia-a-dia podem-se citar varios exemplos: um cartao de bingo, uma agenda de compromissos (6.2), etc. Einteressante que haja uma maneira de representar esse tipo de estrutura, para que se possautiliza-la na solucao de problemas.

Na figura 6.2 tem-se que as linhas representam os dias do mes, as colunas representam osmeses do ano e os elementos da matriz representam um determinado dia do mes.

Considerando que essa matriz sera utilizada para representar se ha ou nao compromissonaquele dia do mes, temos uma matriz bidimensional porque a cada celula dessa matriz estao

164

Page 165: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

6.2. DEFINICAO E ACESSO 165

Figura 6.1: Uma matriz 5 por 3

Figura 6.2: Agenda de compromissos e sua representacao matricial

associadas duas informacoes (mes e dia). Por outro lado, se for necessario listar varios compro-missos para cada dia do mes ter-se-a uma matriz tridimensional, porque a cada celula da matrizestarao associadas tres informacoes (mes, dia e hora).

E fato que a visualizacao das matrizes utilizadas facilita o entendimento deste conceito. Porexemplo, uma matriz bidimensional pode ser visualizada como um quadro e uma tridimensionalpode ser visualizada como um cubo formado por varios cubos menores. Apesar de ser difıcilvisualizar matrizes com mais de tres dimensoes, vale ressaltar que elas existem e que e possıveldeclara-las em C. Como exemplo da utilizacao de matrizes com mais de tres dimensoes pode-seutilizar o exemplo anterior supondo que se queira representar tambem o ano. Entao, teremosuma matriz de quatro dimensoes (ano, mes, dia e hora).

6.2 Definicao e Acesso

Para que um problema seja modelado atraves de uma matriz e necessario que se defina umavariavel para representa-la, para que assim se possa utilizar seus elementos para guardar in-formacoes e posteriormente aplicar operacoes sobre essa estrutura.

Page 166: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

166 CAPITULO 6. MATRIZES

6.2.1 Definicao

Para definir uma variavel do tipo matriz e necessario que se saiba o tamanho de cada dimensao.No entanto, existem duas maneiras de estabelecer o tamanho dessas dimensoes: estaticamentee dinamicamente.

Estaticamente

No momento em que se define a matriz e necessario estabelecer um tamanho para cada dimensao,sendo que esse tamanho nao podera ser alterado durante a execucao do programa. O codigo doexemplo 6.1 mostra como isso pode ser feito em C:

1 int matriz [5][10];

Exemplo 6.1: Definicao estatica

O numero entre o primeiro par de colchetes ([5]) define o tamanho da primeira dimensao(numero de linhas). O numero entre o segundo par de colchetes ([10]) define o tamanho dasegunda dimensao (numero de colunas), e assim por diante. No caso acima a variavel matrizpossui 5 linhas e 10 colunas, como se pode ver na figura 6.3. Os tracos na matriz representam ainformacao armazenada na celula, a qual e o compartimento onde estao localizados os elementosda matriz.

Figura 6.3: Matriz 5 por 10

Inicializacao

Vale ressaltar que na declaracao de matrizes mostrada anteriormente, os valores das celulas damatriz nao foram inicializados e isso pode gerar resultados inesperados. Uma vez que nao sesabe quais valores estavam armazenados anteriormente nas areas de memoria utilizadas. Paraevitar esse tipo de problema e uma boa pratica de programacao inicializar os elementos dasmatrizes antes de tentar acessar seus valores, mesmo que posteriormente esses elementos sejamconfigurados com outros valores. A forma mais simples de se fazer isso, em C, pode ser vista noexemplo 6.2.

Page 167: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

6.2. DEFINICAO E ACESSO 167

1 int main(){

2

3 int i,j;

4 int matriz [2][2] = {0};

5

6 return 0;

7 }

Exemplo 6.2: Inicializacao de uma matriz

Na linha 4 do exemplo 6.2 temos a inicializacao de todos os elementos da matriz com o valorzero.

6.2.2 Acesso

Agora que a matriz ja foi inicializada, para se utilizar os dados contidos nela sera necessariofazer uma operacao de acesso, como no exemplo 6.3:

1 #define NMESES 12

2 #define NDIAS 31

3 #define NHORAS 24

4

5 main(){

6

7 int reservaSala[NMESES ][ NDIAS][ NHORAS] = {0};

8 int resposta =0;

9 .

10 .

11 .

12 resposta=reservaSala [5][1][10];

13

14 if(resposta ==0){

15

16 reservaSala [5][1][10]=1;

17 }

18

19 }

Exemplo 6.3: Acesso e atualizacao de um elemento

A variavel resposta recebe 0 ou 1 indicando, respectivamente, se as 11 horas do dia 2 dejunho a sala esta livre ou reservada. Note que, assim como em vetores, o primeira posicaode cada dimensao da matriz tem ındice 0. Apos acessar um elemento da matriz chamadareservaSala (linha 12) e verificar que em uma determinada data e horario a sala esta livre (linha14), atualiza-se o estado da sala de livre para ocupada (linha 16).

Page 168: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

168 CAPITULO 6. MATRIZES

6.3 O TAD implementacional tMatriz

O TAD implementacional tMatriz e usado como ferramenta para resolver problemas que possuamcaracterıstica de armazenamento relacionados a matrizes. Uma de suas principais vantagens epoder simular uma matriz cujo tamanho pode ser alterado dinamicamente, o que proporciona areutilizacao dessa estrutura.

6.3.1 Atributos

O primeiro passo para definir o TAD tMatriz envolve escolher os seus atributos. Como a ideiae modelar o problema por uma matriz, e necessario que um dos atributos seja a propria matrizque armazenara os elementos. Alem disso e necessario guardar a quantidade de elementos decada dimensao.

Apesar de ser possıvel definir uma matriz com um numero qualquer de dimensoes e quearmazene um tipo qualquer de dado (int, float, char, etc), neste capıtulo serao utilizadas apenasmatrizes bidimensionais de inteiros, por serem comumente utilizadas.

Portanto, os atributos de uma matriz bidimensional de inteiros sao:

• Numero de linhas (nLinhas): Armazena a quantidade de elementos de cada coluna.

• Numero de colunas (nColunas): Armazena a quantidade de elementos de cada linha.

• Matriz (valores): Armazena os dados da matriz propriamente dita.

No exemplo 6.4 pode ser vista uma maneira de se definir o TAD tMatrizInt, de forma arepresentar matrizes bidimensionais de inteiros.

1 #define MAX_DIM 5

2

3 typedef struct{

4

5 int valores[MAX_DIM ][ MAX_DIM ];

6 int nLinhas;

7 int nColunas;

8 }tMatrizInt;

Exemplo 6.4: Estrutura basica do tipo tMatrizInt

No exemplo 6.4 a matriz valores e declarada estaticamente, sendo seu tamanho definido pelaconstante MAX DIM. Como os proprios nomes evidenciam, nLinhas e nColunas sao variaveisinteiras que representam o numero de linhas e colunas, respectivamente, da matriz.

Na figura 6.4 pode-se visualizar a estrutura da matriz dados de uma variavel do tipo tMa-trizInt inicializada como no exemplo abaixo:

1 tMatrizInt dados;

Page 169: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

6.3. O TAD IMPLEMENTACIONAL TMATRIZ 169

2 int i,j;

3

4 dados.nLinhas = 3;

5 dados.nColunas = 3;

6

7 for( i=0; i < dados.nLinhas; i++){

8 for ( j=0; j < dados.nColunas; j++){

9 dados.valores[i][j]=0;

10 }

11 }

Exemplo 6.5: Inicializacao de uma estrutura tMatrizInt

Nas linhas 4 e 5 o tamanho da matriz e definido como 3 por 3. Na linha 7, o comando forpercorre as linhas da matriz de ındice zero a nLinhas-1. O segundo comando for percorre todasas colunas (para cada laco do for anterior) de ındice zero a nColunas-1. Dessa forma percorrem-se todos os elementos da matriz valores, dentro das dimensoes passadas, atribuindo-se a eles ovalor zero.

A figura 6.4 representa a matriz valores da estrutura dados do exemplo 6.5.

Figura 6.4: Estrutura da matriz valores pertencente a variavel dados (para MAX DIM igual a5)

Apesar da matriz valores pertencente a variavel dados ter 5 linhas e 5 colunas, somente oselementos pertencentes as 3 primeiras linhas e colunas foram inicializados. Isso porque definiu-se,nas linhas 4 e 5, que a matriz deveria ter somente esse numero de linhas e colunas. Dessa forma,em todas as operacoes efetuadas sobre essa variavel somente os elementos pertencetes a essasubmatriz (formada pelos zeros na figura) devem ser considerados. Todos os outros (marcadoscom sinal ’-’) possuem valores nao determinados, por nao terem sido inicializados, e devem serignorados.

6.3.2 Operacoes

Uma das vantagens de se implementar um tipo abstrato de dado e facilitar a solucao de pro-blemas, atraves do uso de operacoes que atuem sobre o tipo abstrato de dado definido. Dessa

Page 170: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

170 CAPITULO 6. MATRIZES

forma, vamos definir algumas operacoes sobre o tMatrizInt: inicializacao, atualizacao devalor, acessoa valor, exibicao, soma dos elementos de uma linha, soma dos elementosde uma coluna e produto escalar.

Inicializacao

Uma operacao essencial para se realizar sobre tMatrizInt e a inicializacao. Ela deve ser a primeiraa ser realizada, caso contrario as demais podem gerar resultados inesperados (como termino doprograma, por exemplo). Isso porque, durante a inicializacao, preparam-se as estruturas internasdo TAD para se adequar ao caso desejado. No caso do tipo tMatrizInt proposto nesse capıtulo,a operacao de inicializacao definira as dimensoes iniciais da matriz.

O codigo do exemplo 6.6 mostra como isso pode ser implementado:

1 tMatrizInt inicializa(int nLinhas , int nColunas){

2

3 tMatrizInt resultado;

4

5 resultado.nLinhas = nLinhas;

6 resultado.nColunas = nColunas;

7

8 return resultado;

9 }

Exemplo 6.6: Funcao de inicializacao

Na definicao da funcao Inicializa (linha 1), os argumentos nLinhas e nColunas servem paradefinir a quantidade de linhas e colunas da matriz respectivamente, e esses valores sao atribuıdosa estrutura tMatriz nas linhas 6 e 7. Finalmente, na linha 16 a estrutura e retornada atraves davariavel resultado.

Atualizacao de Valor

Como nao e interessante que uma matriz apresente todos os elementos com os mesmos valores,e necessario definir uma forma de atualiza-los individualmente. Isso pode ser feito atraves daoperacao de escrita definida pela funcao do exemplo 6.7.

1 tMatrizInt atualizaMatriz(tMatrizInt matriz , int linha , int coluna , int valor){

2

3 if( (linha >=0 && linha <matriz.nLinhas) && (coluna >=0 && coluna <matriz.

nColunas)){

4 matriz.valores[linha ][ coluna] = valor;

5 }

6

7 return matriz;

8 }

Page 171: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

6.3. O TAD IMPLEMENTACIONAL TMATRIZ 171

Exemplo 6.7: Escrita em um elemento da matriz

Na linha 3 e verificado se o elemento pertence a matriz(se o numeros de sua linha e de sua colunaestao dentro das dimensoes da matriz). Caso tudo esteja correto, o valor passado e atribuıdo aoelemento desejado e a funcao retorna o numero 0, informando que a operacao foi realizada comsucesso. Caso contrario a funcao retorna o numero -1 para informar que a escrita nao pode serefetuada.

Acesso a valor

Tendo em vista a importancia de utilizar o valor de um determinado ıtem, e necessario construiruma funcao para acessar os dados da matriz (exemplo 6.8).

1 int acessaMatriz(tMatrizInt matriz , int linha , int coluna)

2 {

3

4 if( (linha >=0 && linha <matriz.nLinhas) && (coluna >=0 && coluna <matriz.

nColunas)){

5 return matriz.valores[linha ][ coluna ];

6

7 }else{

8 return -1;

9 printf(‘‘ Item inexistente\n’’);

10

11 }

12 }

Exemplo 6.8: Funcao de acesso aos dados da matriz

Na linha 4 e realizada a mesma verificacao que na linha equivalente do exemplo 6.7. Se oelemento pertencer a matriz o seu valor e retornado. Caso contrario, o valor -1 e retornado euma mensagem de erro e impressa na tela. Note que, na maioria das aplicacoes, nao sera possıvelverificar a execucao correta da funcao analisando o valor de retorno, pois o valor retornado (-1)pode fazer parte do universo de valores validos para a aplicacao.

Exibicao

Para poder visualizar todos os elemetos de uma matriz de inteiros e necessario definir umaoperacao de exibicao (ou impressao) da matriz na tela (exemplo 6.9).

1 int exibeMatriz(tMatrizInt matriz){

2

3 int i=0, j=0;

4

5 for(i=0; i < matriz.nLinhas; i++){

Page 172: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

172 CAPITULO 6. MATRIZES

6 for(j=0; j < matriz.nColunas; j++){

7 printf(" %5d\0", matriz.valores[i][j]);

8

9 }

10 printf("\n");

11 }

12 }

Exemplo 6.9: Exibicao da matriz na tela

No exemplo 6.9 tem-se, na linha 5, um comando for para varrer as linhas da matriz, e paracada linha tem-se outro comando for, na linha 6, para varrer os elementos dessa linha. Na linha7, o trecho “%5d” faz com que os numeros sejam exibidos sempre com 5 dıgitos, o que faz comque a forma de exibicao seja regular, como pode ser visto na figura 6.5.

Figura 6.5: Exemplo de saıda da operacao exibe

Soma dos elementos de uma linha

Como em muitas aplicacoes e necessario obter o valor da soma dos elementos de uma linha, seradefinida uma operacao para efetuar esse calculo.

1 int somaLinhaMatriz(tMatrizInt matriz , int linha){

2

3 int i=0, soma =0;

4

5 for(i=0; i < matriz.nColunas; i++){

6 soma = soma + matriz.valores[linha ][i];

7 }

8

9 return soma;

10 }

Exemplo 6.10: Soma dos elementos de uma linha

A variavel soma e inicializada com o valor zero. O for da linha 5 percorre todos os elementosda linha da matriz e, para cada laco, adiciona o valor da celula da matriz a soma. A variavelsoma funciona, entao, como um acumulador e, ao final dos lacos, armazena o valor da soma doselementos da linha.

Page 173: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

6.3. O TAD IMPLEMENTACIONAL TMATRIZ 173

Soma dos elementos de uma coluna

Anteriormante foi definida a somda dos elementos de uma linha. Agora sera definida umaoperacao para efetuar a soma dos elementos de uma coluna.

1 int somaColunaMatriz(tMatrizInt matriz , int coluna){

2

3 int i=0, soma =0;

4

5 for(i=0; i < matriz.nLinhas; i++){

6 soma = soma + matriz.valores[i][ coluna ];

7 }

8

9 return soma;

10 }

Exemplo 6.11: Soma dos elementos de uma coluna

A variavel soma e inicializada com o valor zero. O for da linha 5 percorre todos os elementosda coluna da matriz e, para cada laco, adiciona o valor da celula da matriz a soma. A variavelsoma funciona, entao, como um acumulador e, ao final dos lacos, armazena o valor da soma doselementos da coluna.

Produto Escalar

Agora, sera definida uma operacao de composicao chamada produto escalar, que gera uma matrizM de cujos elementos sao resultados de uma composicao dos elementos de A e B 1(M=A.B).Nesta operacao os elementos mij da matriz M sao resultantes do somatorio dos produtos entreos elementos das linhas i da primeira matriz, e os elementos das colunas j da segunda matriz,para que esta operacao seja executada e necessario que o numero de colunas da matriz A sejaigual ao numero de linhas da matriz B.

1 tMatrizInt produtoEscalar(tMatrizInt matriz1 , tMatrizInt matriz2){

2

3 int i=0, j=0, k=0;

4 tMatrizInt produto;

5

6 if( matriz1.nColunas == matriz2.nLinhas){

7

8 for(i=0; i < matriz1.nLinhas; i++){

9

10 for(j=0; j < matriz2.nColunas; j++){

11

12 produto.valores[i][j]=0;

13

14 for(k=0; k < matriz1.nColunas; k++){

1Vale ressaltar que A.B e diferente de B.A . Logo, o produto escalar entre matrizes nao e comutativo

Page 174: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

174 CAPITULO 6. MATRIZES

15

16 produto.valores[i][j] += matriz1.valores[i][k] *

17 matriz2.valores[k][j];

18 }

19 }

20 }

21

22 produto.nLinhas=matriz1.nLinhas;

23 produto.nColunas=matriz2.nColunas;

24 }else{

25

26 produto.nLinhas=produto.nColunas =0;

27 }

28

29 return produto;

30 }

Exemplo 6.12: Soma dos elementos de uma fila

6.4 Exercıcios Resolvidos

Exercıcio Resolvido 6.1 - Alocacao de sala

Deseja-se desenvolver um programa para controlar a reserva de uma sala ao longo de umano. Ao usuario devem ser fornecidas as seguintes operacoes:

1. Reservar a sala

2. Cancelar reserva

3. Dado um mes, listar dias em que a sala esta disponıvel

4. Informar o ındice de ocupacao de cada mes

Implemente o programa utilizando o TAD tMatrizInt.

Solucao Possıvel:Para se armazenar as informacoes de reserva da sala sera utilizada uma matriz com 31 linhas

(representando os dias) e 12 colunas (representado os meses). Dessa forma, para se reservar asala para o dia 1o de janeiro, atribui-se ao elemento da linha 0 e coluna 0 o valor 1.

Para resolver o problema sera criada uma funcao para cada operacao.

1. Reservar a sala:

A primeira coisa a ser feita e verificar a reserva da sala para a data informada. Se a salaestiver livre sera reservada, uma mensagem de sucesso impressa na tela e a matriz alteradasera retornada. Caso contrario, a matriz e retornada inaltarada e uma mensagem de erroimpressa na tela.

Page 175: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

6.4. EXERCICIOS RESOLVIDOS 175

1 tMatrizInt reservaSala(tMatrizInt mat , int dia , int mes){

2

3 if (acessaMatriz(mat , dia , mes) == 0){

4 printf("Sala reservada com sucesso\n");

5 return atualizaMatriz(mat , dia , mes , 1);

6 } else {

7 printf("Sala ja reservada para a data informada\n");

8 return mat;

9 }

10 }

Exemplo 6.13: Reservar a sala

2. Cancelar a reserva:

Novamente, deve-se verificar a reserva da sala para a data informada. Se a sala estiverreservada a reserva sera cancelada, uma mensagem de sucesso impressa na tela e a matrizalterada sera retornada. Caso contrario, a matriz e retornada inaltarada e uma mensagemde erro impressa na tela.

1 tMatrizInt cancelaReserva(tMatrizInt mat , int dia , int mes){

2

3 if (acessaMatriz(mat , dia , mes) != 0){

4 printf("Reserva cancelada");

5 return atualizaMatriz(mat , dia , mes , 0);

6 } else {

7 printf("Sala n~ao reservada para a data informada\n");

8 return mat;

9 }

10 }

Exemplo 6.14: Cancelar reserva

3. Listar dias livres do mes:

Deve-se verificar, em um laco, todos os dias do mes escolhido e, para cada dia, verificara reserva da sala. Se ela estiver ocupada, entao o dia sera impresso na tela de modo ainformar isso ao usuario. Note que o numero de dia de cada mes varia e, portanto, devehaver um controle de forma que o laco termine com o numero de dias correto para o mesescolhido.

1 void listaDiasLivres(tMatrizInt mat , int mes){

2

3 int dia;

4 int numeroDiasMes [] = {31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31};

5 printf("Dias livres para o mes %d\n", mes +1);

6

Page 176: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

176 CAPITULO 6. MATRIZES

7 for(dia = 0; dia < numeroDiasMes[mes]; dia ++){

8 if (acessaMatriz(mat , dia , mes) == 0){

9 printf("%d\n", dia +1);

10 }

11 }

12 }

Exemplo 6.15: Listar dias livres do mes

4. ındide de ocupacao de cada mes:

O ındice de ocupacao de um mes nada mais e do que o numero de dias com a sala reservadanaquele mes. Alem disso, como a sala ocupada e representada pelo numero 1 e a sala vaziapelo numero 0, somando-se a coluna que representa um determinado mes obtem-se onumero de dias ocupados para esse mes. Assim sendo, para resolver o problema, bastapercorrer todas as colunas da matriz e, para cada uma delas, efetuar a soma de seuselementos.

1 void imprimeIndiceOcupacao(tMatrizInt mat){

2

3 int mes;

4 int indice;

5

6 printf(" ındice de ocupac~ao dos meses do ano\n");

7

8 for(mes = 0; mes < 12; mes ++){

9 indice = somaColunaMatriz(mat , mes);

10

11 printf("Mes %d: %d dias ocupados\n", mes , indice);

12 }

13 }

Exemplo 6.16: ndide de ocupacao de cada mes

Uma vez definidas as funcoes que realizam as operacoes, falta entao definir a funcao principaldo programa onde a interacao com o usuario sera feita e as funcoes serao chamadas.

1 int main()

2 {

3 tMatrizInt reservas;

4 int codigo , dia , mes;

5

6 reservas = inicializa (31, 12);

7

8 for(mes=0; mes <12; mes ++){

9 for(dia =0; dia <31; dia ++)

10 reservas.valores[dia][mes] = 0;

11 }

Page 177: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

6.4. EXERCICIOS RESOLVIDOS 177

12

13 do {

14 printf("\\n\\n\\n\\n\\n\\n\\n");

15 printf("## Reserva de Salas ##\\n\\ nEscolha uma operac~ao :\\n");

16 printf(" 1- Reservar a sala\\n");

17 printf(" 2- Cancelar uma reserva \\n");

18 printf(" 3- Listar dias livres \\n");

19 printf(" 4- Exibir ındice de ocupac~ao \\n");

20 printf(" 5- Sair\\n");

21 printf("Digite o codido da opecac~ao escolhida: ");

22 scanf("%d", &codigo);

23

24 switch(codigo){

25 case 1:

26 printf("\\n\\ nDigite a data da reserva (dia/mes): ");

27 scanf("%d/%d", &dia , &mes);

28 reservas = reservaSala(reservas , dia , mes);

29 break;

30

31 case 2:

32 printf("\\n\\ nDigite a data da reserva a cancelar (dia/mes): ");

33 scanf("%d/%d", &dia , &mes);

34 reservas = cancelaReserva(reservas , dia , mes);

35 break;

36

37 case 3:

38 printf("\\n\\ nDigite o mes: ");

39 scanf("%d", &mes);

40 listaDiasLivres(reservas , mes);

41 break;

42

43 case 4:

44 imprimeIndiceOcupacao(reservas);

45 break;

46 }

47 }while (codigo != 5);

48

49 return 0;

50

51 }

Exemplo 6.17: Interacao com usuario

Exercıcio Resolvido 6.2 - Soma de elementos

Dada uma matriz bidimensional de inteiros, defina operacoes que realizem os seguintescalculos:

• A soma dos elementos da diagonal principal

• A soma dos elementos da submatriz triangular

Page 178: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

178 CAPITULO 6. MATRIZES

Solucao Possıvel:

• A soma dos elementos da diagonal principal

Para calcular a soma dos elementos da diagonal principal de uma matriz M[i,j] e necessarionotar que todos os elementos da diagonal principal apresentam ındices referentes a colunae a linha iguais (M[i,i]). Assim, varrer-se a diagonal principal da matriz atraves de umloop, na linha 6, onde a cada laco soma-se o valor do elemento M[i,i] a variavel soma eincrementa-se o valor do ındice i de uma unidade.

1 int somaDiagonal(tMatrizInt matriz){

2

3 int soma =0;

4 int i;

5

6 for(i=0; i<matriz.nLinhas && i<matriz.nColunas; i++){

7 soma = soma + acessaMatriz(matriz , i, i);

8 }

9

10 return soma;

11 }

Exemplo 6.18: Soma da diagonal principal

• A soma dos elementos da submatriz triangular superior

Como os elementos da matriz triangular superior sao os elementos que estao situados acimados elementos da diagonal principal, pode-se notar que para cada linha esses elementosestao situados nas colunas a direita do elemento da diagonal principal. Dessa forma, varre-se a matriz triangular superior atraves de um loop, na linha 6, que varre todas as linhas ida matriz, e para cada linha tem-se outro loop, linha 7, para varrer as colunas de ındicei+1 ate nColunas. Entao, soma-se o valor de cada elemento visitado a variavel soma,linha 8.

1 int somaTriangular(tMatrizInt matriz){

2

3 int soma =0;

4 int i,j;

5

6 for(i=0; i<matriz.nLinhas; i++){

7 for(j=i+1; j<nColunas; j++){

8 soma = soma + acessaMatriz(matriz , i, j);

9 }

Page 179: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

6.4. EXERCICIOS RESOLVIDOS 179

10 }

11

12 return soma;

13 }

Exemplo 6.19: Soma da matriz triangular superior

Exercıcio Resolvido 6.3 - Uns isolados

Dada uma matriz bidimensional nxn de ‘’zeros” e ‘’uns”, defina uma operacao para calcularo numero de uns isolados dessa matriz. Considere que um numero um esta isolado se nenhumdos elementos adjacentes a ele, apenas na horizontal e vertical, sao ‘’uns”.

Solucao Possıvel:Para cada celula que contenha o valor um, sera necessario checar no maximo quatro celulas

adjacentes a ela para saber se a mesma contem um numero um isolado. Os loops das linhas 5 e7 servem para varrer a matriz completamente, e a cada celula visitada checa-se se suas celulasadjacentes sao zeros, dependendo de quantas ela possa ter. Assim, se o elemento visitado estiverna primeira linha (linha 9) ele pode ser: o primeiro da linha (11), e entao so tera adjacentesabaixo e a direita (12); o ultimo da linha (linha 16), e entao so tera adjacentes abaixo e a esquerda(17); ou caso nao seja nem o primeiro e nem o ultimo, tera adjacentes abaixo, a esquerda e adireita. Caso o elemento esteja na ultima linha (linha 27) ele pode ser: o primeiro da linha(linha 29), e entao so tera adjacentes acima e a direita (linha 30); o ultimo da linha (linha 34),e entao so tera adjacentes acima e a esquerda (linha 35); ou caso nao seja nem o primeiro e nemo ultimo tera adjacentes acima, a esquerda e a direita (linha 39). Apos checar se o elementovisitado esta na primeira ou na ultima linha da matriz, temos o caso dele estar na primeiraou na ultima coluna, desconsiderando os elementos dessas colunas que estejam na primeira ouna ultima linha. Se ele estiver na primeira coluna (linha 45) tera adjacentes acima, abaixo e adireita (linha 46); e se ele estiver na ultima coluna (linha 50), tera adjacentes acima, abaixo e aesquerda (linha 51). Finalmente, se o elemento visitado nao estiver na primeira linha, na ultimalinha, na primeira coluna e nem na ultima coluna (linha 53); ele tera adjacentes acima, abaixo,a esquerda e a direita (linha 55).

1 int unsIsolados(tMatrizInt matriz){

2

3 int i,j,unsisolados =0;

4

5 for(i=0;i<matriz.nLinhas;i++){

6

7 for(j=0;j<matriz.nColunas;j++){

8

9 if(i==0){

10

11 if(j==0){

Page 180: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

180 CAPITULO 6. MATRIZES

12 if(acessaMatriz(matriz , i, j+1) ==0 && acessaMatriz(matriz , i+1, j

)==0 && acessaMatriz(matriz ,i,j)==1)

13 unsisolados ++;

14 }else{

15

16 if(j== matriz.nColunas -1){

17 if(acessaMatriz(matriz , i, j-1) ==0 && acessaMatriz(matriz , i

+1, j)==0 && acessaMatriz(matriz ,i,j)==1)

18 unsisolados ++;

19 }else{

20

21 if(acessaMatriz(matriz , i+1, j)==0 && acessaMatriz(matriz , i,

j+1)==0 && acessaMatriz(matriz , i, j-1)==0 && acessaMatriz

(matriz ,i,j)==1)

22 unsisolados ++;

23 }

24 }

25 }else{

26

27 if(i== matriz.nLinhas -1){

28

29 if(j==0){

30 if(acessaMatriz(matriz , i, j+1) ==0 && acessaMatriz(matriz , i

-1, j)==0 && acessaMatriz(matriz ,i,j)==1)

31 unsisolados ++;

32 }else{

33

34 if(j== matriz.nColunas -1){

35 if(acessaMatriz(matriz , i, j-1) ==0 && acessaMatriz(matriz ,

i-1, j)==0 && acessaMatriz(matriz ,i,j)==1)

36 unsisolados ++;

37 }else{

38

39 if(acessaMatriz(matriz , i-1, j)==0 && acessaMatriz(matriz ,

i, j+1) ==0 && acessaMatriz(matriz , i, j-1) ==0 &&

acessaMatriz(matriz ,i,j)==1)

40 unsisolados ++;

41 }

42 }

43 }else{

44

45 if(j==0 && i>0 && i<matriz.nLinhas -1){

46 if( acessaMatriz(matriz , i, j+1) ==0 && acessaMatriz(matriz , i

+1, j)==0 && acessaMatriz(matriz , i-1, j)==0 &&

acessaMatriz(matriz ,i,j)==1)

47 unsisolados ++;

48 }else{

49

50 if(j== matriz.nColunas -1 && i>0 && i<matriz.nLinhas -1){

51 if( acessaMatriz(matriz , i, j-1) ==0 && acessaMatriz(matriz ,

i+1, j)==0 && acessaMatriz(matriz , i-1, j)==0 &&

Page 181: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

6.5. RESUMO 181

acessaMatriz(matriz ,i,j)==1)

52 unsisolados ++;

53 }else{

54

55 if(acessaMatriz(matriz , i, j+1) ==0 && acessaMatriz(matriz ,

i, j-1) ==0 && acessaMatriz(matriz , i+1, j)==0 &&

acessaMatriz(matriz , i-1, j)==0 && acessaMatriz(matriz ,

i,j)==1)

56 unsisolados ++;

57 }

58 }

59 }

60 }

61 }

62 }

63

64 return unsisolados;

65 }

Exemplo 6.20: Soma da matriz triangular superior

6.5 Resumo

• Uma matriz e um tipo de dado composto homogeneo na qual seus elementos sao organi-zados em uma estrutura multidimensional.

• E necessario inicializar a matriz para evitar situacoes de acesso a elementos que contenhamvalores indeterminados.

• O TAD tMatriz e composto pelos seguintes atributos: numero de linhas da matriz, numerode colunas da matriz e a estrutura que armazenara os elementos.

• Quando se tenta acessar um elemento com posicao nao definida na matriz, e necessarioretornar uma mensagem de erro para indicar que ocorreu um erro na execucao do programa.

6.6 Exercıcios Propostos

1. Escreva um subprograma que determine o maior valor em uma matriz de valores inteiroscom n > 0 linhas e m > 0 colunas.

2. Altere o subprograma anterior para exibir na tela todas as posicoes da matriz em que seencontra tal valor maximo.

3. Faca um programa que calcule a matriz resultante da soma de duas matrizes de dimensoesm linhas e n colunas, com valores inteiros.

Page 182: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

182 CAPITULO 6. MATRIZES

4. Escreva um subprograma que calcule a transposta de uma dada matriz. Considere comomatriz trasposta At de A a matriz de cujos elementos At[i,j] sao iguais a os elementosA[j][i] para 1<=i<=m e 1<=j<=n, onde m representa o numero de linhas e n o numerode colunas da matriz A.

5. Escreva uma funcao que verifica se uma matriz nxn e simetrica. Uma matriz A e simetricase A[i,j] = A[j,i] para todo 1<=i,j<=n.

6. Faca um subprograma que calcule a soma dos termos que se situam na diagonal secundariaou abaixo dela numa matriz quadrada com elementos inteiros. Assuma que o numeromaximo de linhas e colunas e 100, mas que a matriz pode estar preenchida apenas parci-almente.

Observacao: Antes de escrever o subprograma, voce deve apresentar a declaracao do tipoda matriz que deve ser colocada nos programas que usarao este subprograma.

7. Faca um subprograma que receba uma matriz quadrada (dimensoes N x N) totalmentepreenchida com numeros inteiros e troque os elementos acima da diagonal principal pe-los que estao abaixo dela. Atente para o fato que a matriz recebida deve ser retornadamodificada e que voce nao pode usar uma matriz ou vetor auxiliar para fazer a troca doselementos.

Exemplo para matriz 3 x 3:

1 2 34 5 67 8 9

antes

1 4 72 5 83 6 9

depois

8. Uma matriz quadrada inteira e chamada de ‘’quadrado magico” se a soma dos elementosde cada linha, a soma dos elementos de cada coluna e a soma dos elementos das diagonaisprincipal e secundaria sao todos iguais.

Exemplo de um quadrado magico:

8 0 74 5 63 10 2

Page 183: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

6.6. EXERCICIOS PROPOSTOS 183

Escreva uma funcao que verifica se uma matriz de n linhas e n colunas representa umquadrado magico.

9. Um quadrado latim de ordem n contem os numeros de 1 ate n de forma que nenhum numeroe repetido na mesma linha ou coluna. Este quadrado pode ser usado, por exemplo, emalguns torneios esportivos para assegurar que cada equipe joga com todas outras equipesuma e somente uma vez. Escreva uma funcao booleana que recebe uma matriz quadradae checa se ele e realmente um quadrado latim.

Exemplo de quadrado latim:

1 2 3 42 3 4 13 4 1 24 1 2 3

(numero de

10. Considere 2 matrizes quadradas do tipo tMatrizInt. Faca um subprograma para cada itemabaixo (note que as matrizes devem obrigatoriamente ser passadas como parametros aossubprogramas):

11. A matriz abaixo representa o triangulo de pascal de ordem 6:

11 11 2 11 3 3 11 4 6 4 11 5 10 10 5 1

Os elementos extremos de cada linha sao iguais a 1. Os outros elementos sao obtidossomando-se os dois elementos que aparecem imediatamente acima e a esquerda na linhaanterior. Assim 10 = 4 + 6. Escreva um programa que, dado n, gere e exiba na tela otriangulo de Pascal de ordem n. A impressao nao deve conter zeros acima da diagonalprincipal.

12. Considere uma matriz de inteiros. Define-se como vizinhanca de uma posicao da matriz asoma de todos os numeros que estejam em posicoes adjacentes. Escreva um programa quedetermine a posicao do elemento de maior vizinhanca.

a)Exibir uma matriz com as caracterısticas definidas acima (considere que a dimensaoN, isto e, seu numero de linhas ou colunas, da matriz sera lida no programa principal epassada como parametro para o subprograma);b)determinar se as duas matrizes sao identicas;c)determinar se a segunda matriz e uma rotacao de 90 graus a direita sobre a primeira;

Page 184: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

184 CAPITULO 6. MATRIZES

d)determinar se a segunda matriz e uma rotacao de 180 graus a direita sobre a primeira;e)determinar se a segunda matriz e a imagem espelhada vertical da primeira;f)determinar se a segunda matriz e a imagem espelhada horizontal da primeira;

As figuras abaixo ilustram cada tipo de matriz com um exemplo de dimensao3 x 3:

1 2 34 5 67 8 9

original

1 2 34 5 67 8 9

identica

7 4 18 5 29 6 3

90◦ a direita

9 8 76 5 43 2 1

180◦ a direita

13. Escreva ainda um programa que leia 2 matrizes e determine as relacoes existentes entreelas utilizando os subprogramas do exercıcio anterior.

14. Escreva uma funcao que receba uma matriz preenchida com caracteres maiusculos dotipotMatrizChar e um vetor do tipo tVetor contendo uma palavra em letras maiusculase retorne o numero de ocorrencias da palavra na matriz. A palavra pode estar escritana matriz de cima para baixo, da esquerda para a direita ou nas diagonais paralelas adiagonal principal ou na propria.

Page 185: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

6.7. TRABALHOS SUGERIDOS 185

6.7 Trabalhos Sugeridos

1. Caca-Palavras

Considere o jogo caca-palavras que consiste em procurar uma palavra dada em uma matrizde letras. Considera-se que a palavra foi encontrada se ela estiver inteiramente dispostaem uma linha, em uma coluna ou em uma diagonal da matriz. Define-se uma palavra comouma sequencia de letras maiusculas (para facilitar nao considere acentuacao). As palavrasestao escritas na matriz sempre de cima para baixo, da esquerda para a direita ou nasdiagonais paralelas a diagonal principal ou na propria diagonal. Faca um programa quetenha como entrada um conjunto de n palavras e a matriz de caracteres, ambas fornecidaspelo teclado. O programa deve ser capaz de:

1. Verificar quais palavras foram encontradas e computar o numero de ocorrencias de cadauma delas na matriz.2. Escrever em um arquivo texto, a lista das palavras encontradas e a listas das palavrasnao encontradas. As duas listas devem estar em ordem alfabetica.3. Escrever em seguida, no mesmo arquivo texto, a lista das palavras encontradas na ma-triz, ordenadas pelo seu numero de ocorrencias (considerar ordem decrescente).Informar tambem nestes casos, a posicao na matriz do caractere inicial de cada ocorrenciada palavra, alem da direcao que ela se encontra na matriz. As direcoes sao definidas como:diagonal, vertical, horizontal.4. Informe a direcao que mais palavras foram encontradas: diagonal, vertical ou horizontal.Informe tambem a quantidade de palavras encontradas nesta direcao.

O arquivo texto de saıda deve seguir o formato apresentado no exemplo a seguir:

Exemplo:

Conjunto de palavras: CAPELA, LAPIS, FLORESTA, AULA, ALEGRIA, MANGA

Matriz:

F L O R E S T A R SH J V N O A C I W ZC A P E L A P I S CI K V D I P M B S FT Y G C S A L U O PQ L K C A D U O L CA A S A R P R Y O AN E N E F T E B A UJ K D D S H W L F LI O T U G J J V A A

Arquivo de saıda:

Lista de palavras encontradas em ordem alfabetica:

Page 186: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

186 CAPITULO 6. MATRIZES

AULACAPELAFLORESTALAPIS

Lista de palavras nao encontradas em ordem alfabetica:

ALEGRIAMANGA

Lista de palavras encontradas, ordenadas pelo numero de ocorrencias na matriz:

CAPELA 2 (2, 0) horizontal (4, 3) diagonalAULA 1 (6,9) verticalFLORESTA 1 (0, 0) horizontalLAPIS 1 (2,4) horizontal

Direcao em que mais palavras foram encontradas: horizontalNumero de palavras encontradas nesta direcao: 3

6.8 Topicos Avancados

Definicao Dinamica de uma matriz

Alem da definicao estatica abordada na secao 6.2.1, uma matriz pode ser definida dinamica-mente. Nesse caso o tamanho de suas dimensoes so sera estabelecido durante a execucao doprograma, conforme e visto no exemplo 6.21:

1 #include <stdio.h>

2

3 main(){

4

5 int n, m;

6

7 printf(‘‘Forneca as dimens~oes da matriz:’’);

8 scanf(‘‘%d%d’’,&n,&m);

9 int matriz[n][m];

10 .

11 }

Exemplo 6.21: Definicao dinamica

Nesse exemplo a matriz so sera definida apos a execucao da funcao scanf, onde o tamanhode suas dimensoes sera lido do teclado.

Page 187: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

Capıtulo 7

ApontadoresAutores:

Igor Magri ValeDouglas Almonfrey

Flavio Varejao

Objetivos:

• Definir o que sao apontadores;

• Apresentar a sintaxe de apontadores;

• Mostrar a importancia dos apontadores na passagem de parametros sem copia, no retornode multiplos valores nas funcoes e na alocao dinamica de memoria;

• Apresentar os principais problemas no uso de apontadores;

• Definir o TAD Lista Encadeada e suas principais operacoes;

Neste capıtulo procurou-se dar enfase a aspectos relevantes, de caracter introdutorio, paraque este texto seja utilizado como primeira leitura, e posterior consulta, sobre apontadores.

7.1 Variaveis Apontadores

Em um programa, cada variavel possui seu endereco e um conteudo. A Figura 7.1 exibe cincoenderecos de memoria e seus respectivos conteudos.

Os apontadores sao um tipo especial de variavel, cujo conteudo nao e um simples valor, e simum endereco de memoria. Na Figura 7.2, pode ser observado que o conteudo de uma variavelapontador corresponde a um endereco de uma variavel nao-apontador.

Neste capıtulo, serao estudados os apontadores, tambem chamados de ponteiros. Como osapontadores sao variaveis que guardam enderecos, trata-se de um conceito de baixo nıvel, muitoligado a arquitetura de computadores. Apontadores sao ferramentas poderosas na linguagem de

187

Page 188: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

188 CAPITULO 7. APONTADORES

Figura 7.1: Formato Abstrato da Memoria

Figura 7.2: Apontadores e Nao-Apontadores

programacao C. Dentre diversas funcoes, apontadores permitem passagem de parametros semcopia de muitos dados, retorno de mltiplos valores em funcoes, alocacao dinamica de memoria econstrucao de listas encadeadas.

No decorrer do capıtulo, serao utlizados modelos de figuras ilustrativas para auxiliar naexplicacao. Na Figura 7.3, tem-se o modelo para representar uma variavel e seu endereco.

Como pode ser observado na Figura 7.3, um quadrado sera usado como formato abstratode variavel de memoria. Dentro deste quadrado estara representado o conteudo da variavel.Alem disso, um cırculo negro no seu vertice superior esquerdo representara abstratamente seuendereco.

Ja para representar a ligacao entre um apontador e a variavel que esta sendo apontada porele, sera utilizado o modelo da Figura 7.4. Tal ligacao e ilustrada por meio de uma seta, que saida variavel apontador, e aponta o cıculo negro (endereco) da variavel nao-apontador.

7.2 A Sintaxe dos Apontadores

Na linguagem C, o operador asterisco * e que especifica se uma variavel guarda um endereco,ou seja, se e um apontador. A declaracao de um apontador segue o seguinte formato:

Page 189: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.2. A SINTAXE DOS APONTADORES 189

Figura 7.3: Formato Abstrado de uma Variavel

Figura 7.4: Abstracao de uma Variavel Apontador

<tipo do apontador> * <nome da variavel>

No lugar do tipo do apontador, devem-se utilizar alguns dos tipos padroes da linguagem C,como char, int e float, ou ate mesmo novos tipos definidos pelo programador. No Exemplo 7.1,tem-se como criar apontadores dos tipos char, int, float e tAluno.

1 typedef struct {

2 char nome [30];

3 int matricula;

4 }tAluno;

5

6 main ( ) {

7 char *c;

8 int *p;

9 float *f;

10 tAluno *x;

11 }

Page 190: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

190 CAPITULO 7. APONTADORES

Exemplo 7.1: Declaracao de apontadores

Assim, no codigo do Exemplo 7.1, c pode apontar para uma area de memoria que guardauma variavel do tipo caracter, enquanto p, f e x dos tipos inteiro, ponto flutuante e tAluno,respectivamente.

Dois outros operadores tambem estao associados a sintaxe de apontadores: o operador en-dereco de memoria e o operador seta. Eles serao discutidos nas duas proximas subsecoes.

7.2.1 Operador Endereco de Memoria

Em C, o operador unario &, quando aplicado a uma variavel, retorna o endereco dela. Portanto,quando um apontador e declarado, pode-se inicializa-lo usando o operador &, que faz o apontadorreceber um endereco de uma variavel ja existente.

O Exemplo 7.2 mostra o uso do operador (&) para inicializar uma variavel apontador. Avariavel p recebe o endereco da variavel d. Note que ambas variaveis sao do mesmo tipo, poise fundamental que o apontador aponte para uma variavel de tipo compatıvel com a declaracaodele.

1 int *p;

2 int d = 10;

3 p = &d;

4 printf ("%p\n%p\n", &d, p);

Exemplo 7.2: Inicializacao de um apontador usando o operador endereco de memoria

No Exemplo 7.2, serao impressos o endereco de d, e logo apos, o valor do apontador p,que e o endereco de d. Portanto, dois valores iguais serao impressos na tela. O %p, utilizadono Exemplo 7.2, e usado pela funcao printf para identificar o tipo de valor que sera impresso,neste caso %p informa que o valor de um apontador sera impresso, ou seja, o endereco de umavariavel.

7.2.2 O Operador Seta

Outro operador associado a apontadores e a seta (− >). Quando um apontador indica umavariavel do tipo estrutura, para que se acesse os atributos desta variavel, ao inves do ponto (.),utiliza-se (− >). Observe o Exemplo 7.3.

1 typedef struct {

2 char nome [30];

3 int matricula;

4 }tAluno;

5

6 main ( ) {

Page 191: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.3. ACESSO A VARIAVEL POR MEIO DE APONTADORES 191

7 tAluno *x;

8 tAluno y;

9

10 x = &y;

11 x->matricula = 2031;

12

13 printf ("%d\n", y.matricula);

14 }

Exemplo 7.3: Acesso ao atributo de uma estrutura por meio do operador seta

Note que no Exemplo 7.3, x e um apontador para uma estrutura tAluno e y uma variaveltAluno. Apos fazer x apontar para o endereco de y, para acessar a matrıcula de y atraves de x,deve ser utilizado o operador − >. Ja para imprimir o atual valor da matricula de y, que passoua ser 2031, basta utilizar o ponto.

7.3 Acesso a Variavel por Meio de Apontadores

O operador unario * tem uma outra funcao alem de especificar uma multiplicacao ou se umavariavel e apontador. Este operador tambem pode retornar o valor armazenado na variavelapontada pelo apontador. Por isso, apontadores podem ser usados para atribuir valores a outrasvariaveis. Observe o Exemplo 7.4.

1 int *p;

2 int c = 10;

3 int d;

4 p = &c;

5 d = *p;

Exemplo 7.4: Acesso ao conteudo de variaveis por meio de apontadores

No Exemplo 7.4, p recebe o endereco de c. Atraves de p portanto, pode-se agora acessar ovalor de c. Com esse recurso, na quinta linha do Exemplo 7.4, d recebe o valor de c por meiode p.

Uma variavel pode ser atribuıda atraves do uso de apontadores. No Exemplo 7.5, a variavelc tem seu valor alterado atraves de uma atribuicao feita a p.

1 float *p;

2 float c = 15;

3 p = &c;

4 *p = *p + 1;

5 printf ("%f", c);

Exemplo 7.5: Alterando valor de variaveis por meio de apontadores

Page 192: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

192 CAPITULO 7. APONTADORES

Pode ser observado no Exemplo 7.5, que p aponta para c. Assim, a expressao na linha 4incrementa o conteudo da variavel apontada por p em uma unidade, ou seja, c passa a ter ovalor 16, o qual e impresso na tela.

Uma variavel pode receber o valor de outra por meio de apontadores. Na linha 7 do Exemplo7.6, a variavel i apontada por v tem seu valor alterado para o de d, pois d esta apontado por j.

1 float *v;

2 float *j;

3 float d = 15.0;

4 float i = 17.0;

5 j = &d;

6 v = &i;

7 *v = *j;

8 v = j;

Exemplo 7.6: Alterando valor de variaveis atraves de apontadores

Um apontador tambem pode ser atribuıdo a outro apontador. No Exemplo 7.6, linha 8, vpassa a apontar para o mesmo endereco que j aponta.

Por fim, esse acesso a variaveis atraves de apontadores e muito importante, pois e pormeio deste recurso que as variaveis passadas como parametros de uma funcao sao alteradasdefinitivamente, dentro da propia funcao.

7.4 Uso de Apontadores nas Passagens de Parametros

O conceito de funcao em C, conforme ja discutido em capıtulos precedentes, e fundamental.Uma das principais vantagens de apontadores, no que diz respeito a funcao, e a passagem devalores sem copia.

Na passagem por copia, os variaveis que sao passadas como argumentos da funcao tem seusvalores copiados. Sao essas copias que a funcao utilizara no decorrer da sua execucao. Assim,qualquer alteracao dos valores das copias nao implicara em mudanca nas variaveis originais.

Por meio de apontadores, e possıvel alterar os valores das variaveis passadas como argumentospara uma funcao. Ao declarar que um parametro de uma funcao e apontador, deve-se passarum endereco de uma variavel como argumento correspondente. Nesse tipo de passagem, nao ecopiado o valor da variavel argumento, mas com o endereco dela, pode-se acessar o conteudo emodifica-lo no decorrer da execucao da funcao. O Exemplo 7.7 mostra a passagem por copia epor apontadores.

1 void adicionaX1 (int x, int b) {

2 b = b + x;

3 }

4

5 void adicionaX2 (int x, int *b) {

6 *b = *b + x;

Page 193: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.4. USO DE APONTADORES NAS PASSAGENS DE PARAMETROS 193

7 }

8

9 main ( ) {

10 int a = 0;

11

12 adicionaX1 (10, a);

13 printf ("a = %d\n", a);

14 adicionaX2 (10, &a);

15 printf ("a = %d\n", a);

16 }

Exemplo 7.7: Passagem de valor por copia e atraves de apontadores

Em adicionaX1 , no Exemplo 7.7, uma copia do valor de a e passada com argumento dafuncao, ou seja, b recebe uma copia do valor 0 de a. Dentro da funcao, o valor de b muda para10, mas o de a continua o mesmo. Assim, o primeiro valor impresso e 0. Ja em adicionaX2 , oendereco de a e passado para o ponteiro b e, na execucao da funcao, e adicionado x ao conteudoda variavel apontada por b, o que faz a ter seu valor modificado para 10. Portanto, o queimpresso no segundo printf e a = 10. A Figura 7.5 ilustra as passagens de parametro de a parab, em adicionaX1 e adicionaX2 .

Figura 7.5: Passagem de Valor por Copia e por Apontadores

Na Figura 7.5, repare que na passagem por copia, o valor de a e copiado para o conteudo deb, enquanto que na passagem por apontador, b passa a apontar para o endereco de a.

Uma aplicacao da passagem de valor por apontadores e proporcionar que uma funcao retornemultiplos valores. O Exemplo 7.8 mostra como isso e feito.

1 void troca (int *x, int *y) {

2 int aux;

Page 194: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

194 CAPITULO 7. APONTADORES

3

4 aux = *x;

5 *x = *y;

6 *y = aux;

7 }

8

9 main ( ) {

10 int a, b;

11 a = 10;

12 b = 20;

13

14 troca (&a, &b);

15 printf ("a = %d, b = %d\n", a, b);

16 }

Exemplo 7.8: Retorno de multiplos valores por uma funcao

No Exemplo 7.8, desejava-se uma funcao para trocar o conteudo de a e b. Contudo, umafuncao pode retornar apenas um valor no return. Assim, por meio dos apontadores, os doisconteudos sao alterados e retornados no escopo da funcao, pois a e b sao passados sem copia,ou seja, sao passados seus enderecos como parametros da funcao troca .

7.5 Alocacao Dinamica de Memoria

Apontadores tambem sao fundamentais no que diz respeito a alocacao dinamica, economia dememoria e tempo de execucao.

Apontadores permitem alocacao de memoria em tempo de execucao (alocacao dinamica).Para tanto, uma variavel apontador aponta para uma area dememoria livre definida durante aexecucao do programa. As Figuras 7.6 e 7.7 ilustram o processo de alocacao dinamica.

Figura 7.6: Areas de Memoria Livres

A Figura 7.6 mostra as areas livres da memoria. Em um determinado momento, um endereco,

Page 195: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.5. ALOCACAO DINAMICA DE MEMORIA 195

que era livre, passa a ser apontado por uma variavel apontador, podendo assim ser utilizado, oque e ilustrado na Figura 7.7.

Figura 7.7: Area de Memoria Alocada Dinamicamente

Em C, a funcao malloc (abreviatura de memory allocation), da biblioteca padrao stdlib.h,aloca um bloco de bytes consecutivos na memoria do computador e devolve o endereco dessebloco. O Exemplo 7.9 mostra seu uso.

1 int *p

2 p = (int *) malloc (4*( sizeof (int)));

Exemplo 7.9: Alocacao dinamica de quatro inteiros

No Exemplo 7.9, a expressao sizeof retorna o numero de bytes de um tipo passado comoparametro, no caso int. Alem disso, como a funcao malloc devolve um apontador do tipo void(void *) para um bloco de bytes consecutivos, esse apontador deve ser convertido em apontadorpara o tipo desejado, por meio do cast (int *) nesse caso, uma vez que a variavel p e do tipo int,garantindo assim, a consistencia de tipos.

A Figura 7.8 ilustra um espaco de 4 inteiros, alocados dinamicamente pelo Exemplo 7.9.Um espaco de memoria deve ser desalocado quando nao e mais necessario. Isto significa

que a area de memoria que foi apontada por um apontador agora passa a ser novamente livre.Somente variaveis alocadas dinamicamente podem ser desalocadas em tempo de execucao.

A desalocacao de memoria, em C, esta no Exemplo 7.10.

1 int *p;

2 p = (int *) malloc (4 * sizeof (int));

3 free (p);

Exemplo 7.10: Utilizacao da funcao free para liberar memoria

No Exemplo 7.10, a funcao free, assim como malloc, esta na biblioteca stdlib.h e desalocauma area de memoria. Note que a funcao free deve receber como parametro uma variavel

Page 196: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

196 CAPITULO 7. APONTADORES

Figura 7.8: Vetor de Inteiros Alocados Dinamicamente

apontador. Assim, o area de memoria apontada por ele sera entao liberada. A Figura 7.9 ilustraa desalocacao de memoria.

Figura 7.9: Desalocacao Dinamica de Memoria

Na Figura 7.9, pode-se observar a que no decorrer da execucao do programa, a variavelapontador deixa de apontar para area de memoria, que volta para a grupo de enderecos livres.

O processo de alocacao dinamica pode ser usado para ler linhas de um documento de texto.Usando-se alocacao dinamica, define-se o tamanho n x m fixo da matriz limitando o tamanho dotexto e da linha que podem ser lidos. Para se conseguir ler todas as linhas, define-se o tamanhom da matriz como o tamanho da maior linha que sera lida e n um numero alto suficiente paraarmazenar todas as linhas. Entretanto, esse procedimento acarreta perda de memoria com linhaspequenas, que nao utilizam todo o espaco alocado para elas, e tratando-se de textos com grandesquantidades de linhas essa perda torna-se consideravel.

Considere a Figura 7.10, que ilustra como seria o processo de alocacao dinamica de umamatriz para ler um pequeno texto de caracteres. Percebe-se facilmente para a quarta linha damatriz, que 9 espacos seriam perdidos.

Page 197: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.5. ALOCACAO DINAMICA DE MEMORIA 197

Figura 7.10: Matriz que Armazena um Texto

Para contornar o problema de perda de memoria com espacos nao utilizados, faz-se uso daalocacao dinamica. A cada necessidade de se ler uma linha com certo numero de caracteres,aloca-se o exato tamanho da linha, ou seja, a quantidade de caracteres da string que sera lida.

O Exemplo 7.11 mostra a implementacao em linguagem C de uma matriz de caracteres,dinamicamente alocada. Esta matriz possui 4 linhas de tamanhos alocados de acordo com otamanho da string armazenada, e cada linha da matriz recebe uma linha do texto da Figura7.10. A matriz declarada no Exemplo 7.11 e simplesmente um vetor de apontadores para stringse os elementos do vetor g contem os enderecos dos primeiros elementos de cada string. Essevetor de apontadores para strings e chamado matriz de apontadores ou matriz de strings. NaFigura 7.11 esta ilustrada a matriz de strings correspondente ao texto.

Figura 7.11: Matriz de Strings

1 main ( ) {

2 char *g[4];

3 g[0] = (char *) malloc (strlen ("Joao ama Maria") * sizeof (char));

4 strcpy (g[0], "Joao ama Maria");

5 g[1] = (char *) malloc (strlen ("Maria ama pedro") * sizeof (char));

6 strcpy (g[1], "Maria ama pedro");

7 g[2] = (char *) malloc (strlen ("Ana ama quem ama Maria") * sizeof (char));

8 strcpy (g[2], "Ana ama quem ama Maria");

9 g[3] = (char *) malloc (strlen ("Quem Ana ama?") * sizeof (char));

10 strcpy (g[3], "Quem Ana ama?");

Page 198: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

198 CAPITULO 7. APONTADORES

11 }

Exemplo 7.11: Definicao de uma matriz de caracteres dinamica

7.6 Problemas Gerados por Apontadores

Apesar de serem muito importantes, quando usados inapropiadamente, apontadores sao fontes deerros difıceis de serem encontrados. Apontadores nao inicializados, objetos pendentes, referenciapendente, e programacao macarronica sao alguns desses erros.

7.6.1 Apontadores Nao Inicializados

Quando se trata de apontadores, um erro muito comum e utiliza-lo antes de faze-lo apontarpara algum endereco valido, ou seja, sem inicializa-lo. O Exemplo 7.12 mostra como isso podeocorrer. O valor da variavel apontada por p recebe o valor de h, mas p nao foi inicializado ainda,ou seja, nao apontava para nenhum espaco de memoria valido.

1 float *p, h = 15.0;

2 *p = h;

Exemplo 7.12: Apontador nao inicializado

As consequencias da utilizacao de um apontador nao inicializado sao imprevisıveis, podendoprovocar uma paralisacao do sistema.

7.6.2 Objetos Pendentes

Objetos pendentes ocorrem quando uma area de memoria alocada fica inacessıvel. Veja o Exem-plo 7.13. A area de memoria apontada por p fica inacessıvel, pois p passa a apontar para o mesmoendereco de g. A Figura 7.12 ilustra como ocorre objetos pendentes.

Figura 7.12: Objetos pendentes

Page 199: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.6. PROBLEMAS GERADOS POR APONTADORES 199

1 int *p = (int*) malloc (sizeof (int));

2 int *q = (int*) malloc (sizeof (int));

3 p = q;

Exemplo 7.13: Objetos pendentes

7.6.3 Referencia Pendente

Quando e liberado um endereco de memoria, que e apontado por mais de uma variavel apontador,ocorre a referencia pendente. Assim, algumas variaveis ficam referenciando um endereco quefoi desalocado. Veja o Exemplo 7.14 que mostra um caso de referencia pendente. O enderecoda variavel h e liberado, portanto p aponta para um espaco de memoria liberado. A Figura7.13 ilustra o problema de referencia pendente. Um espaco de memoria livre pode ser alocadoa qualquer momento por outras variaveis do sistema. Ao se utilizar variaveis que tiveram seuespaco de memoria liberado, pode-se estar acessando areas importantes do sistema, que alocacouo espaco de memoria que acabara de ser liberado, e isto pode provocar uma paralisacao dosistema.

Figura 7.13: Referencia pendente

1 int *p;

2 int *h;

3 h = (int*) malloc (sizeof (int));

Page 200: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

200 CAPITULO 7. APONTADORES

4 p = h;

5 free (h);

Exemplo 7.14: Referencia pendente

7.6.4 Programacao Macarronica

Um mesmo endereco de memoria pode ser apontado por varios apontadores. Isso pode tornarconfuso o entendimento do programa e a identificacao de erros. O Exemplo 7.15 mostra umtrecho de codigo difıcil de entender devido ao uso indiscriminado de apontadores.

1 typedef struct {

2 int numerosala;

3 int numeroalunos;

4 } tsala;

5

6 acresentaAluno (tsala *g) {

7 g->numeroalunos = g->numeroalunos + 1;

8 }

9

10 main ( ) {

11 int p;

12 tsala sala;

13 sala.numerosala = 1;

14 sala.numeroalunos = 0;

15 tsala *x;

16 tsala *y;

17

18 y = &sala;

19 x = y;

20 acrescentaAluno (x);

21 acrescentaAluno (y);

22 }

Exemplo 7.15: Programacao macarronica causada pelo uso indiscriminado de apontadores.

No Exemplo 7.15, o numero de alunos da variavel sala e alterado duas vezes, uma peloapontador x, outra por meio do apontador y. Portanto, quando apontadores sao usados de umamaneira indiscriminada, pode-se diminuir a legibilidade do codigo.

7.7 TAD Implementacional Lista Encadeada tLista

Um exemplo de implementacao utilizando os apontadores e o TAD Lista Encadeada.Uma lista encadeada e uma estrutura cujos elementos sao acessados sequencialmente por

meio de apontadores. Nessa estrutura estao armazenados os apontadores para o comeco eo fim de uma sequencia de blocos, conhecidos como nos, alem de uma variavel inteira que

Page 201: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.7. TAD IMPLEMENTACIONAL LISTA ENCADEADA TLISTA 201

indica a quantidade atual destes na lista. Cada um dos nos, por sua vez, possuem informacoesarmazenadas, um apontador para o proximo no e no caso de uma lista duplamente encadeada,tambem um apontador para o no anterior. Na Figura 7.14, tem-se um esquema de uma listasimplesmente encadeada, com tres nos e com apontadores para o primeiro e o ultimo elemento.

Figura 7.14: Esquema de Uma Lista Simplesmente Encadeada

Note que cada um dos nos possui um apontador para o proximo, com excecao do ultimo, noqual ha um apontador para null, pois nao ha proximo. Repare tambem que a estrutura da listapossui apontadores para o inıcio e o fim da lista, alem de armazenar seu tamanho corrente, nocaso, tres elementos.

Pode-se perceber que incluir em uma lista encadeada torna-se um processo simples. Se umnovo dado necessita ser incluıdo, basta alocar um espaco de memoria para o no, atualizar osapontadores da sequencia de nos e a quantidade deles na lista. Excluir um dado da lista e umprocesso semelhante, com a diferenca de que, ao inves de se alocar, desaloca-se uma area damemoria.

Vale destacar que as estruturas da lista e de cada um dos dados armazenados em um nosao exemplos do uso de abstracao, pois se encapsulam informacoes, seleciona-se o que deveser apresentado de uma funcao a outra e possibilita-se o trabalho em nıveis de implementacaoe uso, pratica fundamental na modularizacao de um codigo. Conforme visto no capıtulo 4,pode-se dizer que o tipo de abstracao utilizada na lista encadeada e uma abstracao de dadosimplementacional, por meio do uso de Tipo Abstratos de Dados - TADs.

Anteriormente foi visto que TADs sao conjuntos de valores com comportamento uniformedefinido por operacoes, que sao tipicamente os componentes responsaveis pela interface entreos diferentes nıveis e modulos de implementacao. Essa interface e responsavel por encapsular eproteger os dados.

A implementacao do TAD lista encadeada tLista sera apresentada a seguir. Tambem seraodetalhadas varias operacoes fundamentais sobre a lista. Inicialmente, sera definido o tipo tNo,o qual e um componente importante de tLista.

Page 202: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

202 CAPITULO 7. APONTADORES

7.7.1 Definicao do Tipo tNo

De acordo com o que foi dito ate agora, cada no deve ser responsavel por armazenar um dado,alem de conter um apontador para o proximo no, no caso de uma lista simplesmente encadeada.Assim, segue abaixo um exemplo de como pode ser a estrutura tNo:

1 typedef int tInfo;

2

3 typedef struct no {

4 tInfo info;

5 struct no *proximo;

6 } tNo;

Exemplo 7.16: Estrutura tNo

Ha necessidade de se incluir o termo no apos o primeiro struct porque, ao se incluir aestrutura proximo, ocorre uma definicao recursiva do tipo no, ou seja, a estrutura no possui umcampo do mesmo tipo que ela. Assim, caso fosse retirado o primeiro termo no, nao se saberiaqual o tipo de proximo. Tambem e importante dizer que a variavel inteira info poderia sersubstituıda por qualquer outro tipo, tais como char, float e, ate mesmo, estruturas compostaspor uma variedade de tipos. Bastaria alterar o termo int na definicao do tipo tInfo.

A partir de agora, devido ao uso do typedef, sempre que for utilizado o termo tNo antes deum identificador, significa que esta sendo declarada uma estrutura como a do Exemplo 7.16.

Como frequentemente sera necessario incluir novos nos, torna-se importante criar uma funcaoque aloque dinamicamente um espaco de memoria para um no. O Exemplo 7.17 mostra umaforma de implementar tal funcao.

1 tNo *criaNo (tInfo elem) {

2 tNo *no = (tNo *) malloc (sizeof (tNo));

3 no->proximo = NULL;

4 no->info = elem;

5 return no;

6 }

Exemplo 7.17: Implementacao da operacao criaNo

Apos a alocacao do espaco de memoria, o apontador proximo e inicializado como NULL. Emseguida, o campo info do no criado e associado ao valor do elemento passado como argumento.Por fim, e retornado um apontador para a area de memoria inicializada na funcao.

7.7.2 Atributos de tLista

Sera utilizada uma estrutura para tLista com apontadores para o primeiro e ultimo no. Essaestrututa e chamada cabecalho da lista e cabe ressalvar que existem diferentes implementacoes.A adotada aqui (ver Exemplo 7.18) e apenas uma delas.

Page 203: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.7. TAD IMPLEMENTACIONAL LISTA ENCADEADA TLISTA 203

1 typedef struct {

2 tNo *primeiro;

3 tNo *marcador;

4 tNo *ultimo;

5 int tam;

6 }tLista;

Exemplo 7.18: Estrutura tLista

Repare que tres atributos de tLista sao apontadores para o tipo tNo, o qual foi definido nasecao anterior. Dois deles, primeiro e ultimo, apontam para o comeco e para o fim da lista,enquanto marcador aponta para qualquer posicao. A variavel inteira tam e a responsavel porguardar o atual tamanho, ou numero de nos, da lista.

O apontador marcador e responsavel por apontar o no corrente num processo de buscasequencial. Por exemplo, na operacao de imprimir a lista, que sera explicada mais adiante,a informacao e extraıda do no apontado por marcador e, este vai sendo posicionado desde oprimeiro no ate o ultimo.

7.7.3 Operacoes de tLista

Como ja se tem definidas as abstracoes de dados, tNo e tLista, necessita-se criar as operacoesque serao responsaveis por trabalhar com estes conjuntos de valores, concluindo assim, a imple-mentacao do TAD lista encadeada.

Operacoes Construtoras

As operacoes construtoras sao responsaveis por garantir a alocacao da estrutura tLista, alem deinicializa-la com os valores desejados, geralmente com os apontadores apontando para NULL eas variaveis numericas com valor zero.

Inicializacao (vazia)

O Exemplo 7.19 mostra a funcao de inicializacao de uma lista.

1 void iniciaLista (tLista *lista) {

2 lista ->primeiro = NULL;

3 lista ->marcador = NULL;

4 lista ->ultimo = NULL;

5 lista ->tam = 0;

6 }

Exemplo 7.19: Inicializacao de uma lista

Na funcao iniciaLista os apontadores primeiro, marcador e ultimo sao inicializados comNULL, pois nao ha nos na lista e, garante-se assim, que estes apontem para uma area de memoria

Page 204: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

204 CAPITULO 7. APONTADORES

indevida. Em seguida, o tamanho da lista e zerado uma vez que o atual tamanho da lista e nulo.

Operacoes Analisadoras

Em algumas situacoes e importante analisar a posicao atual do marcador, tal como se ele estano fim da lista, e se a lista esta vazia. Por exemplo, ao se percorrer a lista, uma condicao deparada importante e quando o final da lista for alcancado e, ao se incluir ou excluir um elementoda lista, e necessario saber se a lista esta vazia.

Essas analises sao importantes para que nao se cometa acessos indevidos com os apontadores,um dos problemas explicados neste capitulo.

Final

O Exemplo 7.20 mostra a implementacao da funcao analisadora de fim da lista.

1 int finalLista (tLista *lista) {

2 return (lista ->marcador == NULL);

3 }

Exemplo 7.20: Verificacao de fim da lista

Essa funcao simplesmente retorna o resultado da comparacao do marcador da lista comNULL. Isso porque o ultimo no da lista aponta tem como proximo este valor, bem como alista vazia, que tem seus apontadores iniciais todos apontando para NULL. Na Figura 7.15, omarcador nao esta apontando para NULL, assim nao e o fim da lista e a funcao final retorna 0.

Figura 7.15: Marcador Apontando para uma Posicao da Lista

Ja na Figura 7.16 o marcador aponta para NULL, ou seja para o fim da lista. Assim, oretorno da funcao e 1.

Vazia

O Exemplo 7.21 mostra a implementacao da funcao analisadora de lista vazia.

Page 205: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.7. TAD IMPLEMENTACIONAL LISTA ENCADEADA TLISTA 205

Figura 7.16: Marcador Apontando para o Fim da Lista

1 int vaziaLista (tLista *lista) {

2 return (lista ->tam == 0);

3 }

Exemplo 7.21: Verificacao se a lista esta vazia

Assim como na analise do fim da lista, vaziaLista retorna o resultado de uma comparacao.Nesse caso, porem, se o tamanho da lista e igual zero. Como o tamanho da lista e inicializadocom este valor e, sempre que um novo no for adicionado, ou removido, este tamanho deve seratualizado, a unica possibilidade de ele ser zero e quando a lista estiver realmente vazia.

Um exemplo da utilizacao de vazia e quando se deseja incluir, ou excluir um no da lista. Enecessario um tratamento especial na primeira inclusao, pois o primeiro e ultimo elemento saoos mesmos, e na exclusao, uma vez que seria um erro tentar remover elementos de uma listavazia.

Operacoes Modificadoras

Uma das caracterısticas interessantes da lista encadeada e a facilidade de se incluir e excluirelementos, em tempo de execucao, com praticidade, uma vez que e necessario somente alocar edesalocar nos, respectivamente. E importante, entao, conhecer as funcoes de insercao e exclusao,tratadas como operacoes modificadoras, pois alteram a composicao corrente da lista. Seguem,assim, os exemplos de implementacao.

Insercao no Final

No Exemplo 7.22, o novo elemento e a lista no qual ele sera inserido sao passados como argu-mentos. A passagem do cabecalho lista e feita por apontador, pois assim, qualquer modificacaoem seus elementos e feita diretamente na funcao, sem necessidade de passar toda lista por copiae retorna-la ao fim da execucao da funcao. O elemento sera incluıdo no fim da lista, mas dife-rentes implementacoes, nas quais ele e inserido no comeco, ou numa dada posicao, tambem saopossıveis.

Page 206: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

206 CAPITULO 7. APONTADORES

1 void incluirFimLista (tLista *lista , tInfo elem) {

2 tNo *no;

3

4 no = criaNo (elem);

5 if (vaziaLista (lista)) {

6 lista ->primeiro = no;

7 } else {

8 lista ->ultimo ->proximo = no;

9 }

10 lista ->ultimo = lista ->marcador = no;

11 lista ->tam ++;

12 }

Exemplo 7.22: Funcao de inclusao de um novo no na lista

Como pode ser visto no exemplo acima, inicialmente o novo no deve ser criado para armazenaro elemento a ser incluıdo. Para isso e utilizada a funcao inicializadora criaNo, que alocaum espaco de memoria do tamanho de tNo, faz a chave ser igual ao elemento passado comoargumento e retorna um apontador para o espaco alocado. A Figura 7.17 mostra o estado dalista, antes da inclusao, e o novo no a ser incluıdo.

Figura 7.17: Lista Antes da Inclusao

Agora que se ja se tem o novo no, e necessario incluı-lo na lista, ou seja, atualizar o valor detam e os apontadores. Como a lista tem mais um no, seu tamanho deve ser incrementado emuma unidade. Quanto a atualizacao dos apontadores, os apontadores ultimo e marcador devemapontar para o no incluıdo, respectivamente, porque ele e incluıdo no fim da lista e no ultimono acessado. Antes, porem, e importante verificar se a lista esta vazia, pois caso esteja, quemtambem vai apontar para no a ser incluıdo, sera o apontador primeiro da lista, caso contrario,sera apontador proximo do ultimo no da lista. Vale destacar que a analise se a lista esta vaziae um exemplo de uso da funcao vaziaLista , que foi explicada anteriormente.

A Figura 7.18 exibe a lista apos a inclusao do novo no.

Exclusao

Page 207: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.7. TAD IMPLEMENTACIONAL LISTA ENCADEADA TLISTA 207

Figura 7.18: Lista Apos a Inclusao

O Exemplo 7.23 mostra a implementacao de uma operacao de exclusao.

1 void excluirNoLista (tLista *lista , int pos) {

2 tNo *auxA , *auxB;

3 int i;

4

5 if (pos < 0 || pos >= lista ->tam)

6 return;

7

8 auxA = lista ->primeiro;

9 for (i=0;i<pos;i++) {

10 auxB = auxA;

11 auxA = auxA ->proximo;

12 }

13 if (auxA != lista ->primeiro) {

14 auxB ->proximo = auxA ->proximo;

15 if (auxA == lista ->ultimo) {

16 lista ->ultimo = auxB;

17 }

18 } else {

19 lista ->primeiro = auxA ->proximo;

20 if (lista ->ultimo == auxA) {

21 lista ->ultimo = auxA ->proximo;

22 }

23 }

24 lista ->marcador = NULL;

25 lista ->tam --;

26 free (auxA);

27 }

Exemplo 7.23: Funcao de exclusao de um no da lista

Page 208: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

208 CAPITULO 7. APONTADORES

Na funcao de exclusao, sao passadas como parametros a lista e a posicao do no a ser excluıdo.Assim, e importante saber, inicialmente, se o valor de pos e valido e, caso nao seja, a funcao eencerrada.

Sao criados dois apontadores auxiliares do tipo tNo: auxA e auxB. Para buscar o no daposicao pos, auxA aponta para o primeiro no da lista e inicia-se um laco for, ate que o valor dei, que inicialmente e zero, seja pos. A cada iteracao desse laco, auxB vai apontar para o ultimono apontado por auxA e este, por sua vez, aponta para o proximo no da lista. Portanto, quandoauxA estiver apontando para o no a ser excluıdo, o anterior a ele e apontado por auxB, o que eimportante na hora de se atualizarem os apontadores, conforme sera explicado.

Apos ter encontrado o no da posicao pos, tem que se analisar quatro situacoes possıveis: 1)esse no a ser excluıdo nao ser nem o primeiro e nem o ultimo no da lista; 2) ser o ultimo; 3) sero primeiro; 4) e ser o unico no. No caso 1, basta fazer o apontador proximo do no apontado porauxB apontar para o no apontado pelo proximo do no apontado por auxA. No caso 2, tambemse deve fazer o ultimo no da lista ser auxB. Vale lembrar que, no caso de auxA ser o ultimo,ao se fazer o proximo de auxB ser o proximo de auxA, esta se fazendo simplesmente auxB tercomo proximo o valor NULL. Ja no caso 3, coloca-se o proximo de auxA como o no inicial e,no caso 4, faz-se tambem o apontador ultimo da lista apontar para o proximo de auxA. Nesseultimo caso, esta se redirecionando os apontadores, primeiro e ultimo da lista, para NULL.

Agora que ja se tem os apontadores atualizados e retirado o no que sera excluıdo da sequenciade nos, coloca-se o marcador da lista como NULL, pois sera perdido o ultimo no acessado. Entao,diminui-se o tamanho da lista e, finalmente, libera-se o espaco de memoria apontado por auxA.A Figura 7.19 ilustra a lista da Figura 7.16 apos a exclusao do no 2.

Figura 7.19: Lista Apos a Exclusao do No 2

Operacoes Produtoras

As funcoes produtoras possibilitam extrair alguma informacao da lista. Dividem-se em duascategorias: as que permitem posicionar o marcador no no, cuja informacao sera extraıda, e asque realmente obtem a informacao. Serao mostradas inicialmente as operacoes que marcam aposicao de um elemento. Apresentam-se a que posiciona o marcador no primeiro no da lista e aque posiciona no proximo no do marcador atual. A fim de ilustrar a utilizacao destas funcoes,sera dado como exemplo o uso delas na funcao imprimir.

O Exemplo 7.24 e a implementacao da funcao que posiciona o marcador no primeiro no da

Page 209: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.7. TAD IMPLEMENTACIONAL LISTA ENCADEADA TLISTA 209

lista.

1 void primeiroLista (tLista *lista) {

2 lista ->marcador = lista ->primeiro;

3 }

Exemplo 7.24: Posicionado o marcador no comeco da lista

Para fazer o marcador de uma lista apontar para o primeiro elemento dela, basta igualaro marcador ao apontador primeiro. O objetivo da operacao primeiroLista e posicionar omarcador no inıcio da lista, para permitir que seja feita uma busca nos elementos da lista apartir do seu inıcio.

A operacao proximoLista e mostrada no Exemplo 7.25.

1 void proximoLista (tLista *lista) {

2 if (lista ->marcador != NULL) {

3 lista ->marcador = lista ->marcador ->proximo;

4 }

5 }

Exemplo 7.25: Posicionado o marcador no proximo no da lista

A funcao proximoLista e para posicionar o marcador, fazendo-o apontar para o seu proximoelemento da lista. A verificacao se o marcador atual e diferente de NULL evita o acesso indevidoa memoria.

O Exemplo 7.26 mostra a operacao responsavel por retornar a informacao do no apontadopelo marcador da lista.

1 tInfo obterInfo (tLista *lista , int *x) {

2 if (lista ->marcador == NULL) {

3 *x = 0;

4 }

5 *x = 1;

6 return lista ->marcador ->info;

7 }

Exemplo 7.26: Funcao para recuperar a informacao de um no

A funcao obterInfo tem por objetivo retornar o conteudo do no apontado pelo marcador.E gravado no endereco x se houve sucesso, ou nao, em se obter a informacao. Assim, impede-sede acessar um local indevido da memoria.

O Exemplo 7.27 ilustra o uso dessas informacoes por meio do uso de uma funcao que imprimetodos os dados de uma lista. Para a funcao e passada a lista cujos elementos serao impressos.Inicialmente primeiroLista e utilizada para posicionar o marcador no inıcio da lista e, emseguida, comeca um laco enquanto o final dela nao e alcancado, verificacao feita pela funcaofinalLista , conforme descrito anteriormente.

Page 210: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

210 CAPITULO 7. APONTADORES

1 void imprimirLista (tLista lista) {

2 tInfo x;

3 int erro = 0;

4

5 primeiroLista (& lista);

6 while (! finalLista (& lista)) {

7 x = obterInfo (&lista , &erro);

8 if (erro) {

9 printf ("Elemento: %d\n", x);

10 }

11 proximoLista (& lista);

12 }

13 }

Exemplo 7.27: Impressao de todos elementos de uma lista

Para cada posicao do marcador, obterInfo retorna o valor de info do no apontado pelomarcador da lista. Esse valor e impresso caso tenha ocorrido sucesso na obtencao da informacao,ou seja, a variavel erro ter o valor 1. O valor a ser impresso e inteiro, visto que x e do tipo tInfo(int, como declarado anteriormente). Por fim, proximoLista posiciona o marcador no proximono da lista e, somente quando este marcador for NULL, o laco enquanto sera encerrado.

Operacoes Destrutoras

Quando a lista nao e mais necessaria, e importante desalocar o espaco de memoria ocupado porseus nos. As funcoes responsaveis por desalocar a lista e seus elementos sao conhecidas comodestrutoras.

Finalizacao

A seguinte funcao para a finalizacao da lista e um exemplo de operacao destrutora. Repareque a desalocacao de memoria e feita no por no. Note que ao final da operacao, os valores dosatributos de lista sao modificados para apontarem para NULL para evitar que fiquem referenci-ando areas ja desalocadas.

1 void destroiLista (tLista *lista) {

2 tNo *aux;

3

4 primeiroLista (lista);

5 while (! finalLista (lista)) {

6 aux = lista ->marcador;

7 proximoLista (lista);

8 free (aux);

9 }

10 lista ->primeiro = NULL;

11 lista ->marcador = NULL;

Page 211: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.7. TAD IMPLEMENTACIONAL LISTA ENCADEADA TLISTA 211

12 lista ->ultimo = NULL;

13 lista ->tam = 0;

14 }

Exemplo 7.28: Desalocacao das areas de memoria ocupados pelos nos da lista

Semelhante a funcao de imprimir, primeiroLista e utilizada para posicionar o marcadorno inicio da lista e, em seguida, inicia-se um laco enquanto o final dela nao e alcancado.

A cada iteracao, um no auxiliar aux guarda o endereco de memoria apontado pelo marcadorda lista. Em seguida, posiciona-se o marcador no proximo no da lista e a regiao apontada poraux e liberada com o uso do free.

Quando se chega ao final da lista, o laco enquanto sera encerrado e os atributos de listas saoincializados, assim, seus apontadores apontam para NULL e o tamanho e zero.

7.7.4 Uso

A fim de ilustrar a utilizacao do TAD implementacional lista encadeada, sera utilizado umcadastro simples de alunos na universidade. Veja o Pseudocodigo 7.1.

Pseudocodigo 7.1 Uso de uma lista simplesmente encadeada.

Descricao: Programa de cadastro de alunos.Dados de Entrada: nomes e as respectivas matriculas.Saıda do Programa: lista impressa.

Inicializac~ao da lista;Leitura de um nome;Leitura da matricula;

Validac~ao da matriculaSe a matricula for menor ou igual a zero:

Parar de ler informac~oes. Ir para "Leitura da posic~ao";Se n~ao for menor que zero:

Continuar a ler informac~oes. Ir para "Leitura de um nome";Leitura da posic~ao

Validac~ao da Posic~aoSe a posic~ao for maior ou igual a zero:

Se a posic~ao contiver algum no:Excluir o no, imprimir a lista e voltar para "Leitura da posic~ao";

Se for menor que zero:Parar de ler informac~oes. Ir para "Destruic~ao da lista";

Destruic~ao da lista.

O Pseudocodigo 7.1 descreve os passos para o programa de cadastro simples, no qual apenaspode-se ler e armazenar algumas entradas. Apos a leitura, alguns dados podem ser excluıdos eas informacoes restantes serem impressas.

Page 212: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

212 CAPITULO 7. APONTADORES

No cadastro, havera apenas o nome e o numero de matrıcula do aluno, mas vale lembrar que,para um registro de informacoess mais detalhado, basta acrescentar mais atributos no exemplode estrutura tInfo do exemplo apresentado.

Observe o Exemplo 7.29, no qual se tem a transcricao do Pseudocodigo 7.1. Foram utilizadastodas as funcoes estudadas nesta secao, porem com algumas modificacoes, uma vez que o campoinfo, da estrutura do no, nao e mais um inteiro, e sim, uma outra estrutura. So estao mostradasas estruturas e as operacoes anteriores que sofreram modificacao.

1 typedef struct {

2 int matricula;

3 char nome [30];

4 } tInfo;

5

6 void imprimirLista (tLista lista) {

7 tInfo x;

8 int erro = 0;

9

10 primeiroLista (& lista);

11 while (! finalLista (& lista)) {

12 x = obterInfo (&lista , &erro);

13 if (erro) {

14 printf ("Aluno: %s\n", x.nome);

15 printf ("Matricula: %d\n\n", x.matricula);

16 }

17 proximoLista (& lista);

18 }

19 }

20

21 main ( ) {

22 tLista lista;

23 tInfo dados;

24 int pos;

25

26 iniciaLista (&lista);

27

28 do {

29 printf ("Entre com o nome do aluno: ");

30 scanf ("%s", &dados.nome);

31 printf ("Entre com a matricula do aluno: ");

32 scanf ("%d", &dados.matricula);

33 if (dados.matricula <= 0)

34 break;

35 incluirFimLista (&lista , dados);

36 } while (1);

37

38 imprimirLista (lista);

39

40 printf ("Digite a posic~ao do elemento a ser excluıdo: ");

41 scanf ("%d", &pos);

Page 213: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.8. EXERCICIOS RESOLVIDOS 213

42 while (pos >= 0) {

43 excluirNoLista (&lista , pos);

44 imprimirLista (lista);

45 scanf ("%d", &pos);

46 }

47

48 destroiLista (&lista);

49 }

Exemplo 7.29: Cadastro de alunos na universidade

O programa implementado no Exemplo 7.29 apenas le as informacoes do teclado enquantonao se digita um valor invalido, no caso matricula menor ou igual a 0. Se for digitado tal valorpara matricula o comando break faz a execucao do programa sair do laco infinito (a condicaoe sempre 1). Cada nome e matricula sao armazendos na lista e, apos o termino de leitura dedados, eles sao impressos na tela.

Em seguida, pode-se apagar as informacoes fornecendo a posicao na lista do dado a serapagado. A cada elemento excluıdo, a lista e atualizada e impressa e, quando for passadoum valor de posicao negativo, encerra-se o laco de exclusao. Por fim, antes de se encerrar oprograma, a lista e destruıda.

7.8 Exercıcios Resolvidos

Exercıcio Resolvido 7.1 - Acesso ao Conteudo de Variaveis por Apontadores

Para o trecho de codigo do Exemplo 7.30, ilustre os estados das variaveis apontadores enao-apontadores. Utilize para a ilustracao os padroes adotados na Figura 7.3 e Figura 7.4, pararepresentar uma variavel nao apontador e apontador respectivamente.

1 int *p;

2 int *q;

3 int a;

4 int b;

5 int c;

6

7 b = 10;

8 c = 15;

9 a = c;

10 p = &b;

11 q = &c;

12 *p = *q;

Exemplo 7.30: Codigo para o Exercıcio Resolvido 7.1

Page 214: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

214 CAPITULO 7. APONTADORES

Solucao Possıvel:Inicialmente sao criados dois apontadores para inteiro, p e q, e tres variaveis inteiras: a b e

c. Em seguida, b passa a armazenar o valor 10, enquanto c, 15. Ja a rebece o valor de c, ouseja, 15. Isso e ilustrado nas tres primeiras cenas da Figura 7.20.

Figura 7.20: Solucao do Exercıcio Resolvido 7.1

Por fim, p e q passam a apontar b e c, repectivamente. Assim, na ultima linha, o conteudoda variavel apontada por p recebe o valor de c, pois este e a variavel apontada por q, o que fazb receber o valor 15. Vejas os tres ultimos passos da Figura 7.20.

Exercıcio Resolvido 7.2 - Multiplo Retorno em uma Funcao

A funcao calculaPot , do Exemplo 7.31, calcula a potencia quadrada de um inteiro. Modi-fique esta funcao para que ela passe a retornar tambem a potencia cubica deste numero. Facaas devidas alteracoes na main.

1 int calculaPot (int valor){

2 int potQuadrada;

3 potQuadrada = valor * valor;

4 return potQuadrada;

Page 215: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.8. EXERCICIOS RESOLVIDOS 215

5 }

6

7 main ( ){

8 int x;

9 int quadrado;

10

11 scanf("%d", &x);

12 quadrado = calculaPot (x);

13 printf ("Quadrado de %d = %d\n", x, quadrado);

14 }

Exemplo 7.31: Funcao calculaPot

Solucao Possıvel:O dado de entrada do programa e um numero inteiro, e as saıdas devem ser as pontencias

quadrada e cubica deste numero, calculadas pela funcao apresentada no Exemplo 7.31, com suasdevidas alteracoes. O Pseudocodigo 7.2 exibe as etapas para a solucao.

Pseudocodigo 7.2 Calculo das potencias quadradas e cubicas de um numero inteiro.

Descricao: Programa que retorna as potencias quadrada e cubica de um numero inteiro, calculadas poruma funcao apenas.Dados de Entrada: um numero inteiro.Saıda do Programa: potencias quadrada e cubica do valor de entrada.

Leitura do numero inteiro;Passagem de parametros para a func~ao calculaPot;Calculo das potencias pela func~ao calculaPot.

Para atender a etapa Calculo das potencias pela funcao calculaPot , a funcao calcu-laPot deve ser alterada para tambem calcular e retornar o cubo do valor. Contudo, o retornodessa funcao ja e o quadrado do parametro de entrada. Nesse sentido, a passagem por apon-tadores e a ferramenta para multiplos retornos numa funcao, o que torna importante o passoPassagem de parametros para a funcao calculaPot

As modificacoes no Exemplo 7.31 podem ser observadas no Exemplo 7.32.

1 int calculaPot (int valor , int *potCubica){

2 int potQuadrada;

3 potQuadrada = valor * valor;

4 *potCubica = valor * valor * valor;

5 return potQuadrada;

6 }

7

8 main ( ){

9 int x;

10 int quadrado;

11 int cubo;

12

Page 216: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

216 CAPITULO 7. APONTADORES

13 scanf("%d", &x);

14 quadrado = calculaPot (x, &cubo);

15 printf ("Quadrado de %d = %d\nCubo de %d = %d\n", x, quadrado , x, cubo);

16 }

Exemplo 7.32: Multiplo retorno em calculaPot

Como pode ser observado, calculaPot passa a ter um parametro que ira receber o enderecoda variavel cubo, declarada na main. Dessa forma, ao termino da execucao de calculaPot ,cubo ira conter a potencia cubica do valor.

Exercıcio Resolvido 7.3 - Insercao no Inıcio de Lista Simplesmente Encadeada

Foi visto anteriormente como inserir um elemento no final da lista. Agora, pretende-se criaruma funcao que insere no comeco de uma lista simplesmente encadeada.

Solucao Possıvel:Para inserir um novo no, no comeco da lista, os passos que devem ser seguidos pela funcao

aparecem no Pseudocodigo 7.3, onde tambem pode-se observar os dados de entrada e o retornoda funcao.

Pseudocodigo 7.3 Insercao no comeco de uma lista simplesmente encadeada.

Descricao: Funcao que insere um no no comeco de uma lista simplesmente encadeada.Dados de Entrada: a lista e o elemento a ser enserido.Saıda da Funcao: a lista apos a insercao.

Criac~ao de um no para armazenar o novo elemento;Verificar se a lista esta vazia

Se estiver vazia:O novo no tambem passa a ser o ultimo da lista;

Se n~ao estiver vazia:Faz o novo no ter como seu proximo o antigo primeiro;

O primeiro da lista passa a ser o no criado;Posicionar o marcador no no incluıdo;Incrementar o tamanho da lista.

O Exemplo 7.33 mostra a implementacao em C. Para tal funcao, a passagem da lista serafeita por apontador, pois assim, qualquer modificacao em seus elementos sera feita diretamentena funcao e, por conseguinte, o retorno e void. A lista poderia ser passada por copia, mas alista modificada teria estar apos um comando return.

1 void incluirInicioLista (tLista *lista , tInfo elem) {

Page 217: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.8. EXERCICIOS RESOLVIDOS 217

2 tNo *no;

3

4 no = criaNo (elem);

5 if (vaziaLista (lista)) {

6 lista ->ultimo = no;

7 } else {

8 no ->proximo = lista ->primeiro;

9 }

10 lista ->primeiro = lista ->marcador = no;

11 lista ->tam ++;

12 }

Exemplo 7.33: Funcao de inclusao de um novo no no comeco da lista

No Exemplo 7.33, um novo no e criado com a utilizacao de criaNo. Ao incluı-lo no inicıo, osapontadores primeiro e marcador devem apontar para o no ser incluıdo, respectivamente porqueele e incluıdo no comeco da lista e no ultimo no acessado.

Contudo, antes de atualizar o apontador primeiro, e fundamental verificar se a lista estavazia, pois caso nao esteja, o novo no deve guardar, como seu proximo, o antigo primeiro dalista. Ja se a lista estiver vazia, basta fazer o apontador ultimo tambem apontar para o novono. Por fim, o tamanho da lista deve ser incrementado em uma unidade.

A figura 7.21 mostra a Figura 7.17, apos a inclusao do novo no no comeco da lista.

Figura 7.21: Lista da Figura 7.17, Apos a Inclusao do No no Comeco

Exercıcio Resolvido 7.4 - Ordenacao de uma Lista Simplesmente Encadeada

Para ilustrar a odenacao de uma lista, considere que ela e formada por nos cuja informacaoarmazenada seja um nome e uma idade. Ulizando as estruturas e funcoes ja apresentadas, alemde novas funcoes, crie um programa que le as informacoes do teclado ate que uma idade invalidaseja digitada (menor que zero). O programa deve imprimir a lista ordenada crescentemente por

Page 218: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

218 CAPITULO 7. APONTADORES

idade, apos a leitura das informacoes.

Solucao Possıvel:De forma geral, o programa deve seguir o Pseudocodigo 7.4.

Pseudocodigo 7.4 Ordenacao de uma lista simplesmente encadeada.

Descricao: Programa que ordena um grupo de pessoas por idade.Dados de Entrada: nomes e as respectivas idades.Saıda do Programa: lista de nomes ordenados crescentemente por idade.

Inicializac~ao da lista;Leitura de um nome;Leitura da idade;Validac~ao da idade

Se a idade for menor que zero:Parar de ler informac~oes. Ir para "Ordenac~ao da Lista";

Se n~ao for menor que zero:Continuar a ler informac~oes. Ir para "Leitura de um nome";

Ordenac~ao da lista;Impress~ao da lista ordenada;Destruic~ao da lista.

O passo Ordenacao da lista pode ser decomposto como segue no Pseudocodico 7.5. Aideia consiste em posicionar o marcador no comeco da lista e, enquanto o final desta nao eatingido, buscar o menor elemento a frente do atual marcador. Se encontrar algum, deve-setrocar as informacoes entre o no marcador e o que guarda a menor idade a frente.

Pseudocodigo 7.5 Processo para a ordenacao de uma lista simplesmente encadeada.

Processo componente "Ordenac~ao da lista":Posicionar o marcador no comeco da lista;Enquanto n~ao chegar no fim da lista:

Buscar o no que guarda uma idade menor que a do marcador;Se existir um no com menor idade:

Trocar as informac~oes entre o marcador e o no encontrado;Posicionar o marcador no proximo no da sequencia da lista;

FIM-Processo componente "Ordenac~ao da lista".

Page 219: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.8. EXERCICIOS RESOLVIDOS 219

No Exemplo 7.34, tem-se a trascricao dos Pseudocodigos 7.4 e 7.5 para C.

1 typedef struct {

2 char nome [30];

3 int idade;

4 } tInfo;

5

6 void imprimirLista (tLista lista) {

7 tInfo x;

8 int erro = 0;

9

10 primeiroLista (& lista);

11 while (! finalLista (& lista)) {

12 x = obterInfo (&lista , &erro);

13 if (erro) {

14 printf ("Nome: %s\n", x.nome);

15 printf ("Idade: %d\n\n", x.idade);

16 }

17 proximoLista (& lista);

18 }

19 }

20

21 tNo *menorIdade (tLista lista) {

22 tNo *aux , *menor;

23

24 menor = lista.marcador;

25 aux = menor ->proximo;

26 while (aux != NULL) {

27 if (aux ->info.idade < menor ->info.idade)

28 menor = aux;

29 aux = aux ->proximo;

30 }

31 return menor;

32 }

33

34 void ordenaPorIdade (tLista *lista) {

35 tNo *aux;

36 tInfo x;

37

38 primeiroLista (lista);

39 while (! finalLista (lista)) {

40 aux = menorIdade (* lista);

41 if (lista ->marcador != aux) {

42 x = lista ->marcador ->info;

43 lista ->marcador ->info = aux ->info;

44 aux ->info = x;

45 }

46 proximoLista (lista);

47 }

48 }

49

Page 220: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

220 CAPITULO 7. APONTADORES

50 main ( ) {

51 tLista lista;

52 tInfo dados;

53 int pos;

54

55 iniciaLista (&lista);

56 do {

57 printf ("Entre com o nome: ");

58 scanf ("%s", &dados.nome);

59 printf ("Entre com a idade: ");

60 scanf ("%d", &dados.idade);

61 if (dados.idade < 0)

62 break;

63 incluirFimLista (&lista , dados);

64 } while (1);

65 ordenaPorIdade (&lista);

66 imprimirLista (lista);

67 destroiLista (&lista);

68 }

Exemplo 7.34: Cadastro de nomes e idades

Novamente, o programa implementado apenas le as informacoes do teclado enquanto nao sedigita uma idade invalida (nesse cado, menor que 0). Se for digitado tal valor para a idade, ocomando break faz a execucao do programa sair do laco infinito.

Cada nome e idade sao armazendos na lista e, apos o termino de leitura de dados, eles saoordenados por ordem crescente de idade. Na funcao ordenaPorIdade , posiciona-se o marcadorno comeco da lista e, enquanto o final desta nao e atingido, busca-se o menor elemento a frentedo atual marcador. Caso seja encontrado algum, trocam-se as informacoes dos nos marcador eaux, o qual guarda o no com menor idade obtido da funcao menorIdade .

A funcao menorIdade procura e retorna um no que guarda uma idade menor do que a queesta no marcador, e que se encontra a frente deste na lista. Assim, a variavel menor guarda o noque contem a menor idade e e inicializado como sendo o atual marcador. A partir do proximo noapos ao atual marcador, enquanto o final da lista nao e atingido, busca-se um no que contenhauma idade menor do a que esta armazenada em menor. Se for encontrada alguma, menor passaa apontar para o no que contem esta menor idade. Repare que e utilizada uma variavel auxpara percorrer a lista, pois nao se pretende alterar a posicao do marcador, o qual e utilizado nafuncao ordenaPorIdade .

No fim da execucao do programa, a lista ordena e impressa e, antes de se encerrar o programa,ela e destruıda.

Exercıcio Resolvido 7.5 - Media de valores de uma Lista Simplesmente Encadeada

Considere uma lista de funcionarios de uma empresa na qual sao armazenados o nome e osalario destes. Pretende-se imprimir na tela todos os funcionarios cujos salarios estao acima da

Page 221: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.8. EXERCICIOS RESOLVIDOS 221

media.

Solucao Possıvel:O programa principal segue os passos descritos no Pseudocodigo 7.6.

Pseudocodigo 7.6 Media dos valores de uma lista simplesmente encadeada.

Descricao: Programa que imprime os funcionarios cujos salarios estao acima da media.Dados de Entrada: nomes e os respectivos salarios.Saıda do Programa: lista de nomes que tem o salario acima da media.

Inicializac~ao da lista;Leitura de um nome;Leitura da idade;Validac~ao da idade

Se a idade for menor que zero:Parar de ler informac~oes. Ir para "Verificar quem esta acima da media";

Se n~ao for menor que zero:Continuar a ler informac~oes. Ir para "Leitura de um nome";

Verificar quem esta acima da media;Destruic~ao da lista.

O passo Verificar quem esta acima da media pode ser descrito como o Pseudocodigo7.7. Para achar a media, basta somar todos os salarios e dividir pelo total de nos. Tendo amedia, procura-se, no por no, quem tem o salario maior que ela.

Pseudocodigo 7.7 Processo para ver quem esta com salario acima da media

Processo componente "Verificar quem esta acima da media":Posicionar o marcador no comeco da lista;Enquanto n~ao chegar no fim da lista:

Somar os salarios;Posicionar o marcador no proximo no da sequencia da lista;

Achar a media (Divide-se o total somado pelo tamanho da lista);Posicionar o marcador no comeco da lista;Enquanto n~ao chegar no fim da lista:

Se existir um no com salario maior que a media:Imprimir as informac~oes do funcionario.

Posicionar o marcador no proximo no da sequencia da lista;FIM-Processo componente "Verificar quem esta acima da media".

Page 222: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

222 CAPITULO 7. APONTADORES

No Exemplo 7.35, o programa implementado contem uma main semelhante a do Exemplo7.34. A diferenca e que agora e fornecido o salario em vez da idade. Alem disso, no lugar daordena , e chamada a funcao que procura e imprime os funcionarios com salario acima da media.

1 typedef struct {

2 char nome [30];

3 float salario;

4 } tInfo;

5

6 void imprimirLista (tLista lista) {

7 tInfo x;

8 int erro = 0;

9

10 primeiroLista (& lista);

11 while (! finalLista (& lista)) {

12 x = obterInfo (&lista , &erro);

13 if (erro) {

14 printf ("Nome: %s\n", x.nome);

15 printf ("Salario: %f\n\n", x.salario);

16 }

17 proximoLista (& lista);

18 }

19 }

20

21 void acimaMedia (tLista lista) {

22 tInfo x;

23 int erro = 0;

24 float total , media;

25

26 total = 0;

27 primeiroLista (& lista);

28 while (! finalLista (& lista)) {

29 x = obterInfo (&lista , &erro);

30 if (erro)

31 total += x.salario;

32 proximoLista (& lista);

33 }

34

35 media = total/lista.tam;

36

37 primeiroLista (& lista);

38 while (! finalLista (& lista)) {

39 x = obterInfo (&lista , &erro);

40 if (erro) {

41 if (x.salario > media) {

42 printf ("Nome: %s\n", x.nome);

43 printf ("Salario: %f\n\n", x.salario);

44 }

45 }

46 proximoLista (& lista);

Page 223: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.9. RESUMO 223

47 }

48 }

49

50 main ( ) {

51 tLista lista;

52 tInfo dados;

53 int pos;

54

55 iniciaLista (&lista);

56 do {

57 printf ("Entre com o nome: ");

58 scanf ("%s", &dados.nome);

59 printf ("Entre com o salario: ");

60 scanf ("%f", &dados.salario);

61 if (dados.salario < 0)

62 break;

63 incluirFimLista (&lista , dados);

64 } while (1);

65 acimaMedia (lista);

66 destroiLista (&lista);

67 }

Exemplo 7.35: Cadastro de nomes e salarios

Na funcao acimaMedia , total e inicializado como 0 e, a partir do primeiro elemento dalista, esse total e incrementado com o salario de cada no. Quando o final da lista e alcancado,a media de salarios e computada como sendo o total obtido dividido pelo tamanho da lista, ouseja, o numero de funcionarios.

Com a media calculada, inicia-se um nova busca na lista, desde o primeiro elemento ate ofinal da lista, a fim de que se encontre os salarios acima da media. Caso algum no contenha umsalario maior que a media, os dados do funcionario sao impressos na tela.

7.9 Resumo

• Apontadores sao um tipo de variavel que guarda o endereco de outras variaveis. Trata-sede um conceito de baixo nıvel, ligado essencialmente a arquitetura de computadores.

• Em C, a declaracao de uma variavel apontador segue o formato:

<tipo do apontador> * <nome da variavel>

No lugar de tipo do apontador, podem ser utilizados os tipos padroess da linguagem C,assim como os tipos definidos pelo programador.

• O operador & retorna o endereco de memoria de uma variavel. Ja o operador seta (− >)e utilizado para acessar, por meio de apontadores, os atributos de uma estrutura.

Page 224: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

224 CAPITULO 7. APONTADORES

• Os apontadores podem alterar o conteudo da variavel apontado por ele. Por meio deapontadores tambem e possıvel a passagem de parametros sem copia. A passagem deparametros por apontadores permite multiplos retornos em uma funcao, evita a copia demuitos dados e possibilita a alteracao das variaveis do programa no decorrer da execucaoda funcao.

• Dentre os principais problemas com o uso de apontadores estao: apontadores nao iniciali-zados, objetos pendentes, referencias pendentes e programacao macarronica.

• A alocacao dinamica e uma forma de reservar espacos de memoria no decorrer da execucaodo programa, o que evita o despercıcio de recursos da maquina. Em C, as funcoes malloce free sao responsaveis por alocar e desalocar areas de memoria, respectivamente.

• O TAD Implementacional Lista Encadeada e uma forma eficiente de armazenar dados numprograma, pois aloca-se e desaloca-se os espacos para os dados dinamicamente, o que tornamuito simples as operacoes de incluir e excluir elementos.

7.10 Lista de Exercıcios

1. Cite tres vantagens e tres desvantagens de se utilizar apontadores.

2. Explique quais as funcionalidades dos operadores * e &.

3. Liste as diferencas entre variaveis apontadores e nao apontadores. Faca um codigo emC, que realize a soma de duas variaveis float a e b, usando dois apontadores g e h, queapontem para a e b respectivamente. Quais sao os tipos dos apontadores g e h?

4. No Exemplo 7.36, escrito na linguagem C, encontre os erros de sintaxe na utilizacao deapontadores. Justifique cada erro encontrado.

1 main ( ){

2 int p;

3 int *d;

4 int q = 10;

5 float *j;

6 float t = 15.0;

7 j = &t;

8 p = &q;

9 d = j;

10 }

Exemplo 7.36: Exercıcio Proposto 4

Page 225: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.10. LISTA DE EXERCICIOS 225

5. No Exemplo 7.37, escrito na linguagem C, encontre os problemas causados pela utilizacaoindevida de apontadores. Justifique cada problema encontrado.

1 main ( ){

2 int *p = (int*) malloc(sizeof(int));

3 int *q = (int*) malloc(sizeof(int));

4 int *j;

5 int *h;

6 int *v;

7 int d = 20;

8 int e = 30;

9 *q = e;

10 *j = d;

11 p = &d;

12 h = &e;

13 v = q;

14 free(q);

15 }

Exemplo 7.37: Exercıcio Proposto 5

6. Ilustre as atribuicoes e referenciamentos feitos no trecho de codigo do Exemplo 7.6. Utilizepara a ilustracao os padroes adotados na Figura 7.3 e Figura 7.4, para representar umavariavel nao apontador e apontador respectivamente.

7. Implemente na linguagem C, uma matriz de strings alocada estaticamente e uma alocadadinamicamente. Explique um caso em que a alocacao dinamica seja importante paraeconomia de memoria.

8. Explique o que e alocacao e desalocacao de memoria em tempo de execucao e quais funcoesem C executam essas funcionalidades. Cite uma vantagem de se desalocar memoria naomais utilizada.

9. Crie uma funcao que insere um novo elemento na lista numa dada posicao. Considere queos argumentos da funcao sao:

- Um apontador para a lista no qual o elemento sera inserido.- Um elemento de um tipo tInfo previamente definido.- Um inteiro que indica a posicao na qual ocorrera a insercao.

Sugestao: verifique se a posicao fornecida a funcao e valida.

10. Considere duas listas simplesmente encadeadas ”A”e ”B”, contendo inteiros ordenadoscrescentemente. Assim, pede-se implementar uma funcao que retorne uma lista encade-ada ordenada formada pela intercalacao dos elementos de ”A”e ”B”, considerando que a

Page 226: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

226 CAPITULO 7. APONTADORES

lista resultante nao possua chaves repetidas e que ”A”e ”B”tambem nao possuem chavesrepetidas.

11. Numa lista duplamente encadeada, os nos possuem um apontador para o no anterior aele na lista, alem do ja apresentado apontador para o proximo. Com base nisso, imple-mente todas as funcaoes e estruturas discutidas no capıtulo na forma de lista duplamenteencadeada.

12. Pilhas sao um cso particular da lista simplesmente encadeada, no qual insere-se e retira-seum elemento apenas do fim, uma polıtica conhecida como LIFO (last in first out). Sejaentao P=( a(1), a(2), ..., a(n) ) uma pilha. Assim, a(1) e o elemento da base da pilha;a(n) e o elemento topo da pilha; e a(i+1) esta acima de a(i). As operacoes associadas sao:

- criar (P) - criar uma pilha P vazia.

- push (P, x) - inserir o elemento x no topo de P (empilha).

- vazia (P) - verifica se P esta vazia.

- topo (P) - acessa o elemento do topo da pilha, sem desempilhar.

- pop (P) - elimina o elemento do topo de P (desempilha).

Com base nessas informacoes, implemente uma pilha de dados ”pilha de inteiros”em C,utilizando as estruturas e funcoes apresentadas sobre lista simplemente encadeada.

13. Duas pilha sequenciais numericas estao ordenadas crecentemente a partir do topo. Trans-fira os elementos dessas pilhas para uma terceira pilha, inicialmente vazia, de modo que elafique ordenada decrescentemente (maior valor no topo). Suponha que nao haja restricoesquanto a capacidade das pilhas.

14. O problema do abre/fecha parenteses. Este problema consiste em verificar se uma ex-pressao matematica esta corretamente formada em termos de abre/fecha parenteses.

Exemplos:

7-((X*((X+Y)/(J-3))+Y)/(4-2.5))

((A+B)

) A + B ( - C

(A + B)) - (C + D

Numa expressao correta o numero de ”)”deve ser igual ao numero de ”(”. Cada ”)”deveser precedido por um ”(”. Para isto, pode utilizar-se de um contador inicialmente igual azero que, ao percorrer a expressao da direita para a esquerda, e decrementado quando seencontra um ”(”e incrementado quando se encontra um ”)”. Assim, o contador no finalda expressao deve ser igual a zero e, em nenhum momento, o ele deve ser menor que zero.

Page 227: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.10. LISTA DE EXERCICIOS 227

Entao, implemente um programa C que leia uma expressao com parenteses e verifiquese ela esta corretamente formada em termos de abre/fecha parenteses usando o metodoacima, utilizando as estruturas e funcoes de pilha criadas nos exercıcios anteriores, masmodificadas para receber caracteres.

15. Outro caso particular da lista simplesmente encadeada e a fila. Agora, a insercao e feitaapenas no fim da lista e a remocao no inıcio. Seja entao F=( a(1), a(2), ..., a(n) ) umafila. Dessa forma, a(1) e o comeco da fila; a(n) e o final da pilha; e a(i+1) esta atras dea(i). As operacoes associadas sao:

- criar (F) - criar uma fila F vazia.

- insere (F, x) - inserir o elemento x no final de F.

- vazia (F) - verifica se F esta vazia.

- inicio (F) - acessa o elemento do inıcio da fila, sem retira-lo.

- retira (F) - elimina o elemento do final de F.

Com base nessas informacoes, implemente uma fila de dados ”fila de nomes”em C, utili-zando as estruturas e funcoes apresentadas sobre lista simplemente encadeada.

16. Duas filas sequenciais de nomes estao ordenadas crecentemente a partir do inıcio. Transfiraos elementos que ocorrem nessas duas filas para uma terceira fila, inicialmente vazia, demodo que ela tambem fique ordenada crescentemente, ou seja, o primeiro nome em ordemalfabetica no comeco da fila.

17. Uma palavra e um palındromo se tem a mesma sequencia de letras, quer seja lida daesquerda para a direita ou da direita para a esquerda (exemplo: raiar). Implemente umasolucao para verificar se uma palavra e um palındromo, usando pilha(s) e/ou fila(s).

18. Suponha uma fila de inteiros F. Mude a posicao de um elemento desta fila, tendo apenasuma pilha vazia P e uma variavel do tipo inteiro x como auxiliares. Considere apenas asoperacoes associadas aos tipos fila e pilha.

19. Implemente uma lista encadeada que armazene as informacoes sobre os DVDs de umalocadoras. Tais informacoes sao tıtulo do filme, nome do diretor, principais atores e numerode copias disponıveis na locadora. Apresente um menu e crie funcoes que atendam asseguintes opcoes:

- Dado um tıtulo de filme, verificar se locadora possui em seu acervo.

- Dado um tıtulo de filme, verificar se ha alguma copia disponıvel.

- Dado um diretor, imprimir as informacoes sobre os filmes dirigido por ele.

Page 228: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

228 CAPITULO 7. APONTADORES

- Dado um ator, imprimir as informacoes sobre os filmes nos quais ele foi um dos atoresprincipais.

20. Sabe-se que um texto e uma sequencia de caracteres contendo apenas letras, espacos embranco e sinais de pontuacao. Uma palavra e definida como um segmento do texto queconsiste apenas de letras. Escreva uma funcao que recebe um texto do teclado e imprimeuma relacao de todas as palavras que ocorrem no texto juntamente com o numero deocorrencias de cada palavra.

7.11 Trabalhos Sugeridos

1. Notas de Alunos

O Colegiado de Engenharia de Computacao mantem uma listagem com informacoes sobreo desempenho de cada aluno do curso. Esta listagem contem as notas obtidas pelo alunoem cada uma das disciplinas que ele cursou e e organizada da seguinte maneira:

Matrıcula do Aluno Codigo da Disciplina Carga Horaria Nota00018 0001 60 4.511111 3232 30 8.700234 0500 75 9.000018 0001 60 7.0... ... ... ...09999 0786 60 7.5

Para facilitar a consulta a esta listagem, o coordenador do colegiado precisa de um pro-grama em C que realize algumas operacoes sobre os dados da lista. Ele te pediu para quevoce elabore um programa interativo que permita ao usuario:

(a) Ler os dados da listagem e coloca-los em quatro listas. O usuario deve poder incluirtantos dados quanto quiser. A indicacao de fim de entrada de dados e feita atravesde um aluno de Matrıcula 0 (zero).

(b) Mostrar as notas de um aluno numa disciplina. Lembre-se que o aluno pode tercursado mais de uma vez uma mesma disciplina por motivo de reprovacao.

(c) Incluir uma nota de um aluno em uma disciplina.

(d) Retificar uma nota de um aluno em uma disciplina.

(e) Excluir uma nota de um aluno em uma disciplina.

(f) Excluir todos os dados de um aluno jubilado.

(g) Calcular o o coeficiente de rendimento (C.R.) de um aluno. Lembre-se que o C.R. ecalculado da seguinte maneira:

Page 229: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.11. TRABALHOS SUGERIDOS 229

C.R. = (Σ (Carga Horaria x Nota)) / (Σ (Carga Horaria))

(h) Identificar o aluno de melhor CR.

(i) Identificar os alunos com CR abaixo de 5.0.

(j) Identificar se um determinado aluno ja cumpriu a carga horaria mınima do curso(defina um valor).

Exemplo de Programa

Escolha Operacao:0 - Sair1 - Ler dados2 - Mostrar Notas3 - Incluir Nota4 - Corrigir Nota5 - Excluir Nota6 - Excluir Aluno7 - CR de Aluno8 - Melhor Aluno9 - Maus Alunos10 - Formando

Opcao: 1Dados do aluno: 18 1 60 4.5Dados do aluno: 1111 3232 30 8.7Dados do aluno: 234 500 75 9.0Dados do aluno: 18 1 60 7.0... ... ...Dados do aluno: 0 0 0 0.0

Opcao: 2Matrıcula: 18Disciplina: 1Notas: 4.5 7.0

Opcao: 3Matrıcula: 1111 Disciplina: 316Carga Horaria: 60Nota: 7.0

Page 230: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

230 CAPITULO 7. APONTADORES

Opcao: 4Matrıcula: 1111 Disciplina: 316Carga Horaria: 60Nota: 7.0Nova Nota: 8.5

Opcao: 5Matrıcula: 1111 Disciplina: 316Nota: 7.0

Opcao: 6Matrıcula: 234

Opcao: 7Matrıcula: 1111CR: 7.2

Opcao: 8Matrıcula: 234

Opcao: 9Matrıculas: 194

Opcao: 10Matrıcula: 1111Nao cumpriu carga horaria mınima.

... ... ...

Opcao: 0Ate a proxima!

2. Controlador de Trafego Aereo

Descricao

Controle de Trafego Aereo e um servico prestado por controladores, em terra, que guiamaeronaves (geralmente avioes) no ar e no solo, para garantir um fluxo de trafego seguro e

Page 231: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.11. TRABALHOS SUGERIDOS 231

ordenado. Os controladores de trafego aereo forencem indicacoes e autorizacoes de voo,de acordo com as caracterısticas operacionais das aeronaves e as condicoes de trafego emdeterminado momento. Estas autrorizacoes podem incidir sobre a rota, altitude e/ou ve-locidade propostas pelo operador da aeronave para determinado voo, devendo os pilotoscumprirem as instrucoes recebidas.

Espaco Aereo

Em muitos paıses, os servicos de trafego aereo sao prestados em toda a extensao do espacoaereo e estes servicos sao utilizados por todos os usuarios (aeronaves privadas, militares ecomerciais). Os espacos aereos onde o controlador e responsavel por prover separacao entreas aeronaves sao chamados de espaco aereo controlado em oposicao ao espaco aereoespaco aereo nao controlado no qual pilotos das aeronaves sao responsaveis por mantera separacao entre a sua aeronave e outras. Dependendo do tipo de voo e de classe do espacoaereo, o controlador de trafego aereo pode emitir instrucoes que os pilotos devem seguirou apenas informacoes de voo para ajudar os pilotos operando no espaco aereo. Em todosos casos, entretanto, o piloto tem a responsabilidade final pela seguranca da aeronave, epode nao cumprir as intrucoes numa emergencia.

Os servicos de controloe de trafego aereo incluem o controle de rotas das aeronaves queestao no espaco aereo do aeroporto, o controle da autorizacao de pousos e decolagens e ocontrole das pistas de taxi-aereo e patios.

O Trabalho

O trabalho consiste em implementar um programa que faca o controle dos pousos em umaeroporto que apresente tres portoes de embarque e desembarque (A,B,C). O trabalho deveser feito em dois modulos: controle de espacos aereos e controle de pista, e a estruturapara armazenamento dos dados deve ser uma lista encadeada dinamica.

• Controle de espaco aereo

Como o controle da torre consiste em controlar as aeronaves enquanto elas estiveremno espaco aereo do aeroporto, pode-se dividir essa tarefa em duas subtarefas:

Controle de rotas

A partir do momento em que as aeronaves entram no espaco aereo do aeroporto, ocontrole das suas rotas devera ser realizado pelo seu programa. Para isso considereque a funcao basica do seu programa e impedir que ocorram colisoes, e para isso umadas aeronaves em risco devera ser redirecionada para a rota mais proxima a uma das

Page 232: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

232 CAPITULO 7. APONTADORES

rotas envolvidas. Existem duas ocoasioes em que ocorrerao colisoes: se duas aero-naves estiverem utilizando a mesma rota ou se duas aeronaves estiverem utilizandorotas que apresentem interseccao. Considere que duas rotas apresentam interseccaose uma delas e multipla da outra.

Controle de aproximacao

Dado que o controle de rotas ja foi realizado sera necessario definir qual sera a ordemdas aeronaves a pousar. Para isso devera ser considerada a sequencia de prioridadesabaixo:

CLASSE > ALTITUDE > VELOCIDADE

Assim, define-se que existem apenas duas classes (militar e comercial) e que duasalttudes sao consideradas iguais se a diferenca entre elas for menor que 2000 pes.Alem disso, a classe militar tem prioridade frente a classe comercial; quanto menora altitude de uma aeronave maior sera a sua prioridade e quanto maior a velocidadede uma aeronave maior sera a sua prioridade. Considere que cada operacao de pousodura 5 minutos.

• Controle de pistaApos o pouso de uma aeronave e necessario que o trafego em solo tambem sejacontrolado. Com isso, a segunda parte do consistira em controlar o momento emque cada aeronave devera encostar em uma plataforma que esta livre. Caso todasas tres plataformas estejam ocupadas no momento em que uma aeronave pouse, estadevera esperar no patio de espera ate que alguma das plataformas seja desocupada.Considere que cada operacao de desembarque dure 30 minutos.

Especificacao

Modulo 1

Essa primeira parte do trabalho consiste em determinar a fila de aeronaves que ira pusar eas novas rotas das aeronaves que precisam mudar de rota. Para isso, considere que quandoduas aeronaves apresentem chance de colisao a aeronave que apresentar numero de rotamaior devera ser redirecionada para uma rota com numero igual ao primeiro numero primomaior que a rota de maior numero.

Modulo 2

Page 233: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

7.11. TRABALHOS SUGERIDOS 233

A segunda parte consiste em determinar a que horas a operacao de desembarque de cadaaeronave foi realizada.

Entrada

As informacoes referente as aeronaves serao fornecidas atraves do teclado. As informacoesserao as seguites: identificacao da aeronave (0103, 0407, 1114,...); numero inteiro que ser-vira para indentificar qual rota que a aeronave esta percorrendo (1, 2, 4, 6,...); classe daaeronave (”comercial”ou ”militar”); altitude na qual a aeronave se encontra no momentoem que entra no espaco aereo do aeroporto (7700, 9060, 1120, ...); velocidade com quala aeronave esta (650, 680, 810, ...) e a hora de entrada da aeronave no espaco aereo doaeroporto (14:30, 14:29, 14:31, ...). Considere que a hora apresentara o caracter ”:”paraseparar hora de minuto.

Obs.: As horas de entrada no espaco aereo do aeroporto sao muito proximas,com diferenca entre o menor e o maior horario de no maximo 5 minutos. Cadanova aeronave deve ser adicionada na lista ja na ordem de prioridade de pouso,do mais para o menos prioritario. Assim, apos todas as insercoes, as colisoesdeve ser verificadas, aeronave por aeronave, na sequencia de pouso obtida.

Exemplo:01032militar710067014:30

030710comercial820077014:29

020013militar100071014:30

Page 234: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

234 CAPITULO 7. APONTADORES

070810comercial860064014:29

11024militar910070014:30

Saıda

Os dados de saıda do programa devem ser exibidos no console. O formato da saıda deveseguir o exemplo abaixo.

Exemplo:02001315:00

0103215:05

11021715:10

03071915:30

07082315:35

Page 235: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

Capıtulo 8

ArquivosAutores:

Estefhan Dazzi WandekokemFlavio Varejao

Objetivos:

• Definir e apresentar arquivos;

• Definir e diferenciar variaveis transientes e variaveis persistentes;

• Definir e diferenciar arquivos de texto e arquivos binarios;

• Mostrar algumas operacoes que podem ser feitas com arquivos;

• Mostrar outras funcoes e exemplos de programas que usam arquivos;

8.1 Variaveis Transientes X Variaveis Persistentes

Quando os programas sao executados, eles lidam com variaveis. Elas sao a forma abstratapela qual os programadores enxergam os dados que seus programas manipulam. Internamente,variaveis indicam celulas de memoria. Por exemplo, numa arquitetura de 32 bits (que pode serum Pentium da Intel), normalmente o tipo inteiro de C correspondera a 32 bits, o que podesignificar que uma variavel int dessa linguagem ocupara 4 bytes (4 celulas de memoria).

A memoria principal de um computador (muitas vezes chamada de memoria RAM) e o localonde os programas em execucao, e tambem as variaveis que eles utilizam, sao armazenados.Chamam-se essas variaveis armazenadas na memoria principal de variaveis transientes porqueseu tempo de existencia e limitado pelo tempo que o programa se encontra em memoria. Assimque o usuario ou o Sistema Operacional decidir que o programa deve ser finalizado, todas essasvariaveis deixarao de existir.

Os computadores teriam sua utilidade muito reduzida se a informacao so pudesse ser arma-zenada enquanto os programas estivessem na memoria principal (e a maquina, ligada). Para

235

Page 236: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

236 CAPITULO 8. ARQUIVOS

resolver esse problema, existem as variaveis persistentes, as quais tem seu conteudo armazenado,e possıvel de ser acessado, independentemente do programa que as criou estar na memoria princi-pal. Variaveis persistentes devem ser armazenadas em algum dispositivo de memoria secundaria,como discos rıgidos, CD’s, memoria flash e DVD’s, os quais tem a capacidade de manter porum longo tempo o valor da informacao neles contida, independente do conteudo da memoriaprincipal do computador, ou mesmo de ele estar ligado. Deve-se ressaltar que o tempo de acessoe de gravacao das variaveis armazenadas em meio secundario e muito maior que o das variaveisarmazenadas na memoria principal, por isso essa ultima e tao importante.

O conceito por tras das variaveis persistentes e o de arquivo, e esse sera o tema dessecapıtulo. Por meio de arquivos, essas variaveis podem ser armazenadas e as informacoes queelas guardam, acessadas e processadas no futuro, tanto pelo programa que as criou quanto poroutros programas.

8.2 Tipos de Arquivos

Existem dois tipos de arquivos: arquivos texto e arquivos binarios. Ambos tem a mesma fi-nalidade: armazenar variaveis persistentes. Quando o programador cria um arquivo em seuprograma, deve indicar a qual tipo ele pertencera. Isso determina o formato das variaveis per-sistentes que ele gravara e acessara do arquivo.

8.2.1 Tipos de Arquivos - Arquivos Texto

Um arquivo texto e uma sequencia de caracteres. Se um arquivo texto for aberto num editorde texto convencional, o usuario podera ler seu conteudo (ou ao menos ver os caracteres lacontidos), e podera ate mesmo modifica-lo de uma forma que faca sentido.

Por exemplo, na linguagem C, tome uma variavel int que guarde o numero 43. Uma formade escrever essa variavel num arquivo texto seria gravar ”43”, mas note que, com isso, doiscaracteres foram gravados: o ’4’ seguido do ’3’. Isso poderia significar, por exemplo, paraum arquivo numa arquitetura que salve caracteres como variaveis de 1 byte, que dois bytesforam gravados no arquivo, o primeiro armazenando o caractere ’4’ e o segundo armazenando ocaractere ’3’.

Figura 8.1: Exemplo de um arquivo texto.

Page 237: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.2. TIPOS DE ARQUIVOS 237

8.2.2 Tipos de Arquivos - Arquivos Binarios

Por meio de um arquivo binario, as variaveis armazenadas na memoria principal podem ter seusbytes armazenados num arquivo fısico, sem traducao para caracteres e com correspondenciade um para um. Isso significa que, usando-se arquivos binarios, torna-se possıvel criar um”espelho”da memoria principal, mas salvo em memoria secundaria.

A fim de exemplificar esse conceito na linguagem C, sera citada a gravacao de uma struct,uma das razoes pela qual arquivos binarios sao tao uteis nessa linguagem. Ja foi estudado queuma struct e um tipo especial de variavel que armazena outras variaveis. Tome, por exemplo, astruct

struct pessoa {char nome[50];int idade;float salario;

}

Como guardar essa informacao em um arquivo? Pode-se guarda-la num arquivo texto,escrevendo-se o nome da pessoa, entao sua idade e finalmente seu salario. Sabendo o formatocomo essa informacao foi escrita, o programador pode criar um programa que a le.

De modo alternativo, pode-se armazena-la num arquivo binario usando um comando (quesera mostrado depois) que trata toda a struct como uma unica variavel. Ela pode ser lidatambem se usando um comando que a trata da mesma forma. Isso e possıvel, pois se sabe oformato como essa struct foi armazenada no arquivo binario. Esse formato poderia ser, parauma arquitetura de 32 bits de palavra, na linguagem C, de 50 bytes que armazenam cada umadas variaveis char, mais 32 bits (4 bytes) que armazenam uma variavel int, e mais 32 bits (4bytes) que armazenam uma variavel float.

Figura 8.2: Exemplo de um arquivo binario.

Page 238: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

238 CAPITULO 8. ARQUIVOS

8.3 Definicao de arquivos

Para serem utilizados nos programas, os arquivos sao tratados como variaveis. Entao, comotodas as outras variaveis, eles devem ser declarados. Dessa forma, tambem podem ser usadoscomo argumentos para funcoes.

Para lidar com arquivos, existem funcoes responsaveis por realizar todas as operacoes ne-cessarias. Por exemplo, criar um novo arquivo em branco, excluir um ja existente, gravarinformacao ou ler as ja contidas num arquivo, dentre outras.

Na linguagem C, o tipo FILE, definido na biblioteca stdio.h, e usado para se tratar arquivos.Um ponteiro para FILE deve ser declarado sempre que uma variavel arquivo for utilizada noprograma. Por exemplo, o seguinte comando declara uma variavel do tipo ponteiro para arquivodenominada arq:

FILE *arq;

Os ponteiros para FILE tratam arquivos referenciando-os a areas de memoria chamadasbuffers, as quais armazenam, na memoria principal, informacoes que foram lidas de um arquivofısico ou que serao escritas em um, mas que ainda nao foram descarregadas (gravadas no discorıgido, por exemplo). De qualquer forma, o programador pode abstrair o conceito de buffer;ele usara a variavel FILE* declarada, associara um arquivo fısico a ela, e entao a usara comoargumento para as funcoes de arquivo.

8.4 Operacao sobre arquivos

Arquivos demandam algumas operacoes, como abertura e fechamento, para seu funcionamento.Os valores ja armazenados nos arquivos devem poder ser lidos, e novos valores devem poder serescritos, para que tenham utilidade. As operacoes que realizam essas tarefas sao fornecidas pelalinguagem de programacao, em varios formatos.

8.4.1 Abertura

Apos a declaracao de uma variavel do tipo arquivo, essa deve ser associada a um nome dearquivo, o qual identifica um arquivo de fato, com correspondencia na memoria secundaria.

Se o arquivo com o nome especificado ja existir, entao o programador tera acesso a seuconteudo, e podera le-lo e altera-lo. Mas um nome de arquivo que ainda nao existe tambempode ser utilizado. Nesse caso, um novo arquivo, ”em branco”, com o nome especificado, seracriado. Esses detalhes sao resolvidos passando-se as informacoes corretas a funcao responsavelpor abrir o arquivo.

Na linguagem C, essa funcao e a fopen(). Seu prototipo e:

FILE *fopen (const char *nomearq, const char *modo);

Page 239: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.4. OPERACAO SOBRE ARQUIVOS 239

A funcao retorna um ponteiro para FILE, que devera ser recebido pela variavel usada paramanipular o arquivo. O primeiro argumento de fopen(), nomearq, e uma string, e refere-se aonome do arquivo que sera aberto. O segundo argumento, modo, tambem uma string, e umcodigo passado a fopen(), responsavel por indicar que tipo de arquivo e operacao sera realizadasobre esse arquivo. Os codigos sao descritos na tabela 8.1:

Parametro Efeitor Abre um arquivo-texto para leituraw Cria um arquivo-texto para escritaa Abre um arquivo-texto para gravar ao fim deler+ Abre um arquivo-texto para leitura/escritaw+ Cria um arquivo-texto para leitura/escritaa+ Abre ou cria (se nao existir) um arquivo-texto para ler dele ou gravar ao fim delerb Abre um arquivo binario para leiturawb Cria um arquivo binario para escritaab Abre um arquivo binario para gravar ao fim deler+b Abre um arquivo binario para leitura/escritaw+b Cria um arquivo binario para leitura/escritaa+b Abre ou cria um arquivo binario para gravar ao fim dele

No exemplo 8.1, a seguir, serao criados dois arquivos: o arquivo texto somente escrita.txt,o qual nao existia antes da execucao de fopen(), e que sera usado somente para gravacao deinformacao (no caso, caracteres); e leio e escrevo.meu, binario, no qual as informacoes poderaoser lidas e escritas. Note como as variaveis FILE* sao declaradas, inicialmente, e depois recebemo retorno da funcao fopen().

1 FILE *arq_ex1 , *arq_ex2;

2 /* ... */

3 arq_ex1 = fopen ("somente_escrita.txt", "w");

4 arq_ex2 = fopen ("leio_e_escrevo.meu", "a+b");

Exemplo 8.1: Abertura de arquivo

Um ponto importante a ser ressaltado sobre a funcao fopen() e a avaliacao de seu valor deretorno. Muitas vezes ocorrem erros na abertura de um arquivo, como, por exemplo, passar parafopen() o codigo ”r”mas o arquivo com o nome especificado nao existir no disco. Esses errospodem ser detectados porque a funcao fopen() retornara NULL para indicar que houve falha naabertura de um arquivo.

No exemplo 8.2, e declarada uma variavel de arquivo. Em seguida, e chamada fopen() pararealizar a abertura de arquivo. Imediatamente depois, e verificado se ele foi aberto corretamente.Se nao foi, o usuario sera notificado e o programa, encerrado. Esse encerramento e feito com o

Page 240: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

240 CAPITULO 8. ARQUIVOS

uso da funcao exit() (definida na biblioteca stdlib.h), a qual finaliza o programa e retorna parao Sistema Operacional o codigo numerico passado como argumento.

1 FILE *arq_ex3;

2 arq_ex3 = fopen ("alunos.txt", "r");

3 if (arq_ex3 == NULL) {

4 printf ("Erro com a abertura de arquivo! O programa sera abortado ...");

5 exit (1);

6 }

Exemplo 8.2: Abertura de arquivo com verificacao de sucesso

Todas as vezes que fopen() for usada deve-se verificar imediatamente se a abertura de arquivoocorreu sem problemas. Essa abordagem evitara muitos problemas posteriores.

Quando um arquivo e aberto, passa a estar associado a ele um indicador de posicao, res-ponsavel por indicar em qual ponto do arquivo novas informacoes sao lidas ou gravadas (ele podeser imaginado como o cursor em um texto sendo editado num editor de texto). No momento emque um arquivo e aberto, esse indicador estara no comeco do arquivo; e sempre que as variaveispersistentes do arquivo forem sendo lidas ou gravadas, o indicador de posicao se movimenta,ficando sempre a frente da ultima variavel lida ou gravada.

8.4.2 Fechamento

Quando um arquivo aberto nao for mais utilizado num programa, ele deve ser fechado. Essefechamento desassocia o arquivo fısico, em disco (por exemplo), com a variavel do tipo arquivousada para abrı-lo. Um arquivo aberto pode ser fechado usando-se uma funcao que execute essatarefa e que o receba como argumento.

E muito importante lembrar-se de fechar um arquivo. Arquivos abertos sao recursos queo sistema operacional deve gerenciar; dessa forma, muitos arquivos abertos significam maisrecursos sendo gerenciados.

Na linguagem C, a funcao fclose() e usada para fechar um arquivo. Seu prototipo e:

int fclose (FILE *fp);bel=exe:fseek,

Ela retorna 0 se a operacao de fechamento foi bem-sucedida, e diferente de 0 caso nao.Recebe como parametro um ponteiro para FILE, o qual e o arquivo a ser fechado.

Apos fechar um arquivo, ele deve ser aberto novamente, usando-se fopen(), caso se queirausa-lo no programa outra vez.

Quando fclose() e chamada, qualquer informacao que ainda esteja no buffer sera gravada noarquivo. Somente apos isso o arquivo fısico e finalmente desassociado da variavel FILE* usada.

Page 241: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.5. OPERACOES SOBRE ARQUIVOS TEXTO 241

8.5 Operacoes sobre arquivos texto

Ja foi mostrado que um arquivo texto e aquele que armazena caracteres. Dessa forma, somentecaracteres sao lidos e gravados em um arquivo-texto; algumas funcoes especiais existem, contudo,para que strings (vetores de caracteres) e numeros possam ser lidos e gravados.

8.5.1 Leitura

A linguagem C fornece uma serie de funcoes para leitura de informacoes em arquivos de texto.Serao mostradas a seguir duas delas: fscanf() e fscanf()

fscanf()

A funcao fscanf() funciona de forma semelhante a scanf(), ja estudada em capıtulos anteriores.A diferenca esta no fato de que fscanf() trabalha com arquivos, e nao com a entrada padrao(normalmente o teclado), caso de scanf()

Seu prototipo e:

int fscanf ( FILE *fp, const char *format, ... );

A passagem de argumentos e semelhante a de scanf()., com o acrescimo de que deve sercolocado como primeiro argumento o ponteiro para FILE representando o arquivo do qual seraolidas as variaveis.

No formato comum de uso, fcanf(), assim como scanf()., encerra a leitura de uma string (ouseja, argumento de codigo ”%s”) assim que um caractere de espaco em branco, tabulacao ouquebra de linha e encontrado. Dessa forma, fscanf() nao e recomendada para a leitura de strings.C oferece outra funcao para esse fim, que sera estudada em seguida: fgets().

O exemplo 8.3 mostra como a funcao fscanf() pode ser usada para ler um inteiro, uma string(nao formada por espacos ou quebras de linha) e um float de um arquivo-texto. Note que enecessario o uso de & antes da variavel int e float, ja que deve-se passar o endereco delas afscanf(), e que isso nao e necessario com a variavel string (como ocorre com o uso de scanf() ).

1 \begin{verbatim}

2 #include <stdio.h>

3 #define NOME_ARQUIVO "meu_texto.txt"

4 #define TAM_STR 50

5

6 int main (void)

7 {

8 int inteiro;

9 float real;

10 char str[TAM_STR ];

11 FILE *arq;

12

13 if ( !(arq = fopen (NOME_ARQUIVO , "r")) ) {

Page 242: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

242 CAPITULO 8. ARQUIVOS

14 printf (Erro na abertura de arquivo! Abortando o programa ...);

15 exit (1);

16 }

17 fscanf(arq , "%d\n%s\n%f", &inteiro , str , &real);

18 }

Exemplo 8.3: Uso de fscanf().

Dessa forma, um arquivo texto que contenha os seguintes caracteres:

1145segunda_linha45.99

caso lido com o codigo acima, resultaria o valor 1145 na variavel inteiro, ”segunda linha”emstr e 45.99 na variavel real.

fgets()

Outra funcao de C utilizada para ler informacoes de um arquivo texto e fgets(), que permite lerstrings completas. Seu prototipo e:

char *fgets (char *str, int length, FILE *fp);

Essa funcao le os caracteres do arquivo fp passado como argumento e armazena-os na string str,tambem passada como argumento, ate que ou length-1 caracteres sejam lidos ou um caractere denova linha (’\n’) seja lido. Se um caractere de nova linha for lido, ele sera armazenado em str. Jaquando a leitura de caracteres do arquivo finaliza, fgets() encerrara a string str armazenando ’\0’ noproximo caractere (ou seja, finalizando a string).

Dessa forma, um arquivo texto que contenha os seguintes caracteres: ”primeira linha\nsegundalinha”, tal como mostrado a seguir,

primeira linhasegunda linha

pode ser lido usando-se duas chamadas a funcoes fgets(). Duas strings serao lidas e gravadasnas variaveis string: str1 contera ”primeira linha\n”, e str2 contera ”segunda linha”. O exemplo 8.4mostra como isso pode ser feito:

1 char str1 [50];

2 char str2 [40];

3 FILE *arquivo;

4

5 If ( !( arquivo = fopen (NOME_ARQUIVO , "r")) ) {

6 printf (Erro na abertura de arquivo! Abortando o programa ...);

Page 243: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.5. OPERACOES SOBRE ARQUIVOS TEXTO 243

7 exit (1);

8 }

9

10 fgets (str1 , 50, arquivo);

11 fgets (str2 , 40, arquivo);

Exemplo 8.4: Uso de fgets().

Note que o tamanho maximo passado a fgets() corresponde ao tamanho das strings definidas.

8.5.2 Escrita

A linguagem C oferece a funcao fprintf(), que pode ser usada para gravar em arquivos de texto. Elasera estudada a seguir.

fprintf()

A funcao fprintf() e semelhante a printf().Seu prototipo e:

int fprintf ( FILE *fp, const char *format, ... );

A passagem de parametros e semelhante a de printf(), com o acrescimo de que deve ser colocadocomo primeiro argumento o ponteiro para FILE representando o arquivo no qual serao gravadas asinformacoes.

A gravacao de strings pode ser feita sem problemas com o uso de fprintf().O exemplo 8.5 mostra o uso dessa funcao. Nesse programa, tres variaveis, uma float, uma de

caracteres e uma string, sao criadas e tem valores associados; entao, o arquivo e aberto e elas saogravadas la.

1 #include <stdio.h>

2 #define NOME_ARQUIVO "meu_texto.txt"

3 #define TAM_STR 50

4

5 int main (void)

6 {

7 float real = 547.32;

8 char carac = ’T’;

9 char str[TAM_STR] = "teste para string";

10 FILE *arq;

11

12 if ( !(arq = fopen (NOME_ARQUIVO , "w")) ) {

13 printf (Erro na abertura de arquivo! Abortando o programa ...);

14 exit (1);

15 }

16 fprintf(arq , "%f\nIsso e uma string constante\n%s\n%c", real , str , carac);

17 }

Page 244: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

244 CAPITULO 8. ARQUIVOS

Exemplo 8.5: Uso de fprintf().

A execucao desse programa resultara num arquivo com o seguinte texto:

547.32Isso e uma string constanteteste para stringT

8.6 Operacoes sobre arquivos binarios

Como ja explicado, arquivos binarios armazenam bytes que correspondem diretamente aos valoresdas variaveis na memoria principal (as variaveis transientes), e nao somente armazenam valorescaracteres, como os arquivos de texto.

Sao muito uteis principalmente por poderem ser usados para ler e escrever diretamente tiposdefinidos pelo programador, como estruturas.

8.6.1 Leitura

A linguagem C possui a funcao fread() que pode ser usada para ler um arquivo binario.

fread()

O prototipo da funcao fread() e:

size t fread (void *buffer, size t num bytes, size t count, FILE *fp);

O primeiro parametro dessa funcao, buffer, e um ponteiro para uma regiao de memoria querecebera as variaveis lidas do arquivo. O numero de bytes a serem lidos e especificado por num bytes;e essa variavel que informa a funcao qual o tipo de variavel persistente a ser lida, pelo uso do operadorsizeof() (que retorna o tamanho do tipo passado como argumento). O parametro count indicaquantas variaveis do tamanho num bytes deverao ser lidas com essa chamada da funcao fread(). Efp e um ponteiro para o arquivo de onde serao lidos os valores.

O tipo de retorno da funcao, size t, e definido no arquivo stdio.h, e e aproximadamente iguala um inteiro sem sinal. Esse retorno pode ser avaliado para verificar se algum erro ocorreu, poisfread() retornara a quantidade de itens lidos. Esse valor deve ser igual a count; se nao for, entao oarquivo chegou ao final antes de ler a quantidade solicitada ou um erro ocorreu.

O exemplo 8.6 mostra a leitura de um inteiro, depois de um float, e entao de um caractere, deum arquivo binario. Considere que o arquivo arq1 ja foi aberto nesse trecho de codigo.

Page 245: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.6. OPERACOES SOBRE ARQUIVOS BINARIOS 245

1 int inteiro;

2 float real;

3 char carac;

4 /* ... */

5 fwrite (&inteiro , sizeof (int), 1, arq1);

6 fwrite (&real , sizeof (float), 1, arq1);

7 fwrite (&carac , sizeof (char), 1, arq1);

Exemplo 8.6: Uso de fwrite().

Note que as tres variaveis devem estar gravadas em sequencia no arquivo. Note tambem quebuffer e um ponteiro para as variaveis que armazenarao valores lidos do arquivo.

8.6.2 Escrita

Ja para se realizar a escrita de variaveis persistentes num arquivo binario, a linguagem C oferece afuncao fwrite().

fwrite()

Seu prototipo e:

size t fwrite (void *buffer, size t num bytes, size t count, FILE *fp);

Essa funcao se assemelha muito com fread(). O parametro buffer e um ponteiro para a variavelque sera escrita no arquivo. Ja num bytes e usado com o operador sizeof() para informar a funcaoquantos bytes contem o tipo da variavel a ser escrita. count indica quantas variaveis (do tamanhode num bytes) serao escritas. E, finalmente, fp e o ponteiro para FILE que indica em qual arquivodevem ser escritas as variaveis.

O exemplo 8.7 mostra um programa completo que gera uma struct, a grava em um arquivo edepois fecha-o. Entao, esse arquivo e reaberto e essa struct e lida dele (somente para exemplo, poisos valores da struct ainda estavam corretos). Depois, esses dados lidos serao gravados em um outroarquivo, texto.

1 #include <stdio.h>

2

3 typedef struct {

4 char nome [50];

5 int idade;

6 char sexo;

7 } TPessoa;

8

9 int main (void)

10 {

11 FILE *arq;

Page 246: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

246 CAPITULO 8. ARQUIVOS

12 TPessoa p;

13

14 p.nome = "Marcia Maia";

15 p.idade = 46;

16 p.sexo = ’F’;

17

18 if ( !(arq = fopen ("arquivo_bin.teste", "wb")) ) {

19 printf (Erro na abertura de arquivo! Abortando o programa ...);

20 exit (1);

21 }

22 fwrite (&p, sizeof (TPessoa), 1, arq);

23 fclose (arq);

24

25 if ( !(arq = fopen ("arquivo_bin.teste", "rb")) ) {

26 printf (Erro na abertura de arquivo! Abortando o programa ...);

27 exit (1);

28 }

29 fread (&p, sizeof (TPessoa), 1, arq);

30 fclose (arq);

31

32 if ( !(arq = fopen ("arquivo_texto.txt", "w")) ) {

33 printf (Erro na abertura de arquivo! Abortando o programa ...);

34 exit (1);

35 }

36 fprintf(arq , "%s\n%d\n%c", p.nome , p.idade , p.sexo);

37 fclose (arq);

38 }

Exemplo 8.7: Gravacao e leitura de struct em arquivos

Pode-se ver que ao final da execucao do programa, arquivo texto.txt contera os dados da pessoa,e poderao ser lidos assim que o arquivo for aberto por um editor de texto qualquer (fato que naoocorre com o arquivo arquivo bin.teste, binario).

8.7 Outras funcoes uteis para arquivos

As secoes anteriores mostraram as funcoes basicas para se trabalhar com arquivos em C. Porem,essas funcoes nao sao suficientes para realizar todas as tarefas que arquivos permitem.

Serao apresentadas duas funcoes nessa secao: feof(), usada para verificar se o indicador deposicao num arquivo chegou ao final dele; e fseek(), usada para posicionar o indicador de posicaonum local especıfico do arquivo.

Os exemplos apresentados nessa sessao serao de programas completos e mais complexos dos queos anteriormente mostrados.

Page 247: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.7. OUTRAS FUNCOES UTEIS PARA ARQUIVOS 247

8.7.1 feof()

Uma funcao essencial usada para trabalhar com arquivos e feof(). Seu prototipo e:

int feof (FILE *fp);

Essa funcao retornara 0 se o arquivo fp passado como argumento ainda nao chegou ao final.A verificacao se da pelo indicador de posicao no arquivo. Assim, a funcao feof() e utilizada paraverificar quando um arquivo, tanto de texto quando binario, termina.

No exemplo 8.8, existe um arquivo previamente criado, binario, que armazena muitas variaveisstruct do tipo TFuncionario. O programa abre esse arquivo, le todas as variaveis la presentes (umaquantia inicialmente desconhecida), e vai gravando-as num arquivo texto.

Note que esse programa usa o tipo TFuncionario como um TAD (tipo abstrato de dados):existe uma funcao para inicializar o funcionario, e funcoes que operam com um funcionario (lendo,gravando...). A funcao main(), que usa essas funcoes, nao acessa os campos de uma struct TFun-cionario. Alias, o programador da funcao main(), que usa o TAD funcionario, nem sequer precisasaber como ele e implementado!

O programa funciona da seguinte forma: a funcao main() abre os arquivos, e entao, usa a funcaole func() para ler um funcionario de cada vez do arquivo de leitura (se a leitura do funcionario naoocorrer corretamente, a funcao le func() usa a funcao invalida func() para indicar que a leituradesse funcionario nao foi feita corretamente). Entao, a main() verifica se esse funcionario foi lidocorretamente, usando a funcao func valido(). Se sim, grava-o no arquivo texto, usando a funcaograva func().

1 #include <stdio.h>

2 #define ARQUIVO_LEITURA binario

3 #define ARQUIVO_ESCRITA texto.txt

4

5 typedef struct {

6 char nome [50];

7 char sexo;

8 int idade;

9 int matricula;

10 float salario;

11 } TFuncionario;

12

13 TFuncionario inicializa_func (void);

14 TFuncionario le_func (FILE *arqbin);

15 TFuncionario invalida_func (void);

16 int func_valido (TFuncionario f);

17 void grava_func (TFuncionario f, FILE *arqtex);

18

19 int main (void)

20 {

21 FILE *arqbin , *arqtex;

22 TFuncionario f = inicializa_func ();

Page 248: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

248 CAPITULO 8. ARQUIVOS

23

24 /* Bloco de codigo responsavel pela correta abertura dos arquivos */

25 if ( !( arqbin = fopen (ARQUIVO_LEITURA , "rb")) ||

26 !( arqtex = fopen (ARQUIVO_ESCRITA , "rb")) ) {

27 printf ("Erro na abertura de arquivos! Abortando ...");

28 exit (1);

29 }

30

31 /* Bloco de codigo que contem o loop while , que usa a func~ao feof() para

32 ler o arquivo */

33 while ( !feof (arqbin) ) {

34 f = le_func (arqbin);

35 if ( func_valido(f) ) {

36 grava_func (f, arqtex);

37 } else {

38 printf ("Erro na leitura de funcionarios. Abortando ...");

39 exit (1);

40 }

41 }

42 }

43

44 TFuncionario inicializa_func (void)

45 {

46 TFuncionario f;

47 f.matricula = 0;

48 return (f);

49 }

50

51 TFuncionario le_func (FILE *arqbin)

52 {

53 TFuncionario f;

54

55 if ( (fread (&f, sizeof(TFuncionario), 1, arqbin)) != 1) {

56 f = invalida_func ();

57 }

58

59 return (f);

60 }

61

62 TFuncionario invalida_func (void)

63 {

64 TFuncionario f;

65 f.matricula = -1;

66 return (f);

67 }

68

69

70 int func_valido (TFuncionario f)

71 {

72 if (f.matricula < 0) {

73 return (0);

Page 249: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.7. OUTRAS FUNCOES UTEIS PARA ARQUIVOS 249

74 }

75 else {

76 return (1);

77 }

78 }

79

80 void grava_func (TFuncionario f, FILE *arqtex)

81 {

82 fprintf (arqtex , Nome: %s\nSexo: %c\nIdade: %d\nMatricula: %d\n

83 Salario: %f\n\n, f.nome , f.sexo , f.idade , f.matricula , f.salario);

84 }

Exemplo 8.8: Uso de feof() e outras funcoes no TAD TFuncionario

8.7.2 fseek()

Muitas vezes, deseja-se ter controle sobre o indicador de posicao num arquivo. Ao se saber, porexemplo, qual o ındice de uma estrutura especıfica ja gravada, do total de todas as estruturas quefazem parte de um arquivo binario, pode-se buscar essa estrutura desejada sem ter que carregar paraa memoria todas as outras. Isso pode ser feito posicionando-se o indicador de posicao no arquivo elendo somente a proxima estrutura (que sera a desejada).

A funcao em C que permite fazer isso e fseek(). Seu prototipo e:

int fseek (FILE *fp, long numbytes, int origin);

A funcao retornara 0 se for bem-sucedida; caso contrario, retornara diferente de 0. Seus argu-mentos sao: fp, um ponteiro para arquivo ja aberto por fopen(); numbytes, um numero que indicaquantos bytes a partir do parametro origin estara o indicador de posicao; e, finalmente, origin serauma das tres macros mostradas abaixo (que estao definidas no arquivo STDIO.H):

Posicao Parametro

Inıcio do arquivo SEEK TEST

Posicao atual SEEK CUR

Final do arquivo SEEK END

Assim, para se posicionar duas variavel int a frente da posicao inicial do arquivo arq (ou seja,pronto para ler a terceira variavel int armazenada), faca:

fseek (arq, 2 * sizeof(int), SEEK SET);

O exemplo 8.9 mostra a funcao obtem func posicao(). Essa funcao e usada para ler structsTFuncionario (definidas no Exemplo 8.8) contidas no arquivo binario (tambem definido no exemplo)passando-se o ındice do funcionario que se deseja ler. Ela recebe um ponteiro para o arquivo binario

Page 250: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

250 CAPITULO 8. ARQUIVOS

de leitura, ja aberto com fopen(), de onde tentara ler a struct de ındice i, um parametro inteiropassado. Assim, se i=1, o retorno da funcao sera a primeira struct; se i=3, sera a terceira; etc.Ela usara a funcao invalida func(), tambem definida nesse exemplo, para indicar que houve erro naleitura do funcionario especificado.

1 funcionario obtem_func_posicao (int i, FILE *arqbin)

2 {

3 funcionario f;

4

5 if ( fseek (arqbin , (i-1) * sizeof(funcionario), SEEK_SET) ) {

6 f = invalida_func ();

7 return (f);

8 }

9 if ( (fread (&f, sizeof(funcionario), 1, arqbin)) != 1) {

10 f = invalida_func ();

11 }

12 return (f);

13 }

Exemplo 8.9: Uso de fseek() para posicionamento num arquivo binario

8.8 Exercicios Resolvidos

Nessa secao sera proposto e resolvido um exercıcio que engloba muitos temas que foram estudadosnesse e nos capıtulos anteriores.

8.8.1 O Tipo Abstrato de Dados TDicionario

O exercıcio consiste na na implementado de um TAD (Tipo Abstrato de Dados) Dicionario. Essetipo correspondera a uma serie de duplas (chave, valor), em que tanto chave quanto valor sao strings;a interpretacao desses dados e que chave corresponde a palavras que serao explicadas por valor. Porexemplo, duas entradas do dicionario poderiam ser (”Espırito Santo”, ”estado brasileiro localizadona regiao Sudeste”) e (”C”, ”Linguagem de programacao de nıvel medio”).

A uma variavel do tipo TDicionario declarada corresponderao varios valores de (chave, valor).Essas entradas deverao ficar armazenadas num arquivo, denominado arquivo de dados. Assim, sempreque se desejar consultar se alguma palavra esta definida no dicionario (exemplo: ”ha alguma entradapara ’cachorro’?”), o arquivo de dados daquela variavel dicionario devera ser consultado. O mesmopara quando uma palavra for inserida num dicionario: ela sera acrescentada ao arquivo de dadosdesse dicionario, ao final dele.

Supoe-se que o arquivo de dados sera muito grande e que nao podera ser carregado todo paraa memoria principal. Tambem, carregar, do disco para a memoria, sequencialmente, as entradas dodicionario salvas no arquivo de dados (a fim de fazer uma busca, por exemplo) nao sera uma solucao

Page 251: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.8. EXERCICIOS RESOLVIDOS 251

aceitavel pelo tempo que isso demanda: o acesso ao disco se da na ordem de milissegundos, muitosuperior aos tempos envolvidos nas operacoes da memoria e do processador.

Por esse motivo, um segundo arquivo estara tambem associado a cada variavel TDicionario: umarquivo de ındices. Esse arquivo contera duplas (chave, ındice), em que chave corresponde as mesmaschaves incluıdas no arquivo de dados, e ındice indica o ındice (numerico) dessa chave no arquivo dedados.

Segue exemplo de uma variavel TDicionario denominada meu dic, e associada a arquivos comnome meu dicionario. Note que ambos os arquivos sao binarios, assim, o que e mostrado abaixo eapenas o aspecto deles – eles nao poderiam ser lidos diretamente de um editor de texto convencional.

Arquivo de dados: meu dicionario dados

Espırito Santoestado brasileiro localizado na regi~ao SudesteClinguagem de programac~ao de nıvel mediocachorromamıfero considerado "o melhor amigo do homem"

Arquivo de ındices: meu dicionario indice

Espırito Santo0C1cachorro2

O arquivo de ındices, por ser consideravelmente menor que o de dados, podera ser carregado todopara a memoria e entao acessado, a fim de realizar-se uma busca. Dessa forma, pode-se descobrirque ’cachorro’ e, sim, uma entrada, e esta no ındice 2 (terceira entrada) do arquivo de dados.

As entradas do arquivo de dados serao structs com dois campos strings, e as do arquivo de ındicesstructs com um campo string e um campo int. Uma variavel TDicionario sera uma struct com camposque indicam o nome dos seus dois arquivos associados, um campo que armazena a matriz de ındicesem memoria, e um campo que guarda o total de entradas armazenadas no dicionario.

As operacoes que o TAD dicionario aceitara sao: inicializacao de um novo dicionario, aberturade um dicionario ja existente, busca de uma palavra e acrescimo de uma palavra. Seguem abaixodefinicoes dessas funcoes:

TDicionario inicializa dic (char *nome do dicionario)

Ao chamar essa funcao, o usuario passara o nome do dicionario como argumento (uma string).Entao os dois arquivos serao criados; seus nome serao a string nome do dicionario acrescida de

Page 252: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

252 CAPITULO 8. ARQUIVOS

” dados”, para o caso do arquivo de dados, e ” indice”, para o arquivo de ındices. Na memoriaficara armazenada uma tabela de ındices (ou seja, um vetor de structs), inicialmente vazia.

TDicionario carrega dic (char *nome do dicionario)

Essa funcao e usada para abrir um dicionario ja existente. Sua chamada acarreta na abertura doarquivo de ındices (com nome indicado por nome do dicionario) e seu carregamento para a memoria;apos isso, o arquivo de ındices sera fechado.

int busca dic (TDicionario dic, char *palavra, char **retorno)

O uso dessa funcao acarreta na busca, na matriz de ındices em memoria (indicada por dic), dastring indicada por palavra. Se for encontrada, entao se sabera seu ındice; o arquivo de ındice entaosera aberto, o indicador de posicao sera posicionado nesse ındice indicado, e a informacao desejada (ovalor correspondente a essa chave) sera lida e armazenada no argumento retorno. A funcao retornara1 para indicar que a palavra foi encontrada e 0 senao.

int insere dic (TDicionario dic, char *chave, char *valor)

Essa funcao sera usada para inserir, no dicionario dic, a palavra chave com a sua descricao valor.Inicialmente uma busca pela chave devera ser realizada (na tabela de ındices em memoria); se elanao existir, aı sim podera ser inserida. Nesse caso, o arquivo de dados e aberto, e a chave e ovalor sao armazenados ao fim dele; ele e fechado apos isso. A matriz de ındices em memoria deveratambem ser modificada, com o acrescimo, ao fim dela, da chave e do seu ındice no arquivo de dados(e possıvel saber o ındice observando a quantidade de entradas ja armazenadas, indicada por dic). Oarquivo de ındices devera entao ser aberto, a matriz de ındices em memoria (ja atualizada) gravadanele, e logo em seguida fechado.

Implementacao do TAD TDicionario

1 #include <stdio.h>

2 #include <string.h>

3 #include <stdlib.h>

4

5 #define TAM_CHAVE 50

6 #define TAM_VALOR 500

7 #define TAM_NOME_ARQ 20

8 #define MAX_ENTRADAS 200

9

10 /* duplas (chave , valor) */

11 typedef struct {

12 char chave[TAM_CHAVE ];

13 char valor[TAM_VALOR ];

Page 253: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.8. EXERCICIOS RESOLVIDOS 253

14 } entrada_dic;

15

16 /* duplas (chave , indice) */

17 typedef struct {

18 char chave[TAM_CHAVE ];

19 int indice;

20 } indice_dic;

21

22 /* definicao da variavel do TAD dicionario */

23 typedef struct {

24 char nome_arq_dados[TAM_NOME_ARQ ];

25 char nome_arq_indices[TAM_NOME_ARQ ];

26 indice_dic matriz_indices[MAX_ENTRADAS ];

27 int tam;

28 } TDicionario;

29

30 /* funcao que inicializa um novo dicionario */

31 TDicionario inicializa_dic (char *nome_do_dicionario)

32 {

33 TDicionario dic;

34 FILE *arq;

35

36 /* acrescenta "_indice" ao nome_do_dicionario */

37 strcpy (dic.nome_arq_indices , nome_do_dicionario);

38 strcat (dic.nome_arq_indices , "_indice");

39

40 /* criacao do arquivo de indices */

41 if ( (arq=fopen(dic.nome_arq_indices , "wb")) == NULL) {

42 printf ("Erro na criacao de arquivos! Abortando ...");

43 exit (1);

44 }

45 fclose(arq);

46

47 /* acrescenta "_dados" ao nome_do_dicionario */

48 strcpy (dic.nome_arq_dados , nome_do_dicionario);

49 strcat (dic.nome_arq_dados , "_dados");

50

51 /* criacao do arquivo de dados */

52 if ( (arq=fopen(dic.nome_arq_dados , "wb")) == NULL) {

53 printf ("Erro na criacao de arquivos! Abortando ...");

54 exit (1);

55 }

56 fclose(arq);

57

58 dic.tam = 0;

59

60 return (dic);

61 }

62

63 /* funcao que carrega um dicionario */

64 void carrega_dic (TDicionario *dic , char *nome_do_dicionario)

Page 254: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

254 CAPITULO 8. ARQUIVOS

65 {

66 FILE *arq;

67 int i;

68

69 /* acrescenta "_dados" ao nome_do_dicionario */

70 strcpy (dic ->nome_arq_dados , nome_do_dicionario);

71 strcat (dic ->nome_arq_dados , "_dados");

72

73 /* acrescenta "_indice" ao nome_do_dicionario */

74 strcpy (dic ->nome_arq_indices , nome_do_dicionario);

75 strcat (dic ->nome_arq_indices , "_indice");

76

77 /* abertura do arquivo de indices */

78 if ( (arq=fopen(dic ->nome_arq_indices , "rb")) == NULL) {

79 printf ("Erro na abertura de arquivos! Abortando ...");

80 exit (1);

81 }

82

83 /* leitura e contagem do numero de entradas no arquivo de indice */

84 dic ->tam = 0;

85 for (i=0; !feof(arq); i++) {

86 fread (&dic ->matriz_indices[i], sizeof(indice_dic), 1, arq);

87 dic ->tam ++;

88 }

89 }

90

91 /* funcao que busca uma chave no dicionario passado. Se encontrar

92 retornara 1 e retornara seu valor no argumento retorno */

93 int busca_dic (TDicionario *dic , char *chave , char *retorno)

94 {

95 int i;

96 FILE *arq;

97

98 entrada_dic entrada;

99

100 /* procura na tabela de indices em memoria a chave */

101 for (i=0; i < dic ->tam; i++) {

102 if (! strcmp(dic ->matriz_indices[i].chave , chave)) {

103 /* se estou aqui , entao encontrei a palavra! */

104

105 if ( (arq=fopen(dic ->nome_arq_dados , "rb")) == NULL) {

106 printf ("Erro na abertura de arquivos! Abortando ...");

107 exit (1);

108 }

109 /* posiciona , le e retorna o valor da chave */

110 fseek (arq , i*sizeof(entrada_dic), SEEK_SET);

111 fread (&entrada , sizeof(entrada_dic), 1, arq);

112 strcpy (retorno , entrada.valor);

113 fclose(arq);

114 return 1;

115 }

Page 255: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.8. EXERCICIOS RESOLVIDOS 255

116 }

117 /* se cheguei ate aqui , entao nao encontrei a palavra */

118 return 0;

119 }

120

121 /* funcao que insere , no dicionario , a chave (palavra) passada

122 e seu valor. Retorna 1 se inserir , 0 senao */

123 int insere_dic (TDicionario *dic , char *chave , char *valor)

124 {

125 char pega_valor[TAM_VALOR ];

126 FILE *arq;

127 entrada_dic entrada;

128 indice_dic chave_ind;

129

130 if ( !busca_dic (dic , chave , pega_valor) ) {

131 /* Se a chave nao existe no dic., anexo ao arquivo de dados */

132

133 if ( (arq=fopen(dic ->nome_arq_dados , "ab")) == NULL) {

134 printf ("Erro na abertura de arquivos! Abortando ...");

135 exit (1);

136 }

137

138 strcpy (entrada.chave , chave);

139 strcpy (entrada.valor , valor);

140

141 fwrite (&entrada , sizeof(entrada_dic), 1, arq);

142 fclose(arq);

143

144 /* insere ao final da tabela e arquivo de indices */

145

146 strcpy ( dic ->matriz_indices[dic ->tam].chave , chave);

147 dic ->matriz_indices[dic ->tam]. indice = dic ->tam;

148 dic ->tam ++;

149

150 if ( (arq=fopen(dic ->nome_arq_indices , "ab")) == NULL) {

151 printf ("Erro na abertura de arquivos! Abortando ...");

152 exit (1);

153 }

154

155 strcpy (chave_ind.chave , chave);

156 chave_ind.indice = dic ->tam;

157 fwrite (&chave_ind , sizeof(indice_dic), 1, arq);

158 fclose(arq);

159

160 return 1;

161 }

162 else printf ("A chave passada ja existe no dicionario !\n");

163 return 0;

164 }

165

166 int main()

Page 256: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

256 CAPITULO 8. ARQUIVOS

167 {

168 TDicionario dic , outro_dic;

169 entrada_dic entrada;

170

171 dic = inicializa_dic ("meu_dicionario");

172

173 strcpy(entrada.chave , "Espirito Santo");

174 strcpy(entrada.valor , "estado brasileiro localizado na regiao Sudeste");

175 insere_dic (&dic , entrada.chave , entrada.valor);

176

177 strcpy(entrada.chave , "C");

178 strcpy(entrada.valor , "linguagem de programacao de nivel medio");

179 insere_dic (&dic , entrada.chave , entrada.valor);

180

181 carrega_dic (&outro_dic , "meu_dicionario");

182 strcpy(entrada.chave , "C");

183 strcpy(entrada.valor , "linguagem de programacao de nivel medio");

184 insere_dic (&outro_dic , entrada.chave , entrada.valor);

185 }

Exemplo 8.10: Implementacao do TAD TDicionario

Alguns aprimoramentos para o TAD TDicionario

Pelo fato das insercoes de novos valores se darem sempre ao final das estruturas de dados, ja queinsere-se ao final da tabela de indices em memoria, do arquivo de indices e tambem do arquivo dedados, os ındices das entradas acabam sempre coincidindo. Isso faz com que, por exemplo, a terceiraentrada do dicionario seja a terceira entrada do arquivo de dados, do arquivo de ındices e da tabelade ındices em memoria (e que a tabela armazene o ındice 2 para esse elemento).

Uma alteracao pode ser feita com a tabela de ındices em memoria. Ela pode ser mantidaordenada se cada novo elemento for inserido nela respeitando a ordem alfabetica de sua chave. Comessa ordenacao, as entradas podem ser buscadas rapidamente na tabela, mediante o uso, por exemplo,de uma busca binaria, um algoritmo de busca que trabalha particionando o vetor de busca (ordenado)em duas metades, e entao, recursivamente, refaz a busca ou na metade superior ou inferior, via aobservacao do valor a ser buscado. Uma sugestao para a implementacao desse aprimoramento ea criacao de duas novas funcoes: uma delas, que seria usada pela funcao busca dic(), realizaria abusca binaria de um valor string num vetor de indice dic passado; a outra funcao, a ser usada porinsere dic(), faria a insercao ordenada no vetor de indice dic passado (note que essa funcao poderiausar a funcao de busca binaria anteriormente descrita).

O arquivo de ındices poderia ser mantido desordenado, via a insercao de novos valores sempreao seu final. O importante, para demandar o menor tempo computacional possıvel, e usar menosentrada e saıda (como o acesso aos dados do disco). Mas, como a tabela de ındices em memoria deveser mantida organizada, ao ser carregado um dicionario (via a funcao carrega dic() ), as informacoesdevem ser lidas do arquivo e inseridas ordenadamente no vetor em memoria.

Com esse aperfeicoamento descrito, um valor seria encontrado muito mais rapidamente na tabela

Page 257: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.9. RESUMO 257

de ındices em memoria, para entao ser descoberto seu ındice no arquivo de dados, e a dupla (chave,informacao) desejada finalmente ser carregada para memoria.

8.9 Resumo

• Variaveis transientes sao armazenadas na memoria principal. Tem tempo de acesso rapido, masduracao limitada: so existem enquanto o programa que as esta utilizando estiver na memoria.Variaveis persistentes nao perdem suas informacoes quando o programa que as criou nao estamais em memoria, pois estao armazenadas em meio secundario: disco rıgido, memoria flash,disquete, CD...

• Arquivos texto so armazenam caracteres, e sao compreensıveis ao serem lidos em um editor detexto. Ja arquivos binarios armazenam variaveis no formato em que elas sao armazenadas emmemoria;

• Um arquivo deve ser aberto para poder ser utilizado, e apos essa utilizacao, deve ser fechado;

• As variaveis persistentes podem ser escritas e lidas dos arquivos. Existem funcoes especıficaspara essas tarefas, algumas designadas para arquivos binarios e outras para arquivos texto;

• A linguagem C oferece uma serie de funcoes para lidar com arquivos, e esse capıtulo apre-sentou algumas, como fopen(), usada para abrir arquivos, e fread(), usada para ler variaveispersistentes de arquivos binarios.

8.10 Exercıcios

1. Escreva um programa em C que abra um arquivo texto e que conte a quantidade de caracteresarmazenados nele. Imprima o numero na tela. O programa deve solicitar ao usuario que digiteo nome do arquivo.

2. Escreva um programa em C que solicite ao usuario a digitacao do nome de um arquivo textoja existente, e que entao gere um outro arquivo, que sera uma copia do primeiro.

3. Considere um arquivo texto que armazene numeros em ponto flutuante em cada uma de suaslinhas. Ou seja, o arquivo inicia com uma quantidade de um ou mais caracteres representandonumeros inteiros, entao segue um caractere de ponto (’.’) e mais alguns inteiros; em seguida,uma quebra de linha; na proxima linha esse formato prossegue, ate que, no fim da ultima linha,nao ocorre quebra de linha. Escreva um programa em C que determine o valor maximo, o valormınimo e a media desses valores armazenados no arquivo. Imprima esses valores na tela.

4. Considere o programa escrito para a questao anterior. Exiba na tela, agora, o valor n corres-pondente a quantidade de numeros reais contidos no arquivo e o valor maximo, mınimo e a

Page 258: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

258 CAPITULO 8. ARQUIVOS

media calculados anteriormente, porem agora divididos por n. Depois, gere um novo arquivoque contenha cada um dos numeros reais do arquivo divididos por n, um por linha. Procurereutilizar, nessa questao, o maior numero possıvel das funcoes que voce tenha construıdo paraa questao anterior. Modularizar seu codigo (usar funcoes) e uma forma de organizacao e depoupar trabalho duplicado.

5. Considere um arquivo texto que armazene caracteres variados, ou seja, um texto digitado.Escreva um programa que o leia e gere um novo arquivo que contenha somente as letras doarquivo original, na ordem em que la aparecem (ou seja, caracteres de A-Z ou a-z).

6. Para um arquivo do mesmo tipo do da questao anterior (que armazene caracteres variados),escreva um programa em C que determine a media dos comprimentos de todas as palavrasque se encontram nele. Entende-se por palavra um conjunto de caracteres de letras que estaseparado de outros conjuntos de caracteres no arquivo por um (ou mais) caractere de espacoem branco ( ’ ’, tabulacoes ou quebra de linha); e seu comprimento sera a quantidade decaracteres que o formam.

7. Considere um arquivo texto como o usado na questao anterior. Faca um programa que o leiae que permita ao usuario consultar uma das linhas do arquivo, solicitando a ele que informeo ındice n dessa linha. O programa deve imprimir a linha especificada ou a mensagem de queela nao existe.

8. Escreva um programa em C que receba via teclado o nome de um arquivo texto e uma palavra.O programa deve imprimir todas as linhas que possuem essa palavra. Dica: procure usaralgumas funcoes que voce tenha construıdo para a questao anterior; provavelmente, algumasdelas poderao ser reaproveitadas.

9. Escreva um programa em C que receba via teclado o nome de um arquivo texto. O programadeve solicitar ao usuario que digite o ındice da linha inicial e da linha final, e o programa deveimprimi-las e todas as linhas entre elas. Se o ındice superior de linhas nao existe, esse erro deveser informado ao usuario (mas as linhas existentes devem, ainda, ser impressas). Novamente,procure usar algumas funcoes que voce tenha escrito para as questoes anteriores.

10. Considere, agora, os numeros inteiros armazenados num arquivo texto como os usados nasquestoes anteriores. Entende-se por um numero inteiro nesse arquivo um conjunto de caracteresrepresentando numeros inteiros (ou seja, no intervalo 0-9) separados de outros conjuntos decaracteres por um (ou mais) caractere de espaco em branco ( ’ ’, tabulacoes ou quebras delinha). Escreva um programa em C que produza dois arquivos texto: o primeiro com os numerospares da sequencia original e o segundo com os numeros impares. Os arquivos de saıda devemconter um numero por linha.

Page 259: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

8.10. EXERCICIOS 259

11. Escreva um programa em C que leia um texto fornecido pelo usuario via teclado e o armazeneem um arquivo. O fim da entrada de texto e sinalizada por um ponto no inıcio de uma novalinha. O ponto utilizado para marcar o fim da entrada de texto nao deve aparecer no arquivogerado pelo programa.

12. Considere um arquivo que apresente o nome de um aluno na primeira linha; na seguinte anota de sua primeira prova; e na seguinte a nota de sua segunda prova. Essas 3 linhas deinformacoes se repetem no total de alunos no arquivo de entrada. Faca um programa queimprima os nomes de todos os alunos que tem a media das duas notas menor que 7.0.

13. Escreva um programa que leia um arquivo texto contendo linhas de dados. Em cada linha doarquivo ha o nome de um aluno e duas notas. Esses dados estao separados por ponto e vırgula.Existe um ponto e vırgula no final de cada linha. O programa deve ler esses dados e imprimiros valores lidos, a media das duas notas, e se o aluno foi aprovado ou nao (com nota maior ouigual a 5).

14. Escreva um programa em C que solicita ao usuario a digitacao de um nome de arquivo. Essearquivo sera criado e o usuario informara numeros em ponto flutuante, que serao gravados noarquivo. O arquivo sera um arquivo binario. Considere que ele pode armazenar no maximo 50valores, mas que o usuario pode encerrar a entrada de novos valores com a digitacao de umnumero negativo.

15. Escreva um programa em C que receba o nome de um arquivo binario, o qual armazena numerosem ponto flutuante, no mesmo formato que na questao anterior. O programa deve ler todosesses valores e grava-los na memoria; entao, ordena-los, e regrava-los num arquivo texto, comum numero por linha.

16. Escreva um programa em C que receba via teclado o nome de um arquivo binario. Esse arquivoarmazenara nome, idade e sexo de pessoas, como no TAD TFuncionario. O programa devesolicitar ao usuario a digitacao desses dados e armazena-los no arquivo depois. O programatermina quando o usuario digitar enter na entrada do nome, ou seja, informar um nome vazio.

17. Escreva um programa em C que receba via teclado o nome do arquivo binario da questaoanterior. Entao, ele deve abrir o arquivo. Deve existir um menu que ofereca ao usuario apossibilidade de poder: 1) imprimir (na tela) todos os registros la contidos; 2) acessar osdados de uma pessoa passando o ındice dela no arquivo (1 para a primeira pessoa no arquivo,5 para a quinta pessoa no arquivo...); 3) o programa deve informar a quantidade total dehomens e mulheres armazenadas no arquivo; 4) O programa deve permitir ao usuario digitarnovas pessoas. Esses novos dados digitados devem ser gravados no arquivo (e posteriormentedescarregados da memoria) somente quando o usuario escolher, no menu, a opcao para sairdo programa.

Page 260: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

260 CAPITULO 8. ARQUIVOS

8.11 Trabalhos Sugeridos

Falta acesso aos trabalhos sugeridos dos outros capıtulos.

Page 261: Sum ario - Seja Bem-Vindo | Informáticamberger/Disciplinas/2011_2/ProgII/livro_progC.pdf · mento de softwares e tamb em adotada neste livro, a linguagem C[1]. Ela e, ainda hoje,

Referencias Bibliograficas

[1] BRIAN KERNIGHAN and DENNIS RITCHIE. The C Programming Language. second edition,1988.

[2] PAUL STRATHERN. Turing e o Computador em 90 Minutos. first edition, 2000.

[3] ANDREW S TANENBAUM and JAMES R GOODMAN. Structured Computer Organization.fourth edition, 1999.

261