programação 2 linguagem c (ufrpe)

284
Recife, 2009 Programação 2 Sônia Virginia Alves França

Upload: aej400aej

Post on 12-Jun-2015

7.656 views

Category:

Documents


0 download

DESCRIPTION

Programação 2 Linguagem C (UFRPE)

TRANSCRIPT

Page 1: Programação 2 Linguagem C (UFRPE)

Recife, 2009

Programação 2Sônia Virginia Alves França

Page 2: Programação 2 Linguagem C (UFRPE)

Universidade Federal Rural de Pernambuco

Reitor: Prof. Valmar Corrêa de AndradeVice-Reitor: Prof. Reginaldo BarrosPró-Reitor de Administração: Prof. Francisco Fernando Ramos CarvalhoPró-Reitor de Extensão: Prof. Paulo Donizeti SiepierskiPró-Reitor de Pesquisa e Pós-Graduação: Prof. Fernando José FreirePró-Reitor de Planejamento: Prof. Rinaldo Luiz Caraciolo FerreiraPró-Reitora de Ensino de Graduação: Profª. Maria José de SenaCoordenação Geral de Ensino a Distância: Profª Marizete Silva Santos

Produção Gráfica e EditorialCapa e Editoração: Allyson Vila Nova, Rafael Lira, Italo Amorim e Glaydson da SilvaRevisão Ortográfica: Ivanda MartinsIlustrações: Diego AlmeidaCoordenação de Produção: Marizete Silva Santos

Page 3: Programação 2 Linguagem C (UFRPE)

Sumário

Plano da Disciplina ...............................................................................5

Apresentação ........................................................................................9

Conhecendo o Volume 01 ..................................................................10

Capítulo 1 – Introdução ao C .............................................................13

1.1. Programas e Programação de Computadores ..........................13

1.2. Linguagens de Programação .....................................................15

1.3. Breve Histórico da Linguagem de Programação C ...................18

1.4. Criação, Compilação e Execução de um Programa ..................19

Capítulo 2 – Conceitos Preliminares para Programar em C ...........24

2.1. Estrutura de um Programa Básico em C ...................................25

2.2. Palavras Reservadas do C ........................................................28

2.3 Uso de Comentários ...................................................................29

2.4. Os Fundamentos do Ambiente C ...............................................31

2.5. Conhecendo o Dev-cpp .............................................................34

Capítulo 3 – Tipos de Dados, Variáveis e Constantes .....................40

3.1. Tipos de dados ..........................................................................40

3.2. Variáveis e Constantes ..............................................................42

3.3. Operador de Atribuição (=) ........................................................49

Page 4: Programação 2 Linguagem C (UFRPE)

Capítulo 4 – Comandos de Entrada e Saída de Dados ....................54

4.1. Entrada de Dados ......................................................................54

4.2. Saída de Dados .........................................................................59

4.3. Erros Frequentes no Uso dos Comandos de Entrada e Saída .65

4.4. Primeiros programas em C ........................................................66

Capítulo 5 – Operadores, Expressões e Funções Matemáticas .....75

5.1. Operadores Básicos ..................................................................75

5.2. Operadores Aritméticos de Atribuição ......................................87

5.3. Operadores ++ e -- ....................................................................87

5.4. Conversão de tipo ......................................................................88

5.5. Funções Matemáticas (biblioteca math.h) .................................90

Page 5: Programação 2 Linguagem C (UFRPE)

Plano da Disciplina

Carga horária: 60h

Ementa da Disciplina

Introdução à linguagem de programação C. Tipos de dados, variáveis, operadores aritméticos, relacionais e lógicos. Comandos de entrada e saída. Estruturas de seleção e repetição. Modularização. Vetores e registros. Ponteiros. Arquivos. Manipulação de caracteres. Comandos de tela. Comandos de manipulação de data e hora.

Objetivos

Objetivo Geral

• Apresentar técnicas de programação estruturada utilizando como ferramenta a linguagem de programação C

Objetivos Epecíficos

• Desenvolver a capacidade de solução de problemas de programação, com o uso da linguagem C.

• Introduzir métodos de otimização para garantir eficiência e segurança aos programas.

• Desenvolver o auto-aprendizado.

Conteúdo Programático

Módulo 1 - Introdução à Linguagem de Programação C

Carga Horária do Módulo 01: 15 h

Objetivo do Módulo 01: Introdução ao C e seus comandos básicos, para possibilitar a construção dos primeiros programas nesta linguagem.

Conteúdo Programático do Módulo 1

• Introdução ao C

Page 6: Programação 2 Linguagem C (UFRPE)

○ Conceito de programa e linguagem de programação

○ Introdução ao C: Um breve histórico

○ Etapas de desenvolvimento de um programa

• Comandos Básicos do C

○ Estrutura de um programa C

○ Diretivas de compilação

○ Uso de comentário

○ Tipos de dados

○ Variáveis, constantes, identificadores e atribuição

○ Comandos de entrada e saída

○ Operadores aritméticos, relacionais e lógicos

○ Modificadores de tipos de dados

○ Funções matemáticas

Módulo 2 – Estruturas de Controle de Fluxo e Modularização

Carga Horária do Módulo 2: 15 h

Objetivo do Módulo 2: Possibilitar o conhecimento das estruturas de controle (seleção e repetição) do C e métodos para modularização dos programas (criação de procedimentos e funções).

Conteúdo Programático do Módulo 2:

• Estruturas de Controle de Fluxo

○ Sequência

○ Estrutura de seleção: If e Switch

○ Estrutura de repetição: for, do/while e while

○ Comando break

• Modularização

○ Construção de módulos: funções e procedimentos

○ Passagem de parâmetros e escopo de variáveis

○ Comando return

Page 7: Programação 2 Linguagem C (UFRPE)

Módulo 3 – Armazenamento de Dados em Vetores, Registros e Arquivos

Carga horária do Módulo 03: 15 h

Objetivo do Módulo 03: Apresentar as formas de armazenamento de dados homogêneos (vetores) e heterogêneos (registros), além dos comandos para manipulação de arquivos.

Conteúdo Programático do Módulo 03:

• Tipos de Dados Homogêneos e Heterogêneos

○ Vetores

○ Registros

○ Vetor de registro

• Arquivos

○ Ponteiros

○ Comandos para manipulação de arquivo

Módulo 4 – Comandos Avançados

Carga Horária do Módulo 4: 15 h

Objetivo do Módulo 4: Apresentar comandos mais avançados da linguagem C, tais como: manipulação de caracteres, comandos de tela (para melhorias na interface dos programas) e manipulação de data e hora.

Conteúdo Programático do Módulo 4:

• Comandos para Manipulação de Caracteres e Strings

○ Comandos da biblioteca ctype e string

○ Validação de campos

• Comandos de Tela – Interface

○ Comandos da biblioteca conio

• Comandos para Manipulação de data e hora

○ Comandos da biblioteca time

Avaliação

• Avaliação prática em laboratório correspondendo a 60% da nota.

Page 8: Programação 2 Linguagem C (UFRPE)

• Resolução de listas de exercícios, que serão enviadas através do ambiente virtual (30%).

• Avaliação referente à participação do aluno nas aulas presenciais e ambiente virtual: fóruns de discussão, chats, etc (10%).

Bibliografia

Básica:

SCHILDT, Herbert. C Completo e Total. São Paulo: Makron, 1996.

DEITEL, H, M e DEITEL, P. J. Como Programar em C. Rio de Janeiro: LTC, 1999.

Complementar:

ASCENIO, Ana Fernanda Gomes e CAMPOS, Edilene Aparecida Veneruchi. Fundamentos de Programação de Computadores. São Paulo: Prentice Hall, 2002.

Page 9: Programação 2 Linguagem C (UFRPE)

Apresentação

Caro(a) aluno(a),

Seja bem-vindo (a) ao primeiro módulo da disciplina Programação II. Nesta disciplina, você irá aprender a programar na linguagem de programação C, uma das mais utilizadas mundialmente. Desenvolver programas e garantir que estes sejam confiáveis, eficientes e agradáveis de usar requer conhecimento técnico e muito treinamento.

Este livro foi escrito pensando em você, que está iniciando neste mundo da programação de computadores e que precisa ser apresentado, com tranquilidade, a um conjunto de novos conceitos. Os assuntos serão transmitidos gradativamente, de forma que você os absorva com naturalidade.

Este livro contém muitos exemplos de questões resolvidas, comentadas em detalhes, para que você não encontre dificuldades para aprender cada assunto. Além de apresentar dicas para que você desenvolva seus programas de forma eficiente e não cometa os principais erros de programação que ocorrem com quem está iniciando a programar. Ao final de cada capítulo, você poderá testar o seu aprendizado e assimilar melhor o que foi estudado, através da resolução de exercícios. Isto é muito importante! Não deixe de resolvê-los.

De antemão, informamos que programar é muito bom, você vai gostar! Nada melhor do que ver um programa rodando e saber que foi você quem o criou. Mas, não desanime se encontrar alguma dificuldade durante esta caminhada. Às vezes o programa dá um erro e não sabemos onde está o problema. Seja persistente! Ao longo do tempo, a experiência vai te dar mais segurança e você conseguirá encontrar tais erros com facilidade.

O objetivo deste primeiro módulo é fazer uma introdução à linguagem C, conhecer um pouco da sua história e iniciar o estudo da sintaxe da linguagem, que possibilitará a construção de programas básicos. Ao final deste primeiro módulo, você já estará desenvolvendo seus primeiros programas em C. O que você está esperando? Vamos começar?

Bons estudos!

Professora Sônia Virginia Alves França

Page 10: Programação 2 Linguagem C (UFRPE)

10

Programação 2

Conhecendo o Volume 01

Neste primeiro volume, você irá encontrar o módulo 01 da disciplina: Programação II. Este volume está estruturado em cinco capítulos, que serão estudados ao longo de 15h/aula. Para facilitar seus estudos, veja a organização deste primeiro volume.

Capítulo 1: Introdução ao C

Carga Horária do Capítulo 1: 2 h/aula

Objetivos do Capítulo 1: Introduzir os conceitos básicos da área de programação e apresentar um breve histórico sobre a linguagem C.

Conteúdo Programático do Capítulo 1

• Conceito de programas e programação de computadores;

• Linguagens de programação;

• Breve histórico da linguagem de programação C;

• Etapas do desenvolvimento de um programa.

Capítulo 2: Conceitos Preliminares para Programar em C

Carga Horária do Capítulo 2: 3 h/aula

Objetivos do Capítulo 2: Apresentar detalhes mais específicos da linguagem, necessários para dar início à programação em C. Neste capítulo, também será apresentado o ambiente de programação que utilizaremos no desenvolvimento dos programas.

Conteúdo Programático do Capítulo 2

• Estrutura de um programa básico C;

• Palavras reservadas do C;

• Uso de comentários;

• Fundamentos do ambiente C;

• Conhecendo o Dev-cpp.

Page 11: Programação 2 Linguagem C (UFRPE)

11

Programação 2

Capítulo 3: Tipos de Dados, Variáveis e Constantes

Carga Horária do Capítulo 3: 2 h/aula

Objetivos do Capítulo 3: Apresentar os tipos de dados suportados pelo C e introduzir o conceito de variáveis e constantes

Conteúdo Programático do Capítulo 3

• Tipos de dados;

• Variáveis e constantes;

• Operador de atribuição;

Capítulo 4: Comandos de Entrada e Saída de Dados

Carga Horária do Capítulo 4: 4 h/aula

Objetivos do Capítulo 4: Apresentar os comandos de entrada e saída de dados do C. Neste capítulo, você terá acumulado conhecimento suficiente para desenvolver os primeiros programas em C.

Conteúdo Programático do Capítulo 4

• Entrada de dados;

• Saída de dados;

• Desenvolvimento dos primeiros programas C.

Capítulo 5: Operadores, Expressões e Funções Matemáticas

Carga Horária do Capítulo 5: 4 h/aula

Objetivos do Capítulo 5: Apresentar os operadores básicos (aritméticos, relacionais e lógicos), além de funções complementares para o desenvolvimento de programas que executem expressões mais complexas.

Conteúdo Programático do Capítulo 5

• Operadores aritméticos, lógicos e relacionais;

• Operadores aritméticos de atribuição;

• Operadores ++ e --;

Page 12: Programação 2 Linguagem C (UFRPE)

12

Programação 2

• Conversão de tipos;

• Funções matemáticas.

Ao final de cada capítulo você encontrará:

• A seção “Atividades e Orientações de Estudo”: que contém exercícios para a fixação do assunto estudado, além de indicação de fóruns de discussão.

• A seção “Conheça Mais”: que contém dicas de sites e livros que devem ser lidos para ampliar os seus conhecimentos.

• A seção “Vamos Revisar?”: que apresenta um resumo dos principais tópicos abordados no capítulo.

Page 13: Programação 2 Linguagem C (UFRPE)

13

Programação 2

Capítulo 1 – Introdução ao C

Vamos conversar sobre o assunto?

Neste primeiro capítulo, será feita uma apresentação do que é programação e quais as principais linguagens de programação do mercado, dando ênfase à linguagem C. Este capítulo é importante, porque conheceremos um pouco da história da linguagem de programação que iremos aprender nesta disciplina. Sempre que conhecemos uma pessoa nova, queremos saber alguns detalhes da sua vida, não é mesmo? Quantos anos ela tem, onde nasceu, quem são seus pais, etc. Neste capítulo, também, serão introduzidos conceitos utilizados na área de programação, visando a nossa preparação para nos lançarmos nesse mundo intrigante da criação de programas computacionais. Então, prontos (as) para o desafio?

1.1. Programas e Programação de Computadores

Um programa de computador é um conjunto de instruções que descrevem uma tarefa que será executada por um computador. Um programa de computador também é conhecido como software, software aplicativo, software de sistema ou simplesmente programa. O termo software é mais utilizado quando é feita uma referência à parte não física do sistema computacional, juntamente com o termo hardware, que faz referência ao conjunto de componentes eletrônicos que constituem um computador.

Os programas que permitem ao usuário fazer uma ou mais tarefas específicas, como as planilhas eletrônicas, editores de texto e jogos são chamados de software aplicativo ou aplicação. Já os programas que dão suporte funcional aos computadores, como os sistemas operacionais e drivers de dispositivos, são chamados de software de sistema1.

O ato de desenvolver programas é chamado de programação de computadores. A programação é o processo de escrita, teste e manutenção de um programa (ASCENIO e CAMPOS, 2002). O desenvolvimento de programas baseado em metodologias ou processos formalizados é conhecido por engenharia de software.

Saiba Mais

1 Além dos software aplicativo e software de sistema, ainda é possivel utilizar a categoria software embutido ou embarcado, destinado a funcionar dentro de uma máquina que não é um computador. Normalmente, estes software têm um propósito muito específico, como, por exemplo: controlar a injeção eletrônica de um carro ou gerenciar o cozimento dos alimentos no forno de microndas. Mais recentemente, surgiu também o software como serviço, que é um software que roda diretamente na internet, não sendo necessário instalar nada no computador do usuário.

Page 14: Programação 2 Linguagem C (UFRPE)

14

Programação 2

Os programas são escritos em uma linguagem de programação. Assim como o Português, o Inglês e o Espanhol, as linguagens de programação têm as suas regras e devemos seguí-las para escrever nossos programas corretamente. Portanto, a programação de computadores é uma ciência e, por isso, devemos seguir uma metodologia para termos como resultado: programas seguros e eficientes.

Em uma disciplina anterior, vocês aprenderam a desenvolver algoritmos, que são uma sequência de passos para realizar uma tarefa ou resolver um problema. Utilizamos algoritmos no nosso cotidiano para realizar atividades corriqueiras, definindo a sequência de passos que deve ser executada para atingirmos um objetivo, como, por exemplo, os passos que executamos para tomar banho, calibrar um pneu ou fazer um bolo.

Figura 1.1: Exemplos de algoritmos

Para efetuarmos estas atividades, seguimos uma sequência lógica de passos. Se esses passos não tiverem uma lógica, podemos não conseguir atingir o nosso objetivo. Se vocês observarem, para fazer um bolo, existe uma ordem em que os ingredientes devem ser adicionados à receita, caso não sigamos esta ordem, o bolo não ficará bom. Na programação irá ocorrer a mesma coisa, devemos passar as instruções ao computador, utilizando uma linguagem de programação, seguindo uma lógica – a lógica computacional.

Na próxima seção vamos abordar as linguagens de programação, de uma forma mais abrangente, tratando os principais conceitos que envolvem este assunto. Vamos seguir em frente?

Page 15: Programação 2 Linguagem C (UFRPE)

15

Programação 2

1.2. Linguagens de Programação

É através das linguagens de programação que poderemos criar nossos programas. Uma linguagem de programação é um conjunto de regras sintáticas e semânticas usadas para definir um programa. O conjunto de códigos (palavras e símbolos), compostos de acordo com essas regras, constituem o código fonte do nosso programa. Para ser executado pelo processador, o código fonte precisa ser traduzido para código de máquina.

Aprender uma linguagem de programação é um pouco similar a aprender um novo idioma. Temos que saber o significado das palavras, as regras da estruturação das frases, etc., para podermos nos comunicar corretamente no novo idioma.

Figura 1.2: Aprenda a dar ordens ao seu computador

Existem várias linguagens de programação. Vocês sabiam que cada linguagem de programação possui o seu conjunto de regras e um modo de funcionamento próprio? A escolha de uma linguagem de programação para o desenvolvimento de um programa deve estar atrelada ao tipo de problema que deseja resolver. Existem linguagens

Page 16: Programação 2 Linguagem C (UFRPE)

16

Programação 2

que são melhores para resolver um certo tipo de questão do que outras.

De acordo com Sebesta (2003), as linguagens de programação vêm sendo classificadas de várias formas: por geração, de acordo com o paradigma de programação, quanto ao grau de abstração, de acordo com a estrutura de tipos, dentre outras. Uma das classificações mais utilizadas é quanto ao grau de abstração. Segundo esta classificação, as linguagens de programação são divididas em três grupos: linguagens de máquina, linguagens de baixo nível e linguagens de alto nível.

A linguagem de máquina é a linguagem natural dos computadores. Estas linguagens são ininteligíveis para o ser humano não treinado. As linguagens de máquina são representadas por sequências de bits (zeros e uns). Estas sequências representam instruções que serão executadas pelo processador do computador. As instruções correspondem a sequências muito simples de operações, tais como: transferir um dado em memória para a CPU ou somar dois valores. As linguagens de máquina são dependentes do processador, isto é, uma determinada linguagem de máquina só poderá usada por um tipo de computador.

As linguagens de baixo nível são próximas da linguagem de máquina. No entanto, os zeros e uns que formam uma instrução foram substituídos por palavras que representam tais instruções, tornando-as um pouco mais legíveis. Estas linguagens são mais voltadas para a máquina, isto é, são escritas usando as instruções do microprocessador do computador. São chamadas de linguagens Assembly (que significa montagem). Estas linguagens apresentam as seguintes vantagens: os programas são executados com maior velocidade de processamento (já que são executadas diretamente pela máquina) e ocupam menos espaço na memória. No entanto, de modo geral, os programas em Assembly têm pouca portabilidade2 (um código gerado para um tipo de processador não serve para outro) e não são estruturados, tornando a programação mais difícil.

As linguagens de alto nível são mais próximas à linguagem humana (do Inglês, por exemplo) e mais distantes das linguagens de máquina. Por isso, são linguagens mais simples de entender, já que, em geral, utilizam uma sintaxe estruturada, tornando seu código mais legível. Necessitam de compiladores ou interpretadores para gerar instruções do microprocessador. Interpretadores fazem

Saiba Mais

2 No contexto da informática, a portabilidade de um programa é a sua capacidade de ser compilado ou executado em diferentes arquiteturas (seja de hardware ou de software).

Esse termo também vem sendo utilizado pelas empresas de telefonia móvel, quando se referem à portabilidade de número, ou seja, você muda de operadora, mas nao muda o número do celular.

Page 17: Programação 2 Linguagem C (UFRPE)

17

Programação 2

a interpretação de cada instrução do programa fonte executando-a dentro de um ambiente de programação, Basic e Java são exemplos de linguagens interpretadas. Os compiladores fazem a tradução de todas as instruções do programa fonte gerando um programa executável. Estes programas executáveis (*.exe) podem ser executados fora dos ambientes de programação. A linguagem C e Pascal são exemplos de linguagens compiladas.

As linguagens de alto nível ainda podem ser divididas de acordo com a sua aplicação: genéricas (como C, Java e Pascal, que servem para o desenvolvimento de programas de propósito geral) ou específicas (como Fortran - utilizada para execução de cálculos matemáticos, LISP - desenvolvimento de aplicações na área de inteligência artificial e CLIPPER – utilizada para aplicações que manipulam bancos de dados). As vantagens das linguagens de alto nível são: portabilidade (por serem compiladas ou interpretadas podem ser executadas em várias plataformas com pouquíssimas modificações) e facilidade de desenvolvimento de programas. No entanto, as rotinas geradas são mais genéricas (e mais complexas) e por isso são mais lentas e ocupam mais memória.

A figura 1.3, a seguir, apresenta um trecho de código escrito em linguagem de máquina, linguagem de baixo nível e linguagem de alto nível, respectivamente.

Linguagem de Máquina

10110101 11100110 11000100

Linguagem de Baixo Nível

LOAD BASE ADD BONUS

STORE SALARIO

Linguagem de Alto Nível

Salario = Base + Bonus

Figura 1.3: Trecho de código em diferentes linguagens

Notem como o código em linguagem de máquina é incompreensível. Difícil entender essas seqüências de zeros e uns, não é mesmo? O código na linguagem de baixo nível é mais legível e passamos a entender as instruções. Na linguagem de alto nível, o código fica menor e muito mais simples. Em qual tipo de linguagem vocês querem programar? Nem precisamos parar para pensar, não é mesmo?

Page 18: Programação 2 Linguagem C (UFRPE)

18

Programação 2

Figura 1.4: Linguagens de baixo nível x linguagens de alto nível

1.3. Breve Histórico da Linguagem de Programação C

Vamos conhecer um pouco sobre a história do C? A linguagem de programação C nasceu em 1972 nos laboratórios Bell, Estados Unidos. Seus criadores são Brian Kernighan e Dennis M. Ritchie. A linguagem C foi criada a partir da linguagem B (sugestivo, não é?), que havia sido desenvolvida no final dos anos 60 por Ken Thompson.

O C é uma linguagem de alto nível, compilada e estruturada3. No entanto, o C possui instruções de baixo nível, bem próximas à linguagem de máquina, que só o Assembler possui. O objetivo dos seus criadores era usar o C para desenvolver o sistema operacional UNIX, que originalmente foi escrito em Assembly (linguagem de baixo nível). Desde então, espalhou-se por muitos outros sistemas e tornou-se uma das linguagens de programação mais usadas, e influenciando o desenvolvimento de muitas outras linguagens como C++ e Java.

Com a linguagem C podemos construir programas organizados e concisos (características dos programas das linguagens de alto

Saiba Mais

3Uma linguagem é considerada estruturada quando permite que o programador pegue trechos de maior uso do seu programa e transforme-os em pequenos módulos (procedimentos e funções) que serão reutilizados sempre que necessário.

Page 19: Programação 2 Linguagem C (UFRPE)

19

Programação 2

nível), ocupando pouco espaço de memória e com alta velocidade de execução (como o Assembler). Infelizmente, dada toda a flexibilidade da linguagem, também poderemos escrever programas desorganizados e difíceis de serem compreendidos. Portanto, cabe ao programador de C utilizar boas práticas de programação, para ter programas legíveis e de fácil manutenção.

Existem inúmeras razões para que o C seja uma das linguagens mais preferidas dos programadores. As características da linguagem C mostram o porquê de sua ampla aceitação. Vejamos algumas características da linguagem C.

• Portabilidade entre máquinas e sistemas operacionais;

• Dados compostos em forma estruturada;

• Programas estruturados;

• Total interação com o sistema operacional;

• Código compacto e rápido, quando comparado ao código de outras linguagens de alto nível.

Agora que já conhecemos um pouco mais da linguagem C, vamos entender o processo de desenvolvimento de um programa. Quais são os passos que devemos seguir para termos um programa pronto? Vamos começar a falar sobre isto agora mesmo. Continuem firmes na leitura!

1.4. Criação, Compilação e Execução de um Programa

Nesta seção vamos estudar as etapas de desenvolvimento de um programa em C. O desenvolvimento de um programa é dividido em três etapas, como mostra a figura 1.5.

Figura 1.5: Estados do desenvolvimento de um programa em C

A primeira etapa para o desenvolvimento de um programa em C é

Page 20: Programação 2 Linguagem C (UFRPE)

20

Programação 2

a criação do programa fonte, que consiste no “texto” formado pelo conjunto de comandos que nós desejamos que o computador execute. O programa fonte deve ser escrito respeitando as regras da linguagem. De modo geral, os programas fontes são digitados em editores de texto genéricos ou específicos dos ambientes de programação. No próximo capítulo deste volume, vamos conhecer detalhadamente o ambiente de programação que será utilizado para o desenvolvimento dos nossos programas em C.

Com o programa fonte pronto, passamos para a etapa de compilação. O compilador é um programa que verifica se o programa fonte não apresenta nenhum erro de sintaxe e gera o programa executável. Quando o programa fonte apresenta algum problema, dizemos que ocorreu um “erro de compilação”. Assim, o programador deverá avaliar o programa fonte, para a retirada tais erros. Normalmente, os compiladores indicam os prováveis erros de sintaxe cometidos pelo programador. Se o programa não tiver erros de sintaxe, o compilador irá gerar o programa executável.

A etapa final consiste na execução do programa executável. Neste momento, o programador deverá testar se o programa está produzindo os resultados esperados. Quando o programa apresenta algum erro nesta fase, como, por exemplo, mostrar um resultado incorreto, dizemos que ocorreu um “erro de lógica” ou “erro de execução”. Isso ocorre porque, apesar do programa não ter apresentado erros de sintaxe, o que tornou possível a geração do programa executável, a sequência de comandos não foi definida de forma correta. Quando ocorre um erro de lógica, o programador deverá revisar o seu programa fonte e passá-lo novamente pela fase de compilação, para que um novo executável, sem erros, seja gerado. Como o compilador não nos avisa onde estão os erros de lógica, estes são mais difíceis de serem corrigidos.

Após ter certeza que o programa executável está correto, sem erros de lógica, o programador poderá entregá-lo ao seu cliente. É importante fazermos vários testes nos nossos programas. Testar com vários valores e verificar se está realmente tudo como esperado. Não fica bem nosso cliente ficar ligando, dizendo que o programa está com BUG!4 Lembrem-se sempre, o computador só executa as instruções que nós mandarmos. Se houver erros, a responsabilidade será nossa que não fizemos o programa corretamente! Vocês não vão querer passar por uma situação como essa? Vão?

Saiba Mais

4 Bug é um erro no funcionamento de um programa. É também chamado de erro de lógica, e pode causar discrepâncias no objetivo ou impossibilidade de utilização de um programa de computador. O uso do termo bug para descrever defeitos inexplicáveis foi parte do jargão da engenharia por várias décadas. Acredita-se que o termo foi criado por Thomas Edison quando um inseto (bug, em Inglês) causou problemas de leitura em seu fonógrafo em 1878.

Page 21: Programação 2 Linguagem C (UFRPE)

21

Programação 2

Nesta fase de execução do programa executável, nós também devemos verificar a usabilidade do programa, ou seja, se o programa ficou fácil de ser utilizado pelo seu usuário. Quando o programa é de difícil utilização ou confunde o usuário, induzindo-o ao erro, ele perde o interesse em utilizá-lo ou comprá-lo. Também devemos verificar se nosso programa tem um bom desempenho, ou seja, se ele processa rapidamente as operações. Usuário não gosta de programa lento, não é mesmo?

Atividades e Orientações de Estudo

Agora é o momento de analisarmos se os assuntos abordados neste capítulo foram bem absorvidos. Foram vistos muitos conceitos novos, não é mesmo? Vamos responder as questões a seguir. Caso sintam necessidade, releiam alguma seção que não foi muito bem assimilada ou complementem as respostas com a leitura dos sites indicados na próxima seção. Vocês estão preparados(as)?

1. Para que serve uma linguagem de programação?

2. Quais as desvantagens das linguagens de baixo nível?

3. Por que desejamos programas portáveis?

4. O que motivou a criação da linguagem C?

5. A linguagem C é de baixo ou alto nível?

6. A linguagem C é compilada ou interpretada?

7. Por que os erros de lógica são mais difíceis de serem corrigidos?

8. Por que devemos nos preocupar com a usabilidade dos nossos programas?

Conheça Mais

Para ampliar os seus conhecimentos sobre os assuntos tratados neste capítulo, visite o site da OReilly. Neste endereço,

Page 22: Programação 2 Linguagem C (UFRPE)

22

Programação 2

http://oreilly.com/pub/a/oreilly/news/languageposter_0504.html, foi disponibilizado um pôster, muitíssimo interessante, como uma “árvore genealógica” das principais linguagens de programação dos últimos 50 anos. Vale a pena dar uma olhada.

É muito importante que vocês se cadastrem em algum fórum de discussão sobre a linguagem C. Assim, vocês poderão conversar e trocar idéias com programadores de C mais experientes. Exemplos de fóruns de C: DevMedia e Linha de código.

Vamos revisar?

Vamos dar uma reforçada em nosso aprendizado com esta pequena revisão dos principais conceitos apresentados neste capítulo. Observem o resumo a seguir:

• Programa: é um conjunto de instruções que descrevem uma tarefa que será executada por um computador.

• Programação de Computadores: é o processo de escrita, teste e manutenção de um programa.

• Algoritmo: sequência de passos para realizar uma tarefa ou resolver um problema.

• Linguagem de Programação: é um conjunto de regras sintáticas e semânticas usadas para definir um programa.

• Linguagem de máquina: é a linguagem natural dos computadores. As instruções são formadas por zeros e uns. Estas linguagens não são legíveis para um programador sem experiência.

• Linguagens de baixo nível: são linguagens escritas usando as instruções do microprocessador do computador. Estas linguagens são mais difíceis de entender e criar programas.

• Linguagens de alto nível: são linguagens mais próximas à linguagem humana e mais distantes das linguagens de máquina. São linguagens mais simples de entender, já que, em geral, utilizam uma sintaxe estruturada, tornando seu código mais legível.

• Compiladores: são programas que fazem a tradução de todas as instruções do programa fonte gerando um programa executável.

Page 23: Programação 2 Linguagem C (UFRPE)

23

Programação 2

• Interpretadores: são programas que interpretam cada instrução do programa fonte executando-a dentro de um ambiente de programação.

• Compilação: é o processo, executado pelo compilador, que verifica se existem erros de sintaxe no código fonte e gera um programa executável.

• Erro de sintaxe: ocorre durante o processo de compilação do programa, quando o programador, ao editar o seu programa fonte, não respeita alguma regra de sintaxe da linguagem de programação.

• Erro de lógica: ocorre durante a execução de um programa, devido um erro na lógica dos comandos.

Page 24: Programação 2 Linguagem C (UFRPE)

24

Programação 2

Capítulo 2 – Conceitos Preliminares para Programar em C

Vamos conversar sobre o assunto?

Neste capítulo, serão abordados conceitos preliminares que irão nos preparar para programar em C. Estes conceitos estão relacionados à estrutura de um programa básico em C. Aqui, também, será apresentado o ambiente de programação que utilizaremos para o desenvolvimento dos nossos programas – o Dev-cpp. Este ambiente apresenta uma interface amigável, que facilitará o processo de programação. Vocês devem baixar e instalar o Dev-Cpp5, o quanto antes, no computador que será utilizado para a prática desta linguagem.

É importante que vocês tenham paciência neste início de aprendizado, já que precisamos, inicialmente, acumular o conhecimento necessário para a construção de um programa completo em C. Visando facilitar o aprendizado, em alguns momentos, será feito um paralelo entre a sintaxe do C e do Portugol do VisuAlg6 (linguagem utilizada para escrever algoritmos).

Saiba Mais

5 O Dev-cpp é uma ferramenta gratuita e pode ser baixada acessando o site: www.bloodshed.net/devcpp.html

Saiba Mais

6 Conheça mais o VisuAlg pesquisando no site: http://www.apoioinformatica.inf.br/visualg/linguagem.htm

Page 25: Programação 2 Linguagem C (UFRPE)

25

Programação 2

Figura 2.1: Qualidades de um programador: atenção, paciência e persistência

Vale lembrar que qualquer linguagem de programação é assimilada através da resolução de exercícios. É importantíssimo que a prática de programar faça parte da rotina de vocês. Assim, separem sempre um tempo para resolver as questões propostas neste material. Vocês vão perceber o quanto é bom ver um programa rodando! Que venha o C!

2.1. Estrutura de um Programa Básico em C

Nesta seção, vamos estudar a estrutura de um programa básico em C. Visando facilitar o entendimento e não sobrecarregar vocês com muitos detalhes, alguns elementos da estrutura do programa serão omitidos. Mas, no momento certo, abordaremos tais elementos, certo? Assim, a estrutura do programa que será apresentada nesta seção, é a estrutura mínima de um programa em C.

Nas linguagens de programação em geral, existe uma estrutura que indica a ordem em que deve ser disposto cada elemento do programa. Esta ordem deve ser respeitada para que nossos programas fiquem corretos. Como será a estrutura de um programa em C?

A estrutura básica de um programa C deve seguir a seguinte ordem:

1. Inclusão de bibliotecas (quando necessário);

2. Declaração das constantes (quando necessário);

3. Programa principal;

Page 26: Programação 2 Linguagem C (UFRPE)

26

Programação 2

• Declaração de variáveis (quando necessário);

• Seqüência de comandos.

Para entendermos melhor a estrutura básica de um programa C, vamos analisar o programa de exemplo 2.1, abaixo. Este programa calcula o cubo de um número inteiro fornecido pelo usuário. Na sequência, temos este programa resolvido utilizando o portugol, que é do conhecimento de vocês. Assim, fica fácil compararmos a estrutura do programa em C, com a estrutura do algoritmo. Não se preocupem em entender cada comando do exemplo abaixo, estamos apenas começando a estudar o C, certo?

Exemplo 2.1: Programa C – Cálculo do cubo de um número

1

2

3

4

5

6

7

8

9

10

11

#include <stdio.h>

main()

{

int num,c;

printf(“Cubo de um numero\n\n”);

printf(“Digite o numero: “);

scanf(“%d”,&num);

c = num*num*num;

printf(“\nCubo de %d = %d”,num,c);

getche();

}

Segue abaixo o algoritmo, escrito no VisuAlg, que calcula o cubo de um número.

Page 27: Programação 2 Linguagem C (UFRPE)

27

Programação 2

Exemplo 2.2: Algoritmo – Calculo do cubo de um número

1

2

3

4

5

6

7

8

9

10

algoritmo “Cubo”

var

num, c: inteiro

inicio

escreval(“Cubo de um numero”)

escreva(“Digite o numero: “)

leia(num)

c <- num*num*num

escreval(“Cubo de “, num, “ = “, c)

fimalgoritmo

Um programa em C inicia com a inclusão de bibliotecas. Uma biblioteca é um arquivo que contém comandos complementares, que são utilizados pelo nosso programa. Para a inclusão de uma biblioteca devemos usar um comando que é chamado de diretiva de compilação. Este comando informa ao compilador quais bibliotecas devem ser anexadas ao programa executável. Assim, o comando para a inclusão de uma biblioteca tem a seguinte sintaxe:

Sintaxe

#include <nome_do_arquivo_da_ biblioteca>

De acordo com a sintaxe, para incluir uma biblioteca ao nosso programa devemos colocar a diretiva de compilação #include e, entre os símbolos < e >, colocamos o nome do arquivo da biblioteca. De maneira geral, os arquivos de biblioteca têm a terminação .h (esse h vem de header, ou seja, este é um arquivo de cabeçalho). Para cada biblioteca, que será incluída no nosso programa, devemos colocar um comando #include. No exemplo 2.1, na linha 1, é feita a inclusão de uma biblioteca: stdio.h. Na medida em que formos aprendendo os comandos, serão indicadas quais bibliotecas devem ser incluídas no programa. A quantidade de bibliotecas e quais bibliotecas serão

Page 28: Programação 2 Linguagem C (UFRPE)

28

Programação 2

incluídas, depende dos comandos que serão utilizados no programa. Pode ser que em um programa, não seja necessário incluir nenhuma biblioteca.

O segundo item da estrutura de um programa C é a declaração das constantes, esse item é opcional, só constará no nosso programa, caso seja necessário. Veremos a declaração de constantes, em detalhes, no próximo capítulo. No exemplo 2.1 não foi necessário o uso de constantes.

O terceiro item da estrutura do programa C é o programa principal. É no programa principal que colocaremos a sequência de comandos que deve ser executada para a solução do problema que desejamos resolver. Nós devemos informar onde começa e termina o programa principal. O programa principal inicia com: main()7, como mostra a linha 2, do exemplo 2.1. A sequência de comandos do programa principal é delimitada por um par de chaves: { (abre chaves) e } (fecha chaves). As chaves que delimitam o corpo do programa principal8 aparecem nas linhas 3 e 11, do exemplo 2.1. Fazendo uma comparação com o algoritmo do exemplo 2.2, as chaves fazem o papel do “inicio” e “fimalgoritmo”, das linhas 4 e 10.

Logo no início do programa principal, devem ser declaradas as variáveis (que serão abordadas no próximo capítulo). A declaração de variáveis é um item opcional, pode acontecer de não precisarmos declarar variáveis no nosso programa. No exemplo 2.1, a declaração de variáveis é feita na linha 4. Foram declaradas duas variáveis do tipo inteiro: num e c. No algoritmo, exemplo 2.2, as variáveis são declaradas fora do programa principal, na seção de declaração de variáveis (linhas 2 e 3).

Após a declaração das variáveis, colocamos a sequência de comandos que o programa deverá executar. O programa termina com o fecha chaves que delimita o programa principal.

Agora que já sabemos como é a estrutura de um programa básico em C, vamos começar a aprender a sintaxe dos comandos para darmos início ao desenvolvimento dos nossos programas.

2.2. Palavras Reservadas do C

Como mencionado no capítulo anterior, as linguagens de programação são formadas por um conjunto de regras de sintaxe e

Saiba Mais

7 Do Inglês, main significa principal. Todo programa C começa a sua execução a partir do programa principal. Assim, o programa principal é uma parte obrigatória na estrutura de um programa C.

Saiba Mais

8 Chamamos de corpo do programa principal toda a sequência de comandos que faz parte do programa principal. Ou seja, a seqüência de comando que aparece entre as chaves de abertura e término do programa principal.

Page 29: Programação 2 Linguagem C (UFRPE)

29

Programação 2

semântica que ditam como o programa deve ser escrito. Com isso, dentro dessas regras, existe um conjunto de palavras que tem um significado para a linguagem de programação – são as palavras reservadas. Uma palavra reservada é, essencialmente, um comando e, na maioria das vezes, as palavras reservadas de uma linguagem definem o que pode ser feito e como pode ser feito.

As palavras reservadas são de uso exclusivo da gramática da linguagem, por isso, não podem ser utilizadas, pelo programador, para dar nome a alguma variável, constante ou função do seu programa. Assim, um programador não pode ter uma variável chamada “int” no seu programa C, já que “int” é uma palavra reservada que indica um tipo de dado.

Na linguagem C temos 32 palavras reservadas. Todas as palavras reservadas do C são escritas em minúsculo. A tabela abaixo mostra as palavras reservadas, conforme definido pelo padrão ANSI9, para a linguagem C.

auto break case char const switch volatile

continue

default do

double else

typedef while enum extern

float for

goto union

if int

long register

unsigned return short

signed sizeof static struct void

No Dev-cpp, ambiente de programação que será utilizado, sempre que digitarmos uma palavra reservada no nosso programa, esta aparecerá em negrito. Isto facilita no momento da programação, pois não precisaremos decorar esta lista de palavras reservadas. Que alívio! Assim que uma palavra ficar em negrito no nosso programa, poderemos verificar se estamos utilizando-a de forma correta.

2.3 Uso de Comentários

Os comentários são utilizados para documentar um programa. A colocação de comentários em um programa é uma das boas práticas de programação10. Os comentários irão facilitar o entendimento e manutenção de programas. Por exemplo, um programador é responsável por desenvolver o sistema de controle de vendas

Saiba Mais

9 A sigla ANSI significa: American National Standards Institute (Instituto Nacional Americano de Padronização). É uma organização que tem por objetivo facilitar a padronização dos trabalhos de seus membros.

Saiba Mais

10 Ao desenvolver nossos programas utilizando boas práticas de programação, teremos como resultado um código fonte mais legível e um progama executável mais seguro e eficiente. Ao longo deste material serão ensinadas boas práticas de programação.

Page 30: Programação 2 Linguagem C (UFRPE)

30

Programação 2

da sua empresa. Como o sistema é grande, após um tempo, ele não lembrará mais o porquê de ter colocado uma sequência de comandos no seu programa. Se o programa estiver bem comentado, o programador poderá, rapidamente, ter esta resposta. Além disso, quando desenvolvemos programas em grupo, é importante que os demais membros do grupo entendam o raciocínio do nosso programa e isso pode ser explicado através dos comentários.

Os comentários podem ser colocados em qualquer parte do programa. Quando o compilador identifica um comentário, ele os ignora, já que os comentários são apenas informações para o programador. A linguagem C fornece dois tipos de comentários: de linha e de bloco. Vamos detalhar como funciona cada um deles.

Os comentários de linha são mais utilizados quando desejamos comentar uma única linha do nosso programa. Um comentário de linha possui a sintaxe a seguir:

Sintaxe

// texto do comentário

Um comentário de linha inicia com duas barras “//” e, na sequência, vem o texto do comentário. O exemplo 2.3, a seguir, apresenta um programa comentado. Na linha 7 temos o exemplo de um comentário de linha. Este comentário serviu para informar para que serve a variável C. Assim que o compilador encontra “//”, ele ignora todo texto que vem após as duas barras11. Este tipo de comentário age apenas na linha que ele é inserido.

O segundo tipo de comentário disponível na linguagem C é o comentário de bloco. Os comentários de bloco são utilizados quando queremos fazer um comentário maior, que compreenda mais de uma linha de comentário. A sintaxe do comentário de bloco é a seguinte:

Sintaxe

/* texto do comentário

texto do comentário

texto do comentário */

Um comentário de bloco inicia com barra-asterisco “/*” e termina por asterisco-barra “*/”. O compilador irá ignorar tudo o que encontrar

Saiba Mais

11No Dev-cpp, quando colocamos um comentário, as letras do texto comentado ficam cinza

Page 31: Programação 2 Linguagem C (UFRPE)

31

Programação 2

entre estes dois símbolos. Veja no exemplo 2.3, que nas linhas 2, 3, e 4 aparece um comentário de bloco. Este tipo de comentário do exemplo é utilizado para identificar quem é o programador quando o programa foi feito e o que o programa faz. Devemos Adotar este tipo de comentário no início dos nossos programas. Assim, ao abrir um programa, rapidamente, saberemos para que ele serve. Devemos tomar cuidado para não esquecer o “*/” que fecha o comentário de bloco.

Exemplo 2.3: Programa C Comentado – Calculo do cubo de um número

1

2

3

4

5

6

7

8

9

10

11

12

13

14

#include <stdio.h>

/* Programador: Sônia França

Data: 09/03/2009

Programa calcular o cubo de um número */

main()

{

int Num, C; // C guarda o cubo do numero

printf(“Cubo de um numero\n\n”);

printf(“Digite o numero: “);

scanf(“%d”,&Num);

C = Num*Num*Num;

printf(“\nCubo de %d = %d”,Num,C);

getche();

}

2.4. Os Fundamentos do Ambiente C

Na seção 1.5, do capítulo anterior, foram abordados os processos de criação, compilação e execução de um programa. Nesta seção, vamos detalhar um pouco mais estes processos, entendendo os

Page 32: Programação 2 Linguagem C (UFRPE)

32

Programação 2

fundamentos do ambiente C. A figura 2.2 apresenta um ambiente C, com as seis fases pelas quais passa um programa, desde a sua edição, até a sua execução.

Figura 2.2: Ambiente C

A fase 1 compreende a edição do nosso programa. O programa é criado com a utilização de um editor e é armazenado no disco do computador (HD - Hard Disk). O arquivo que contém o nosso programa tem a terminação .c, e este é chamado de programa fonte ou código fonte.

Ao terminar a edição do programa, o programador solicita que o seu código fonte seja compilado. O compilador traduz o código fonte para o código em linguagem de máquina (também chamado de código objeto). Vocês se lembram das diretivas de compilação? Antes da tradução, temos a fase 2, em que o pré-processador

Page 33: Programação 2 Linguagem C (UFRPE)

33

Programação 2

analisa o código fonte, executando as diretivas de compilação. O pré-processador também é responsável por eliminar os comentários que o programador colocou no seu código fonte. O pré-processador é ativado automaticamente pelo compilador. Na fase 3, é que ocorre o processo de compilação, após o código fonte ter sido pré-processado. Para que o processo de compilação seja concluído, o programa não pode apresentar erros de sintaxe.

Na fase 4, ocorre o processo de linking, que consiste na ligação do código objeto, gerado pelo compilador, com o código das funções que estão disponíveis nas bibliotecas que incluímos no nosso programa. Ou seja, no exemplo 2.1, em que foi incluída uma biblioteca, o linker deverá localizar o arquivo da biblioteca e fazer a ligação com o código objeto. Esta fase termina com a geração do programa executável, armazenando-o no disco do computador. No Dev-cpp, o programa executável é armazenado no mesmo diretório que tiver armazenado o código fonte. Na Figura 2.3, temos um diretório contendo o arquivo do código objeto (.c – C source file) e o programa executável (.exe – application). O arquivo do programa executável não pode ser editado, o que nós podemos editar é o arquivo do código fonte.

Figura 2.3: Diretório contendo código objeto e o programa executável

As fases 5 e 6 consistem na execução do programa executável. Para dar início a execução de um programa, é necessário que o mesmo esteja na memória principal do computador. Isto é feito na fase 5, pelo carregador do programa. O carregador pega o programa executável que está armazenado no disco e o transfere para memória principal. Assim que o programa está na memória principal do computador, ele está pronto para ser executado. A execução de um programa é feita pela CPU12, que executa as instruções do programa, uma após a outra, até o seu término.

Saiba Mais

12 CPU é a sigla para Central Processing Unit, em Inglês, ou Unidade Central de Processamento. A CPU é a parte do computador que processa as instruções contidas em um programa.

Page 34: Programação 2 Linguagem C (UFRPE)

34

Programação 2

Na próxima seção, vamos conhecer o Dev-Cpp, que possibilitará a criação, compilação e execução dos nossos programas. Com o Dev-cpp poderemos observar as fases aqui descritas.

2.5. Conhecendo o Dev-cpp

O Dev-Cpp é um ambiente de programação que edita, compila e executa programas C e C++13. Sabem porque iremos usar o Dev-cpp para desenvolver nossos programas? O Dev-cpp é gratuito (muito importante!) e possui uma interface bastante amigável (mais importante ainda!). A Figura 2.4 apresenta a tela principal do Dev-cpp.

Figura 2.4: Tela principal do Dev-cpp

Como mencionado no início deste capítulo, vocês deverão baixar o Dev-cpp e instalar no seu computador, para que possamos fazer os nossos programas. O processo de instalação não apresenta dificuldades. Vocês só devem ficar atentos no momento que for questionado sobre qual idioma deseja utilizar, para que faça a escolha do idioma correto (Português), certo? Assim, a interface do Dev-cpp ficará toda em Português, facilitando os seus estudos.

Vamos analisar a tela principal do Dev-cpp, apresentada na figura 2.4. Na parte 1 temos o menu principal do Dev-cpp, que disponibiliza

Saiba Mais

13 C++ é uma linguagem de programação que surgiu a partir do C.

Page 35: Programação 2 Linguagem C (UFRPE)

35

Programação 2

as seguintes opções:

• Arquivo: o menu arquivo disponibiliza, basicamente, as opções para criar, salvar, imprimir e fechar arquivos.

• Editar: neste menu encontraremos as opções: copiar, colar, selecionar, refazer e desfazer.

• Localizar: as opções deste menu nos possibilita localizar alguma palavra no programa fonte, além de permitir substituições de uma palavra por outra.

• Exibir: neste menu temos as opções que nos permite exibir ou esconder itens da interface do ambiente, como por exemplo: barra de ferramenta e barra de status.

• Projeto: permite a adição ou remoção de arquivos em um projeto.

• Executar: é através deste menu que iremos chamar as opções para a compilação e execução do nosso programa.

• Debug: o debugador auxilia o programador a encontrar erros no programa, tornando possível acompanhar passo a passo a execução dos comandos do programa. Neste menu teremos as opções para utilização do debugador.

• Ferramentas: no menu ferramentas temos as opções para configurar o ambiente (mudar cores, tipo de letra, dentre outros) e também a opção para atualização do Dev-cpp.

• CVS14: este menu é utilizado por quem faz o controle de versões dos programas. Apesar de ser uma função bastante interessante, é mais utilizado quando trabalhamos em grupo ou com programas grandes.

• Janela: neste menu estão disponíveis as opções que nos permitem escolher qual janela de edição deve ficar visível no momento. Utilizamos esta opção quando temos vários programas abertos ao mesmo tempo.

• Ajuda: neste menu encontramos o help do Dev-cpp.

Na parte 2, da Figura 2.4, temos os ícones de atalhos para as opções mais utilizadas no Dev-Cpp. Se vocês deixarem o mouse sobre o ícone, aparecerá um texto, que informa o que ele faz. Na parte 3 temos a área de edição do programa. Para a área de edição ficar

Saiba Mais

14O CVS, ou Concurrent Version System (Sistema de Versões Concorrentes) é um sistema de controle de versões que permite que se trabalhe com diversas versões do mesmo arquivo. Este sistema mantém as versões antigas do seu arquivo e os logs de quem e quando manipulou os arquivos.

É especialmente útil para se controlar versões de um software durante seu desenvolvimento, ou para composição colaborativa de um documento.

Page 36: Programação 2 Linguagem C (UFRPE)

36

Programação 2

disponível, vocês deverão escolher a opção Arquivo/Novo/Arquivo Fonte. É nesta área que digitaremos os nosso programas (código fonte). A parte 4 fica visível quando nosso programa apresenta algum erro de compilação. O compilador indicará em qual linha foi encontrado um erro, e fornece uma dica do que pode ser o erro. Mesmo que vocês tenham instalado o Dev-cpp em Português, as mensagens de erro são apresentadas em Inglês. Por isso, é importante que vocês comecem a se familiarizar com estas mensagens, para que consigam tirar mais rapidamente os erros dos programas.

Segue abaixo um roteiro do que vocês precisam fazer para editar, compilar e executar seus programas no Dev-cpp:

1. Crie um arquivo fonte novo na opção: Arquivo/Novo/Arquivo Fonte;

2. Digite o programa fonte na área de edição. Ao terminar de editá-lo, salve o arquivo;

3. Compile o programa na opção: Executar/Compilar;

4. Se der algum erro no programa, vejam as indicações de erro fornecidas pelo compilador15. Conserte os erros, salve o arquivo e compile novamente. Isto deve ser feito até que seja apresentada uma mensagem indicando que o programa não tem erros de compilação.

5. Se vocês acessarem o diretório que o arquivo do código fonte foi armazenado, notarão que foi criado um arquivo com a extensão .exe (com o mesmo nome do arquivo do código fonte). Este é programa executável. Para executá-lo, escolha a opção Executar/Executar no Dev-cpp. Imediatamente, aparecerá a janela de execução do programa, como mostra a Figura 2.5.

Figura 2.5: Janela do programa em execução

É nesta janela que o programa será executado. Aqui o usuário

Saiba Mais

15 O erro de compilação pode não estar na linha que o complilador está indicando. O erro poderá estar: na linha que ele está indicando, na linha imediatamente acima, ou ainda, em linhas mais acima (menos comum de acontecer).

Page 37: Programação 2 Linguagem C (UFRPE)

37

Programação 2

deverá fornecer os dados solicitados pelo programa, neste caso o programa está solicitando que seja digitado um número. Além disso, também receberá os resultados fornecidos pelo programa. Quando a execução de um programa é finalizada, esta janela será fechada automaticamente.

Agora que já conhecemos o ambiente de desenvolvimento de programa C, precisamos aprender os comandos para fazer um programa completo. Nos próximos capítulos iremos ver tais comandos, para podermos começar a programar. Não fiquem ansiosos(as), a nossa hora de programar está chegando!

Atividades e Orientações de Estudo

Vamos resolver mais uma lista de exercícios? Note que estamos conhecendo, ao poucos, os detalhes que envolve a programação de computadores. A resolução das atividades propostas fará com que estes conceitos sejam assimilados de forma mais natural. É sempre importante complementar o nosso conhecimento com a leitura de livros e materiais disponíveis na Internet, indicados na seção “Conheça Mais”. Será que vocês estão lembrados (as) das respostas para as questões abaixo?

1. Quando é que precisamos incluir uma biblioteca em um programa C?

2. O que é diretiva de compilação?

3. O que deve ter no corpo do programa principal?

4. O que é uma palavra reservada?

5. Porque devemos comentar nossos programas?

6. Qual a função do pré-processador no momento da compilação de um programa?

7. Qual o papel do linker no processo de compilação?

8. Qual elemento do computador é responsável pela execução do programa?

Page 38: Programação 2 Linguagem C (UFRPE)

38

Programação 2

Conheça Mais

Vocês poderão aprender mais sobre boas práticas de programação nos sites:

http://www.ibm.com/developerworks/aix/library/au-hook_duttaC.html

ht tp: / /www2.eletronica.org/ar t igos/eletronica-dig i ta l /programando-em-c-boas-praticas

Para conhecer mais detalhes do ambiente de programação que iremos utilizar, acessem os sites:

http://www.bloodshed.net/dev/index.html

http://www.uniqueness-template.com/devcpp/

Vamos revisar?

Nesta seção iremos revisar os principais tópicos vistos neste capítulo. Vale a pena dar uma lida para verificar como está o nosso aprendizado. Observem o resumo a seguir:

• A estrutura básica de um programa C deve seguir a seguinte ordem: inclusão de bibliotecas, declaração das constantes e programa principal. No corpo de programa principal temos: declaração de variáveis e seqüência de comandos.

• Uma biblioteca é um arquivo que contém comandos complementares, que são utilizados pelo programa. Para a inclusão de uma biblioteca devemos usar um comando que é chamado de diretiva de compilação.

• As palavras reservadas de uma linguagem definem o que pode ser feito e como pode ser feito. O programador não pode utilizar uma palavra reservada da linguagem para dar nome as suas variáveis, constantes e funções.

• O uso de comentário nos programas é uma boa prática de programação, e facilita o entendimento do código fonte.

Page 39: Programação 2 Linguagem C (UFRPE)

39

Programação 2

• Passos para o desenvolvimento de um programa: edição, pré-processamento, compilação, ligação (linking), carregamento e execução.

• O compilador traduz o código fonte para o código em linguagem de máquina. O pré-processador analisa o código fonte, executando as diretivas de compilação.

• O linker faz a ligação do código objeto, gerado pelo compilador, com o código das funções que estão disponíveis nas bibliotecas que incluímos no programa.

• Ao ser executado, um programa deve ser carregado na memória. O carregador, também conhecido por loader, e responsável por acessar o programa armazenado no disco e carregá-lo para a memória principal do computador.

• Os programas são executados passo a passo pelo processador do computador.

Page 40: Programação 2 Linguagem C (UFRPE)

40

Programação 2

Capítulo 3 – Tipos de Dados, Variáveis e Constantes

Vamos conversar sobre o assunto?

Programas são feitos para manipular dados. Armazenar notas, calcular médias, alterar um endereço, etc. Os dados são a essência de um programa. Dados precisam ser armazenados e modificados ao longo da execução do programa. Neste capítulo, iremos conhecer os tipos de dados suportados pela linguagem C e aprender a definir constantes e variáveis.

Inicialmente, os comandos serão apresentados em separado. Mas, logo em seguida, veremos o ponto em que cada comando deve ser colocado na estrutura do programa, certo? Tenham paciência! Vocês irão notar que muito dos conceitos estudados nos capítulos anteriores serão referenciados neste capítulo. Mas isto não é problema, não é mesmo? Vamos continuar os nossos estudos, conhecendo mais um pouco da linguagem C.

3.1. Tipos de dados

Nesta seção, vamos aprender um conceito importante em programação, que é: tipo de dados. De maneira geral, os programas manipulam dados, armazenando-os e, muitas vezes, modificando seus valores. Primeiramente, vamos conhecer quais os tipos de dados são manipulados na linguagem C. Basicamente, a linguagem C, manipula quatro tipos de dados: inteiro, real, caractere e void16. Para cada tipo de dado, é necessária uma quantidade de bits17 para armazená-lo. Além disso, cada tipo de dado possui um conjunto de operações que pode ser executada sobre ele. Nas subseções seguintes, vamos detalhar cada tipo de dado separadamente.

3.1.1. Inteiro

Os dados do tipo inteiro são toda e qualquer informação numérica que pertença ao conjunto dos números inteiros relativos (negativo, nulo ou positivo). Os números inteiros, em C, se dividem em três tipos, como mostra a tabela a seguir.

Saiba Mais

16A linguagem C não possui o tipo lógico, que armazena verdadeiro ou falso.

Saiba Mais

17Bit é uma abreviatura de “Binary Digit” (dígito binário). Este termo foi criado pelo engenheiro belga Claude Shannon que em 1949 para simbolizar uma unidade de informação. Tudo na informática é medido em bits, desde o tamanho de um número até a velocidade de transferência de dados em uma rede. Por ser uma unidade binária, pode ter apenas dois valores, zero ou um.

A partir do bit, surgiu o byte, que nada mais é do que um conjunto de 8 bits. Existem diversos múltiplos dos bytes: um kilobyte (KB), equivalente a 1.024 bytes; um megabyte (MB), equivalente a 1.024 KB; e um gigabyte, equivalente a 1.024 MB.

Page 41: Programação 2 Linguagem C (UFRPE)

41

Programação 2

Tipo Tamanho Intervalo Suportado

Short 16 bits -32.768 a +32.767

Int 32 bits -2.147.483.648 a + 2.147.483.647

Long

64 bits

-9.223.372.036.854.775.808 a

+9.223.372.036.854.775.807

Qual a diferença entre cada um deles? A diferença entre os tipos short, int e long é a quantidade de memória18 que é reservada para armazená-los. Veja como é simples: à medida que se utiliza mais memória, aumenta o intervalo do valor que pode ser armazenado. Por exemplo, para armazenar um dado do tipo short, são reservados 16 bits de memória. Com isso, o tipo short pode suportar um número inteiro no intervalo de -32.768 a +32.767, como apresentado na tabela. Portanto, dependendo do valor que será armazenado, deve ser escolhido um tipo (short, int ou long) que comporte tal valor. Por exemplo, para armazenar a idade de um funcionário, o tipo short é o mais adequado (já que a idade de uma pessoa é um valor que raramente ultrapassa 100). No entanto, para armazenar a quantidade de eleitores de uma cidade, deve-se usar o tipo int (note que em muitas cidades, a quantidade de eleitores ultrapassará o maior valor suportado pelo tipo short: 32.767). Para facilitar nosso estudo, neste material, sempre será usado o tipo int para armazenar os dados inteiros.

3.1.2. Real

Os dados do tipo real são toda e qualquer informação numérica que pertença ao conjunto de números reais (negativo, positivo ou nulo). Os números reais, em C, podem ser de dois tipos, como mostra a tabela abaixo:

Tipo Tamanho Intervalo Suportado

float 32 bits 3.4E-38 a 3.4E+38

double 64 bits 1.7E-308 a 1.7E+308

Para o tipo float são reservados 32 bits de memória, o que possibilita armazenar um valor no intervalo 3.4–38 a 3.438. Como o tipo float suporta valores bem altos, neste material, sempre será usado o tipo float para armazenar os dados reais.

Atenção

18A memória é a parte do computador que tem como função o armazenamento de dados. Quando um dado vai ser armazenado, precisamos reservar uma quantidade de memória para isto.

Page 42: Programação 2 Linguagem C (UFRPE)

42

Programação 2

3.1.3. Caractere

Na linguagem C, os caracteres são do tipo char, representados por toda e qualquer informação composta por um único caractere alfa numérico (a, b, c,...z, A, B, C,...Z, 0...9) ou especial (como por exemplo: ; # ? @ ! < ?). O tipo char armazena um único caractere. Quando se deseja armazenar vários caracteres, é necessário definir um vetor de caractere (mais detalhes na seção 3.2.2). Por exemplo, o nome de um aluno é formado por uma cadeia de caracteres, assim, será necessário usar um vetor de caracteres. Cada caractere armazenado ocupa o espaço de 8 bits de memória. Um caractere deve ser representado entre apóstrofo, por exemplo: ‘a’. Mas, quando temos uma cadeia de caracteres, esta deve ser representada entre aspas dupla, por exemplo: “Pedro Goncalves”.

3.1.4. Void

Em Inglês, void quer dizer vazio e é isto mesmo que o void é. Void é um tipo que não armazena nada (um tanto esquisito, não é?). Este tipo serve para indicar que um resultado não tem um tipo definido. Ele é utilizado quando estamos definindo funções nos nossos programas. Permiti-nos desenvolver funções que não retornam nada e funções que não têm parâmetros. Voltaremos a falar do tipo void no Volume 2, no capítulo que aborda modularização.

3.2. Variáveis e Constantes

Agora que já sabemos os tipos de dados manipulados pela linguagem C, vamos aprender como reservar espaços de memória para o armazenamento dos nossos dados.

Qualquer dado que seja manipulado pelo programa deve ficar armazenado na memória principal do computador. Para que o armazenamento seja possível, precisaremos reservar espaços na memória principal do computador. As variáveis e constantes são unidades básicas de armazenamento dos dados em programação. Elas são um espaço de memória reservado para armazenar um certo tipo de dado e possuem um identificador (nome) para referenciar o seu conteúdo. Dessa forma, nossos dados ficam armazenados em constantes ou variáveis.

Uma variável pode conter, a cada instante, valores diferentes. No

Page 43: Programação 2 Linguagem C (UFRPE)

43

Programação 2

entanto, as constantes referem-se a valores fixos que não podem ser alterados durante a execução do programa. O modo como cada constante é representada depende do seu tipo (este assunto será detalhado um pouco mais a frente).

Para entender o conceito de variáveis e constantes, vamos fazer a seguinte analogia: um armário cheio de gavetas de tamanhos diferentes. Acompanhem o raciocínio: Pedro tem um armário e decide que em cada gaveta será guardado um tipo de roupa: camisa, bermuda, calça, etc.

Figura 3.1: Armário cheio de gavetas

Em uma dada gaveta, só podem ser armazenadas camisas. Não será permitido o armazenamento de calças nesta gaveta. Para facilitar a identificação, Pedro coloca uma etiqueta informando o que cada gaveta guarda. Com isso, Pedro poderá identificar, rapidamente, em qual a gaveta estão guardadas suas camisas.

Agora vamos associar a ideia das gavetas com a ideia de variáveis, constantes e tipo. As gavetas que guardam as roupas são como os espaços de memória que armazenam nossos dados. Assim como uma gaveta só pode armazenar um tipo de roupa, os espaços de memória são especificados para armazenar um tipo de dado. Dependendo do tipo de roupa, a gaveta precisa ser maior ou menor. Da mesma forma, dependendo do tipo de dado, é feito uma reserva de mais ou menos memória para armazená-lo (de acordo com as tabelas da seção 3.1).

As etiquetas das gavetas são os identificadores dos nossos

Page 44: Programação 2 Linguagem C (UFRPE)

44

Programação 2

espaços de memória. Assim, iremos encontrar, facilmente, um dado armazenado nos nossos espaços de memória. Quando temos uma variável, o conteúdo da nossa gaveta pode mudar ao longo do tempo. Mas, no caso de uma constante, seu conteúdo será sempre o mesmo.

Nas próximas seções, vamos aprender as regras para dar nomes às nossas variáveis e constantes e como criar as nossas gavetas – espaços de memória (variáveis e constantes).

3.2.1. Identificadores

Para que o compilador saiba quais dados estamos querendo manipular, eles precisam ter um nome. É como nós, todos temos um nome. Sabemos quando alguém está nos chamando quando falam o nosso nome. Vai acontecer a mesma coisa com os espaços de memória dos nossos programas, precisamos identificá-los, de alguma forma. Os identificadores são os nomes que damos as nossas variáveis, constantes, funções e procedimentos usados no programa. Para criar um identificador é necessário respeitar as regras a seguir:

• O primeiro caractere deve ser uma letra ou _ (underscore);

• O restante do nome deve ser formado por caracteres pertencentes ao seguinte conjunto: a,b,c,..z, A,B,C,...Z, 0,1,2,...,9, _ (ou seja: letras, números e underscore);

• Não deve haver espaço em branco (ou seja, não existe identificadores compostos, formados por dois ou mais nomes);

• Não utilizar acentos, nem cedilha;

• Os identificadores podem ter até 32 caracteres;

• Não deve haver identificadores repetidos (Se dermos o mesmo nome para duas variáveis do nosso programa, o compilador não vai saber qual delas será chamada, e isso não pode acontecer).

A linguagem C faz distinção de maiúsculas e minúsculas. Assim, os identificadores: Media, MEDIA, MediA e media, são diferentes. O fato de termos uma única letra de forma diferente (maiúscula ou minúscula), já faz com que os identificadores se diferenciem. Esta propriedade é chamada de case sensibility (sensibilidade a letras maiúsculas e minúsculas).

Page 45: Programação 2 Linguagem C (UFRPE)

45

Programação 2

DICA: Boa Prática de Programação

Escolham bem os nomes das variáveis e constantes do programa. Os identificadores escolhidos devem ser claros, a fim de explicitar o conteúdo que será armazenado, mas também não devem ser extensos para não dificultar a escrita.

A seguir, vamos verificar exemplos de identificadores corretos e incorretos:

• Identificadores corretos: a, x2, Nome_Aluno, Media, SalarioFuncionario. Note que, quando queremos usar identificadores com mais de uma palavra, que foi o caso de Nome_Aluno, usamos o _ para ligar uma palavra a outra. Ou usamos as palavras juntas, como o exemplo SalarioFuncionario. Lembrando que não podemos usar espaço em branco.

• Identificadores incorretos: 2m (começou com número), media* (caractere * não é permitido), Nome disciplina (não pode haver espaço em branco), funcionário (não pode acentuar).

Até este momento, vimos os conceitos de tipos de dados, variáveis, constantes e identificadores. Na próxima seção, estes conceitos serão utilizados em conjunto, para que possamos declarar as nossas variáveis, ou seja, criar espaços de memória para armazenar os dados manipulados pelo nosso programa. Continuemos a nossa leitura.

3.2.2. Declaração de Variáveis

Para que se possa usar uma variável em um programa, primeiramente, é necessário fazer a declaração dela. A declaração de uma variável informa ao processador duas coisas: o identificador (nome) da variável e o seu tipo de dado. As variáveis precisam de um nome para que o processador saiba onde desejamos armazenar o nosso dado. Além disso, toda variável precisa ser associada a um tipo de dado, para que o processador reserve o espaço de memória necessário para o seu armazenamento. Como visto na seção 3.1, cada tipo de variável, ocupa uma quantidade de bits diferente. Resumindo, toda variável possui um nome, um tipo e um conteúdo (ou valor que é armazenado na variável).

Page 46: Programação 2 Linguagem C (UFRPE)

46

Programação 2

A declaração de variáveis deve obedecer a seguinte sintaxe:

Sintaxe

tipo [variavel_1, variavel_2, ...];

Onde tipo é o tipo de dado (int, float, char) e variavel_1 é o nome da variável a ser declarada. O nome da variável deve seguir a regra dos identificadores (mencionadas na seção 3.2.1). Se houver mais de uma variável do mesmo tipo, seus nomes são separados por vírgulas. Notem que, no final do comando, aparece um ponto e virgula (;), indicando ao compilador que o comando terminou.

Exemplo 3.1: Declaração de Variáveis

1

2

3

int idade, matricula;

float media, total;

char letra, nome_aluno[20];

As variáveis idade e matricula são espaços de memória que armazenam números inteiros. As variáveis media e total armazenam números reais. Note que na linha 3, temos as variáveis letra e nome_aluno. Quando uma variável caractere tem apenas um único caractere, na sua declaração, é necessário apenas dar um nome a esta variável.

Quando houver necessidade de armazenar vários caracteres, temos o que é chamado de cadeia de caracteres, vetor de caracteres ou string. Uma cadeia de caracteres forma uma palavra ou frases. Para declarar uma variável capaz de armazenar uma cadeia de caracteres, devemos colocar ao lado do nome da variável, entre colchetes, um valor inteiro, que significa quantos caracteres podem ser armazenados nesta cadeia. Assim, a variável nome_aluno, declarada na linha 3, tem capacidade de armazenar uma palavra/frase com até 20 caracteres.

A figura 3.2 representa a memória do computador, após a declaração das variáveis do exemplo. Cada caixa representa uma variável. E, cada variável possui o seu identificador. Assim, esta declaração de variáveis resultou na reserva de seis espaços na memória. Toda vez que precisarmos acessar ou armazenar o conteúdo de uma variável, utilizaremos o seu identificador.

Page 47: Programação 2 Linguagem C (UFRPE)

47

Programação 2

Figura 3.2: Representação da memória do computador após a declaração de um conjunto de variáveis

Atenção

Como dito anteriormente, o C difere as letras minúsculas das maiúsculas. Assim, os tipos de dados e comandos que iremos aprender ao longo da disciplina, DEVEM ser escritos em minúsculo. Se vocês fizerem a seguinte declaração : Int x,y; Vai ocorrer um erro no momento da compilação do seu programa, já que o C não conhece o tipo Int com “I” maiúsculo. Fiquem atentos, pois esse é um erro comum para quem está começando a programar em C.

De acordo com o que foi visto, quando estudamos a estrutura da um programa C, as variáveis devem ser declaradas logo quando inicia o corpo do programa principal. Vamos estudar, a seguir, como fazemos para declarar as nossas constantes.

3.2.3. Declaração de Constantes

Diferente das variáveis, as constantes mantêm seu valor ao longo do programa. Para indicar ao compilador que se trata de uma constante, a diretiva de compilação #define é utilizada. Segue a sintaxe da declaração de uma constante.

Sintaxe

#define <identificador> <valor>

Page 48: Programação 2 Linguagem C (UFRPE)

48

Programação 2

Não é necessário colocar o ponto e vírgula no final da linha e também não precisa informar o tipo de dado da constante. O valor de uma constante não pode ser modificado, de maneira alguma, ao longo da execução do programa.

O modo como cada constante é representada depende do seu tipo. Constantes do tipo inteiro são representadas por números sem o componente fracionário, por exemplo, 123 e 2009. Constantes reais precisam do uso de ponto decimal seguido do componente fracionário do número, por exemplo, 302.54. Constantes caractere são colocadas entre apóstrofos, por exemplo, ‘a’. Constantes cadeia de caractere são colocadas entre aspas duplas, por exemplo, “Casa” e “Maria”. A seguir são apresentadas as declarações de quatro constantes:

Exemplo 3.2: Declaração de Constantes

1

2

3

4

#define DIAS 7

#define PI 3.1416

#define RESPOSTA ‘s’

#define DISCIPLINA “Matemática”

De acordo com o exemplo, a constante DIAS irá armazenar sempre 7. Como o valor que esta constante recebeu foi um valor inteiro, o compilador entende, automaticamente, que esta é uma constante inteira. Da mesma forma, como a constante PI recebeu 3.1416 (um número real), o compilador saberá que se trata de uma constante do tipo real. A constante RESPOSTA armazena um char e DISCIPLINA uma cadeia de caracteres.

É interessante declarar uma constante quando sabemos que um valor não será modificado ao longo da execução do programa. Por questões de padronização, declare as suas constantes com todas as letras em maiúsculo, como apresentado nos exemplos. Assim você estará diferenciando-as das variáveis.

De acordo com a estrutura de um programa C, as nossas constantes são declaradas no início do programa, logo após incluirmos as bibliotecas que serão utilizadas. Estão lembrados(as) disso? Se não estão, deem uma revisada na seção 2.1, certo?

Ao serem criadas, as constantes já recebem o valor que elas vão armazenar ao longo do programa. Isto não acontece com as variáveis.

Page 49: Programação 2 Linguagem C (UFRPE)

49

Programação 2

Mas como fazemos para armazenar um valor em uma variável? Esta resposta vocês encontrarão na próxima seção.

3.3. Operador de Atribuição (=)

Esse operador é utilizado para armazenar um valor em uma dada variável. Assim, o operador de atribuição nos possibilita armazenar um dado em um espaço de memória, que foi previamente declarado. É importante que o dado que será armazenado seja compatível com o tipo da variável que receberá a atribuição. Por exemplo, as variáveis reais podem receber valores reais e inteiros. No entanto, uma variável inteira, não pode receber um valor real. Segue a sintaxe do operador de atribuição.

Sintaxe

Variavel = Valor;

Variavel_1 = Variavel_2;

Variavel = Expressão Aritmética;

Variavel = função;

Variavel_1 = variavel_2 = variavel_3 = valor;

O operador de atribuição é representado pelo símbolo =. No lado esquerdo do operador da atribuição, temos a variável que vai receber o valor. No lado direito do operador, temos o valor que será atribuído à variável. Ao final da linha de atribuição deve ter um ponto e vírgula.

Notem que o operador de atribuição permite várias possibilidades. Para um melhor entendimento, o exemplo 3.3 apresenta cada uma das possibilidades do operador de atribuição.

Page 50: Programação 2 Linguagem C (UFRPE)

50

Programação 2

Exemplo 3.3: Comando de atribuição

1

2

3

4

5

6

7

8

9

float Media, X, Y, Z;

int J, L, M, K, A, B;

char Letra;

Media = 7.5;

Letra = ’D’;

X = Y;

K = A + B;

Z = sqrt(4);

J = L = M = 10;

Nas linhas 1, 2 e 3, temos a declaração das variáveis. Lembrem que só podemos armazenar algum valor, caso tenhamos declarado as variáveis. Uma vez que é necessário ter reservado espaços de memória para nossos dados, entendido?

Na linha 4, a variável Media recebeu 7.5 (para números reais, devemos utilizar ponto ao invés de virgula, para separar a parte inteira da parte fracionária do número)19.

Na linha 5, temos uma atribuição para uma variável char com um único caractere. Note que, neste caso, o valor que a variável receberá vem entre apóstrofo. Assim, a variável Letra está recebendo D.

Atenção

O operador de atribuição não é usado para variáveis do tipo char com vários caracteres. Este tipo de atribuição será visto no capítulo “Comandos de Manipulação de Caracteres”, do Volume 4.

Na linha 6, a variável X receberá o valor que está armazenado na variável Y. Na linha 7, a variável K irá receber o resultado da

Saiba Mais

19Onde aparece o = do comando de atribuição, nos lemos: “recebe”. Assim, o comando da linha 4 do exemplo 3.3, seria lido: “Media recebe 7.5”.

Page 51: Programação 2 Linguagem C (UFRPE)

51

Programação 2

expressão A + B, ou seja, será obtido o valor armazenado na variável A, depois o valor da variável B, os valores são somados e o resultado é atribuído a variável K. Uma variável sempre recebe um valor. Quando a atribuição tem uma expressão matemática, a expressão é resolvida e o resultado é atribuído a variável.

Na linha 8, a variável Z receberá o resultado da chamada da função sqrt (que faz o cálculo da raiz quadrada de um número). Veremos mais detalhes sobre estas funções no capítulo 5.

Na linha 9, aparece o que chamamos de atribuição em cadeia. Quando várias variáveis vão receber o mesmo valor, ao invés de ser feita uma atribuição de cada vez, podemos dizer: variavel1 = variavel2 = variavel3 = valor. Nós podemos atribuir o mesmo valor a quantas variáveis quisermos. Coloquei um exemplo com três, certo? No exemplo da linha 9, as variáveis K, L e M vão receber 10. Mas tem um detalhe, nós só podemos usar a atribuição em cadeia quando todas as variáveis que irão receber o valor são do mesmo tipo. Assim, nesta atribuição do exemplo, as três variáveis K, L e M são do mesmo tipo: int.

Atividades e Orientações de Estudo

Temos agora mais uma lista de exercícios para consolidar o nosso entendimento do assunto visto neste capítulo. Vocês perceberam quantas coisas novas nós já aprendemos até aqui? Como uma linguagem de programação envolve vários detalhes, são os exercícios que vão nos ajudar a não esquecer deles. Prontos (as) para acertar todas as questões?

1. Identifique os tipos dos valores abaixo (int, float, char de um caractere ou char de vários caracteres):

1) 1000 2) “09” 3) – 1.56 4) “VERDADE”

5) – 456 6) 34 7) ‘C’ 8) 45.8976

9) “BRASIL” 10) ‘l’ 11) - 5.6 12) 300

2. Abaixo, temos exemplos de identificadores. Assinale os identificadores válidos e descreva o erro dos operadores inválidos.

Page 52: Programação 2 Linguagem C (UFRPE)

52

Programação 2

1) endereco 2) 21brasil 3) fone$com 4) nome_usuario

5) usuario6 6) nome*usuario 7) end*a-6 8) #media

9) nome aluno 10) média 11) _pais 12) Media_da_Turma

3. De acordo com as declarações abaixo, assinale os comando de atribuição inválidos e descreva o erro.

int NUM, X, SOMA;

float MEDIA, K, L;

( ) SOMA = NUM + 2;

( ) MEDIA = SOMA;

( ) NUM = K + L;

( ) X = X + 1

( ) L = SOMA - K;

( ) SOMA + 2 = NUM + 10;

( ) S = SOMA;

( ) X = SOMA - NUM;

Conheça Mais

Comece a aprofundar mais seus conhecimentos com a leituras dos livros clássicos da linguagem C:

• O mais autêntico de todos, tem como autores os criadores desta linguagem: C - A Linguagem de Programação, de B. W. Kernighan e D. M. Ritchie, editora Campus. Este é um livro relativamente difícil de ler, mas é a “Bíblia” da linguagem.

Dois textos mais didáticos são:

• C Completo e Total, de Herbert Schildt, pela editora MAKRON Books.

• Como programar em C, de H. M. Deitel e P. J. Deitel, pela editora LTC.

Page 53: Programação 2 Linguagem C (UFRPE)

53

Programação 2

A vantagem de ver vários livros é que um autor acaba complementado o que o outro escreveu. Além disso, um autor pode explicar um certo assunto de forma mais clara que o outro. Por isso é bom sempre dar uma olhada em livros novos e material disponível na Internet.

Vamos revisar?

Vamos fazer uma revisão do assunto que foi visto neste capítulo, fazendo a leitura do resumo a seguir:

• Os tipos de dados manipulados pelo C são: inteiro, real, caractere e void.

• O tipo inteiro se divide em: int, short ou long. A diferença entre os três tipos é a quantidade de memória reservada para armazená-los.

• O tipo real se divide em: float e double.

• O tipo char armazena um caractere. Quando desejamos armazenar vários caracteres, para formar um nome ou frase, precisamos declarar uma cadeia de caracteres.

• As variáveis são espaços de memória onde armazenamos nossos dados. Uma variável possui um nome, um tipo e um valor.

• Para que um variável passe a existir, precisamos fazer a sua declaração. Ao declarar uma variável, damos a ela um nome, e dizemos que tipo de dado pode ser armazenado na variável.

• Os nomes da variáveis são os identificadores. Para dar um nome a uma variável, precisamos seguir a regra de criação de identificadores.

• As constantes são espaços de memória onde armazenamos um valor que não será alterado durante a execução do programa.

• O comando de atribuição é utilizado quando desejamos armazenar um valor em uma variável.

• A atribuição de um valor a uma variável só poderá ser executada se o tipo de dado que a variável armazena for compatível com o valor que será atribuído.

Page 54: Programação 2 Linguagem C (UFRPE)

54

Programação 2

Capítulo 4 – Comandos de Entrada e Saída de Dados

Vamos conversar sobre o assunto?

Um programa que não fornece resultados, nem recebe valores para serem processados, não tem muita utilidade. De um modo geral, o objetivo pelo qual escrevemos programas é a obtenção de resultados (Saídas) depois da realização de cálculos ou pesquisas (Processamento) através do fornecimento de um conjunto de dados (Entradas). Neste capítulo, iremos a estudar os comandos de entrada e saída de dados. Assim, com o comando de entrada poderemos fornecer dados para que sejam processados pelo programa. Com o comando de saída poderemos receber os resultados do processamento dos nossos dados. Uma boa notícia é que, a partir deste capítulo, teremos adquirido conhecimento suficiente para construir um programa completo em C! Ficaram felizes? Então não vamos perder mais tempo, vamos logo aprender os comandos de entrada e saída de dados.

4.1. Entrada de Dados

O comando de entrada de dados é utilizado quando desejamos fornecer um valor para um nosso programa. A entrada de dados é feita através de um dispositivo de entrada de dados. Os dispositivos mais comuns são: teclado, mouse20, tela sensível ao toque, scanner, dentre outros. A figura 4.1 apresenta alguns destes dispositivos.

Figura 4.1: Dispositivos de Entrada de Dados

Saiba Mais

20Voce sabe quem inventou o mouse? Embora tenha sido inventado por Bill Enghlish, a sua patente pertence a Douglas Engelbart. Ele apresentou este periférico pela primeira vez em 1968 e o chamou de “XY Position Indicator For A Display System”. O primeiro mouse era feito de madeira, com apenas um botão. O invento de Engelbart ficou sem muita utilização devido a falta de necessidade de tal dispositivo, já que a maioria dos computadores utilizavam apenas textos sem cursores na tela. Vocês se imaginam sem um mouse em seus computadores?

Page 55: Programação 2 Linguagem C (UFRPE)

55

Programação 2

Nesta seção, iremos aprender como executar a entrada de um dado (ou a leitura de um dado, como também é chamada) através do teclado. A execução do comando de leitura pressupõe que os dados serão fornecidos do meio externo (teclado), e serão armazenados na memória (variáveis).

O comando que faz a leitura de um dado fornecido via teclado e o armazena em uma variável do programa é o scanf. Fazendo um paralelo com o Portugol, o scanf é o comando leia. Vamos ver a sua sintaxe.

Sintaxe

scanf(“string de controle”, &variavel);

O comando scanf tem um certo nível de detalhes, para entendê-lo, vamos por partes. Na primeira parte do scanf, entre as aspas, aparece a string de controle. O que vem a ser a string de controle? A string de controle indicará que tipo de dado será lido neste momento. A string de controle deve assumir um dos valores abaixo:

String de Controle Significado

%d leitura de números inteiros

%f leitura de números reais

%c leitura de um caractere

%s leitura de cadeia de caracteres

Assim, quando formos ler um dado que vai ser armazenado em uma variável do tipo inteiro, a string de controle deve ser “%d”. Se o valor a ser lido, for um número real, a string de controle será “%f”. Quando o dado a ser lido for um único caractere, a string de controle é “%c” e para ler uma cadeia de caracteres, é utilizado “%s”. Com a resolução de exercícios, vocês não esquecerão o significado de cada string de controle, certo?

Na segunda parte do scanf, colocamos o nome da variável que vai armazenar o valor que será fornecido via teclado, entendido? Notem que antes do nome da variável, aparece um & (e-comercial). O & faz parte da sintaxe do scanf e não pode ser esquecido. NUNCA! Na linguagem C, o & significa: “Endereço de memória”21. Assim, o comando scanf indica que o dado será lido via teclado e será

Saiba Mais

21Nós acessamos uma variável através do seu nome. No entanto, o processador acessa uma variável utilizando o endereço de memória dela. Cada variável criada no nosso programa possui um endereço de memória. Nós não precisamos conhecer o endereço de memória de uma variável, certo? Só precisamos saber o nome dela.

Page 56: Programação 2 Linguagem C (UFRPE)

56

Programação 2

armazenado no endereço de memória da variável. O comando scanf também termina com ponto e vírgula.

Vamos analisar o exemplo 4.1, que apresenta o uso do scanf.

Exemplo 4.1: Comando de Entrada - scanf

1

2

3

4

5

6

int idade;

float salario;

char letra, nome[20];

scanf(“%d”, &idade);

scanf(“%f”, &salario);

scanf(“%c”, &letra);

Nas linhas 1 a 3, temos as declarações das nossas variáveis. No scanf da linha 4, temos a leitura da variável idade. Como esta variável é do tipo int, a string de controle é “%d”. Na linha 5, temos a leitura da variável salário, que é do tipo float. Assim, a string de controle é “%f”. Por fim, na linha 6, temos a leitura da variável letra, que é do tipo char, contendo apenas um caractere. Por conta disso, a string de controle foi “%c”. A string de controle vem sempre entre aspas duplas, certo? Note que também foi declarada uma variável chamada nome, que é uma cadeia de 20 caracteres. No entanto, o comando scanf não funciona corretamente nas leituras de cadeias de caractere. Portanto, quando for necessário fazer a leitura de variáveis deste tipo, teremos que usar um outro comando, que será visto na próxima seção.

4.1.1. Entrada de Cadeia de Caracteres

Como mencionado, o comando scanf não funciona de maneira correta ao ler uma cadeia de caracteres. O problema é que, se nesta cadeia de caractere tiver um espaço em branco, separando uma palavra da outra, ao encontrar o espaço em branco, o processador entende que a leitura terminou, desprezando parte do nosso dado. Então já viu, não dá para ficar com o dado pela metade, não é mesmo?

A solução é usar outro comando de leitura, específico para a leitura de cadeias de caracteres. Este comando é o gets. A sintaxe do gets é a seguinte:

Page 57: Programação 2 Linguagem C (UFRPE)

57

Programação 2

Sintaxe

fflush(stdin);

gets(variável);

Para a execução de um gets, precisamos informar apenas a variável que irá receber o valor lido. Note também que antes do gets, temos o comando fflush. É assim mesmo. Sempre que tivermos um gets, antes temos que executar um fflush. Não esqueça disso, certo?

O comando fflush é um comando que limpa o buffer de entrada de dados (stdin). Estão querendo saber o que é o buffer de entrada? O buffer é um espaço de memória que armazena, temporariamente, os nossos dados. É assim, suponha que o programa está solicitando que seja digitado o nome do usuário. O usuário vai teclando cada letra que forma seu nome. Ao terminar de digitar, ele tecla enter. O enter indica ao processador, que o usuário encerrou aquela entrada de dados. Enquanto não for teclado o enter, o processador vai armazenado cada tecla que está sendo pressionada, no buffer de entrada. Após o enter ser pressionado, o processador pega o nome completo do usuário, que está no buffer de entrada, e transfere para a variável.

Pode parecer complexo, mas não é. A questão é que, enquanto não terminamos de digitar o dado, ele está sendo formado. Só depois de finalizada a entrada, é que ele é pode ser transferido para a variável. A Figura 4.2 ilustra o esquema da entrada de dados.

4.2: Esquema da entrada de dados

A execução do fflush nos assegura que o buffer de entrada está limpo, sem o conteúdo de algum dado que foi teclado anteriormente.

Page 58: Programação 2 Linguagem C (UFRPE)

58

Programação 2

No caso de entradas de dados usando o scanf, não é necessário limpar o buffer de entrada.

Atenção

O gets e o fflush são comandos que se encontram em uma biblioteca chamada stdio.h. Portanto, se você for utilizar estes comandos, esta biblioteca deverá ser incluída na seção de inclusão de bibliotecas do programa. A inclusão é feita com a diretiva de compilação #include e fica assim: #include <stdio.h>.

Vamos agora analisar o exemplo 4.2, que apresenta o uso do comando gets.

Exemplo 4.2: Comando de Entrada - fgets

1

2

3

4

5

char nome_aluno[20], endereco[50];

fflush(stdin);

gets(nome_aluno);

fflush(stdin);

gets(endereco);

Na linha 1, temos as declarações das variáveis nome_aluno e endereco. A variável nome_aluno armazena até 20 caracteres e a variável endereco armazena até 50 caracteres. Antes de executar o gets da linha 3, responsável por ler o nome_aluno, temos, na linha 2, o fflush, responsável por limpar o buffer de entrada. Na sequência, temos a leitura da variável endereco. Assim, é necessária a execução de um novo fflush antes do gets da linha 5. Notem que na leitura de uma variável cadeia de caractere, só usamos o nome dela, desprezamos o colchetes e o número que indica quantos caracteres ela armazena.

Agora que sabemos como fazer a entrada de dados via teclado, vamos aprender a apresentar os dados na tela. Só falta este comando para darmos início a criação dos nossos programas. Estamos bem perto! Vamos em frente!

Page 59: Programação 2 Linguagem C (UFRPE)

59

Programação 2

4.2. Saída de Dados

O comando de saída de dados é utilizado quando desejamos ver o resultado do processamento do nosso programa. Este comando também é utilizado para passar mensagens na tela, solicitando que o usuário faça algo, como por exemplo, digitar a idade dele. Os dispositivos de saídas de dados mais comuns são: monitor, impressora e caixas de som. A figura 4.3 apresenta tais dispositivos.

Figura 4.3: Dispositivos de saída de dados

Vamos agora aprender o comando que fornece a saída de dados para o dispositivo de saída padrão que é a tela do computador. Este comando é o printf. Fazendo um paralelo com o Portugol, o printf é o comando escreva. Vamos ver a sua sintaxe.

Sintaxe

printf(“string de controle”);

printf(“string de controle”, lista de argumentos);

Existem duas sintaxes para o printf. Na primeira, só temos a string de controle, entre as aspas dupla. Usamos esta sintaxe quando queremos escrever apenas texto na tela. Na segunda, além da string de controle, temos a lista de argumentos. Esta sintaxe é aplicada quando iremos escrever texto e valores armazenados nas variáveis. Apesar de aparecer aqui uma string de controle, ela não é similar a do scanf, certo? No printf, a string de controle é uma “máscara” que especifica (formata) o que será impresso e de que maneira será impresso. Na string de controle pode conter: texto, códigos especiais e especificadores de formatos. Calma! Vamos detalhar mais.

Primeiramente, vamos ver quais são os códigos especiais que podem aparecer na string de controle do printf. Os códigos especiais são formados por uma barra invertida (\), seguida de uma letra. O código especial, indica uma ação que deve ser executada pelo printf.

Page 60: Programação 2 Linguagem C (UFRPE)

60

Programação 2

A tabela a seguir apresenta os códigos especiais e o seu significado.

Código Especial Ação

\n Muda o cursor para o início da linha seguinte.

\t tabulação (tab)

\” Escreve uma aspas dupla na tela

\\ Escreve uma barra invertida na tela

\a Dá um alerta sonoro

Vamos analisar exemplos bem simples de printf, que escrevem, apenas um texto na tela.

Exemplo 4.3: Comando de Saída – printf – Escrevendo textos apenas

1

2

3

4

printf(“Ola Mundo!”);

printf(“\nBom Dia...”);

printf(“\n\nIsso eh um teste.\a”);

printf(“\n\nAte \nmais... \ntchau”);

A execução desta sequência de printf do exemplo 4.3, resulta na seguinte tela (Figura 4.4).

Figura 4.4: Tela de execução de um programa: uso do printf

Vamos entender cada printf do exemplo 4.3. Um detalhe essencial que devemos saber: o printf escreve um texto na tela, no ponto em que o cursor se encontra no momento. Quando um programa é executado, o cursor se encontra na primeira coluna, da primeira linha da tela22. No primeiro printf do exemplo, a string de controle tem apenas o texto que

Saiba Mais

22 A tela tem as seguintes dimensões: 80 colunas x 25 linha. Assim, conseguimos escrever em uma linha de tela, 80 caracteres. E conseguimos ter uma tela com até 25 linhas.

Page 61: Programação 2 Linguagem C (UFRPE)

61

Programação 2

queremos colocar na tela: “Ola Mundo!”23. Após terminar este printf, o cursor estará posicionado após a exclamação.

Na sequência, na linha 2, temos um printf cuja string de controle é: “\nBom Dia...”. O \n serviu para fazer com que o cursor mudasse para o início da linha seguinte e logo em seguida, o texto “Bom dia..” foi impresso, e o cursor ficou no final desta linha.

No printf da linha 3, temos a string de controle: “\n\nIsso eh um teste.\a”. A string de controle começa com dois “\n”. Isso faz com que o cursor mude de linha duas vezes. Assim, teremos uma linha em branco na tela. Além disso, na string de controle, também temos um “\a”, que faz com que seja disparado um beep(sinal sonoro) quando este printf for executado. É interessante usar o sinal sonoro quando quisermos chamar a atenção do usuário.

Finalmente, na linha 4, temos o printf com a string de controle: “\n\nAte \nmais... \ntchau”. Como a string de controle começa com dois “\n”, o cursor muda de linha duas vezes, e escreve “Ate”. Na sequência, temos outro “/n”, o que fez o cursor mudar novamente de linha e escrever “mais...”. Por fim, temos outro “\n”, o cursor vai mudar de linha e escreve “tchau”. Notem que um único printf, pode resultar em um texto em várias linhas da tela. Isso não é possível no Portugol.

Vamos ver agora, como escrevemos textos e valores, armazenados nas nossas variáveis, na tela do computador. Para isto, temos que saber mais um detalhe que vai aparecer na string de controle, que são os especificadores de formato. Um especificador de formato marca o lugar e o formato de impressão das variáveis, contidas na lista argumentos (vejam a segunda sintaxe do printf). Deve haver um especificador de formato para cada variável a ser impressa. Todos os especificadores de formato começam com um %. Os especificadores de formato são apresentados na tabela a seguir.

Especificador de Formato Uso

%d Escrever um valor do tipo inteiro

%f Escrever um valor do tipo real

%c Escrever um caractere

%s Escrever uma cadeia de caracteres

%% Escrever o caractere ‘%’

Saiba Mais

23 Atenção: Não use acentos nos textos que serão escritos na tela. No volume 4, aprenderemos como acentuar nossos textos.

Page 62: Programação 2 Linguagem C (UFRPE)

62

Programação 2

Neste caso de impressão na tela, quando temos textos e valores, na string de controle, devemos colocar um especificador de formato, no ponto onde queremos que um valor seja impresso. O especificador deve ser relativo ao tipo de dado que será impresso. Após a string de controle, coloca-se uma vírgula, e na sequência vem a lista de variáveis que será impressa. Assim, nós primeiro montamos a frase (string de controle), informando em que ponto entrarão os valores (usando os especificadores de formato) e depois, informamos quais variáveis serão utilizadas. Vamos ver alguns exemplos.

Exemplo 4.4: Comando de Saída – printf – Escrevendo textos e valores

1

2

3

4

5

6

7

8

9

10

int X, Y, mat, idade;

float A;

X = 1;

Y = 3;

A = 7.5;

mat = 123;

idade = 25;

printf(“O valor de A = %f”, A);

printf(“\n\nO aluno de matricula %d tem %d anos”, mat, idade);

printf(“\n\nResultado da soma: %d”, X+Y);

A sequência do exemplo 4.4 é iniciada com a declaração das variáveis e com a atribuição de valores, para que possamos entender melhor a montagem dos printf. No primeiro printf, da linha 8, queremos que seja apresentado o valor da variável float A. Assim, montamos a string de controle, informando o ponto da frase onde deve ser colocado o valor da variável A, utilizando o especificador de formato de valores reais, o “%f”. Veja na Figura 4.5, a tela resultante da execução desta sequência de comandos.

Page 63: Programação 2 Linguagem C (UFRPE)

63

Programação 2

Figura 4.5: Tela de execução de um programa usando printf com textos e valores

Quando pedimos para que um número real seja apresentado na tela, este é mostrado com uma precisão de seis casa decimais. Por isso, o valor da variável A, aparece como 7.500000. Podemos decidir quantas casas decimais devem ser apresentadas, nem sempre queremos trabalhar com tantas casas decimais, bem como, poderemos precisar trabalhar com um número com mais casas decimais. Aprenderemos daqui a pouco como informar quantas casas decimais devem ser apresentadas, quando um número real for impresso na tela. Por enquanto, vamos continuar a análise do exemplo 4.4, certo?

No segundo printf, na linha 9, queremos que seja apresentado o número de matrícula do aluno e a sua idade. Aqui temos um printf que irá apresentar mais de um valor. O raciocínio é o mesmo. Montamos a string de controle, informando onde vai aparecer o valor das variáveis, utilizando o especificador de formato. O que muda é depois da string de controle. Após a vírgula, devemos colocar as variáveis que serão impressas, na ordem que elas devem aparecer na frase. Ou seja, se na ordem da frase, vem primeiro a matrícula do aluno, então, coloca-se primeiro a variável mat. Quando temos mais de uma variável, elas são separadas por vírgula. Notem que continuamos usando os códigos especiais na string de controle, neste caso foi colocado o “/n”, para mudar o cursor de linha.

Na linha 10, temos um printf que irá apresentar o resultado de um expressão matemática. Isto também é possível. Assim, na parte do printf que indicamos a variável que será impressa, nós colocamos a expressão matemática. A expressão é resolvida e o seu resultado é apresentado na tela.

Vamos ver agora como fazer para que nossos números reais sejam apresentados com a quantidade de casa decimais que quisermos. O que vai mudar é o especificador de formato dos números reais, o “%f”. Agora ele deve ser assim: entre o “%” e o “f”, colocaremos um ponto, seguido de um número, que representa quantas casas decimais nós

Page 64: Programação 2 Linguagem C (UFRPE)

64

Programação 2

queremos que sejam apresentadas. Vejam os printf do exemplo 4.5.

Exemplo 4.5: Comando de Saída – printf – formatando números reais

1

2

3

4

5

6

7

float A, B,C;

A = 3.4;

B = 1.12345;

C = 7.56789;

printf(“A = %.1f”, A);

printf(“\n\nB = %.2f”, B);

printf(“\n\nC = %.2f”, C);

Primeiro, temos as declarações e atribuições para três variáveis reais. Na linha 5, temos o printf que imprime o valor da variável A, vejam como ficou o especificador de formato: “%.1f”. Neste caso, queremos que seja apresentada apenas uma casa decimal deste número. Vejam a Figura 4.6, que apresenta a tela resultante da execução desta sequência de comandos.

Figura 4.6: Tela de execução de programa: formatação de números reais

Nas linhas 6 e 7, temos os printf que imprimem os valores das variáveis B e C. Neste caso, queremos que sejam apresentadas duas casas decimais, por isso, o especificador de formato ficou: “%.2f”. Só vamos ver mais um detalhe. Notem que, quando pedimos para que um número seja apresentado com poucas casas decimais, o printf apresenta um valor arredondado. Como assim? Veja o valor que foi atribuído a variável C, na linha 4 do exemplo: 7.56789. Veja agora o valor que foi apresentado na tela de execução do programa:

Page 65: Programação 2 Linguagem C (UFRPE)

65

Programação 2

7.57. Funciona assim: se queremos que sejam apresentadas apenas duas decimais, o printf vai verificar qual valor tem na terceira casa decimal, se tiver um valor maior ou igual a cinco, ele arredonda o valor apresentado. Se for um número menor que 5, ele não arredonda. Observe o valor da variável B.

Terminamos aqui os comandos de entrada e saída. Como estes comandos tem muitos detalhes, ficamos sujeitos a cometer vários erros quando os utilizamos: esquecer uma vírgula, uma aspa, dentre outros. Na próxima seção, iremos ver uma lista dos erros mais comuns que ocorrem com o uso destes comandos. Com esta lista, poderemos encontrar os erros dos nossos programas mais rapidamente, certo?

4.3. Erros Frequentes no Uso dos Comandos de Entrada e Saída

Nesta seção, será apresentada uma lista com os erros que são mais frequentemente cometidos por quem está iniciando a programar, e que precisa ficar atento a tantos detalhes da sintaxe dos comandos. Vamos ver, na tabela abaixo, os erros que podemos cometer no uso do scanf, gets e printf.

Comando Erros Consequência

Scanf Esquecer o & antes do nome da variável.

O programa compila, como se não tivesse erro, mas durante a execução ele trava.

Trocar a string de controle. Por exemplo, no lugar de um %d, usar um %f.

O programa compila, mas a variável receberá um valor esquisito (normalmente, um valor bem grande)

Esquecer o ; no final do comando.

O compilador avisa que tem erro.

Esquecer as aspas da string de controle.

O compilador avisa que tem erro.

Esquecer a vírgula entre a string de controle e a variável.

O compilador avisa que tem erro.

Fazer a leitura de uma variável que não foi declarada.

O compilador avisa que tem erro.

Page 66: Programação 2 Linguagem C (UFRPE)

66

Programação 2

Gets Esquecer de colocar o comando fflush antes do gets.

O programa compila, como se não tivesse erro, mas durante a execução, o processador pula a execução do comando gets.

Esquecer de incluir a biblioteca stdio.h.

O compilador avisa que tem erro.

printf Não fechar a string de controle.

O compilador avisa que tem erro.

Esquecer a vírgula entre as variáveis que serão impressas.

O compilador avisa que tem erro.

Usar um especificador de formato incompatível com o valor que será impresso.

O programa compila, mas será impresso um valor esquisito.

Esquecer de colocar um especificador de formato.

O programa compila, mas não imprime o valor da variável.

Notem na coluna “consequência”, que mesmo que sejam cometidos alguns tipos de erros, o programa vai compilar e só durante a execução é que notaremos algo estranho. Atenção: podem ocorrer outros erros que não foram mencionados nesta lista, estes são apenas os mais comuns.

Pronto, enfim poderemos começar a fazer os nossos primeiros programas! Já sabemos, declarar variáveis, atribuir valores a elas, ler valores via teclado e apresentar resultados na tela. Com esses comandos, já podemos fazer uns programas simples em C. Para começar, vocês já tem devem ter instalado o Dev-cpp nos seus computadores. Na próxima seção, veremos dois programas completos comentados. Agora é de verdade, vamos programar!

4.4. Primeiros programas em C

É isso, vamos começar com o nosso primeiro programa em C. Ele será simples, mas com o tempo iremos aumentado o nível de complexidade dos nossos programas. Antes de tudo, vamos a alguns detalhes (Mais detalhes?). Primeiro, vocês devem executar o Dev-cpp e escolher a opção: Arquivo/Novo/Arquivo Fonte. NÃO devemos trabalhar com projetos, certo? Em seguida, comecem a digitar o programa.

Page 67: Programação 2 Linguagem C (UFRPE)

67

Programação 2

Atenção

Por padrão, o Dev-cpp salva os nossos programas no formato do c++ (ou seja, .cpp). Sempre que forem salvar os programas, lembrem de informar que vocês querem que este seja salvo no formato .c. Fiquem atentos a isso!

A Figura 4.7 mostra a tela de como devemos salvar nossos programas. No momento que solicitamos que o programa seja salvo, é aberta uma janela para escolha do diretório que o programa será salvo, o nome dele e podemos também escolher o formato, na opção: “Save as Type”. Nesta opção, você deve escolher: “C source files (*.c)”. Só isso. Se você salvar seu programa como .cpp, ele ficará dando erros.

Figura 4.7: Tela do Dev-cpp: salvando um programa c.

O nosso primeiro programa em C irá ler dois números inteiros e apresenta a soma destes dois números. Segue abaixo o programa completo. Em seguida, vamos comentar cada linha.

Page 68: Programação 2 Linguagem C (UFRPE)

68

Programação 2

Programa Completo 4.1: Ler dois números inteiros e calcula a soma

1

2

3

4

5

6

7

8

9

10

11

12

13

//Ler dois numeros e calcula a soma

main()

{

int n1, n2, soma;

printf(“Calcular a soma de dois numeros\n\n”);

printf(“Primeiro valor: “);

scanf(“%d”, &n1);

printf(“Segundo valor: “);

scanf(“%d”, &n2);

soma = n1 + n2;

printf(“\n\nA soma dos dois numeros = %d\n\n”,soma);

system(“pause”);

}

Comentários sobre cada linha do Programa completo 4.1

• Linha 1: De acordo com a estrutura de um programa C, este inicia com inclusão das bibliotecas, quando necessário. Neste exemplo, não utilizamos nenhum comando que se fez necessária a inclusão de biblioteca. Assim, na linha 1 temos um comentário, indicando o que o programa faz. Sempre coloquem esse tipo de comentário no programa. Assim, ele ficará bem documentado.

• Linha 2: início do programa principal, que é definido pelo: “main()”.

• Linha 3: temos um abre chaves, que irá delimitar o corpo do programa principal.

• Linha 4: temos as declarações das três variáveis do programa24:

Saiba Mais

24Ao ler um enunciado de uma questão procure identificar as variáveis de entrada, ou seja, quais valores serão fornecidos pelo usuário e qual resultado o programa precisa processar. E assim, faça a declaração das suas variáveis.

Page 69: Programação 2 Linguagem C (UFRPE)

69

Programação 2

n1 e n2 (para armazenar os números que serão fornecidos pelo usuário) e soma (que armazena a soma dos dois números).

• Linha 5: um printf que serve para colocar, no início da tela, o título do que o programa faz. Isso é importante para que o usuário saiba para que serve o programa.

• Linha 625: colocamos este printf para que o usuário saiba que precisa fornecer o primeiro valor.

• Linha 7: scanf que lê o primeiro valor e armazena na variável n1.

• Linha 8: printf para que o usuário saiba que precisa fornecer o segundo valor.

• Linha 9: scanf que lê o segundo valor e armazena na variável n2.

• Linha 10: agora que já temos os dois valores armazenados nas variáveis n1 e n2, podemos executar a soma. Nesta linha, temos o comando que atribui a soma das variáveis n1 e n2 para a variável soma.

• Linha 11: printf que apresenta o resultado, que está armazenado na variável soma.

• Linha 12: nesta linha, temos um comando novo. É o seguinte, assim que é terminada a execução do nosso programa, o processador fecha, automaticamente, a janela onde o programa estava sendo executado. Por conta disso, acabamos sem ver algum resultado que tenha sido impresso na tela. Para fazer com que a janela não feche ao término da execução, foi colocado o comando system(“pause”). Este comando dá uma pausa na execução do programa e fica aguardando que o usuário pressione alguma tecla26. Com esta pausa, poderemos ver os resultados apresentados. Assim que pressionamos algo no teclado, a janela irá fechar. Portanto, no final dos nossos programas, teremos que colocar o system(“pause”), certo? Um outro comando que faz a mesma coisa é o getche(), no próximo exemplo, usaremos o getche(), para que vocês possam conhecê-lo.

• Linha 13: fecha chaves, indicando o final do programa principal.

Saiba Mais

25Importante: sempre que temos que fazer uma leitura de dados (com scanf ou gets), devemos colocar uma mensagem para que o usuário saiba o que ele deve digitar. Assim, todo scanf (ou gets), deve ter um printf antes, informado o que o usuário tem que fazer. O programa precisa se comunicar com um usuário.

Saiba Mais

26O comando system(“pause”) escreve na tela de execução do programa a seguinte mensagem: “Press any key to continue...” ou “Pressione qualquer tecla para continuar...”

Page 70: Programação 2 Linguagem C (UFRPE)

70

Programação 2

Vocês devem digitar, compilar e executar este programa utilizando o Dev-cpp. Comecem a se familiarizar com a sintaxe do C. Também procurem se familiarizar com o ambiente de programação. Em breve, vocês não estarão mais tendo que consultar as sintaxes dos comandos com tanta frequência. Vamos logo fazer outro programa!

Nosso segundo programa irá ler o nome do usuário e o ano em que ele nasceu e como resultado imprime uma mensagem dizendo quanto anos o usuário tem.

Programa Completo 4.2: Ler o nome e a idade do usuário e informar a sua idade.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

#include <stdio.h>

//Ler o nome e a idade do usuário e informar a sua idade.

main()

{

char nome[20];

int ano, idade;

printf(“Calcular a idade o usuario\n\n”);

printf(“Seu nome: “);

fflush(stdin);

gets(nome);

printf(“Ano que voce nasceu: “);

scanf(“%d”, &ano);

idade = 2009 - ano;

printf(“\n\n%s, voce esta com %d anos.”, nome, idade);

getche();

}

Page 71: Programação 2 Linguagem C (UFRPE)

71

Programação 2

Programa Completo 4.2: Ler o nome e a idade do usuário e informar a sua idade.

Vamos ver o que está sendo feito em cada linha do programa completo 4.2.

• Linha 1: Neste programa nós teremos que ler uma variável que é uma cadeia de caractere: o nome do usuário. Assim, precisaremos usar o gets e o fflush. Estes comandos ficam na biblioteca stdio.h. Na linha 1, temos a inclusão desta biblioteca.

• Linha 2: Comentário indicando o que o programa faz.

• Linha 3: início do programa principal, que é definido pelo: main().

• Linha 4: temos um abre chaves, que irá delimitar o corpo do programa principal.

• Linha 5: declaração da variável do tipo char, que armazena o nome do usuário.

• Linha 6: declaração das variáveis inteiras: ano (que armazena o ano de nascimento do usuário) e idade (que armazenará a idade do usuário, que será calculada pelo programa).

• Linha 7: printf que indica o que o programa faz, no início da tela de execução.

• Linha 827: printf que solicita que seja digitado o nome do usuário.

• Linha 9: temos o comando fflush, que DEVE sempre vir antes do comando gets.

• Linha 10: gets que efetuará a leitura do nome do usuário.

• Linha 11: printf para que o usuário saiba que precisa fornecer o ano de nascimento.

• Linha 12: scanf que lê o ano de nascimento do usuário.

• Linha 13: atribuição que descobre quantos anos o usuários tem. Para isso, subtraímos o ano atual (2009), do ano que o usuário nasceu. O resultado é atribuído para a variável idade.

• Linha 14: printf que apresenta o resultado. Notem que o nome do usuário vai aparecer na frase. A string de controle começa no dois “\n”, solicitando que o cursor mude de linha e logo temos

Saiba Mais

27Importante: sempre que temos que fazer uma leitura de dados (com scanf ou gets), devemos colocar uma mensagem para que o usuário saiba o que ele deve digitar. Assim, todo scanf (ou gets), deve ter um printf antes, informado o que o usuário tem que fazer. O programa precisa se comunicar com um usuário.

Page 72: Programação 2 Linguagem C (UFRPE)

72

Programação 2

um “%s”, isto é porque queremos que a resposta seja iniciada com o nome do usuário. Um exemplo de frase de resposta é: “Carolina, você esta com 10 anos”.

• Linha 15: temos o comando getche(), similar ao system(“pause”), faz com que a tela de execução não feche ao final do programa. A vantagem do getche() é que ele não escreve nada na tela. Lembram que o system(“pause”) coloca uma frase na tela?

• Linha 16: fecha chaves, indicando o final do programa principal.

A seguir, temos as telas de execução dos programas completos 4.1 e 4.2.

Tela de execução do Programa completo 4.1

Tela de execução do Programa completo 4.2

Figura 4.8: Telas de execução dos programas completos 4.1 e 4.2

Com esses dois programa completamente comentados, já dá para vocês começarem a treinar sozinhos. Não queiram acertar tudo de primeira, vão com calma e sejam persistentes. Vejam que a sintaxe da linguagem C é cheia de detalhes que precisamos ter muita atenção. Na próxima seção, vocês encontrarão sugestões de exercícios.

Atividades e Orientações de Estudo

Como vocês já devem ter notado, uma linguagem de programação envolve muitos detalhes. Vocês só irão aprender realmente, se fizerem muitos exercícios. É a prática que fará com que esta gama de detalhes seja assimilada. Portanto, aqui vai mais uma lista de exercícios. Esta é para ser resolvida no computador, certo? Podem começar a ligar seus computadores!

Page 73: Programação 2 Linguagem C (UFRPE)

73

Programação 2

1. Faça um programa que leia dois números reais A e B e os imprima na tela. O valor da variável A deve ser apresentado com duas casa decimais e o valor da variável B com três casas decimais.

2. Faça um programa que leia o nome do usuário e escreva uma frase de saudação, desejando um bom dia de trabalho para o mesmo. A resposta deve ter o formato deste exemplo: “Ola Joao, tenha um otimo dia de trabalho!”. Faca o programa soar um sinal sonoro(beep) ao escrever esta frase.

4. Faça um programa que leia dois números inteiros A e B e imprima o resultado da subtração de A por B. A resposta deve ter o seguinte formato: “6 – 2 = 4”.

3. Faca um programa que leia o nome do usuário e a sua idade e imprima quantos anos ele terá em 2020. A resposta deve ter o formato deste exemplo: “Carlos, em 2020 voce estara com 45 anos”.

5. Faça um programa que leia o nome do usuário, a idade do usuário, o nome da mãe do usuário e a idade da mãe do usuário. O programa devera imprimir na tela quantos anos a mãe do usuário tinha quando ele nasceu. A resposta deve ter o formato deste exemplo: “Carlos, quando voce nasceu, Dona Cecilia tinha 27 anos”.

Conheça Mais

Aumente os seus conhecimentos sobre comandos de entrada e saída de dados acessando site especializados na linguagem C. Muitos professores e instituições disponibilizam materiais na rede e o principal, vocês podem encontrar muitos enunciados de exercícios.

Vocês já se inscreveram em um fórum de discussão da linguagem de programação C? Nessa fase em que estamos iniciando a programar, ter auxílio de programadores experientes é muito importante. Não deixem de se inscrever, certo?

Page 74: Programação 2 Linguagem C (UFRPE)

74

Programação 2

Vamos revisar?

Para dar uma revisada nos tópicos tratados neste capítulo, observem o resumo a seguir:

• Dispositivos de entrada: são utilizados para passar informações para o computador. São exemplos de tais dispositivos: teclado e mouse.

• Dispositivos de saída: são utilizados para apresentar informações processadas pelo computador.

• scanf: um dos comandos de leitura do C. Esta comando não é adequado para a leitura de cadeia de caracteres.

• gets: comando específico para a leitura de cadeia de caracteres. Para utilizá-lo, é necessário incluir no programa a biblioteca stdio.h.

• fflush: comando que faz a limpeza do buffer de entrada de dados. Sempre que fizermos uma leitura de cadeia de caracteres, devemos colocar o comando fflush.

• printf: comando de saída de dados. O printf pode ser usado para imprimir textos, valores de variáveis e resultados de expressões aritméticas.

• getche() e system(“pause”): comandos para provocar uma parada na tela de execução, fazendo com que o usuário possa conferir o resultado processado pelo programa.

Page 75: Programação 2 Linguagem C (UFRPE)

75

Programação 2

Capítulo 5 – Operadores, Expressões e Funções Matemáticas

Vamos conversar sobre o assunto?

Gostaram de ter feito os primeiros programas em C? Foram programas simples, que utilizavam o assunto visto até o momento. Vamos continuar avançando no estudo da linguagem C e aumentando, gradativamente, o nível de complexidade dos nossos programas. Neste capítulo, iremos aprender quais operadores estão disponíveis na linguagem C e como utilizá-los, através da montagem de expressões aritméticas, relacionais e lógicas. Também iremos abordar as principais funções da biblioteca matemática. Com o assunto deste capítulo, teremos habilidades para resolver questões que requerem a construção de expressões, seja aritmética, relacional ou lógica. Vamos em frente!

5.1. Operadores Básicos

Em toda linguagem de programação, existem operadores que nos permitem armazenar, modificar, comparar e avaliar dados no computador. Aqui veremos três tipos de operadores: aritméticos, relacionais e lógicos. Nas próximas seções, será feito o detalhamento de cada um dos tipos de operadores.

5.1.1 Operadores Aritméticos

Usamos os operadores aritméticos quando precisamos executar operações aritméticas (matemáticas) sobre os nossos dados (variáveis). A tabela abaixo apresenta os operadores aritméticos do C. Notem que o operador da multiplicação é um asterisco.

Operador Descrição

+ Adição

- Subtração

* Multiplicação

Page 76: Programação 2 Linguagem C (UFRPE)

76

Programação 2

/ Divisão

% Retorna o resto da divisão inteira de a por b

( ) Parênteses

Vamos dar uma atenção especial aos operadores da divisão(/) e resto(%). O resultado de uma divisão, em C, depende dos tipos dos dados que estão sendo divididos. A tabela abaixo apresenta o resultado da operação de divisão, de acordo com os tipos de dados do numerador e do denominador.

numerador / denominador resultado

inteiro / inteiro inteiro

inteiro/ real real

real / inteiro real

real/real real

Quando dois números inteiros são divididos, o resultado é a parte inteira do quociente da divisão. Quando pelo menos um dos elementos (numerador e/ou denominador) é real, o resultado é um número real. Vamos analisar a sequência de comandos a seguir:

Exemplo 5.1: Uso de Operadores Aritméticos

1

2

3

4

5

6

7

8

9

int X, Y, Z, W;

float K, L, M;

X = 19;

Y = 3;

Z = X/Y;

W = X % Y;

K = 19;

L = 3;

M = K/L;

Page 77: Programação 2 Linguagem C (UFRPE)

77

Programação 2

Nas linhas 1 e 2, temos as declarações das variáveis: quatro inteiras (X, Y, Z e W) e três reais (K, L, e M). Nas linhas 3 e 4 são atribuídos valores nas variáveis X e Y, que passam a armazenar tais valores. Na linha 5, temos um comando de atribuição, em que a variável Z receberá o resultado da divisão entre a variável X (19) e a variável Y (3). Como as variáveis X e Y são inteiras, o resultado será a parte inteira do quociente da divisão. Assim, se temos: 19/3 = 6.333333, será considerado apenas a parte inteira do resultado, ou seja, 6. Portanto, nesta atribuição da linha 5, a variável Z vai receber 6.

Na linha 6, a variável W vai receber o resto da divisão de X por Y, ou seja, o resto da divisão de 19 por 3. A figura 5.1 ilustra como a operação do resto é feita.

Figura 5.1: Resto de uma divisão

A operação do resto funciona da seguinte forma: os dois números vão sendo divididos, neste caso: 19 é dividido por 3 (primeiro quadro da figura 5.1). Assim, 19 por 3 dá 6 e sobra 1. Como o 1 não dá pra ser dividido por 3, a conta para e pega o resto da divisão que é 1. Portanto, o resultado da operação X%Y (neste caso, 19%3) é 1. Este resultado será atribuído a variável W.

Atenção

O operador do resto (%) só pode ser usado quando as variáveis envolvidas são do tipo inteiro. Não poderemos usar tal operador para obter resto de divisão de números reais. Outra coisa: o operador % não tem nada haver com percentagem, certo?

Nas linhas 7 e 8 são atribuídos valores nas variáveis K e L, que passam a armazenar tais valores. Na linha 9, temos um comando

Page 78: Programação 2 Linguagem C (UFRPE)

78

Programação 2

de atribuição, em que a variável M receberá o resultado da divisão entre a variável K (19) e a variável L (3). As variáveis K e L são reais (float). Dessa forma, teremos 19/3 = 6.333333. O resultado completo será atribuído a variável M, ou seja 6.33333, sem desprezar a parte fracionária do resultado.

A figura 5.2 apresenta o valor que ficou armazenado em cada uma das variáveis, após a execução da sequência de comandos. Note que, nas variáveis reais, mesmo que seja atribuído um valor inteiro, como por exemplo, na linha 7, que foi atribuído 19 à variável K, no momento que o valor é armazenado, ele passa a ter a parte fracionária do número. Por isso, a variável K aparece com 19.000000 de conteúdo (lembrem-se que o ponto deste número, está representando uma virgula, certo?).

Figura 5.2: Resultado final das variáveis

5.1.1.1 Prioridade dos Operadores

Uma questão que devemos tomar bastante cuidado ao montar uma expressão aritmética é a prioridade dos operadores. A prioridade que o operador aritmético tem sob o outro é que vai determinar como a expressão será resolvida. Na matemática, quando montamos uma expressão, usamos parênteses, colchetes e chaves. Nas linguagens de programação, nós só temos os parênteses.

Os parênteses têm um papel importante nas expressões e possibilitam que a ordem das operações seja alterada. Expressões entre parênteses são calculadas primeiro, portanto eles fornecem o maior grau de prioridade às expressões que envolvem. Podemos ter pares de parênteses envolvendo outros pares. Dizemos que os parênteses estão aninhados. Neste caso, as expressões dentro dos parênteses mais internos são avaliadas primeiro.

Page 79: Programação 2 Linguagem C (UFRPE)

79

Programação 2

A tabela abaixo apresenta a prioridade de resolução dos operadores aritméticos:

Prioridade Operador

1º Operações embutidas em parênteses “mais internos”

2º % (resto) e/ou * (multiplicação) e/ou / (divisão)

3º + (adição) e/ou – (subtração)

De acordo com a tabela, as expressões entre parênteses tem maior prioridade, portanto, são resolvidas primeiro. Na sequência, resolve os operadores resto e/ou multiplicação e/ou divisão, e, finalmente, resolve os operadores de adição e/ou subtração. Quando aparecem operadores de mesma prioridade em uma expressão, o operador mais à esquerda será avaliado primeiro.

Vamos analisar o exemplo 5.2, a seguir, e verificar qual o valor final das variáveis A, B, C e D.

Exemplo 5.2: Prioridade de Operadores

1

2

3

4

5

6

7

8

9

int X, Y, Z, W, A, B, C, D;

X = 19;

Y = 3;

Z = 4;

W = 2;

A = X + Y * Z;

B = (X + Y) * Z;

C = X – Y * Z / W;

D = (X-Y) * (Z/W);

Na linha 1, temos as declarações das variáveis que serão usadas (todas elas são do tipo int). Nas linhas 2 a 5, são atribuídos valores às variáveis X, Y, Z e W. Vamos acompanhar a resolução de cada expressão das linhas 6 a 9 na figura 5.3. A parte da expressão que

Page 80: Programação 2 Linguagem C (UFRPE)

80

Programação 2

aparece circulada, é a que tem prioridade de resolução.

Figura 5.3: Acompanhamento da resolução das expressões aritméticas

No primeiro quadro (atribuição para a variável A), aparecem na expressão os operadores da adição e multiplicação. Como a multiplicação tem prioridade, esta é resolvida primeiro. Posteriormente, o operador da adição é resolvido e assim o resultado que será atribuído à variável A.

No segundo quadro (atribuição para a variável B), a expressão também é composta por operadores de adição e multiplicação. No entanto, a adição aparece entre parênteses. Sabe-se que a operação dentro dos parênteses terá prioridade. Assim, a adição é resolvida e, posteriormente, a multiplicação.

No terceiro quadro (atribuição para a variável C), aparecem na expressão os operadores de subtração, multiplicação e divisão. O operador de subtração é o de menor prioridade. No entanto, os operadores de multiplicação e divisão tem a mesma prioridade. Dessa forma, o operador da multiplicação será resolvido primeiro, já que ele aparece mais a esquerda da expressão. Na sequência, a divisão é resolvida. E, finalmente, a subtração.

Finalmente, no quarto quadro (atribuição para a variável D), aparecem na expressão os operadores de subtração, multiplicação, divisão e parênteses. Primeiro, é resolvida a expressão dentro do parêntese mais a esquerda. Posteriormente, a expressão entre parênteses mais a direita. Finalizando com a resolução da multiplicação.

Page 81: Programação 2 Linguagem C (UFRPE)

81

Programação 2

5.1.2 Operadores Relacionais

Os operadores relacionais são utilizados para comparar valores de variáveis ou expressões aritméticas. Uma expressão aritmética tem como resultado um valor numérico. No caso de uma expressão relacional, o resultado será sempre um valor lógico: “Verdade” ou “Falso”. Na tabela abaixo são apresentados os operadores relacionais do C.

Operador Descrição

== Igualdade

!= Diferença ( )

< Menor

> Maior

<= Menor ou Igual ( )

>= Maior ou Igual ( )

Vamos aprender como montar uma expressão relacional. Segue abaixo as possíveis sintaxes de expressões relacionais.

Sintaxe

Variavel operador Valor

Variável1 operador variável2

Variavel operador Expressão Aritmética

Expressão Aritmética operador Expressão Aritmética

Notem que podemos montar a expressão relacional de várias formas. Na tabela abaixo são apresentados exemplos de expressões relacionais.

Exemplo 5.3: Expressões relacionais

1

2

3

4

X == 10

X > Y

X < Y + Z

X * Y > Z / W

Page 82: Programação 2 Linguagem C (UFRPE)

82

Programação 2

Na linha 1, temos uma expressão relacional que verifica se a variável X é igual a 10 (ou ela será igual a 10 ou não, resultando em verdade ou falso). Na linha 2, temos uma expressão relacional que compara duas variáveis. Esta expressão verifica se o valor da variável X é maior que o valor da variável Y. Na linha 3, a expressão relacional compara o valor da variável X com o resultado da expressão aritmética Y + Z. Por fim, na linha 4, temos uma expressão relacional que compara o resultado de duas expressões aritméticas.

Suponha que X = 1, Y = 5, Z = 8 e W = 2. Vamos ver o resultado das expressões do exemplo 5.3 (V é verdade e F é falso):

Resultados das expressões relacionais do exemplo 5.3

1

2

3

4

X == 10 => 1 == 10 => F

X > Y => 1 > 5 => F

X < Y + Z => 1 < 5 + 8 => 1 < 13 => V

X * Y > Z / W => 1 * 5 > 8 / 2 => 5 > 4 => V

Quando as expressões relacionais são compostas por expressões aritméticas (como os exemplos das linhas 3 e 4), a prioridade de resolução é da expressão aritmética. Assim, primeiro resolve-se a expressão aritmética e a comparação é feita com o resultado da mesma.

5.1.3 Operadores Lógicos

Os operadores lógicos servem para interligar duas ou mais expressões relacionais. Uma expressão lógica representa a união de expressões relacionais, permitindo que os resultados de várias expressões relacionais sejam transformados em um único resultado lógico (verdade ou falso).

Os operadores lógicos são: E, OU e NÃO. A tabela a seguir apresenta como os operadores lógicos são representados na linguagem C.

Page 83: Programação 2 Linguagem C (UFRPE)

83

Programação 2

Operador Lógico Operador Lógico em C

E &&

OU ||

NÃO !

Os resultados das expressões lógicas obedecem às tabelas que veremos a seguir, que dependem dos resultados das expressões relacionais envolvidas. Quando montamos uma expressão lógica, as expressões relacionais devem ser colocadas entre parênteses.

Começaremos estudando a tabela de resultados do operador lógico E. Quando este operador interliga duas expressões relacionais, o resultado da expressão lógica só será verdade se as duas expressões relacionais forem verdade. Em qualquer outra situação, o resultado será falso.

Tabela de Resultado do Operador Lógico E (&&)

Expressão Relacional 1 Expressão Relacional 2 Resultado

V V V

V F F

F V F

F F F

Vejamos um exemplo: um aluno só será aprovado se a sua média for maior ou igual a 7. E, se a quantidade de faltas for menor que 15. As duas condições precisam ser verdade, para o aluno ser aprovado. Se o aluno tem a média maior que 7, mas tem mais de 15 faltas, ele não será aprovado. A expressão lógica para testar esta situação é apresentada na linha 1 do exemplo 5.4, a seguir.

Exemplo 5.4: Expressões Lógicas com operador e (&&)

1

2

3

(media >= 7.0) && (faltas < 15)

(A < 5) && (B <> 5)

(X > 10) && (Y > 50) && (Z < 25)

Page 84: Programação 2 Linguagem C (UFRPE)

84

Programação 2

Quando temos mais de duas expressões relacionais, como é o caso do exemplo da linha 3, a expressão lógica vai sendo resolvida da esquerda para a direita. Para acompanhar a resolução das expressões do exemplo, vamos supor que: media = 8.0, faltas = 18, A=3, B=4, X = 15, Y= 70 e Z=30. Vejamos a figura 5.4 a seguir.

Figura 5.4: Resultado das expressões lógicas do operador &&

No primeiro quadro da figura, a primeira expressão relacional é verdade e a segunda expressão é falsa. De acordo com a tabela de resultados do operador lógico E, verdade && falso dá falso. No segundo quadro, as duas expressões relacionais são verdade. Assim, de acordo com a tabela de resultados do operador lógico E, verdade && verdade dá verdade. Finalmente, no terceiro quadro temos três expressões relacionais. Neste caso, iremos resolver a expressão lógica, da esquerda para a direita. Começamos encontrando o resultado da primeira expressão relacional, com a segunda (ou seja, (X>10) && (Y>50)). E depois, pegamos este resultado e continuamos resolvendo o restante da expressão, sempre da esquerda para a direita. Podemos interligar vária expressões relacionais, através dos operadores lógicos.

Agora vamos analisar a tabela de resultados do operador lógico OU. Quando tivermos duas expressões relacionais interligadas pelo operador lógico ou, o resultado da expressão lógica só será falso se as duas expressões relacionais forem falsas. Nos demais casos, o resultado da expressão será verdade.

Tabela de Resultado do Operador Lógico OU (||)

Expressão Relacional 1 Expressão Relacional 2 Resultado

V V V

V F V

F V V

F F F

Page 85: Programação 2 Linguagem C (UFRPE)

85

Programação 2

Vejamos um exemplo: para o aluno ingressar em um curso superior - ele deve ser aprovado no vestibular OU ele deve ser um portador de diploma. Apenas uma situação precisa ser verdade. Assim, se o aluno nem passou no vestibular, nem é portador de diploma, não poderá ingressar no curso. A expressão lógica para testar esta situação é apresentada na linha 1 do exemplo 5.5, a seguir. Vejam outros exemplos de expressões lógicas com o operador OU.

Exemplo 5.5: Expressões Lógicas com operador ou (||)

1

2

3

(Aprovado_Vestibular == ‘S’) || (Portador_Diploma == ‘S’) (A < 3) || (B < 2)

(X < 12) || (Y > 1) || (Z < 35)

A tabela de resultados do operador lógico NÃO é apresentada a seguir. Notem que a finalidade deste operador é inverter(ou negar, como é comumente chamado) o resultado de uma expressão relacional. Assim, se a expressão relacional é verdade, a sua negativa é falso.

Tabela de Resultado do Operador Lógico Não (!)

Expressão Relacional Resultado

V F

F V

No exemplo 5.6, temos duas expressões lógicas com o operador NAO. Este operador deve ser colocado na frente da expressão relacional.

Exemplo 5.6: Expressões Lógicas com operador não (!)

1

2

!(X < 12)

!(Y == 10)

A figura 5.5, ilustra uma situação cotidiana, do uso de operadores lógicos.

Page 86: Programação 2 Linguagem C (UFRPE)

86

Programação 2

Figura 5.5: Uso cotidiano de operadores lógicos

Nós também poderemos ter expressões lógicas, em que aparecem mais de um tipo de operadores lógicos, além de operadores aritméticos. Vejamos o exemplo 5.7.

Exemplo 5.7: Expressões Lógicas com vários operadores

1

2

3

4

(X > 10) && (Y < 30) || (Z == 1)

(A == 2) || (B <> C) && (D < 1) || (E > 10)

!(A == 1) || (B <= C + B)

(X + Y < Z + W) && (A < 3 + D) || (F < 5)

Nestes casos, vamos ver a tabela de prioridade de operadores, para a resolução de tais expressões.

Prioridade Operador

1º Operações embutidas em parênteses “mais internos”;

2º Resto e/ou multiplicação e/ou divisão;

3º Adição e/ou Subtração;

4º Operadores Relacionais;

5º Operadores Lógicos.

Primeiro, resolveremos as expressões aritméticas (seguindo a prioridade dos operadores aritméticos), depois as expressões relacionais e, finalmente, as expressões lógicas.

Page 87: Programação 2 Linguagem C (UFRPE)

87

Programação 2

5.2. Operadores Aritméticos de Atribuição

A linguagem C oferece um conjunto de operadores que é uma combinação de operador de atribuição e operador aritmético, são os operadores aritméticos de atribuição. Eles são utilizados para representar de maneira reduzida uma operação aritmética, seguida de uma atribuição. A próxima tabela apresenta os operadores aritméticos de atribuição e como utilizá-los em nossos programas.

Operador Exemplos de Uso Descrição

+= X += 4; Equivale a X = X + 4;

-= Y -= X; Equivale a Y = Y – X;

*= Z *= W; Equivale a Z = Z * W;

/= K /= 7; Equivale a K = K / 7;

%= L %= M; Equivale a L = L % M

Como pode ser visto, a sintaxe do operador aritmético de atribuição é: um operador aritmético(+, -, *, /, %) seguido do operador da atribuição (=). Uma expressão com este tipo de operador, significa que a variável do lado esquerdo da atribuição, além de receber o resultado, também fará parte da expressão aritmética. Vejamos o exemplo dado para o operador +=. A expressão X += 4, quer dizer que: será obtido o valor da variável X, adiciona 4, e este resultado é atribuído a própria variável X. Neste caso, é como se fosse um acumulador: acumule 4 ao valor que já tem na variável X.

5.3. Operadores ++ e --

Os operadores ++ e -- são utilizados após o nome de uma variável e servem para incrementar (++) ou decrementar (--) uma unidade da variável, ou seja, somar 1 ou subtrair 1 do valor da variável. A tabela abaixo apresenta os operadores ++ e --, seguidos de exemplos de uso. Após o ++ ou --, devemos colocar um ponto e vírgula.

Operador Exemplos de Uso Descrição

++ X++; Equivale a X = X + 1;

-- Y--; Equivale a Y = Y -- 1;

Page 88: Programação 2 Linguagem C (UFRPE)

88

Programação 2

No exemplo X++, significa que, se X=5, será somado 1 ao valor da variável X, e assim, X finalizará com 6. Da mesma forma, no exemplo Y--, significa que, se Y=5, será subtraído 1 do valor da variável Y, e assim, Y finalizará com 428.

5.4. Conversão de tipo

Quando usamos operadores aritméticos, temos que lembrar que o resultado da expressão depende do tipo das variáveis envolvidas. Por exemplo, quando dividimos dois números inteiros, o resultado é a parte inteira do quociente da divisão. Mas, quando dividimos números reais, o resultado vem completo, a parte inteira e a parte fracionária do quociente. Outro detalhe que precisamos lembrar é que alguns operadores só podem ser usados por um tipo de dado. Este é o caso do operador do resto, nós só podemos utilizá-lo com dados do tipo inteiro.

Por conta disso, algumas vezes desejamos, momentaneamente, modificar o tipo do conteúdo de uma variável. Isto é, queremos que uma variável se “comporte” como se ela fosse de um tipo diferente do que ela foi declarada. Por exemplo: declaramos uma variável como int e queremos, momentaneamente, que seu conteúdo seja utilizado como um float. Este procedimento é chamado de conversão de tipo ou casting (moldagem, em Inglês).

A conversão de tipo é usada em uma expressão aritmética e é feita da seguinte forma: antes da variável, colocamos entre parênteses, o tipo que queremos que a variável seja nesta expressão aritmética. É importante salientar que a conversão de tipo é feita com o dado armazenado em uma variável, mas a variável continua tendo o seu tipo original. Vamos ver o exemplo 5.8, que apresenta uso de conversão de tipo.

Saiba Mais

28Os operadores ++, -- e operadores aritméticos de atribuição fazendo com que as nossas expressões fiquem menores, já que precisamos escrever menos coisas para a montagem da expressão.

Page 89: Programação 2 Linguagem C (UFRPE)

89

Programação 2

Exemplo 5.8: Conversão de tipo

1

2

3

4

5

6

7

int A,B,C;

float X,Y;

A=3;

B=5;

X=6.5;

C = (int)X % B;

Y = (float)A/B;

Nas linhas 1 e 2, temos as declarações de cinco variáveis. Nas linhas 3, 4, e 5 foram atribuídos valores as variáveis A, B e X. Na linha 6, precisamos executar uma operação para obter o resto da divisão entre a variável X (que é do tipo float) e a variável B (que é do tipo int). Esta operação não seria possível, já que o operador do resto não aceita números reais na expressão. No entanto, esta operação se torna possível, se fizermos a conversão de tipo da variável X. Queremos que, nesta expressão, o conteúdo de X seja um inteiro. Para isso, colocamos (int) na frente da variável X, como mostra a linha 6 do exemplo. Como a variável X tem 6.5 armazenado, nesta conta, a parte fracionária será desprezada e a conta será feita considerando que X é 6. Assim, 6 % 5 = 1. Então, 1 é o valor que será atribuído a variável C.

Vamos ver agora a atribuição da linha 7. Neste caso, estamos querendo fazer a divisão entre dois números inteiros. Esta conta é possível, mas ela traz como resultado, apenas a parte inteira do quociente. No entanto, há situações em que queremos dividir dois números inteiros, e receber o resultado completo, parte inteira e fracionária do quociente. Este é o caso da linha 7. Para que o resultado venha completo, basta que o conteúdo de uma das variáveis se comporte como um float. Com isso, um float dividido por um int, temos como resultado um float. Dessa forma, fizemos a conversão de tipo da variável A, solicitando que seu conteúdo se comporte como um float. Nesta linha 7 teremos, então, 3.0/5 = 0.6. Este é o valor que será atribuído a variável Y.

Page 90: Programação 2 Linguagem C (UFRPE)

90

Programação 2

5.5. Funções Matemáticas (biblioteca math.h)

A linguagem de programação C possui uma biblioteca que agrupa um conjunto de funções matemáticas. É a biblioteca math.h. Nesta seção, vamos ver quatro funções matemáticas, da biblioteca math.h, que utilizaremos com mais frequência nos nossos programas. São as funções para encontrar a raiz quadrada de um número, potência (elevar um número a uma potência) e duas funções de arredondamento. Esta biblioteca possui outras funções, mas estas são as mais utilizadas nos nossos programas.

As funções matemáticas precisam receber um ou vários parâmetros e nos retornam um resultado. Por exemplo, para descobrir a raiz quadrada de um número, a função precisa saber de que número será calculada a raiz quadrada. Este número que é fornecido a função é o parâmetro. Vamos ver a tabela a seguir, em que é feita a descrição destas funções.

Função Descrição Exemplos de uso

sqrt Função para encontrar a raiz quadrada de um número. A função sqrt precisa receber como parâmetro, o número que desejamos encontrar a sua raiz quadrada. O resultado desta função é um número real. Como uma função retorna um resultado, devemos atribuí-lo a uma variável.

R = sqrt(16);

R = sqrt(A);

pow Função para encontrar a potência de um número, ou seja, eleva um número a um expoente: AB. Assim, se A = 4 e B = 3, 4 elevado a 3 é 64. A função pow irá receber dois parâmetros. O primeiro é a base (neste exemplo é o A) e o segundo é o expoente (neste caso é o B). Esta função retorna um número real como resultado.

P = pow(3,4);

P = pow(A, 3);

ceil A função ceil serve para arredondar um número real. Esta função arredonda o número para cima. Assim, ela retornará como resultado: o primeiro número inteiro maior que o número que desejamos arredondar. Por exemplo: se x = 1.34, e desejamos arredondar com a função ceil, o resultado será 2.0. Ou seja, o primeiro número inteiro acima de 1.34. Apesar do arredondamento, esta função retorna um número real como resultado.

Z = ceil(1.67);

Z = ceil(Z);

Page 91: Programação 2 Linguagem C (UFRPE)

91

Programação 2

floor A função floor serve para arredondar um número real. Esta função arredonda o número para baixo. Assim, ela retornará como resultado: o primeiro número inteiro menor que o número que desejamos arredondar. Por exemplo: se x = 1.34, e desejamos arredondar com a função floor, o resultado será 1.0. Ou seja, o primeiro número inteiro abaixo de 1.34. Apesar do arredondamento, esta função retorna um número real como resultado.

Z = floor(1.67);

Z = floor(Z);

Atenção

Sempre que usarmos estas funções nos nossos programas, devemos incluir a biblioteca matemática, com a diretiva de compilação: #include <math.h>.

Devemos ficar atentos ao tipo de dado que a função retorna, para que seja feita a atribuição para uma variável compatível com o tipo do resultado. Por exemplo, não podemos atribuir o resultado da função pow, para uma variável inteira.

Programas Resolvidos

Nesta seção, vamos acompanhar a resolução de dois programas completos, que utilizarão os comando aprendidos neste capítulo. Vamos lá?

No primeiro programa que iremos analisar, o aluno fornecerá seu nome e as duas notas que tirou nas provas de programação. Como resultado, o programa vai imprimir a média do aluno. Segue abaixo o programa completo 5.1. Em seguida, vamos comentar cada linha.

Page 92: Programação 2 Linguagem C (UFRPE)

92

Programação 2

Programa Completo 5.1: Ler o nome e duas notas do usuário e imprimir a média.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#include <stdio.h>

//ler o nome e as duas notas do aluno e imprimir a media

main()

{

char nome[20];

float nota1, nota2, media;

printf(“Calcular a media do aluno\n\n”);

printf(“Seu nome: “);

fflush(stdin);

gets(nome);

printf(“Nota 1: “);

scanf(“%f”, &nota1);

printf(“Nota 2: “);

scanf(“%f”, &nota2);

media = (nota1 + nota2)/2;

printf(“\n\n%s, sua media = %.2f”, nome, media);

getche();

}

Comentários sobre cada linha do Programa completo 5.1:

• Linha 1: Como iremos ler o nome do aluno, precisamos incluir a biblioteca stdio.h onde estão os comandos fflush e gets.

• Linha 2: Comentário informando o que o programa faz.

Page 93: Programação 2 Linguagem C (UFRPE)

93

Programação 2

• Linha 3: início do programa principal, que é definido pelo: “main()”.

• Linha 4: um abre chaves, que irá delimitar o corpo do programa principal.

• Linhas 5 e 6: declarações das quatro variáveis do programa: nome, nota1, nota2 e média.

• Linha 7: um printf que serve para colocar, no início da tela, o título do que o programa faz.

• Linha 8: printf para que o usuário saiba que precisa fornecer seu nome.

• Linha 9: comando fflush, que DEVE sempre vir antes do comando gets. Utilizado para limpar o buffer de entrada de dados.

• Linha 10: gets que efetuará a leitura do nome do usuário.

• Linha 11: printf para que o usuário saiba que precisa fornecer a primeira nota.

• Linha 12: scanf que lê a primeira nota e armazena na variável nota1.

• Linha 13: printf para que o usuário saiba que precisa fornecer a segunda nota.

• Linha 14: scanf que lê a segunda nota e armazena na variável nota2.

• Linha 15: cálculo da média do aluno. Notem que a soma das nota1 e nota2 aparece entre parênteses. Devemos lembrar que o operador da divisão tem prioridade maior que o operador da soma. Assim, para que a soma das notas seja feita primeiro, ela deve vir entre parênteses. Não esqueçam deste detalhe!

• Linha 16: printf que apresenta a média do aluno. Notem que na mensagem, também será escrito o nome do aluno. A média do aluno será apresentada com duas casas decimais (%.2f)

• Linha 17: comando getche que faz com que a tela de execução do programa fique aberta, e assim podemos ver o resultado do programa. Nesta linha também poderíamos usar o system(“pause”).

Page 94: Programação 2 Linguagem C (UFRPE)

94

Programação 2

• Linha 18: fecha chaves, indicando o final do programa principal.

É importante que vocês digitem estes programas resolvidos, no Dev-cpp, assim vão se familiarizando com a sintaxe do C, certo? Vamos fazer o outro programa?

Nosso segundo programa irá ler um número e vai imprimir a sua raiz quadrada. Segue abaixo o programa completo 5.2. Em seguida, vamos comentar cada linha.

Programa Completo 5.2: Ler um número e imprimir a raiz quadrada

1

2

3

4

5

6

7

8

9

10

11

12

#include <math.h>

//ler um número e encontrar a raiz quadrada

main()

{

float num, raiz;

printf(“Calcular a raiz quadrada de um numero\n\n”);

printf(“Numero: “);

scanf(“%f”, &num);

raiz = sqrt(num);

printf(“\n\nA raiz quadrada de %.1f = %.1f.”, num, raiz);

getche();

}

Comentários sobre cada linha do Programa completo 5.2:

• Linha 1: Para encontrar a raiz quadrada, iremos utilizar a função sqrt da biblioteca math.h. Assim, precisamos incluí-la no nosso programa.

• Linha 2: Comentário informando o que o programa faz.

Page 95: Programação 2 Linguagem C (UFRPE)

95

Programação 2

• Linha 3: início do programa principal, que é definido pelo: “main()”.

• Linha 4: um abre chaves, que irá delimitar o corpo do programa principal.

• Linha 5: as declarações das duas variáveis do programa: num e raiz.

• Linha 6: printf que serve para colocar, no início da tela, o título do que o programa faz.

• Linha 7: printf para que o usuário saiba que precisa fornecer o número.

• Linha 8: scanf que lê o número e armazena na variável num.

• Linha 9: cálculo da raiz quadrada do número. Usamos a função sqrt, passando como parâmetro o número que foi digitado pelo usuário (que está armazenado na variável num). O resultado da função sqrt é atribuído à variável raiz.

• Linha 10: printf que apresenta o resultado. Notem que será apresentada apenas uma casa decimal (%.1f) das variáveis num e raiz.

• Linha 11: comando getche que faz com que a tela de execução do programa fique aberta, e assim podemos ver o resultado do programa.

• Linha 12: fecha chaves, indicando o final do programa principal.

A figura 5.6 apresenta as duas telas de execução dos programas completos 5.1 e 5.2.

Figura 5.6: Telas de execução dos programas completos 5.1 e 5.2

Page 96: Programação 2 Linguagem C (UFRPE)

96

Programação 2

Com estes dois programas comentados, podemos dar início à resolução de mais uma lista de exercícios. Continuem programando!

Atividades e Orientações de Estudo

Temos mais uma lista de exercícios para consolidar o entendimento do assunto visto neste capítulo. A maior parte das questões deve ser resolvida no computador, certo? Continuem fazendo os programas e sempre que der erro tenham calma para encontrá-los. Fiquem atentos(as) com a sintaxe de cada comando, para não cometer erros com tanta frequência. Vamos iniciar nosso novo treino?

1. Dados os valores inteiros abaixo:

MEDIA NOTA TOTAL Z K X I J A

0 2 10 0 7 4 80 -1 -4

Quais os valores resultantes depois da execução dos passos a seguir:

1) X = TOTAL/NOTA;

2) X = X+1;

3) NOTA = X;

4) TOTAL = NOTA + X + TOTAL;

5) MEDIA = 3;

6) K += 9;

7) Z = J / 5;

8) K = I % 5;

9) I ++;

10) I = I+2*A;

2. De acordo com os valores das variáveis abaixo, encontre o resultado das expressões lógicas com VERDADE ou FALSO:

A B C D E

10 3 2 2 25

a) A == D

b) (A>B) && (C==D)

c) (E+2<B+C) && (A==10)

Page 97: Programação 2 Linguagem C (UFRPE)

97

Programação 2

d) (D*E>100) || (B<5)

e) (E==25) && (A >B+C+D) && (C<B)

f) !(A < 15) && (B>=3)

g) (D>2) || (C == 7) && (E > 20)

3. Faça um programa que leia um número qualquer e imprima o seu cubo.

4. Uma empresa vai dar um aumento de salário ao seu funcionário. Faça um programa para ler o salário do funcionário e o percentual de reajuste. Calcular e escrever o valor do novo salário.

5. Faça um programa para ler o número de votos brancos, nulos e válidos de uma eleição. Calcular e escrever o percentual que cada um representa em relação ao total de eleitores.

6. Faça um programa que leia o número total de prestações de um consórcio, o total de prestações pagas e o valor atual da prestação. O programa deve calcular e apresentar o saldo devedor atual e a quantidade de prestações sem pagar.

7. Dada as seguintes entradas: quilometragem inicial, quilometragem final, litros consumidos, preço do litro de combustível. Faça um programa que imprima o seguinte Relatório: distância percorrida, Valor total gasto e o consumo do carro(quantos quilômetros percorre com 1 litro de combustível).

8. Um motorista de táxi deseja calcular o rendimento de seu carro na praça. Sabendo-se que o preço do combustível é de R$2.59, faça um programa para ler: a marcação do odômetro (Km) no início do dia, a marcação (Km) no final do dia, a quantidade de litros de combustível gasto e o valor total (R$) recebido dos passageiros. Calcular e escrever: a média do consumo em km/l e o lucro (líquido) do dia.

9. Faça um programa que leia os preços de uma mercadoria em abril e maio. Tendo como base a variação dos preços desta mercadoria, calcule a taxa de inflação.

10. Faça um programa que leia o tempo de duração de um evento em uma fábrica expressa em segundos e mostre-o expresso em horas, minutos e segundos.

Page 98: Programação 2 Linguagem C (UFRPE)

98

Programação 2

11. Faça um programa para um caixa eletrônico, que lê o valor que o cliente quer sacar e calcula o menor número possível de notas de 100,00, 50, 20 e 10 reais em que o valor lido pode ser decomposto. Escrever o valor do saque e a relação de notas necessárias. Suponha que o sistema monetário não utiliza centavos. Atenção: Só digite números múltiplos de 10.

Exemplo: Valor: R$ 380,00

Notas de R$ 100,00: 3

Notas de R$ 50,00: 1

Notas de R$ 20,00: 1

Notas de R$ 10,00: 1

Conheça Mais

Pesquisem na Internet outra funções matemáticas disponíveis na biblioteca math.h. Comecem a pesquisa pelo site:

http://visualcplus.blogspot.com/2006/03/mathh.html

Vamos revisar?

Para revisarmos os tópicos tratados neste capítulo, observem o resumo a seguir:

• Os operadores aritméticos são utilizados quando desejamos resolver expressões aritméticas. Devemos prestar atenção no tipo das variáveis que estão sendo utilizadas na expressão, pois o tipo interfere no resultado da expressão.

• Os operadores relacionais são utilizados quando desejamos comparar valores de variáveis. O resultado de uma expressão relacional é sempre “verdade” ou “falso”.

• Os operadores lógicos servem para interligar duas ou mais expressões relacionais. O resultado de uma expressão lógica é sempre “verdade” ou “falso”.

Page 99: Programação 2 Linguagem C (UFRPE)

99

Programação 2

• Podemos utilizar os operadores aritméticos de atribuição para reduzir o tamanho das expressões aritméticas.

• Os operadores ++ e – incrementam ou decrementam 1 de uma variável.

• Na biblioteca math.h podem ser encontradas funções matemáticas para encontrar a raiz quadrada de um número, potência, arredondamento de números reais, dentre outras.

Considerações Finais

Neste volume, tivemos a oportunidade de iniciar nosso aprendizado na linguagem de programação C. Nos capítulos 1 e 2, conhecemos os principais conceitos desta área (programação, linguagem de programação, um pouco do histórico do C, dentre outros), nos preparando para um melhor entendimento da linguagem de programação C. Nos capítulos 3, 4 e 5, começamos a estudar a sintaxe da linguagem de programação C, vimos os tipos de dados manipulados pela linguagem, os comandos de entrada e saída e a utilização dos operadores aritméticos, relacionais e lógicos. Estes assuntos nos deram o conhecimento suficiente para iniciar o desenvolvimento dos nossos primeiros programas em C. Mas estamos apenas no início. Temos mais três volumes, que nos darão a capacidade de desenvolver programas mais complexos. Continuem firmes nos estudos! Até o próximo módulo.

Referências

ARAÚJO, Jairo. Dominando a Linguagem C. São Paulo: Ciência Moderna, 2004.

ASCENIO, Ana Fernanda Gomes e CAMPOS, Edilene Aparecida Veneruchi. Fundamentos de Programação de Computadores. São Paulo: Prentice Hall, 2002.

DEITEL, H, M e DEITEL, P. J. Como Programar em C. Rio de Janeiro: LTC, 1999.

LAUREANO, Marcos. Programando em C Para Linux, Unix e

Page 100: Programação 2 Linguagem C (UFRPE)

100

Programação 2

Windows. Rio de Janeiro: Brasport, 2005.

MIZRAHI, Victorine Viviane. Treinamento em Linguagem C – Curso Completo. São Paulo: Makron, 1999.

MONTGOMERY, Eduard. Programando em C: Simples e Prático. São Paulo: Alta Books, 2006.

OLIVEIRA, Ulisses. Programando em C – Volume I – Fundamentos. São Paulo: Ciência Moderna, 2004.

SCHILDT, Herbert. C Completo e Total. São Paulo: Makron, 1996.

SEBESTA, Robert. Conceitos de Linguagem de Programação. São Paulo: Makron, 2003.

Conhecendo a Autora

Sou graduada em Ciência da computação pela Universidade Federal de Sergipe. Fiz mestrado e doutorado na Universidade Federal de Pernambuco, desenvolvendo pesquisas nas áreas de Sistemas Distribuídos e Geoprocessamento. Começei a ensinar em 2000, nos cursos de Ciência da Computação e Sistemas de Informação. Desde o início da minha carreira como professora, ministro disciplinas de Programação e tenho uma paixão pela linguagem C. Atualmente, encontrei uma nova paixão: Educação a Distância.

Page 101: Programação 2 Linguagem C (UFRPE)

Recife, 2009

Programação 2

Sônia Virginia Alves França

Page 102: Programação 2 Linguagem C (UFRPE)

Universidade Federal Rural de Pernambuco

Reitor: Prof. Valmar Corrêa de AndradeVice-Reitor: Prof. Reginaldo BarrosPró-Reitor de Administração: Prof. Francisco Fernando Ramos CarvalhoPró-Reitor de Extensão: Prof. Paulo Donizeti SiepierskiPró-Reitor de Pesquisa e Pós-Graduação: Prof. Fernando José FreirePró-Reitor de Planejamento: Prof. Rinaldo Luiz Caraciolo FerreiraPró-Reitora de Ensino de Graduação: Profª. Maria José de SenaCoordenação de Ensino a Distância: Profª Marizete Silva Santos

Produção Gráfica e EditorialCapa e Editoração: Allyson Vila Nova, Rafael Lira, Italo Amorim e Márcio HeitorRevisão Ortográfica: Marcelo MeloIlustrações: Diego Almeida e Glaydson da SilvaCoordenação de Produção: Marizete Silva Santos

Page 103: Programação 2 Linguagem C (UFRPE)

Sumário

Apresentação ........................................................................................5

Conhecendo o Volume 2 ......................................................................6

Capítulo 1 – Estruturas de Seleção .....................................................8

1.1. Estruturas de Controle .................................................................8

1.2. If… Else (se… senão) ..................................................................9

1.2.1. If Simples ............................................................................10

1.2.2. If Composto ........................................................................14

1.2.3. If Aninhado..........................................................................19

1.3. Switch (Escolha-Caso) ..............................................................24

1.4. Identação de um Programa .......................................................31

Capítulo 2 – Estruturas de Repetição ...............................................39

2.1. For (para... faça) ........................................................................39

2.2. While (enquanto... faça – teste no início) ..................................46

2.3. Do/while (repita... até - teste no final) ........................................49

2.4. Uso do break na Estrutura de Repetição ...................................56

Capítulo 3 – Modularização ................................................................64

3.1. O que são módulos e por que utilizá-los? .................................64

3.2. Estrutura de um módulo ............................................................66

Page 104: Programação 2 Linguagem C (UFRPE)

3.3. Em que ponto do programa os módulos devem ser implementados? ...............................................................................69

3.4. Escopo das Variáveis ................................................................70

3.5. Parâmetros ................................................................................71

3.6. Contexto do Módulo (Ação ou Resultado) .................................72

3.7. Ativando Funções ......................................................................73

Page 105: Programação 2 Linguagem C (UFRPE)

Apresentação

Caro(a) aluno(a),

Seja bem-vindo (a) ao segundo módulo da disciplina Programação II. Nesta disciplina, você está aprendendo a programar na linguagem de programação C, uma das mais utilizadas mundialmente.

No volume I, você aprendeu os comandos básicos do C, que permitiram a construção dos primeiros programas nesta linguagem. Neste volume II, será dado um novo passo, conhecendo um pouco mais desta linguagem, analisando novos comandos que melhorarão a capacidade de resolver problemas computacionais.

Este livro segue a mesma ideia do volume I, os assuntos são apresentados de forma gradativa, com muitos exemplos de programas completos e comentados, visando um bom entendimento, principalmente para as pessoas que estão iniciando no mundo da programação. Ao final de cada capítulo, você poderá testar o seu aprendizado e assimilar melhor o que foi estudado, através da resolução de exercícios. Isto é muito importante! Não deixe de resolvê-los.

Vale lembrar que, para um bom andamento dos estudos destes novos assuntos, você terá que ter assimilado o conteúdo do volume I, pois este continuará sendo utilizado em todos os nossos programas. Mas isto não é um problema para quem vem resolvendo questões de programação regularmente, não é mesmo?

O objetivo deste segundo módulo é apresentar as estruturas de controle de fluxo: seleção e repetição. Além disso, também será analisada a divisão de programas em módulos/funções, visando a um desenvolvimento mais rápido e um código mais legível. Ao final deste módulo, você vai perceber o quanto a sua capacidade de resolver programas foi aumentada. Convido-lhe para uma nova etapa no conhecimento da linguagem de programação C. Vamos começar?

Bons estudos!

Sônia Virginia Alves França

Page 106: Programação 2 Linguagem C (UFRPE)

6

Programação 2

Conhecendo o Volume 2

Neste segundo volume, vocês irão encontrar o módulo 02 da disciplina: Programação II. Este volume está estruturado em três capítulos, que serão estudados ao longo de 15h/aula. Para facilitar seus estudos, veja a organização deste volume.

Capítulo 1: Estruturas de Seleção

Carga Horária do Capítulo 01: 5 h/aula

Objetivos do Capítulo 1: Apresentar a sintaxe das duas estruturas de seleção (if e switch), disponíveis na linguagem de programação C.

Conteúdo Programático do Capítulo 1

• Estruturas de controle

• Estrutura de seleção if: simples, composto e aninhado

• Estrutura de seleção switch.

Capítulo 2: Estruturas de Repetição

Carga Horária do Capítulo 02: 5 h/aula

Objetivos do Capítulo 2: Apresentar a sintaxe das três estruturas de repetição (for, while e do/while), disponíveis na linguagem de programação C.

Conteúdo Programático do Capítulo 2

• Estrutura de repetição for

• Estrutura de repetição while

• Estrutura de repetição do/while

• Comando break.

Capítulo 3: Modularização de Programas

Carga Horária do Capítulo 03: 5 h/aula

Objetivos do Capítulo 3: Apresentar como se criam módulos(funções e procedimentos) em um programa C.

Page 107: Programação 2 Linguagem C (UFRPE)

7

Programação 2

Conteúdo Programático do Capítulo 3

• Estrutura de um módulo

• Variáveis locais e globais

• Parâmetros

• Chamada de um módulo

• Comando return.

Ao final de cada capítulo vocês encontrarão:

• A seção “Atividades e Orientações de Estudo”: que contém exercícios para a fixação do assunto estudado, além de indicação de fóruns de discussão.

• A seção “Conheça Mais”: que contém dicas de sites e livros que devem ser lidos para ampliar os seus conhecimentos.

• A seção “Vamos Revisar?”: que apresenta um resumo dos principais tópicos abordados no capítulo.

Page 108: Programação 2 Linguagem C (UFRPE)

8

Programação 2

Capítulo 1 – Estruturas de Seleção

Vamos conversar sobre o assunto?

Nos programas que desenvolvemos até este momento, todos os comandos que aparecem no programa são executados, ou seja, o processador vai passando e executando cada um dos comandos do programa. Existem situações em que não queremos que todos os comandos sejam executados. Nestes casos, devemos utilizar alguma estrutura de seleção, que nos permite desviar de uma sequência de comandos do programa. Neste capítulo, iremos aprender a utilizar as estruturas de seleção disponíveis na linguagem C, que são: if e switch. Estas estruturas correspondem ao “se” e “escolha” do Portugol. As estruturas de seleção também podem ser chamadas de: estruturas de decisão ou estruturas de desvio. Vamos avançar, um pouco mais, nossos conhecimentos em C?

1.1. Estruturas de Controle

De um modo geral, os comandos de um programa são executados um após o outro, na ordem em que foram escritos – de cima para baixo e da esquerda para a direita. Este é o fluxo de execução de um programa. Mas, através do uso de estruturas de controle, podemos controlar o fluxo de execução dos nossos programas. Existem três tipos de estruturas de controle:

• Sequência: nesta estrutura, todos os comandos são executados uma única vez, de forma linear, um após o outro. Até então, nossos programas foram desenvolvidos desta forma.

• Seleção: esta estrutura permite que um grupo de comandos seja executado ou não, dependendo do resultado de uma condição (representada por expressões relacionais ou lógicas). Dessa forma, poderemos ter um conjunto de comandos do nosso programa que não vai ser executado.

• Repetição: com estas estruturas, poderemos fazer com que uma sequência de comandos seja executada várias vezes.

Page 109: Programação 2 Linguagem C (UFRPE)

9

Programação 2

Para entender melhor as estruturas de controle, vamos fazer a seguinte analogia: imagine que o nosso programa é uma estrada. As retas são as sequências. Os entroncamentos são as estruturas de seleção, que nos permitem pegar um caminho ou outro. As rotatórias e os retornos são as estruturas de repetição, que nos permitem passar várias vezes pelo mesmo local. A Figura 1.1 apresenta estradas com retas, entroncamentos e rotatórias.

Figura 1.1: Retas, entroncamentos e rotatórias

Nas próximas seções, deste capítulo, vamos conhecer as estruturas de seleção do C. No capítulo seguinte, conheceremos as estruturas de repetição.

1.2. If… Else (se… senão)

A estrutura de seleção if é a estrutura de seleção mais simples. No entanto, esta estrutura resolve todo e qualquer problema de seleção. Esta estrutura permite executar um entre vários blocos de comandos. A escolha de qual bloco será executado depende do resultado de uma condição (expressão relacional ou lógica, apresentadas no capítulo 5 do volume I1). A sintaxe geral para o comando if é apresentada abaixo:

Sintaxe

if (condição)

bloco_de_comandos1;

else

bloco_de_comandos2;

Neste comando, a condição é verificada e, caso o resultado seja verdade, o bloco_de_ comandos1 será executado. Caso contrário, o bloco_de_comandos2 é executado. Note que somente um dos blocos

Atenção

1 Vale lembrar que o resultado de uma expressão relacional ou expressão lógica é sempre verdade ou falso.

Page 110: Programação 2 Linguagem C (UFRPE)

10

Programação 2

será executado. Apesar de possuir uma forma geral, esta estrutura pode se apresentar de modos ligeiramente diferentes: if simples, composto ou aninhado. Nas próximas seções vamos analisar, separadamente, cada uma das possibilidades de sintaxe.

1.2.1. If Simples

O if simples é o if sem o else. O if simples é utilizado quando se deseja executar uma sequência de comandos, apenas se a condição for verdade. Dessa forma, não existe uma sequência de comandos para ser executada quando a condição é falsa. A figura 1.2 apresenta o fluxograma do if simples. A condição do if será testada, se for verdade, o bloco de comandos vinculado ao if é executado. Se for falso, o bloco de comandos vinculado ao if é desviado.

Figura 1.2: Fluxograma do if simples

As sintaxes para o if simples são as seguintes:

Sintaxe

if (condição)

comando;

if (condição)

{ comando1;

comando2;

}

Quando o if simples tem apenas um comando, utilizamos a sintaxe da esquerda. Quando o if simples tem mais de um comando para ser executado, devemos colocar a sequência de comandos entre chaves.

Page 111: Programação 2 Linguagem C (UFRPE)

11

Programação 2

As chaves servem para que o compilador saiba quantos comandos2

vão ser desviados, caso a condição seja falsa. Quando não colocamos as chaves, o compilador entende que apenas um comando deve ser desviado. A figura 1.3 apresenta dois exemplos aplicando a sintaxe do if simples.

if simples com um comando if simples com mais de um comando

main()

{ comando 1;

comando 2;

comando 3;

if (condicao)

comando 4;

comando 5;

comando 6;

comando 7;

}

main()

{ comando 1;

comando 2;

comando 3;

if (condicao)

{ comando 4;

comando 5;

}

comando 6;

comando 7;

}

Figura 1.3: Exemplos de if simples

Vamos analisar os exemplos da figura 1.3. O programa principal da esquerda é formado por sete comandos. O programa vai sendo executado, passando pelos comando1, comando2 e comando3. Ao chegar no if, a condição é avaliada. Se a condição for verdade, o comando4 será executado. Se esta condição for falsa, o comando4 será desviado (ou seja, não será executado). Na sequência, são executados os comando5, comando6 e comando7.

O programa principal da direita também é composto de sete comandos. Os comando1, comando2 e comando3 são executados. Na seqüência, temos o if, que tem a sua condição avaliada. Se a condição for verdade, os comando4 e comando5 são executados. Caso contrário, os comando4 e comando5 são desviados. Como este if possui dois comandos, foi necessário colocá-los entre chaves. Na sequência, os comando6 e comando7 são executados.

Atenção

2 Até então, tínhamos somente as chaves que delimitavam o corpo do programa principal. Veremos que as chaves também aparecerão em outras situações.

Atenção

As condições do if devem vir entre parênteses. Se tivermos mais de uma expressão relacional, estas são conectadas por operadores lógicos. O abre chaves que delimita o bloco de comandos vinculado ao if é colocado após a condição do if. O fecha chaves é colocado após o último comando do bloco de comandos do if. O if e o else devem ser escritos todo em letras minúsculas.

Page 112: Programação 2 Linguagem C (UFRPE)

12

Programação 2

Vamos ver um exemplo do uso do if simples? O programa 1.1 solicita o saldo atual do cliente e o valor que ele deseja retirar no banco. O programa vai calcular e apresentar o valor do saldo do cliente, após o saque. Caso o saldo fique negativo, deve ser escrito uma mensagem informando esta situação ao cliente.

Programa Completo 1.1

1

2

3

4

5

6

7

8

9

10

11

12

13

14

main()

{

floatsaldo,valor_saque;

printf(“BancoPoupeAqui\n\n\n”);

printf(“Saldoatual:R$“);

scanf(“%f”,&saldo);

printf(“\n\nValordosaque:R$“);

scanf(“%f”,&valor_saque);

saldo=saldo–valor_saque;

printf(“\n\nSaldo apos o saque: R$%.2f

\n\n”,saldo);

if(saldo<0)

printf(“\nAtencao:suacontaficoucomsaldo

NEGATIVO!\a”);

getche();

}

Comentários sobre o programa completo 1.1:

• Linha 1: início do programa principal, que é definido pelo: “main()”.

• Linha 2: temos um abre chaves, que irá delimitar o corpo do programa principal.

• Linhas 3: temos as declarações das duas variáveis do programa: saldo e valor_saque.

• Linha 4: um printf que serve para colocar, no início da tela, o título do que o programa faz. Neste caso, foi colocado o nome do banco.

Page 113: Programação 2 Linguagem C (UFRPE)

13

Programação 2

• Linha 5: printf para que o usuário saiba que precisa fornecer o seu saldo atual.

• Linha 6: scanf que lê o saldo do cliente.

• Linha 7: printf para que o usuário saiba que precisa fornecer o valor do saque.

• Linha 8: scanf que lê o valor do saque.

• Linha 9: Como já sabemos o valor do saldo e quanto será sacado, podemos calcular quanto ficará o saldo depois do saque.

• Linha 10: printf para apresentar o valor do saldo após o saque.

• Linha 11: if que testa se o saldo ficou negativo. A condição para informar se o saldo está negativo é o saldo ser um valor menor que zero (saldo < 0). Assim, a condição do if é montada e colocada entre parênteses. Se o saldo for menor que zero, a mensagem de saldo negativo deve ser apresentada.

• Linha 12: printf para mostrar que o saldo ficou inválido. Veja que este comando está vinculado ao if, dessa forma, ele só será executado se a condição do if for verdade. Como o if tem apenas um comando, não precisamos colocar chaves.

• Linha 13: comando getche que faz com que a tela de execução do programa fique aberta, e assim podemos ver o resultado do programa. Nesta linha também poderíamos usar o system(“pause”).

• Linha 14: fecha chaves, indicando o final do programa principal.

A figura 1.4 apresenta duas telas de execução do programa completo 1.1. No primeiro caso, o saldo permanece positivo após o saque. Dessa forma, o comando vinculado ao if não foi executado. No segundo caso, o saldo ficou negativo após o saque, assim, o comando vinculado ao if foi executado (printf que imprime mensagem de saldo negativo).

Page 114: Programação 2 Linguagem C (UFRPE)

14

Programação 2

Saldo positivo após o saque

Saldo negativo após o saque

Figura 1.4: Telas de execução do programa completo 1.1

Agora que já sabemos como usar o if simples, vamos aprender a utilizar o if composto.

1.2.2. If Composto

O if composto é o if com o else, dessa forma, teremos uma sequência de comandos que é executada quando a condição resulta em verdade e uma outra sequência que é executada quando a condição é falsa.

A figura 1.5 apresenta o fluxograma do if composto. A condição do if será testada, se for verdade, o bloco de comandos 1 é executado. Se for falsa, o bloco de comandos 2 é executado. Notem que apenas um dos bloco de comando será executado.

Page 115: Programação 2 Linguagem C (UFRPE)

15

Programação 2

Figura 1.5: Fluxograma do if composto

Seguem abaixo as sintaxes para o if composto:

Sintaxe

Caso 1 Caso 2

if (condição)

comando1;

else

comando2;

if (condição)

{ comando1;

comando2;

}

else

comando3;

Caso 3 Caso 4

if (condição)

comando1;

else

{ comando2;

comando3;

}

if (condição)

{ comando1;

comando2;

}

else

{ comando3;

comando4;

}

De um modo geral, na sintaxe do if composto, teremos o if, juntamente com a condição que será testada. Abaixo da linha do

Page 116: Programação 2 Linguagem C (UFRPE)

16

Programação 2

if, temos um comando ou uma sequência de comandos que será executada se a condição for verdade. Logo em seguida temos o else e um comando ou um sequência de comandos que é executada quando a condição do if é falsa.

Vamos ver qual a diferença entre as quatro sintaxes. Existe uma regra que diz: se tivermos mais de um comando para ser executado quando a condição for verdade, temos que colocar a sequência de comandos entre chaves. Para um único comando, as chaves não são necessárias. A mesma regra vale para a sequência de comandos do else, mais de um comando, a sequência deve vir entre chaves.

Analisando a tabela com as quatro sintaxes temos:

• Caso 1: Se a condição for verdade, apenas um comando será executado. Se a condição for falsa, apenas um comando será executado. Como tivemos um comando na sequência do if e um comando na sequência do else, não é necessário colocar chaves.

• Caso 2: Se a condição for verdade, vários comandos serão executados. Dessa forma, é necessário colocar as chaves para delimitar a sequência de comandos do if. Quando a condição for falsa, apenas um comando será executado. Assim, não necessita colocar as chaves no comando do else.

• Caso 3: Se a condição for verdade, apenas um comando será executado. Com isso, não precisamos colocar as chaves no comando do if. No entanto, se a condição for falsa, vários comandos devem ser executados. Com isso, a sequência de comandos do else deve vir entre chaves.

• Caso 4: Se a condição for verdade, vários comandos serão executados. Dessa forma, precisamos colocar a sequência de comandos do if entre chaves. Se a condição for falsa, também serão executados vários comandos. Assim, a sequência do else precisa ser colocada entre chaves.

Vamos analisar um programa completo que utiliza o if composto. Este programa lê o nome do aluno e as suas duas notas. Em seguida, calcula a média do aluno e apresenta uma mensagem informando se o aluno foi aprovado ou reprovado (considerar que a média para ser aprovado é igual ou maior que 7.0).

Atenção

O else não tem condição. A condição é do if. Se a condição for falsa, a sequência do else é executada. Tomar cuidado com as chaves que delimitam a sequência de comandos do if e do else.

Page 117: Programação 2 Linguagem C (UFRPE)

17

Programação 2

Programa Completo 1.2

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#include<stdio.h>

main()

{

floatn1,n2,media;

charnome[20];

printf(“CadernetadeNotas\n\n”);

printf(“Nomedoaluno:“);

fflush(stdin);

gets(nome);

printf(“Nota1:“);

scanf(“%f”,&n1);

printf(“Nota2:“);

scanf(“%f”,&n2);

media = (n1+n2)/2;

if(media>=7)

printf(“\n\n%s foi aprovado(a) com media

%.1f\n”,nome,media);

else

printf(“\n\n%s foi reprovado(a) com media

%.1f\n”,nome,media);

getche();

}

Comentários sobre o programa completo 1.2:

• Linha 1: inclusão da biblioteca stdio, devido o comando fflush, que será usado quando formos ler o nome do aluno.

• Linha 2: início do programa principal, que é definido pelo: “main()”.

• Linha 3: temos um abre chaves, que irá delimitar o corpo do programa principal.

Page 118: Programação 2 Linguagem C (UFRPE)

18

Programação 2

• Linhas 4 e 5: temos as declarações das variáveis do programa.

• Linha 6: o printf que serve para colocar, no início da tela, o título do que o programa faz. Neste caso, será colocado “caderneta de notas”.

• Linhas 7 a 13: leitura das variáveis de entrada: nome do aluno, a primeira e a segunda nota.

• Linha 14: cálculo da média do aluno.

• Linha 15: if composto que verifica qual o valor da média, para escrever a mensagem se o aluno foi aprovado ou reprovado. Para o aluno ser aprovado, a média tem que ser maior ou igual a 7. A montagem da condição é feita utilizando operadores relacionais. Além disso, a condição foi colocada entre parênteses.

• Linha 16: printf que é executado quando a condição do if for verdade. Neste caso, quando a média do aluno for maior ou igual a 7. Note que a mensagem informa que o aluno foi aprovado. Como apenas um comando está vinculado ao if, não houve a necessidade de colocar chaves.

• Linha 17: temos um else, que indica que também teremos uma sequência de comandos para ser executada quando a condição do if for falsa, ou seja, média do aluno menor que 7.

• Linha 18: printf que é executado quando a condição do if for falsa. Note que a mensagem informa que o aluno foi reprovado. Como apenas um comando está vinculado ao else, não houve a necessidade de colocar chaves.

• Linha 19: comando getche que faz com que a tela de execução do programa fique aberta, e assim podemos ver o resultado do programa.

• Linha 20: fecha chaves, indicando o final do programa principal.

A figura 1.6 apresenta duas telas de execução do programa completo 1.2. No primeiro caso, o aluno é aprovado e no segundo caso, é reprovado.

Page 119: Programação 2 Linguagem C (UFRPE)

19

Programação 2

Aluno aprovado

Aluno reprovado

Figura 1.6: Telas de execução do programa completo 1.2

Agora só falta estudarmos o último tipo de if, que é o if aninhado. Vamos aprender mais um pouco?

1.2.3. If Aninhado

O if composto, visto na seção anterior, é usado quando temos duas possibilidades de resposta. Por exemplo, ou o aluno é aprovado ou é reprovado. Apenas uma situação irá ocorrer. O if aninhado ocorre quando temos mais de duas possibilidades de respostas (ou situação). Por exemplo, ao comparar dois números (x e y), temos três possibilidades de resposta: x é menor que y, x é maior que y, ou ainda, x e y são iguais. Assim, a primeira possibilidade será testada na condição do if (verificando se x é menor que y). Se a condição for falsa, ainda temos duas possibilidades de resposta. Para fazer esta verificação, necessitamos de um outro if. Este novo if será colocado dentro da sequência de comandos do else. Assim, teremos um if dentro do outro, por isso é chamado de if aninhado.

Page 120: Programação 2 Linguagem C (UFRPE)

20

Programação 2

A seguir, são apresentadas duas sintaxes de if aninhado. No caso 1, temos três possibilidades de respostas e no caso 2, quatro possibilidades. Vale lembrar que podemos ir aninhando um if dentro do outro, sem um limite de aninhamento. Só depende de quantas possibilidades de situações teremos que testar.

Sintaxe

Caso 1: três possibilidades de resposta

Caso 2: quatro possibilidades de resposta

if (condição1)

comando1;

else

{ if (condicao2)

comando2;

else

comando3;

}

if (condição1)

comando1;

else

{ if (condicao2)

comando2;

else

{ if (condicao3)

comando3;

else

comando4;

}

}

No caso 1, se a condição1 do primeiro if for verdade, o comando1 será executado e toda a sequência do else é desviada. No entanto, se a condição1 do if for falsa, o fluxo do programa é desviado para o else. Quando chega no else, é encontrada uma sequência de comandos (por isso é necessário colocá-la entre chaves). Mas, nesta sequência tem um if, que precisa ter a sua condição avaliada. Se a condicao2 deste if for verdade, o comando2 é executado. Caso seja falsa, o fluxo do programa é desviado para o else e executa o comando3. Dessa forma, apenas um dos comandos (comando1, comando2 ou comando3) será executado, os demais serão desviados.

Um comportamento similar ocorre com o caso 2, que analisa quatro possibilidades de respostas.

Vamos analisar um programa completo que utiliza o if aninhado.

Atenção

Existe if sem else (que é o primeiro caso de if que estudamos – if simples), mas todo else está vinculado a um if. Não colocar ponto e vírgula depois da condição do if

Page 121: Programação 2 Linguagem C (UFRPE)

21

Programação 2

Neste programa, serão lidos dois números inteiros(x e y) e seus valores serão comparados. O programa irá escrever uma das três mensagens: x é maior que y, x é menor que y ou x e y são iguais. Na sequência, as linhas do programa serão comentadas.

Programa Completo 1.3

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

main()

{

intx,y;

printf(“ComparaNumeros\n\n”);

printf(“X:“);

scanf(“%d”,&x);

printf(“\nY:“);

scanf(“%d”,&y);

if(x>y)

printf(“\n\n%dehmaiorque%d”,x,y);

else

{if(x<y)

printf(“\n\n%dehmenorque%d”,x,y);

else

printf(“\n\nXeYsaoiguais:%d”,x);

}

getche();

}

Comentários sobre o programa completo 1.3:

• Linha 1: início do programa principal, que é definido pelo: “main()”.

• Linha 2: temos um abre chaves, que irá delimitar o corpo do programa principal.

• Linha 3: temos as declarações das variáveis do programa.

• Linha 4: o printf que serve para colocar, no início da tela, o título

Page 122: Programação 2 Linguagem C (UFRPE)

22

Programação 2

do que o programa faz. Neste caso, será colocado “Compara Números”.

• Linhas 5 a 8: leitura das variáveis de entrada: x e y.

• Linha 9: Agora que já conhecemos o valor de x e y, devemos começar a comparação. Nesta linha temos um if, com a condição para verificar se x é maior que y. Se esta condição for verdade, o comando da linha 10 será executado e todos os comandos dentro do else serão desviados.

• Linha 10: printf para escrever que x é maior que y.

• Linha 11: temos um else, o programa terá seu fluxo desviado para o else, caso a condição do if seja falsa. Notem que, se o x não é maior que y, ainda temos que descobrir se x é menor que y ou se x e y são iguais. Por conta disto, na sequência de comandos deste else, será necessário colocar um if composto. Por termos uma seqüência de comandos, devemos colocá-la entre chaves.

• Linhas 12: abre chaves para informar que começará a sequência de comandos do else, além do if que verifica a segunda possibilidade de resposta: se x é menor que y.

• Linha 13: printf para escrever que x é menor que y. Este printf é executado caso a condição do if da linha 12 seja verdade.

• Linhas 14: temos um else, que está vinculado ao if da linha 12. Ou seja, se a condição deste if for falsa, o fluxo do programa é desviado para este else.

• Linha 15: printf para escrever que x e y são iguais. Este printf é executado caso a condição do if da linha 12 seja falsa.

• Linhas 16 e 17: temos o getche() e o fecha chaves, indicando o final do programa principal.

A figura 1.7 apresenta telas de execução do programa completo 1.3, mostrando as três possibilidades de respostas.

Page 123: Programação 2 Linguagem C (UFRPE)

23

Programação 2

X menor que Y

X maior que Y

X igual a Y

Figura 1.7: Telas de execução do programa completo 1.3

Agora que já sabemos utilizar os três casos da estrutura de seleção if: simples, composto e aninhado, vamos analisar um outro tipo de estrutura de seleção disponível no C, que é o switch. Vale lembrar que o if é um tipo de estrutura de seleção que pode ser aplicada em qualquer situação em que seja necessária tomar uma decisão no programa. O switch apresenta algumas restrições e nem sempre poderemos utilizá-lo. No entanto, o switch tem uma sintaxe mais “limpa” que a do if. Dessa forma, sempre que for possível o seu uso, é interessante incluí-lo no programa. Vamos ver como o switch funciona?

Page 124: Programação 2 Linguagem C (UFRPE)

24

Programação 2

Figura 1.8: Quadrinhos sobre decisão

1.3. Switch (Escolha-Caso)

O switch é uma estrutura de decisão que permite a execução de uma sequência de comandos a partir da análise do valor de uma variável inteira ou de uma variável com um único caractere. Normalmente, o switch é usado quando sabemos os prováveis valores que uma variável pode armazenar, e para cada valor, temos que executar uma sequência de comandos diferente. A grande restrição do switch é que ele não funciona para variáveis reais, nem cadeia de caracteres. Além disso, o switch testa se a variável é igual a um valor.

No caso de uma condição usada no if, nós podemos usar qualquer tipo de variável, além de podermos verificar se seus valores são: menor que, maior que, diferente de, etc., e não apenas a igualdade. Por conta dessas restrições, não é em toda situação de seleção que o switch pode ser utilizado. No Portugol, o switch é o comando escolha-caso. Significando que uma sequência de comandos será escolhida, caso a variável tenha um certo valor. Vamos analisar as sintaxes do switch.

Page 125: Programação 2 Linguagem C (UFRPE)

25

Programação 2

Sintaxe

Caso 1: sem o default Caso 2: com o default

switch(variavel)

{ casevalor1:comando1;

comando2;

break;

casevalor2:comando3;

comando4;

break;

casevalor3:comando5;

comando6;

break;

}

switch(variavel)

{casevalor1:comando1;

comando2;

break;

casevalor2:comando3;

comando4;

break;

casevalor3:comando5;

comando6;

break;

default:comando7;

comando8;

break;

}

A sintaxe do switch é a seguinte: após o switch, colocamos o nome da variável que será avaliada, entre parênteses. Para cada possível valor que a variável pode assumir, colocaremos um case e ao lado, o valor da variável seguido de dois pontos(:). Em seguida, colocamos a sequência de comandos que deve ser executada, caso a variável tenha este valor. A sequência de comandos deve ser finalizada com o comando break, obrigatoriamente. Assim, para cada valor que a variável pode assumir, teremos um case e a sequência de comandos. A sequência de comandos não precisa vir entre chaves. No entanto, temos as chaves que abre e fecha o comando switch.

Ao executar o switch, o processador irá procurar um case que tenha o valor que a variável está armazenado no momento. Quando encontrar, executa a sequência de comandos relacionada a este valor e o break faz com que o fluxo do programa seja desviado para o primeiro comando depois da chaves que fecha o switch. Assim, só será executada a sequência de comandos de um único case. No entanto, caso a variável não esteja armazenando um dos valores

Page 126: Programação 2 Linguagem C (UFRPE)

26

Programação 2

previstos, nenhuma sequência de comandos será executada.

Além dos case com os prováveis valores das variáveis, também podemos colocar a cláusula default no nosso switch (Caso 2, da sintaxe). O default funciona como um else, ou seja, se a variável não tiver nenhum dos valores previstos nos case, será executada a sequência de comandos do default. O default é opcional, assim, podemos ter switch com ou sem default.

Abaixo, temos o exemplo 1.1 que apresenta um switch sem o default. A variável cargo é inteira e pode assumir os valores 1, 2 ou 3. Dependendo do cargo do funcionário, é dado um aumento diferenciado ao salário do mesmo. Notem o break no final de cada sequência de comandos dos case.

Exemplo 1.1: Switch sem default

1

2

3

4

5

6

7

8

switch(cargo)

{ case1:sal=sal+200;

break;

case2:sal=sal+400;

break;

case3:sal=sal+600;

break;

}

No exemplo 1.2 temos um switch com o default. Neste exemplo, se a variável cargo não estiver com 1, 2 ou 3, será executada a sequência de comandos do default. Ou seja, qualquer outro valor diferente dos valores previstos, a sequência de comandos do default será executada.

Atenção

O default deve ser, sempre, a última sequência de comandos do switch. Não podemos colocar dois case testando o mesmo valor. Quando a variável do switch for um char, devemos colocar os possíveis valores da variável entre apóstrofos, por exemplo: case ‘a’:.

Page 127: Programação 2 Linguagem C (UFRPE)

27

Programação 2

Exemplo 1.2: Switch com default

1

2

3

4

5

6

7

8

9

10

switch(cargo)

{ case1:sal=sal+200;

break;

case2:sal=sal+400;

break;

case3:sal=sal+600;

break;

default:sal=sal+100;

break;

}

Uma outra situação que pode acontecer é: uma mesma sequência de comandos deve ser executada para diferentes valores da variável. Por exemplo, para os funcionários dos cargos 1 e 2 será dado o mesmo aumento salarial. Assim, para não repetirmos a mesma sequência de comandos no case 1 e 2, faremos como mostra a linha 2 do exemplo 1.3. Coloca-se o primeiro case com o respectivo valor e após os dois pontos, vem o próximo case e o valor que será testado. Podemos colocar quantos case sejam necessários.

Exemplo 1.3: Switch

1

2

3

4

5

6

7

8

switch(cargo)

{ case1:case2: sal=sal+200;

break;

case3:sal=sal+600;

break;

default:sal=sal+100;

break;

}

Vamos analisar um programa completo que faz uso do switch. Uma empresa concederá um aumento de salário aos seus funcionários,

Page 128: Programação 2 Linguagem C (UFRPE)

28

Programação 2

variável de acordo com o cargo, conforme a tabela abaixo. Faça um programa que leia o cargo de um funcionário (1-Gerente,2-Engenheiro,3-Técnico) e o seu salário atual e calcule o novo salário. Se o cargo do funcionário for inválido, deverá ser impressa uma mensagem de erro. Como resultado, mostre o salário antigo, o novo salário e a diferença de salário.

Cargo Percentual

Gerente 10%

Engenheiro 20%

Técnico 30%

Page 129: Programação 2 Linguagem C (UFRPE)

29

Programação 2

Programa Completo 1.4

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

main()

{

intcargo;

floatsal,nsal;

printf(“EmpresaLegal\n\n\n”);

printf(“Cargo(1-Gerente/2-Engenheiro/3-

Tecnico):“);

scanf(“%d”,&cargo);

printf(“\nSalarioatual:“);

scanf(“%f”,&sal);

switch(cargo)

{ case1:nsal=sal*1.1;break;

case2:nsal=sal*1.2;break;

case3:nsal=sal*1.3;break;

default: printf(“\n\nCargo Invalido!\n”);

break;

}

if((cargo>=1)&&(cargo<=3))

{ printf(“\n\n______________________________

\n”);

18

20

21

22

23

24

25

printf(“\n\nResultados\n\n”);

printf(“\nSalarioAntigo..............:R$

%.2f\n”,sal);

printf(“\nSalarioNovo................:R$

%.2f\n”,nsal);

printf(“\nDiferenca de Salarios: R$

%.2f\n”,nsal-sal);

}

getche();

}

Page 130: Programação 2 Linguagem C (UFRPE)

30

Programação 2

Comentários sobre o programa completo 1.4:

• Linhas 3 e 4: temos as declarações das variáveis do programa. O cargo do funcionário será armazenado em uma variável do tipo int. Quando tiver armazenado 1, significa que o funcionário é um gerente, 2 é engenheiro e 3 é técnico.

• Linha 5: o printf que serve para colocar, no início da tela, o título da empresa.

• Linha 6: printf que solicita que o usuário digite o cargo do funcionário. Como estamos usando uma legenda, ou seja, um número representando cada cargo, precisamos colocar neste printf o significado de cada número.

• Linha 7: scanf para ler o cargo do funcionário.

• Linha 8: printf para solicitar a digitação do salário do funcionário.

• Linha 9: scanf para lê o salário do funcionário.

• Linha 10: switch que avalia o cargo do funcionário, para calcular seu novo salário. Cada cargo tem um aumento de salário diferente. Como foi solicitado que imprima uma mensagem de erro quando o cargo foi inválido, será colocado o default.

• Linhas 11 a 15: nestas linhas temos os case de cada valor da variável cargo, além do default. Para cada case, colocamos a fórmula para o cálculo do novo salário. No default, temos o printf que escreve a mensagem de cargo inválido. Notem que o break aparece no final da sequência de comando de cada case.

• Linha 16: este if foi colocado para testar se o cargo digitado é válido. Sendo válido, podemos apresentar os resultados.

• Linhas 17 a 23: temos os printf que apresentam os resultados do programa: o salário antigo, o novo e a diferença dos salários.

• Linhas 24 e 25: temos o getche() e o fecha chaves, indicando o final do programa principal.

A figura 1.9 apresenta duas telas de execução do programa completo 1.4.

Atenção

Atenção: neste programa a variável cargo armazenará 1 (quando o cargo for gerente), 2 (quando for engenheiro) e 3 (quando for técnico). Dessa forma, esta variável será do tipo inteiro.

Page 131: Programação 2 Linguagem C (UFRPE)

31

Programação 2

Cargo Válido

Cargo Inválido

Figura 1.9: Telas de execução do programa completo 1.4

Notem que, quando o cargo é inválido, apenas a mensagem de erro é apresentada. Quando o cargo é válido, os resultados são apresentados.

Agora que já sabemos usar as estruturas de seleção do C, vamos abrir um parênteses para falar sobre a identação dos comandos dos programas.

1.4. Identação de um Programa

A identação é a forma como alinhamos os comandos do nosso programa. O alinhamento faz com que o código fique mais fácil de ser lido. Vamos entender a identação do programa completo 1.4, analisando a figura 1.10.

Page 132: Programação 2 Linguagem C (UFRPE)

32

Programação 2

main()

{

intcargo;

floatsal,nsal;

printf(“EmpresaLegal\n\n\n”);

printf(“Cargo(1-Gerente\2-Eng.\3-Tecnico):“);

scanf(“%d”,&cargo);

printf(“\nSalarioatual:“);

scanf(“%f”,&sal);

switch(cargo)

{ case1:nsal=sal*1.1;break;

case2:nsal=sal*1.2;break;

case3:nsal=sal*1.3;break;

defaul: printf(“\n\nCargo Invalido!\n”);

break;

}

if((cargo>=1)&&(cargo<=3))

{ prinft(“\n\n____________________________\n”);

prinft(“\n\nResultados\n\n”);

prinft(“\nSalarioAntigo...:R$%.2f\n”,sal);

prinft(“\nSalarioNovo....:R$%.2f\n”,nsal);

prinft(“\nDiferenca:R$%.2f\n”,nsal-sal);

}

getche();

}

Figura 1.10: Código Identado

Cada chaves que abre deve ficar no mesmo alinhamento da chaves que fecha. Assim, a chaves que abre o programa, fica alinhada com a chaves que fecha o programa. Com as chaves alinhadas fica mais fácil

Page 133: Programação 2 Linguagem C (UFRPE)

33

Programação 2

de verificar se alguma chave está “descasada”. As chaves3também devem ficar alinhadas com a estrutura que elas estão delimitando. Vejam a chaves do main, do switch e do if.

Notem também, que a sequência de comandos dentro do switch e do if fica um pouco mais para dentro. Dessa forma, nós destacamos os comandos que estão dentro da estrutura. Quando colocamos todos os comandos do nosso programa no mesmo alinhamento, fica mais difícil de visualizar quais comandos fazem parte de uma estrutura de controle.

A figura 1.11 apresenta o mesmo código, mas sem a identação, vejam que o switch e o if ficam menos visíveis.

Dica de Programação

3 Sempre que abrir uma chaves no seu programa, já coloque a chaves que fecha. Assim não corre o risco de esquecer a chaves que fecha uma sequência de comandos.

Page 134: Programação 2 Linguagem C (UFRPE)

34

Programação 2

main()

{

intcargo;

floatsal,nsal;

printf(“EmpresaLegal\n\n\n”);

printf(“Cargo(1-Gerente\2-Engenheiro\3-Tecnico):“);

scanf(“%d”,&cargo);

printf(“\nSalarioatual:“);

scanf(“%f”,&sal);

switch(cargo)

{case1:nsal=sal*1.1;break;

case2:nsal=sal*1.2;break;

case3:nsal=sal*1.3;break;

defaul:printf(“\n\nCargoInvalido!\n”);break;}

if((cargo>=1)&&(cargo<=3))

{prinft(“\n\n____________________________\n”);

prinft(“\n\nResultados\n\n”);

prinft(“\nSalarioAntigo..........:R$%.2f\n”,sal);

prinft(“\nSalarioNovo...........:R$%.2f\n”,nsal);

prinft(“\nDiferenca de Salarios: R$ %.2f\n”, nsal -

sal);

}

getche();

}

Figura 1.11: Código sem Identação

Bem melhor ler o código identado, não é mesmo? Não deixem de identar todos os programas. Vocês verão que fica mais fácil e rápido de entender.

Page 135: Programação 2 Linguagem C (UFRPE)

35

Programação 2

Atividades e Orientações de Estudo

Os nossos programas vão começar a crescer de tamanho e, a cada capítulo que avançamos, teremos novas possibilidades de fazer coisas bem interessantes. Nesta seção, temos uma lista de programas que devemos resolver, para efetivar o nosso conhecimento nas estruturas de seleção. Vocês irão notar que algumas questões só podem ser feitas usando o if, mas outras podem ser resolvidas com o uso do switch. Liguem o computador e comecem a programar!

1. Faça um programa que lê 2 valores A e B (inteiros) e informa se A é divisível por B ou não.

2. Faça um programa que leia um número inteiro e mostre uma mensagem indicando se este número é par ou ímpar, e se é positivo ou negativo.

3. Tendo como dados de entrada a altura e o sexo(1-feminino/2-masculino) de uma pessoa, construa um programa que calcula e escreve seu peso ideal, utilizando as seguintes fórmulas:

• para homens: (72.7*altura)-58

• para mulheres: (62.1*altura)-44.7

4. Um hotel cobra R$ 50,00 reais a diária e mais uma taxa de serviços. A taxa de serviços é de:

• 15,30 por dia, se número de diárias <15

• 10,00 por dia, se número de diárias =15

• 8,50 por dia, se número de diárias >15

Faça um programa que lê a quantidade de dias que o hóspede ficou no hotel e imprime a taxa e total a pagar.

5. Elaborar um programa que irá ler três números inteiros diferentes e informa qual é o maior valor.

6. Elaborar um programa que irá ler quatro inteiros diferentes e informa qual é o menor valor.

7. Escrever um programa que lê a matrícula do aluno e suas 3 notas. Calcular a média e verificar qual o seu conceito, conforme

Page 136: Programação 2 Linguagem C (UFRPE)

36

Programação 2

a tabela:

Média Conceito

>= 9,0 A

>= 7,5 e < 9,0 B

>= 6,0 e < 7,5 C

>= 4,0 e < 6,0 D

< 4,0 E

O programa deve escrever a matrícula do aluno, suas notas, a média, o conceito correspondente e a mensagem: APROVADO se o conceito for A, B ou C e REPROVADO se o conceito for D ou E.

8. Escrever um programa que lê a hora de início e hora de término de um jogo, ambas subdivididas em dois valores distintos: horas e minutos. Calcular e escrever a duração do jogo, também em horas e minutos, considerando que o tempo máximo de duração de um jogo é de 24 horas e que o jogo pode iniciar em um dia e terminar no dia seguinte.

9. Fazer um programa que leia uma data (dia e mês) e informe se é primavera, verão, outono ou inverno. Sabe-se que as estações, no hemisfério sul, começam nas seguintes datas:

• Primavera: 22/Set

• Verão: 21/Dez

• Outono: 20/Mar

• Inverno: 20/Jun

10. Faça um programa para ler o peso de uma encomenda, tipo de entrega(1-sedex, 2-sedex 10) e região onde será entregue a encomenda(1- Norte, 2-Nordeste, 3-Centro-Oeste, 4-Sudeste, 5-Sul). Calcular o valor de postagem baseado nas tabelas abaixo:

Até 1 Kg R$ 5,00

De 1 Kg a 5 Kg R$ 10,00

Page 137: Programação 2 Linguagem C (UFRPE)

37

Programação 2

Acima de 5 Kg R$ 15,00 + R$ 3,00 por Kg excedente

Para entrega por Sedex Adicionar R$ 9,00

Para entrega por Sedex 10 Adicionar R$ 11,00

Para entregar na região Norte Adicionar R$ 3,00

Para entregar na região Nordeste Adicionar R$ 2,00

Para entregar na região Centro-Oeste Adicionar R$ 6,00

Para entregar na região Sudeste Adicionar R$ 5,00

Para entregar na região Sul Adicionar R$ 7,00

Conheça Mais

Para ampliar nossos conhecimentos sobre os assuntos tratados neste capítulo, leiam o capítulo que aborda as estruturas de seleção, do livro:

SCHILDT, Herbert. C Completo e Total. São Paulo: Makron, 1996.

Vamos Revisar?

Vamos revisar um pouco o assunto visto neste capítulo? Façamos uma leitura do resumo a seguir:

• Estruturas de seleção servem para analisar condições e valores de variáveis verificando se uma sequência de comandos deve ser executada ou desviada.

• As estruturas de seleção do C são: if e switch.

• O if pode ser: simples(quando não tem o else), composto (quando tem o else) e aninhado (quando temos um outro if dentro da sequência de comandos do else).

Page 138: Programação 2 Linguagem C (UFRPE)

38

Programação 2

• O if avalia uma condição, se a mesma for verdade, a sequência de comandos do if é executada.

• O switch é uma estrutura de seleção que avalia o valor de uma variável inteira ou caractere.

• No final da sequência de comando do case, devemos colocar um break, forçando a saída da estrutura de seleção switch.

• A identação dos comando de um programa torna o código mais legível e fácil de entender.

Page 139: Programação 2 Linguagem C (UFRPE)

39

Programação 2

Capítulo 2 – Estruturas de Repetição

Vamos conversar sobre o assunto?

Neste capítulo, vamos abordar as estruturas de repetição. Como mencionado da seção 1.1 do capítulo anterior, com estas estruturas poderemos repetir uma sequência de comandos quantas vezes forem necessário. A linguagem de programação C fornece três tipos de estrutura de repetição: for, while e do/while. Entendendo as características de cada estrutura de repetição, poderemos escolher a mais adequada para resolver um dado problema. Vamos em frente!

Figura 2.1: Quadrinho sobre repetição

2.1. For (para... faça)

A estrutura de repetição for é equivalente ao para/faça do Portugol. Esta estrutura costuma ser utilizada quando sabemos quantas vezes a sequência de comandos deve ser repetida. A contagem dos ciclos é feita por uma variável chamada de contador. A estrutura for também é chamada de estrutura de repetição com contador. Sua sintaxe é a seguinte:

Page 140: Programação 2 Linguagem C (UFRPE)

40

Programação 2

Sintaxe

for (var-controle = inicio; condição;

atualização_var-controle)

comando1;

for (var-controle = inicio; condição;

atualização_var-controle)

{ comando1;

comando2;

comandon;

}

Onde:

• var-controle: é a variável que controla a quantidade de repetições. Esta variável é inicializada e atualizada a cada repetição.

• início: é o valor inicial da variável que controla o for. Ao iniciar a repetição, a variável de controle é inicializada com este valor.

• condição: expressão relacional ou lógica que é testada ao final de cada repetição. Se a condição for verdade a sequência de comandos é executada mais uma vez. Quando a condição é falsa, a repetição para. Dessa forma, temos que ter certeza que algum momento a condição se tornará falsa. Caso contrário, entraremos em um loop infinito. Ou seja, o programa fica repetindo a sequência de comandos infinitamente.

• atualização_var-controle: a cada vez que a repetição é executada, a variável de controle deve ser atualizada. Nesta parte do for, colocamos a expressão que atualizará a variável de controle. É com esta atualização que faremos com que a condição do for se torne falsa e a repetição tenha fim.

Notem que cada parte do for é separada por ponto e vírgula. Mas não colocamos o ponto e vírgula depois do comando que atualiza a variável de controle, nem após o fecha parênteses.

A estrutura de repetição for funciona da seguinte forma:

Page 141: Programação 2 Linguagem C (UFRPE)

41

Programação 2

• Passo 1: a variável de controle é inicializada.

• Passo 2: a condição é analisada. Se for verdade, a sequência de comandos da repetição é executada.

• Passo 3: ao terminar de executar a sequência de comandos da repetição, a variável de controle é atualizada. E retorna ao passo 2, verificando se a condição continua sendo verdade (para repetir mais uma vez a sequência de comandos) ou se é falsa ( parando a repetição).

A figura 2.2 apresenta o funcionamento da estrutura de repetição for.

Figura 2.2 Funcionamento da estrutura de repetição for.

Assim como o if, se houver mais de um comando vinculado ao for, devemos colocar a sequência de comandos entre chaves. Se houver apenas um comando, não há necessidade de colocar as chaves.

Vamos ver dois exemplos do uso do for. No exemplo 2.1 temos um for que será repetido 10 vezes. A variável de controle i é inicializada com 1. Cada vez que é finalizada uma execução do comando vinculado ao for, é incrementado 1 valor da variável 14. Esta repetição vai parar quando i for igual a 11. Cada vez que o for é executado, é escrito o valor atual de i na tela. Assim, será escrito de 1 a 10 na tela.

Exemplo 2.1: for com variável de controle sendo incrementada

1

2

for(i=1;i<=10;i++)

printf(“\nOvalordei=%d”,i);

No exemplo 2.2, temos um for que também será repetido 10 vezes. No entanto, a variável de controle inicia com 10 e é decrementada a

Atenção

A variável de controle do for deve ser do tipo inteiro. O for deve ser escrito todo em minúsculo.

Atenção

4 Estão lembrados do operador ++? Este operador acrescenta uma unidade a uma variável. Ele foi abordado na seção 5.3 do Volume I.

Page 142: Programação 2 Linguagem C (UFRPE)

42

Programação 2

cada final da repetição. Notem que esta repetição vai parar quando o i é 0. Este for também faz a impressão de 1 a 10 na tela. Só que, dessa vez, os números serão impressos na ordem decrescente.

Exemplo 2.2: for com variável de controle sendo decrementada

1

2

for(i=10;i>=1;i--)

printf(“\nOvalordei=%d”,i);

Vamos agora analisar um programa completo que usa o comando for. Uma loja quer calcular um bônus que dará a cinco clientes. O bônus depende de quanto cada cliente comprou. Os clientes que compraram menos de R$ 500 receberão de bônus 10% do valor das compras. Os clientes que compraram a partir de R$ 500 receberão de bônus, 15% do valor das compras. O programa deve ler o código do cliente e o valor das compras e escrever o valor do bônus, para cada um dos cinco clientes.

Page 143: Programação 2 Linguagem C (UFRPE)

43

Programação 2

Programa Completo 2.1

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

main()

{ floatvalor;

intcod,i;

for(i=1;i<=5;i++)

{ system(“cls”);

printf(“LojaCompreTudo\n\n”);

printf(“CodigodoCliente%d:“,i);

scanf(“%d”,&cod);

printf(“\nValordascompras:“);

scanf(“%f”,&valor);

if(valor<500)

printf(“\n\nValordobonusR$%.2f\n”,

valor*0.1);

else

printf(“\n\nValordobonusR$%.2f\n”,

valor*0.15);

printf(“\n\ntecle enter para

continuar...”);

getche();

}

}

Comentários sobre o programa completo 2.1:

• Linhas 2 e 3: temos as declarações das variáveis do programa. O valor das compras, o código do cliente e o i, que será a variável de controle do for.

• Linha 4: primeira linha do for, indicando que a variável i será inicializada com 1, a condição para permanecer repetindo é i ser menor ou igual a 5 e o incremento do i, que terá seu valor aumentado em uma unidade a cada repetição. Da linha 5 até 17 temos a sequência de comandos que será repetida 5 vezes.

Page 144: Programação 2 Linguagem C (UFRPE)

44

Programação 2

• Linha 5: abre chaves para delimitar a sequência de comandos vinculada ao for. Nesta linha também temos um comando novo: system(“cls”); Este comando5 limpa a tela, eliminado tudo que tem escrito. Com o uso deste comando, cada vez que formos cadastrar os dados de um novo cliente, a tela é limpa, ficando assim mais organizado. Depois vocês podem comentar esse comando do programa e vejam o que acontece sem ele.

• Linha 6: printf para colocar o nome da empresa.

• Linha 7: printf para solicitar a digitação do código do funcionário. Vejam que nesta mensagem, é colocado o valor do i, isto é interessante para que o usuário saiba qual cliente está sendo digitado no momento, se é o primeiro, o quarto, etc.

• Linha 8: scanf para ler o código do cliente.

• Linha 9: printf que solicita o valor das compras do cliente.

• Linha 10: scanf para ler o valor das compras do cliente.

• Linhas 11: Como já sabemos o valor das compras do cliente, devemos calcular o valor do bônus. O bônus pode ser de 15% ou 10%. Para decidir qual bônus o cliente levará, usaremos uma estrutura de decisão. Assim, nesta linha temos um if composto, que verifica se o valor das compras é menor que R$500.

• Linhas 12: printf que é executado se a condição do if for verdade. Notem que no próprio printf é feita a conta de quanto o cliente receberá de bônus. Aqui é dado um bônus de 10% ao cliente.

• Linha 13: temos o else, já que se trata de um if composto.

• Linha 14: printf que é executado se a condição do if for falsa. Aqui é dado um bônus de 15% ao cliente.

• Linha 15: temos os printf que dá uma mensagem para que o usuário tecle enter e dê prosseguimento a um novo cadastro.

• Linha 16: temos o getche() que faz com que possamos ver o valor do bônus do cliente.

• Linha 17: fecha chaves que delimita a sequência de comandos do for.

• Linha 18: fecha chaves do programa principal6.

Atenção

5 cls significa clear screen. Ou seja, limpe a tela.

Atenção

6 Fiquem atentos a identação do programa.

Page 145: Programação 2 Linguagem C (UFRPE)

45

Programação 2

A figura 2.3 apresenta uma tela de execução do programa completo 2.1.

Figura 2.3: Tela de execução do programa completo 2.1

Na próxima seção iremos estudar o segundo tipo de estrutura de repetição do C, o while.

Figura 2.4: Quadrinho - O castigo de Pablo

Page 146: Programação 2 Linguagem C (UFRPE)

46

Programação 2

2.2. While (enquanto... faça – teste no início)

A estrutura de repetição while é equivalente ao enquanto/faça do Portugol. Nesta estrutura uma condição é avaliada, e enquanto a condição for verdade, a sequência de comandos será executada. Se a condição for falsa, a repetição será interrompida. O while avalia a condição antes da primeira iteração7, isto significa que, eventualmente, pode não ocorrer sequer a primeira iteração. Por isso, esta estrutura é chamada também de: repetição que faz teste no início. A sintaxe do while é a seguinte:

Sintaxe

while(condição)

comando;

while(condição)

{ comando1;

comando2;

comandon;

}

Ao lado do while colocamos a condição (entre parênteses) que será avaliada e que faz com que a repetição seja executada ou não. Ao final de cada iteração, a condição é avaliada para verificar se continua sendo verdade, para que a repetição seja executada mais uma vez ou pare. No while também poderá acontecer o problema de loop infinito. Por isso, temos que ter certeza que em algum momento a condição se tornará falsa, para que a repetição tenha fim. Seguindo a mesma regra do if e do for, se tivermos mais de um comando vinculado ao while, devemos colocar a sequência de comandos entre chaves. Podemos ler o comando while da seguinte forma: “enquanto a condição for verdade, faça esta sequência de comandos”. A figura 2.5 apresenta o esquema de funcionamento da estrutura while.

Saiba Mais

7 Iteração é um termo muito utilizado na computação e significa repetição.

Page 147: Programação 2 Linguagem C (UFRPE)

47

Programação 2

Figura 2.5: Funcionamento da estrutura de repetição while

Como podemos ver na figura 2.5, antes de entrar na sequência de comandos do while a condição é testada, se for verdade, executa os comandos vinculados ao while, quando termina, retorna para testar a condição novamente. Enquanto for verdade, fica repetindo a sequência de comandos. Quando for falsa, desvia para o primeiro comando depois do while.

Vamos analisar o programa completo 2.2, que resolve a mesma questão do programa completo 2.1, só que usando a estrutura de repetição while. Para garantir que a repetição será executada 5 vezes, será declarada uma variável responsável por contar cada vez que é terminada uma iteração do while. O valor desta variável será testado na condição do while, e a repetição será executada enquanto o contador for menor ou igual a 5.

Page 148: Programação 2 Linguagem C (UFRPE)

48

Programação 2

Programa Completo 2.2

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

main()

{

floatvalor;

intcod,contador;

contador=1;

while(contador<=5)

{ system(“cls”);

printf(“LojaCompreTudo\n\n”);

printf(“CodigodoCliente%d:“,contador);

scanf(“%d”,&cod);

printf(“\nValordascompras:“);

scanf(“%f”,&valor);

if(valor<500)

printf(“\n\nValordobonusR$%.2f\n”,

valor*0.1);

else

printf(“\n\nValordobonusR$%.2f\n”,

valor*0.15);

contador++;

printf(“\n\ntecle enter para

continuar...”);

getche();

}

}

Comentários sobre o programa completo 2.2:

• Linhas 3 e 4: temos as declarações das variáveis do programa. O valor das compras, o código do cliente e o contador que irá controlar a repetição.

• Linha 5: Nesta linha temos a inicialização do contador. Assim,

Page 149: Programação 2 Linguagem C (UFRPE)

49

Programação 2

é atribuído 1 ao contador. Isto indica que iremos começar a primeira iteração do while.

• Linha 6: temos o while, juntamente com a condição de permanência da repetição. Assim, esta repetição é feita enquanto o contador for menor ou igual a 5. Notem que, obrigatoriamente, a condição virá entre parênteses, certo?

• Linhas 7 a 20: sequência de comandos vinculada ao while, que será executada cinco vezes. Para cada cliente é pedido o seu código e o valor das suas compras. O bônus é calculado de acordo com o valor das compras e apresentado na tela.

• Linha 17: observem que nesta linha é somado mais 1 ao valor do contador. Dessa forma, cada vez que passamos pela repetição, o contador vai aumentado seu valor, até fazer com que a condição se torne falsa e a repetição pare. Quando usamos o for, a inicialização, a condição e o incremento da variável do controle fica tudo ao lado do for. No while, temos estas três partes, só que separadas: na linha 5 tivemos a inicialização do contador, na linha 6 temos a condição e na linha 17 o incremento do contador. Se esquecermos de incrementar o contador, a condição não se tornará falsa, nunca, e entraremos em um loop infinito.

• Linha 21: fecha chaves do programa principal.

A execução deste programa resulta em uma tela idêntica a do programa anterior, apresentada na figura 2.3.

Vamos agora entender o funcionamento do terceiro e último tipo de repetição do C, que é o do/while.

2.3. Do/while (repita... até - teste no final)

A estrutura de repetição do/while equivale ao repita...até do Portugol. A principal diferença entre o do/while e o while é o ponto onde a condição é testada. Como vimos na seção anterior, a condição do while fica no início do bloco e assim, a verificação é feita antes de executar o bloco de comandos. Se a condição for falsa já no primeiro teste, os comando vinculados ao while não são executados nenhuma vez. No caso do do/while, a condição só vem após a sequência de comandos. Com isso, o teste só é feito após a execução dos comandos

Page 150: Programação 2 Linguagem C (UFRPE)

50

Programação 2

do do/while. A sintaxe do do/while é a seguinte:

Sintaxe

do

comando;

while(condição);

do

{ comando1;

comando2;

comandon;

} while(condição);

O comando do/while começa com o do, e logo em seguida colocamos a sequência de comandos que será repetida. Após a sequência de comandos, coloca-se o while com a condição que será testada para verificar se continua a repetição ou não. Quando tivermos mais de um comando, as chaves que delimitam os comandos do do/while são obrigatórias. Prestem atenção o local correto das mesmas. O abre chaves que indica o início da sequência deve vir depois do do. O fecha chaves que indica o final da sequência, deve vir antes do while. Outro detalhe importante é que, depois da condição (que deve vir entre parênteses), devemos colocar um ponto e vírgula8.

O esquema da execução do do/while é apresentado na figura 2.6.

Figura: 2.6: Funcionamento da estrutura de repetição do/while

O do serve, na verdade, para indicar que a sequência de comandos vai começar. A sequência de comandos é executada e, ao encontrar

Atenção

8 Não colocamos ponto e virgula após a condição do if, nem após a condição do while.

Page 151: Programação 2 Linguagem C (UFRPE)

51

Programação 2

o while, a condição é testada. Se a condição for verdade, retorna ao primeiro comando da sequência. Se a condição for falsa, executa o primeiro comando depois do do/while. O comando do/while pode ser lido da seguinte forma: “faça a sequência de comandos enquanto a condição for verdade”.

Agora, vamos fazer o programa completo 2.1, usando o do/while. Do mesmo modo que foi necessário no while, teremos que ter uma variável que serve de contador, para ficar verificando se já executou a repetição cinco vezes.

Page 152: Programação 2 Linguagem C (UFRPE)

52

Programação 2

Programa Completo 2.3: uso do do/while

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

main()

{

floatvalor;

intcod,contador;

contador=1;

do

{ system(“cls”);

printf(“LojaCompreTudo\n\n”);

printf(“CodigodoCliente%d:“,contador);

scanf(“%d”,&cod);

printf(“\nValordascompras:“);

scanf(“%f”,&valor);

if(valor<500)

printf(“\n\nValordobonusR$%.2f\n”,

valor*0.1);

else

printf(“\n\nValordobonusR$%.2f\n”,

valor*0.15);

contador++;

printf(“\n\ntecle enter para

continuar...”);

getche();

} while(contador<=5);

}

Comentários sobre o programa completo 2.3:

• Linhas 3 e 4: temos as declarações das variáveis do programa. O valor das compras, o código do cliente e o contador que irá controlar a repetição.

• Linha 5: Nesta linha temos a inicialização do contador.

Page 153: Programação 2 Linguagem C (UFRPE)

53

Programação 2

Linha 6: temos o do, indicando que será iniciada uma estrutura de repetição do/while.

• Linhas 7 a 19: sequência de comandos vinculada ao do/while, que será executada cinco vezes. Para cada cliente é pedido o seu código e o valor das suas compras. O bônus é calculado de acordo com o valor das compras e apresentado na tela. Notem que na linha 17 temos o incremento do contador.

• Linha 20: temos o fecha chaves e o while, juntamente com a condição que é avaliada para que prossiga uma nova repetição da sequência de comandos ou pare de executar o do/while.

• Linha 21: temos o fecha chaves do programa principal.

Vimos aqui um mesmo problema sendo resolvido com os três tipos de repetição do C. No problema em questão, foi mencionado quanto elementos (clientes) seriam cadastrados. Assim, estes programas SEMPRE repetem a sequência 5 vezes. Em várias situações, não sabemos previamente quantos elementos serão cadastrados. Dessa forma, não saberíamos o valor a ser colocado na condição da estrutura de repetição para indicar a sua parada. Mas tem uma solução: quando não soubermos quantos elementos serão cadastrados, usaremos o do/while, da forma como será apresentada no programa completo abaixo. Este programa tem o mesmo enunciado do programa 2.1, no entanto, ele poderá cadastrar uma quantidade indeterminada de clientes.

Page 154: Programação 2 Linguagem C (UFRPE)

54

Programação 2

Programa Completo 2.4: uso do do/while

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

main()

{

floatvalor;

intcod,continuar;

do

{ system(“cls”);

printf(“LojaCompreTudo\n\n”);

printf(“CodigodoCliente:“);

scanf(“%d”,&cod);

printf(“\nValordascompras:“);

scanf(“%f”,&valor);

if(valor<500)

printf(“\n\nValordobonusR$%.2f\n”,

valor*0.1);

else

printf(“\n\nValordobonusR$%.2f\n”,

valor*0.15);

printf(“\n\n\nDeseja cadastrar outro

(1-sim/2-nao)?“);

scanf(“%d”,&continuar);

} while(continuar==1);

}

Comentários sobre o programa completo 2.4:

• Notem que não teremos a variável contador. Teremos agora uma variável inteira que foi chamada de continuar. A condição de parada deste do/while avalia o valor armazenado na variável continuar.

• Linhas 3 e 4: temos as declarações das variáveis do programa. O valor das compras, o código do cliente e a variável inteira continuar que irá controlar a repetição.

Page 155: Programação 2 Linguagem C (UFRPE)

55

Programação 2

• Linha 5: do que inicia a sequência da repetição.

• Linhas 6 a 17: sequência de comandos vinculada ao do/while. Nesta sequência temos a solicitação dos dados do cliente, e apresentação do bônus que o cliente tem direito.

• Linha 16: Após apresentar o valor do bônus, é feita a seguinte pergunta ao usuário: “deseja cadastrar outro (1-sim/2-não)? “. Na linha 16 temos o printf que escreve esta pergunta na tela. O usuário deverá digitar 1 se quiser cadastrar outro, que significa: “sim, eu quero cadastrar”. Ou digitar 2 porque não tem mais clientes para cadastrar.

• Linha 17: scanf para ler a resposta do cliente, que deve ser 1 para continuar ou 2 para parar. O valor que o usuário digitar, será armazenado na variável continuar.

• Linha 18: temos o fecha chaves e o while, juntamente com a condição que é avaliada para que prossiga uma nova repetição da sequência de comandos ou pare de executar o do/while. Notem que a condição é: (continuar == 1). Ou seja, enquanto o usuário estiver respondendo 1, informando que quer continuar cadastrando, novos cadastros serão feitos. A parada ocorre quando o usuário responde 2. Dessa forma, não precisamos determinar a quantidade de vezes que a repetição será executada. A execução dependerá apenas da resposta do usuário. Assim, uma vez nós poderemos executar a repetição 2 vezes, na outra 10, na outra 3, etc. Diferente da outra forma de resolver, que sempre executava uma quantidade de vezes pré-determinada. A resolução da questão desta forma, trás mais flexibilidade ao programa, uma vez que o usuário repete o cadastro quantas vezes ele desejar. Uma outra observação é que não houve a necessidade de colocarmos o getche(). A questão é que, como nós tivemos que fazer a leitura da variável continuar, o scanf que lê esta variável, faz com que a tela fique parada esperando o usuário fornecer a resposta. Por isso, não houve necessidade de colocar o getche().

• Linha 19: temos o fecha chaves do programa principal.

A figura 2.7 apresenta uma tela de execução do programa completo 2.4.

Page 156: Programação 2 Linguagem C (UFRPE)

56

Programação 2

Figura 2.7: Tela de execução do programa completo 2.4

De acordo com a figura 2.7, após os usuário fornecer os dados do cliente e receber o valor do bônus que o cliente tem direito, é feita a pergunta se ele deseja ou não cadastrar outro. Assim que for respondido 2, ou seja, não quer mais cadastrar, a janela do programa irá fechar. Enquanto estiver respondendo 1, novos cadastros são feitos.

2.4. Uso do break na Estrutura de Repetição

Vimos anteriormente o comando break finalizando a sequência de comandos de um case, da estrutura de seleção switch. Mas, este comando também pode ser usado para forçar o encerramento de uma estrutura de repetição. Se um break for executado dentro de uma estrutura de repetição, o fluxo do programa será desviado para o primeiro comando depois da repetição. Mesmo que a repetição ainda não tenha sido executada a quantidade de vezes que foi determinada. Normalmente, o comando break é colocado na sequência de comandos de uma estrutura de seleção e só é executado, caso alguma situação aconteça.

Vamos analisar o programa completo 2.5. Neste programa, o cliente tem um limite de R$ 200 no cartão de crédito da loja. Conforme as suas compras vão sendo passadas no caixa, seu saldo vai sendo avaliado. Se a compra de um novo item ultrapassar o limite permitido, o programa deve parar a venda. Mas, se ele tiver limite, a compra pode ser feita e finalizada normalmente.

Atenção

Todas as estruturas de repetição são escritas em minúsculo. Atentem a identação dos comandos do programa. A sequência de comandos de uma estrutura de controle, seja de repetição ou de seleção, poderá ser composta por qualquer comando válido da linguagem. Assim, poderemos ter uma estrutura de repetição dentro da outra.Se houver necessidade de colocar um for na sequência de comandos de outro for, devemos utilizar uma variável de controle diferente para cada for

Page 157: Programação 2 Linguagem C (UFRPE)

57

Programação 2

Programa Completo 2.5: uso do break na repetição

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

main()

{ floatpreco,total;

intcontinuar;

total=0;

do

{ system(“cls”);

printf(“Loja Compre Tudo - Adicionar

produto\n\n”);

printf(“Precodoproduto:“);

scanf(“%f”,&preco);

if((total+preco)<=200)

total=total+preco;

else

{ printf(“\n\nA adicao deste produto

vaiextrapolaroseulimite!”);

printf(“\n\nTecle enter para

finalizar...”);

getche();

break;

}

printf(“\n\nDeseja adicionar outro

(1-sim/2-nao)?“);

scanf(“%d”,&continuar);

}while(continuar==1);

printf(“\n\nTotalapagar:%.2f”,total);

22

23

getche();

}

Comentários sobre o programa completo 2.5:

• Linhas 2 e 3: declaração das variáveis do programa: preço

Page 158: Programação 2 Linguagem C (UFRPE)

58

Programação 2

do produto, total das compras e continuar (para verificar se a repetição deve ser executada ou não).

• Linha 4: inicialização da variável total, que armazena o valor total das compras9.

• Linha 5: do que inicia a sequência da repetição.

• Linhas 6 a 20: sequência de comandos vinculada ao do/while. Nesta sequência temos a solicitação do preço do produto que o cliente está comprando. A cada novo produto comprado é preciso verificar se o total da compra extrapola os 200 reais do limite do cartão. Esta verificação é feita no if da linha 10. Se o limite extrapolar, será executada a sequência de comandos do else da linha 12. Assim, é impressa uma mensagem que não pode mais adicionar produtos e, logo em seguida, executa o break da linha 16, forçando a saída do do/while. Como não pode mais comprar produtos, temos que sair da repetição. Por isso foi usado o break. Mas, se a compra não extrapolar o limite, o cliente vai fazendo as compras dos produtos que ele desejar. Dessa forma, a execução do break ocorre mediante a ocorrência de uma situação, que neste caso foi o estouro do limite.

• Linha 21: Após sair da repetição, devemos imprimir quanto foi o valor das compras do cliente. Neste printf será escrito o total.

• Linhas 22 e 23: temos getche() e o fecha chaves do programa principal.

A figura 2.8 apresenta duas telas de execução do programa completo 2.5.

Adição de produto na Nota Fiscal

Atenção

9Sempre que uma variável for servir de acumulador, seu conteúdo deve ser inicializado. Normalmente com zero.

Page 159: Programação 2 Linguagem C (UFRPE)

59

Programação 2

Adição de produto que extrapola o limite

Figura 2.7: Telas de execução do programa completo 2.5

Agora que já vimos alguns exemplos completos de programas que utilizam as estruturas de repetição, que tal resolvermos umas questões?

Atividades e Orientações de Estudo

Estamos aqui, mais uma vez, para colocar nossos conhecimentos em prática. Nesta lista, temos 12 questões que utilizam comandos de repetição. Nos enunciados, quando for indicado que a quantidade de elementos é desconhecida, resolva a questão utilizando um do/while (que pergunta se o usuário quer continuar ou parar). Coloquem comentários nos seus programas, deixando-os bem documentados. Além disso, prestem muita atenção para manter o código identado. É importante ser um programador organizado. Vamos começar?

1. Uma empresa deseja aumentar seus preços em 20%. Faça um programa que leia o código e o preço de custo de cada produto e calcule o preço novo. Calcule também, a média dos preços com e sem aumento. Mostre o código e o preço novo de cada produto e, no final, as médias. A quantidade de dados que serão cadastrados é desconhecida.

2. Pablo tem 1,50 m e cresce 2 centímetros por ano, enquanto Edson tem 1,10 m e cresce 3 centímetros por ano. Construa um programa que calcule e imprima quantos anos serão necessários para que Edson seja maior que Pablo.

3. Escrever um programa que leia 5 pares de valores, o primeiro valor é a matrícula do aluno, e o segundo a sua altura em

Page 160: Programação 2 Linguagem C (UFRPE)

60

Programação 2

centímetros. Encontre o aluno mais alto e o mais baixo. Mostre a matrícula do aluno mais alto e do mais baixo, junto com suas alturas.

4. Escrever um programa que leia um conjunto de 10 informações contendo, cada uma delas, a altura e o sexo(1- mas/2- fem), calcule e mostre o seguinte:

• a maior e a menor altura da turma

• a média da altura das mulheres

• a média da altura da turma.

5. Foi feita uma pesquisa entre os 50 habitantes de uma região. Foram coletados os dados de idade, sexo (1-mas/2-fem) e salário. Faça um programa que informe:

• a média de salário do grupo;

• maior e menor idade do grupo;

• quantidade de mulheres com salário até R$ 200.

6. Com o lançamento de notebooks no mercado nacional, um fabricante deseja obter determinadas informações dos seus possíveis consumidores. Para cada empresa ou órgão pesquisado foi digitado os seguintes dados:

• Preferência desejada (fabricante): 1-Toshiba/2-HP/3-Sony

• Possuem computadores de grande porte: 1-Sim/2-Não

• Necessitam de notebooks: 1. Sim/2. Não

Deseja-se saber:

• A quantidade de empresas pesquisadas;

• Quantas empresas possuem computadores de grande porte;

• Percentual de empresa que necessitam de notebooks

• Percentual de empresas que tem preferência pela Toshiba.

A quantidade de dados que serão cadastrados é desconhecida.

7. Foi feita uma pesquisa estatística nas 50 principais cidades de quatro Estados para coletar dados sobre acidentes de trânsito. Foram obtidos os seguintes dados:

Page 161: Programação 2 Linguagem C (UFRPE)

61

Programação 2

• Código da cidade

• Estado (1-PE, 2-PB, 3-RN, 4-CE)

• Número de veículos de passeio (em 2008)

• Número de acidentes de trânsito com vítimas (em 2008)

Deseja-se saber:

• qual o maior e o menor índice de acidentes de trânsito e a que cidades pertencem;

• qual a média de veículos nas cidades;

• qual a média de acidentes com vítimas entre as cidades do Estado de Pernambuco.

8. A Empresa Legal decidiu fazer um levantamento dos candidatos que se inscreveram para preenchimento de vaga no seu quadro de funcionários, utilizando processamento eletrônico e você foi contratado, então faça um programa que:

Leia um conjunto de informações para cada candidato, contendo: número de inscrição do candidato, idade, sexo(1-fem/2-mas), experiência anterior(1-sim/2-nao)

Calcule:

• Quantidade de candidatos

• Quantidade de candidatas

• Média de idade dos homens com experiência

• Percentagem dos homens com mais de 45 anos, entre os homens

• Quantidade de mulheres com idade inferior a 35 anos e com experiência

• Menor idade entre as mulheres que já tem experiência no serviço

A quantidade de dados que serão cadastrados é desconhecida.

9. Faça um programa para realizar a totalização dos votos da eleição para a prefeitura concorrida entre 3 candidatos. Para cada seção são informados o número de votos do candidato

Page 162: Programação 2 Linguagem C (UFRPE)

62

Programação 2

A, o número de votos do candidato B, o número de votos do candidato C, o número de votos brancos e o número de votos nulos. A quantidade de seções que serão cadastradas é desconhecida. Determine e imprima:

• O número de votantes;

• O total de votos de cada candidato;

• O total de votos brancos e total de votos nulos;

• O total de votos válidos;

• O candidato com maior número de votos;

• Se a eleição foi válida e para isso o total de votos brancos mais votos nulos deve ser menor que o total de votos válidos;

• Se haverá segundo turno, para não haver segundo turno basta que o total de votos do candidato vencedor seja maior que 50% dos votos válidos

• Percentual de votos nulos.

10. Ler 20 notas e imprimir as três maiores.

Conheça Mais

Vocês poderão encontrar mais detalhes sobre estruturas de repetição no livro:

ASCENIO, Ana Fernanda Gomes e CAMPOS, Edilene Aparecida Veneruchi. Fundamentos de Programação de Computadores. São Paulo: Prentice Hall, 2002.

O interessante é que, os autores primeiro dão as explicações em Portugol, e depois fazem a tradução para a sintaxe da linguagem de programação C e Pascal.

Page 163: Programação 2 Linguagem C (UFRPE)

63

Programação 2

Vamos Revisar?

Vamos revisar as estruturas de repetição? Observem o resumo a seguir:

• As estruturas de repetição possibilitam que uma sequência de comandos possa ser executada várias vezes.

• As estruturas de repetição da linguagem de programação C são: for, while e do/while.

• A estrutura de repetição for é mais utilizada quando sabemos quantas vezes uma repetição será executada.

• A estrutura de repetição while avalia o resultado de uma condição para verificar se deve ou não executar uma sequência de comandos. Enquanto a condição for verdade, a repetição é executada. A condição do while fica no início da sequência de comandos.

• A estrutura de repetição do/while também avalia uma condição para permanecer repetindo a execução de uma sequência de comandos. No entanto, a condição só é avaliada após a execução da sequência de comandos.

• O comando break também pode ser utilizado para forçar a parada de uma repetição.

• Quando não tomamos cuidado de tornar a condição de uma repetição falsa, ocorre o loop infinito.

Page 164: Programação 2 Linguagem C (UFRPE)

64

Programação 2

Capítulo 3 – Modularização

Vamos conversar sobre o assunto?

Neste capítulo, vamos aprender a programar de forma modularizada. Até agora, toda a sequência de comandos dos nossos programas foi escrita dentro do programa principal (main), em um bloco único. Vocês vão ver que podemos dividir os nossos programas em módulos. A modularização é uma das alternativas mais utilizadas para desenvolver grandes programas, pois deixa o código mais legível e aumenta a produtividade dos programadores. No entanto, a modularização apresenta muitas outras vantagens. Vamos descobrir isso agora?

3.1. O que são módulos e por que utilizá-los?

A melhor maneira de desenvolver um programa grande é construí-lo a partir de pequenas partes, que são chamadas de módulos. Esta técnica é chamada dividir para conquistar, uma estratégia de guerra criada pelos romanos e muito utilizada por Napoleão Bonaparte10,quando tentou conquistar o mundo. Como o território a ser conquistado era muito extenso, ele o dividiu em pequenos territórios e foi conquistando cada parte por vez.

Uma vantagem desta técnica é que focamos a nossa atenção em um problema pequeno de cada vez. No final, teremos a solução do problema como um todo. Para compreender melhor este conceito, vamos fazer uma analogia: suponham que nós precisamos construir uma casa. Mas esta não é uma atividade simples, devido a sua complexidade. No entanto, podemos dividir esse problema em partes menores: alvenaria, sistema elétrico, sistema hidráulico, acabamento, pintura, etc. e assim, fica mais simples de entendermos cada parte separadamente (Figura 3.1). Caso ainda existam partes complexas, podemos continuar dividindo em partes ainda menores. Por exemplo, o sistema hidráulico pode ser dividido em caixa de água, bombas, canos, registros, etc. Este processo de decomposição contínua também é conhecido como refinamentos sucessivos, porque se parte de um problema complexo e abrangente, que é sucessivamente dividido até resultar em problemas mais simples e específicos.

Saiba Mais

10 Napoleão Bonaparte foi imperador da França e esteve no poder durante 15 anos. Nesse tempo conquistou grande parte do continente europeu. Os biógrafos afirmam que seu sucesso deu-se devido ao seu talento como estrategista, além do seu espírito de liderança.

Page 165: Programação 2 Linguagem C (UFRPE)

65

Programação 2

Figura 3.1: Divisões da construção de uma casa

Os módulos (também chamados de funções, rotinas ou subprogramas) são a essência da programação estruturada. Os módulos são segmentos de programa que executam uma tarefa específica. Os módulos servem para dividir um grande programa em diversas partes menores. De acordo com as boas práticas de programação: “sempre que possível, evite códigos extensos, separando os mesmos em módulos, visando a um rápido entendimento e uma manutenção facilitada”.

A modularização permite que cada módulo do programa seja escrito, testado e revisado individualmente sem alterar o funcionamento do programa como um todo. Os programadores podem testar suas funções separadamente, permitindo que muitos erros do sistema completo sejam retirados antes que ele esteja totalmente pronto. A modularização também permite que um programa seja escrito por vários programadores ao mesmo tempo, cada um desenvolvendo um módulo em separado. É como a construção de uma casa, que podemos contratar vários funcionários. Esta divisão do trabalho acelera o desenvolvimento dos programas e reduz custos. Uma outra utilização da modularização é quando um trecho de código é utilizado várias vezes em um programa. Devemos colocar este trecho em um módulo e, sempre que preciso, fazemos a “chamada” do módulo. Com isso, reduzimos a quantidade de linhas de código do programa.

A maior parte das linguagens de programação fornece um conjunto de funções (módulos) que são utilizadas pelos programadores, evitando que o mesmo tenha que implementá-las. A utilização de

Sistema Hidráulico

Sistema ElétricoAlvenaria

Pintura

Page 166: Programação 2 Linguagem C (UFRPE)

66

Programação 2

funções que já existem, diminui o tempo de desenvolvimento do programa. Além disso, o fato de utilizar uma função que já foi testada em diversos programas, reduz o risco de erros. É como se costuma dizer: “não vamos reinventar a roda”. Se a função está pronta, disponível e correta, o programador não deve perder tempo em implementar a mesma coisa. É só fazer uso da mesma. Um exemplo de uso de módulos que já existem, é quando utilizamos alguma função da biblioteca math, como sqrt (raiz quadrada) e pow (potência).

As próximas seções descrevem como devemos fazer para desenvolver programas modularizados.

3.2. Estrutura de um módulo

Ao receber um problema, o programador deverá verificar se este problema pode ser resolvido com uma solução particionada ou modularizada. Vamos usar o seguinte exemplo: fazer um programa que calcule a média do aluno e verifique se o mesmo foi aprovado ou reprovado. A princípio, podemos pensar que o cálculo da média do aluno e a descoberta da sua situação (aprovado ou reprovado) serão implementados em dois módulos. Dessa forma, nosso programa seria formado por 2 módulos, além do programa principal. Mas poderemos notar, durante a implementação, que algumas partes de código se repetem em diversos pontos do programa e por isso, elas também são candidatas a se tornarem módulos. A sintaxe para construir módulos, em C, é a seguinte:

Sintaxe

tipo_de_retorno nome_da_função([declaração de

parâmetros])

{ [declaraçãodevariáveislocais]

blocodeinstruçõesdafunção

[return]

}

Toda a declaração de módulos/funções darieve seguir ao formato acima. As partes entre colchetes são opcionais. Vamos ver o que significa cada componente da estrutura de um módulo:

• Tipo_de_retorno: especifica qual o tipo de dado é retornado

Page 167: Programação 2 Linguagem C (UFRPE)

67

Programação 2

pela função, podendo ser qualquer tipo de dado da linguagem (int, float, char, etc.). Se a função não retorna nenhum valor, devemos definir o retorno como void, que significa ausente de retorno. Vale ressaltar que existe apenas um valor de retorno para funções em C. Um exemplo de módulo que retorna um valor é o sqrt, ou seja, ao ser executado, ele nos retorna a raiz quadrada de um número.

• Nome da função: indica o nome pelo qual o bloco de código correspondente à função será chamado. É através do nome da função que poderemos chamá-la quando desejarmos a sua execução. As regras para nomear um função são as mesmas que utilizamos para nomear as nossas variáveis.

• Declaração de parâmetros: é na declaração de parâmetros que informamos ao compilador quais serão as entradas da função. Para cada um dos parâmetros deve ser declarado o seu tipo e nome. Se a função não receber nenhum parâmetro, deve-se deixar os parênteses sem nada entre eles. Os parâmetros servem para passarmos alguma informação para a função. A função sqrt recebe um número real como parâmetro. Para calcular uma raiz quadrada, a função precisa que o programador informe de qual valor será calculada a raiz quadrada. O valor que é fornecido a função, é o parâmetro. Já a função pow, precisa receber dois parâmetros para que possa elevar um número a um expoente qualquer.

• Declaração das variáveis locais: as variáveis que são específicas de um módulo são chamadas de variáveis locais. Todas as variáveis locais devem ser declaradas dentro da função, antes de qualquer comando. Uma variável local somente pode ter seu valor acessado dentro da função em que foi declarada. Um módulo pode não ter nenhuma variável local.

• Corpo da função: sequência de comandos que compõem a função. É similar ao corpo do programa principal. O corpo de uma função é delimitado por chaves.

• return: o comando return finaliza a execução da função que está sendo executada. Se a função retornar algum valor (o tipo de retorno não é void) este comando é obrigatório. Se a função tiver retorno do tipo void, este comando não precisa ser colocado.

Page 168: Programação 2 Linguagem C (UFRPE)

68

Programação 2

A figura 3.2 apresenta uma função que calcula a média das duas notas de um aluno.

floatcalc_media(floatn1,floatn2)

{ floatm;

m = (n1 + n2)/2;

returnm;

}

Figura 3.2: Função para calcular a média do aluno

Vamos identificar cada parte da estrutura desta função. Esta função se chama calc_media e precisa receber dois parâmetros para calcular a média do aluno. Os parâmetros são as duas notas do aluno: n1 e n2. Como cada nota é um número real, na frente de cada parâmetro é colocado o seu tipo (float) e separa por vírgula. Mesmo que os parâmetros sejam do mesmo tipo, precisamos colocar o tipo de cada parâmetro, na frente do seu nome.

O objetivo desta função é calcular uma média. Dessa forma, ao terminar a sua execução, a função irá retornar a média do aluno. Por isso, o tipo de retorno da função é float. Como esta função tem um retorno, no final da sequência de comandos, devemos colocar o comando return, e ao lado dele, o nome da variável que tem armazenado o valor que será retornado. Neste caso, a variável que tem este valor é m. Esta é uma variável local, ou seja, uma variável que foi declarada dentro deste módulo. Por conta disto, só pode ser usada no módulo calc_media.

Vamos discutir um pouco mais sobre alguns dos conceitos apresentados, para depois iniciarmos a implementação de mais funções.

Tipo de retorno Lista de parâmetrosNome da função

Retorno da funçãoVariável Local

Page 169: Programação 2 Linguagem C (UFRPE)

69

Programação 2

3.3. Em que ponto do programa os módulos devem ser implementados?

A execução de um programa C é sempre iniciada pelo main(), que é o módulo principal do programa, por isso ele tem esse nome. Um programa pode ter várias funções, bem como poderá utilizar funções definidas em outros programas. Além disso, uma função poderá fazer uso de outra função. Dessa forma, as funções definidas no programa devem ser escritas antes do programa principal. E ainda, se a funcao1, faz uso da funcao2, a função2 deve ser escrita antes da funcao1. Isto é feito por uma razão. Ao compilar o programa, o compilador precisa conhecer, com antecedência, quais são os tipos de retorno e quais são os parâmetros das funções para que o código seja gerado corretamente. É por isto que as funções são colocadas antes do programa principal. Quando o compilador chegar no programa principal (main), ele já terá compilado as funções e já saberá seus formatos.

Quando são utilizadas funções que estão em outros programas, o programador deverá informar, através da diretiva #include, a biblioteca ou o arquivo onde a função foi implementada. O caso mais comum é o uso de funções que estão nas bibliotecas padrão do C, como por exemplo, o comando para limpar o buffer de entrada: fflush(stdin), que se encontra na biblioteca stdio (standard in/out).

A figura 3.3 apresenta a nova estrutura dos nossos programas C.

InclusãodasBibliotecas

DeclaraçãodeConstantes

DeclaraçãodeVariáveisGlobais

DeclaraçãodosMódulos

ProgramaPrincipal

Figura 3.3: Nova estrutura dos programas C

O que temos nesta nova estrutura é a seção de declaração de variáveis globais, que são as variáveis que são utilizadas por todos os módulos do programa (mais detalhes na próxima seção). Além da seção de declaração dos módulos, que vem antes do programa principal. É neste ponto do programa que devemos declarar nossos módulos.

Page 170: Programação 2 Linguagem C (UFRPE)

70

Programação 2

3.4. Escopo das Variáveis

Quando programamos sem utilizar modularização, as variáveis são declaradas no início do programa principal. Com esta forma de declaração, as variáveis só podem ser acessadas pelo programa principal. Agora que começaremos a programar com módulos, para que uma variável possa ser acessada por todos os módulos do programa, ela deve ser declarada fora de qualquer módulo. Estas variáveis são chamadas de globais. As variáveis globais devem ser declaradas fora de qualquer módulo e programa principal, logo após a inclusão das bibliotecas.

Quando programamos de forma modularizada, em alguns casos, uma determinada variável é utilizada apenas por um módulo específico, o que não justifica uma definição global, pois somente será utilizada dentro dos limites do módulo. Quando isto acontece, a variável deve ser declarada dentro do módulo e é denominada variável local.

O escopo ou abrangência de uma variável indica por quais módulos do programa esta variável é visível e pode ser utilizada. Assim, podemos dizer, então, que as variáveis globais são visíveis por todos os módulos, e as variáveis locais, são visíveis apenas ao módulo onde esta foi declarada. Podemos ter quantos módulos quisermos com uma variável local chamada x, por exemplo, e elas não apresentarão conflito entre si. Vamos analisar a figura 3.4 a seguir:

int A, B, C;

Modulo 1

int x, y, z;

Modulo 2

int x, w;

Figura 3.4: Escopo de variáveis locais e globais

As variáveis A, B e C são globais, portanto, podem ser utilizadas pelos módulos 1 e 2. No módulo 1 temos as variáveis x, y e z, que só podem ser utilizadas por este módulo. Dessa forma, o módulo 2

Page 171: Programação 2 Linguagem C (UFRPE)

71

Programação 2

não tem acesso a tais variáveis. Notem que, tanto o módulo 1 quanto o módulo 2, tem uma variável chamada x. Variáveis com o mesmo nome em módulos diferentes não causam conflito no programa. Também pode ocorrer de uma função ter uma variável local com o mesmo nome de uma variável global, quando isto acontece, a função dará preferência à variável local11.

Um ponto interessante que devemos atentar ao declarar as variáveis do programa é que as variáveis locais só existem (e consequentemente, ocupam memória) enquanto o módulo estiver ativo e são destruídas quando a execução do módulo termina. Com isso, há uma melhor utilização da memória do programa.

3.5. Parâmetros

Ao desenvolver um módulo, devemos ficar atentos para que o mesmo seja definido de forma bem genérica, com o objetivo de que este possa ser reutilizado mais vezes. Por exemplo, se criamos um módulo para calcular 2 elevado a 3, a sua aplicação será muito restrita. Porém se generalizarmos o módulo de forma a torná-lo capaz de calcular o valor de qualquer base elevada a qualquer expoente, sua aplicação será mais abrangente. Portanto, dizemos que um módulo é generalizado quando ele for parametrizado.

A utilização de parâmetros nos módulos funciona de forma muito similar às funções matemáticas, como por exemplo:

f (x , y) = x y

• em que x e y são parâmetros.

Essa função foi definida em termos de parâmetros x e y. Para calcularmos a função para algum valor particular de x e y devemos substituí-los pelos valores dos argumentos desejados.

f (3 , 2) = 3 2 = 9

Uma correspondência é estabelecida entre os parâmetros da definição e os argumentos utilizados. No exemplo, o parâmetro x foi substituído pelo 3 e o parâmetro y foi substituído pelo 2. É importante perceber que a ordem dos parâmetros é crucial, pois f(3,2) não é o mesmo que f(2,3).

Uma função pode receber qualquer número de parâmetros. Mas

Atenção

11 Lembrem que não podemos ter duas variáveis globais com o mesmo nome.

Page 172: Programação 2 Linguagem C (UFRPE)

72

Programação 2

também poderemos escrever uma função que não receba nenhum parâmetro. No caso de uma função sem parâmetros pode-se escrevê-la da seguinte forma: deixando a lista de parâmetros vazia, mantendo entretanto os parênteses. O exemplo 3.1 apresenta uma função sem parâmetros.

Exemplo 3.1: função sem parâmetro

1

2

3

4

5

voidcabecalho()

{system(“cls”);

printf(”FaculdadeLegal\n”);

printf(“__________________________________\n”);

}

A função cabecalho, apresentada no exemplo 3.1 tem o objetivo de limpar a tela e escrever o nome da empresa no início da tela, além de passar uma linha logo abaixo. Como esta função não precisou receber nenhuma informação para a sua execução, ela não tem parâmetros, mas temos que colocar os parênteses em branco logo após o nome da função. Esta função também não tem retorno, por isso o tipo de retorno é void.

3.6. Contexto do Módulo (Ação ou Resultado)

Um módulo possui o contexto de ação quando ele se preocupa com um processo em particular, como por exemplo, o módulo responsável por fazer o cadastramento dos dados dos alunos ou o módulo responsável por apresentar todos os dados dos alunos cadastrados. Neste tipo de módulo, teremos a execução de uma ação que é o cadastramento de alunos ou a listagem dos dados dos alunos.

Um módulo possui o contexto de resultado quando a sua característica é a de calcular um resultado. Para exemplificar podemos pensar no módulo que é responsável por calcular a média das duas notas de um aluno. Ao ser executado, este módulo retornará como resultado, a média do aluno.

A essência de um módulo com contexto de resultado é que seu conjunto de ações visa um objetivo único, retornar ao ponto de sua chamada, um valor. Para que um módulo retorne um valor, em C, será

Page 173: Programação 2 Linguagem C (UFRPE)

73

Programação 2

necessário que seja indicado qual é o valor a ser retornado, o que será efetuado com a utilização do comando return. Vamos analisar mais uma vez a função que calcula a média do aluno.

Exemplo 3.2

1

2

3

4

5

floatcalc_media(floatn1,floatn2)

{ floatm;

m = (n1 + n2)/2;

returnm;

}

A função calc_media recebe como parâmetro as duas notas do aluno e retorna como resultado um float, que é a sua média. As duas notas passadas como parâmetros nas variáveis n1 e n2 são somadas e depois divididas por 2. No final da função, temos o comando return, que retorna o valor da variável local m, que tem armazenado a média do aluno. Não é necessário usar o comando return nas funções que não retornam nenhum valor (contexto de ação).

3.7. Ativando Funções

A ativação de um módulo ocorre quando um determinado ponto do programa contém o identificador do módulo (nome do módulo). A ativação é conhecida como chamada de um módulo e serve para executá-lo. Uma chamada de função é feita escrevendo-se o nome da função seguido dos argumentos fornecidos, entre parênteses. Se não houver argumentos, ainda assim devem ser mantidos os parênteses, para que o compilador diferencie a chamada da função de uma variável. As funções só podem ser chamadas depois de terem sido declaradas.

Quando queremos chamar uma função que retorna valor, devemos chamá-la através de um comando de atribuição, para que o valor que ela retorna de resultado, seja armazenado nesta variável. Este tipo de função também pode ser chamada/ativada em um comando de saída. Dessa forma, ao invés de armazenamos o resultado, o apresentamos na tela.

Durante a chamada de um módulo, o fluxo de execução do

Page 174: Programação 2 Linguagem C (UFRPE)

74

Programação 2

programa é desviado para o módulo chamado, e logo após a sua conclusão, o fluxo de execução do programa retorna para o comando seguinte após a sua ativação. A figura 3.5 mostra a ativação de dois módulos no programa. Vale lembrar que após a ativação de um módulo, todas as suas variáveis locais são desalocadas da memória.

main()

{ comando1;

comando2;

comando3;

comando4;

modulo1();

comando5;

comando6;

modulo2();

comando7;

comando8;

}

voidmodulo1()

{ comando1;

comando2;

comando3;

}

voidmodulo2()

{ comando1;

comando2;

comando3;

comando4;

}

Figura 3.5: Chamada de Funções

Para ilustrar melhor o assunto explanado, o programa completo 3.1 apresenta um programa que calcula o quadrado de um número. Foram definidos dois módulos, além do programa principal (main). É no main que as funções deste exemplo serão chamadas.

Page 175: Programação 2 Linguagem C (UFRPE)

75

Programação 2

Programa Completo 3.1

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

voidescreva_cabecalho()

{ system(“cls”);

printf(“Encontrarquadradodeumnumero\n”);

printf(“_______________________________\n\n”);

}

intquadrado(intnumero)

{ intq;

q=numero*numero;

returnq;

}

main()

{ intn,r;

escreva_cabecalho();

printf(“\nInformeonumero:“);

scanf(“%d”,&n);

r=quadrado(n);

printf(“\n\nResultado\n\n”);

printf(“Oquadradode%d=%d\n\n”,n,r);

getche();

}

O programa começa a sua execução pelo programa principal (linha 13). Logo no início, encontra a chamada para a função escreva_cabecalho. A função escreva_cabecalho é usada para escrever o título do programa, esta função, não recebe parâmetros, nem retorna nenhum valor, ela apenas escreve um texto na tela. A chamada desta função foi feita na linha 15, logo após a declaração das variáveis do programa principal. Para chamar esta função, foi necessário apenas

Page 176: Programação 2 Linguagem C (UFRPE)

76

Programação 2

informar o seu nome e, como ela não tem parâmetros, os parênteses são colocados sem nada entre eles.

Na sequência do programa, será lido o número que se deseja calcular o quadrado e logo em seguida é feita a chamada da função quadrado (linha 18). A função quadrado recebe um parâmetro inteiro (que é o número que se deseja calcular o quadrado) e retorna como resultado um valor inteiro. Como mencionado anteriormente, funções que retornam valor, devem ser chamadas através de um comando de atribuição. Neste caso, a variável r, receberá o retorno da função quadrado. Além disso, como esta função precisa saber de qual número será calculado o quadrado, na chamada da função, entre os parênteses, devemos colocar o valor ou a variável que será utilizada no cálculo, neste caso, será passado como parâmetro o valor da variável n. O programa finaliza apresentado o resultado, que é o quadrado do número (linhas 19 e 20).

A figura 3.6 apresenta a tela de execução do programa completo 3.1

Figura 3.6: Tela de execução do programa completo 3.1

Nos demais volumes deste livro, estaremos desenvolvendo nossos programas de forma modularizada. Quando passarmos a desenvolver programas maiores, veremos com mais clareza as vantagens de usar a modularização.

Atividades e Orientações de Estudos

Vamos treinar o desenvolvimento de módulos? Para cada questão abaixo, crie um programa principal, para que se possa testar/chamar

Page 177: Programação 2 Linguagem C (UFRPE)

77

Programação 2

o módulo desenvolvido.

1. Desenvolva uma função que recebe as três notas do aluno como parâmetro e retorne a sua média.

2. Desenvolva uma função que recebe dois números inteiros como parâmetro, e retorna o resto da divisão do primeiro parâmetro pelo segundo.

3. Desenvolva uma função que receba três números inteiros como parâmetros e retorne o menor valor.

4. Desenvolva uma função que recebe o ano de nascimento do usuário e retorna a sua idade. Faça o cálculo usando o ano atual.

5. Desenvolva uma função que recebe como parâmetro o mês atual e retorna quantos meses faltam para o final do ano.

6. Desenvolva uma função que recebe como parâmetros o dia do mês, o mês e o ano e retorna quantos dias faltam para o final do mês. Lembrem que os meses que têm 28, 29, 30 ou 31 dias.

Será realizado um fórum de discussão que discutirá sobre modularização de programas em C. É importante que vocês participem ativamente deste fórum. É uma oportunidade para discutirmos e trocarmos idéias sobre este assunto tão abrangente. Apareçam por lá!

Conheça Mais

Vocês podem aumentar o entendimento deste assunto lendo o capítulo 7 do livro:

LAUREANO, Marcos. Programando em C Para Linux, Unix e Windows. Rio de Janeiro: Brasport, 2005.

Vamos Revisar?

Vamos fazer uma revisão do assunto que foi visto neste capítulo,

Page 178: Programação 2 Linguagem C (UFRPE)

78

Programação 2

fazendo a leitura do resumo a seguir:

• Modularização é um técnica de programação que tem como objetivo desenvolver o programa de maneira mais simples e legível.

• Um módulo deve ser bem específico, ou seja, deve ser projetado para resolver uma única ação.

• As variáveis declaradas dentro de um módulos são de uso exclusivo deste módulo e são chamadas de variáveis locais.

• As variáveis globais podem ser acessadas por qualquer módulo do programa.

• Um programa C começa a sua execução a partir do programa principal (main).

• Se o módulo retornar algum valor, devemos utilizar o comando return.

• Os módulos que recebem parâmetros tem mais chances de serem reutilizados.

• Para ativar a execução de um módulo, devemos fazer a sua chamada.

• Ao iniciar a execução de um módulo, o fluxo do programa é desviado para o módulo chamado. Ao terminar, o fluxo de execução do programa volta para o ponto onde o módulo foi chamado.

Page 179: Programação 2 Linguagem C (UFRPE)

79

Programação 2

Considerações Finais

Neste volume, demos continuidade ao nosso aprendizado na linguagem de programação C. Nos capítulos 1 e 2, conhecemos as estruturas de repetição, que tem a capacidade de mudar o fluxo de execução do programa, desviando de uma parte de comandos ou fazendo com que um grupo de comandos fosse executado várias vezes. No capítulo 3, foi abordada a modularização, que nos permite uma programação mais organizada, reaproveitamento de código e desenvolvimento do programa em etapas. Esperamos que vocês estejam a cada dia, gostando mais da linguagem de programação C. Temos mais dois volumes, que nos darão a capacidade de desenvolver programas ainda mais complexos. Continuem firmes nos estudos! Até o próximo módulo.

Referências

ARAÚJO, Jairo. Dominando a Linguagem C. São Paulo: Ciência Moderna, 2004.

ASCENIO, Ana Fernanda Gomes e CAMPOS, Edilene Aparecida Veneruchi. Fundamentos de Programação de Computadores. São Paulo: Prentice Hall, 2002.

DEITEL, H, M e DEITEL, P. J. Como Programar em C. Rio de Janeiro: LTC, 1999.

LAUREANO, Marcos. Programando em C Para Linux, Unix e Windows. Rio de Janeiro: Brasport, 2005.

MIZRAHI, Victorine Viviane. Treinamento em Linguagem C – Curso Completo. São Paulo: Makron, 1999.

MONTGOMERY, Eduard. Programando em C: Simples e Prático. São Paulo: Alta Books, 2006.

OLIVEIRA, Ulisses. Programando em C – Volume I – Fundamentos. São Paulo: Ciência Moderna, 2004.

SCHILDT, Herbert. C Completo e Total. São Paulo: Makron, 1996.

Page 180: Programação 2 Linguagem C (UFRPE)

80

Programação 2

Conhecendo a Autora

Sônia Virginia Alves França

Sou graduada em Ciência da computação pela Universidade Federal de Sergipe. Fiz mestrado e doutorado na Universidade Federal de Pernambuco, desenvolvendo pesquisas nas áreas de Sistemas Distribuídos e Geoprocessamento. Começei a ensinar em 2000, nos cursos de Ciência da Computação e Sistemas de Informação. Desde o início da minha carreira como professora, ministro disciplinas de Programação e tenho uma paixão pela linguagem C. Atualmente, encontrei uma nova paixão: Educação a Distância.

Page 181: Programação 2 Linguagem C (UFRPE)

Recife, 2009

Programação 2

Sônia Virginia Alves França

Page 182: Programação 2 Linguagem C (UFRPE)

Universidade Federal Rural de Pernambuco

Reitor: Prof. Valmar Corrêa de AndradeVice-Reitor: Prof. Reginaldo BarrosPró-Reitor de Administração: Prof. Francisco Fernando Ramos CarvalhoPró-Reitor de Extensão: Prof. Paulo Donizeti SiepierskiPró-Reitor de Pesquisa e Pós-Graduação: Prof. Fernando José FreirePró-Reitor de Planejamento: Prof. Rinaldo Luiz Caraciolo FerreiraPró-Reitora de Ensino de Graduação: Profª. Maria José de SenaCoordenação de Ensino a Distância: Profª Marizete Silva Santos

Produção Gráfica e EditorialCapa e Editoração: Allyson Vila Nova, Rafael Lira, Italo Amorim e Marcella AlmeidaRevisão Ortográfica: Marcelo MeloIlustrações: Diego Almeida e Glaydson da SilvaCoordenação de Produção: Marizete Silva Santos

Page 183: Programação 2 Linguagem C (UFRPE)

Sumário

Apresentação ........................................................................................5

Conhecendo o Volume 3 ......................................................................6

Capítulo 1 – Armazenamento de Dados em Vetores .........................8

1.1 O que são vetores? ......................................................................8

1.2 Declaração de Vetores .................................................................9

1.3 Referência a elementos de vetor ................................................11

1.4 Inicialização de vetores ..............................................................13

1.5 Leitura de elementos para o vetor ..............................................15

1.6 Impressão dos elementos de um vetor .......................................22

1.7 Tamanho de um vetor e segmentação de memória ...................27

1.8 Passando vetores como parâmetros de funções .......................28

Capítulo 2 – Armazenamento de Dados em Registros ....................35

2.1 O que são registros? ..................................................................35

2.2 Declaração de um Registro ........................................................36

2.3 Acessando os campos do registro ..............................................39

2.4 Vetor de registro .........................................................................40

2.5 Acessando os campos do vetor de registro ................................42

2.6 Usando vetor de registro ............................................................43

Page 184: Programação 2 Linguagem C (UFRPE)

Capítulo 3 – Armazenamento de Dados em Arquivos .....................61

3.1 O que são arquivos? ...................................................................61

3.2 Comandos para manipular arquivos binários .............................64

3.3 Implementação das operações básicas em um arquivo .............76

Considerações Finais .......................................................................102

Conhecendo a Autora .......................................................................104

Page 185: Programação 2 Linguagem C (UFRPE)

Apresentação

Caro(a) aluno(a),

Seja bem-vindo (a) ao terceiro módulo da disciplina Programação II. Neste módulo, vamos dar mais um passo no nosso aprendizado sobre a linguagem de programação C.

Nos dois volumes anteriores, aprendemos os comandos básicos do C, a utilizar as estruturas de controle (seleção e repetição) e a modularizar nossos programas em módulos ou funções. Com estes assuntos, adquirimos a capacidade de desenvolver programas mais elaborados.

Neste livro, nós vamos aprender novas formas de armazenar nossos dados. Com os vetores e registros, poderemos manusear um volume maior de dados, de forma facilitada. Outro assunto muito importante que será abordado neste volume é o armazenamento de dados em arquivos. Atualmente, ao terminar a execução do programa, todos os dados que foram digitados são perdidos. Com o armazenamento de dados em arquivos, isto não acontece. Assim, iremos desenvolver programas com operações como: cadastro de elementos, remoção, alteração, consultas, listagens, etc.

Continuem resolvendo as questões propostas no final de cada capítulo, além de executar buscas na Internet, visando um maior aprofundamento de cada assunto. Ao final deste módulo, teremos a capacidade de resolver questões com operações presentes nos principais sistemas de controle do mercado, como por exemplo: sistema de controle de estoque, sistema de controle de cliente, etc. Vamos começar mais uma nova etapa no conhecimento da linguagem de programação C?

Bons estudos!

Professora Sônia Virginia Alves França

Page 186: Programação 2 Linguagem C (UFRPE)

6

Programação 2

Conhecendo o Volume 3

Neste terceiro volume, vocês irão encontrar o módulo 03 da disciplina: Programação II. Este volume está estruturado em três capítulos, que serão estudados ao longo de 15h/aula. Para facilitar seus estudos, veja a organização deste volume.

Capítulo 1: Armazenamento de Dados em Vetores

Carga Horária do Capítulo 1: 5 h/aula

Objetivos do Capítulo 1: Apresentar o uso de vetores para o armazenamento de dados.

Conteúdo Programático do Capítulo 1

• Definição de vetores;

• Declaração, leitura e escrita de dados em vetores;

• Passagem de vetores como parâmetros de funções;

Capítulo 2: Armazenamento de Dados em Registros

Carga Horária do Capítulo 2: 5 h/aula

Objetivos do Capítulo 2: Apresentar o uso de registros para o armazenamento de dados.

Conteúdo Programático do Capítulo 2

• Definição de registros;

• Declaração, leitura e escrita de dados em registros;

• Vetor de registro;

Capítulo 3: Armazenamento de Dados em Arquivos

Carga Horária do Capítulo 3: 5 h/aula

Objetivos do Capítulo 3: Apresentar os principais comandos para o armazenamento de dados em arquivos. Com os arquivos, os dados manipulados no programa podem ser armazenados definitivamente.

Conteúdo Programático do Capítulo 3

• Definição de arquivos;

Page 187: Programação 2 Linguagem C (UFRPE)

7

Programação 2

• Ponteiros;

• Comandos para manipulação de dados em arquivos;

Ao final de cada capítulo vocês encontrarão:

• A seção “Atividades e Orientações de Estudo”: que contém exercícios para a fixação do assunto estudado, além de indicação de fóruns de discussão.

• A seção “Conheça Mais”: que contém dicas de sites e livros que devem ser lidos para ampliar os seus conhecimentos.

• A seção “Vamos Revisar?”: que apresenta um resumo dos principais tópicos abordados no capítulo.

Page 188: Programação 2 Linguagem C (UFRPE)

8

Programação 2

Capítulo 1 – Armazenamento de Dados em Vetores

Vamos conversar sobre o assunto?

Neste terceiro volume, vamos aprender novas formas de armazenar nossos dados. Começaremos aprendendo como armazenar os dados em vetores. Com os vetores, nós podemos armazenar um grande conjunto de dados, facilitando o acesso e manuseio dos mesmos. Os dados são a “alma” de um programa. Assim, a manipulação dos dados de forma mais adequada e facilitada, trará ganhos para o programa e para o programador. Vamos continuar a nossa caminhada?

1.1 O que são vetores?

Imaginem que um professor nos encomendou um programa, que tenha que armazenar as médias dos 50 alunos de uma turma. Como faríamos para armazenar essas médias? Até o ponto que estudamos a linguagem C, teríamos que declarar 50 variáveis do tipo float, uma por uma. Que trabalheira, não é mesmo? E se o professor tivesse 300 alunos? Passaríamos um tempão só declarando variáveis e, além disso, teríamos muito trabalho para fazer o controle das mesmas. Mas não se preocupem, com os vetores, o professor pode ter mais de 1000 alunos, que a declaração e manuseio dos dados será bem fácil.

Os vetores são usados quando precisamos armazenar um conjunto de dados do mesmo tipo. Por exemplo: armazenar as 50 médias dos alunos de uma turma (todas as médias são do tipo float). Os vetores são bem convenientes já que iremos colocar todas as informações dentro de um mesmo conjunto e faremos referência de cada dado, individualmente, através de um índice1. De maneira mais formal, os vetores são chamados de estruturas de dados homogêneas (já que armazenam dados do mesmo tipo). Os vetores são formados por dados de mesmo tipo (homogêneo) e possuem número fixo de elementos (estático).

Para entendermos melhor os vetores, vamos visualizar a sua representação gráfica, na figura 1.1.

Saiba Mais

1 Em inglês, um vetor é chamado de array (que significa cadeia). Assim, quando temos um array, temos uma cadeia de inteiros, reais ou caracteres.

Page 189: Programação 2 Linguagem C (UFRPE)

9

Programação 2

media 3.0 7.5 5.8 9.5 8.2

0 1 2 3 4

Figura 1.1: Representação gráfica de um vetor

Na figura 1.1 temos um vetor chamado media, formado por 5 elementos. Vocês lembram quando tínhamos uma variável simples? Representávamos com uma única caixa. Agora, com os vetores, teremos um conjunto de dados, por isso ele é formado por várias caixas. Em cada uma delas poderemos armazenar um valor. Todas as caixas têm um único nome. Neste exemplo, o vetor se chama media. Notem que, abaixo de cada caixa temos um número. Estes números são chamados de índices. É através do índice, que iremos informar qual das caixas do vetor é que estamos querendo acessar. Já que todas as caixas têm um único nome (media), a forma de diferenciar uma da outra é o índice. Entenderam?

Na linguagem C, o índice de um vetor, começa a partir de 0. Assim, em um vetor com 5 elementos, os índices variam de 0 a 4 (como no exemplo da figura 1.1). Por isso, o primeiro elemento do vetor media está na posição de índice 0. Podemos dizer que a média do segundo aluno está na posição de índice 1 do vetor media, e é igual a 7.5.

Esta não é a única maneira de estruturar um conjunto de dados. Também podemos organizar dados sob forma de tabelas. Neste caso, cada dado é referenciado por dois índices e dizemos que se trata de um conjunto bidimensional (ou matriz).

Vamos aprender, nas próximas seções, como manusear os vetores nos nossos programas.

1.2 Declaração de Vetores

Como já foi mencionado, um vetor é um conjunto de variáveis do mesmo tipo, que possuem um nome identificador e um índice de referência. A sintaxe para a declaração de um vetor é a seguinte:

Sintaxe

tipo identificador[tamanho];

Page 190: Programação 2 Linguagem C (UFRPE)

10

Programação 2

onde:

• tipo: é o tipo de dados que o vetor armazena: int, float, char, etc.

• identificador: é o nome do vetor. As regras para nomear um vetor são as mesmas usadas para nomear variáveis, constantes e funções.

• tamanho: é o tamanho do vetor. Isto é, o número de elementos que o vetor pode armazenar.

A seguir, são apresentados exemplos de declarações de vetores. Os vetores são declarados na seção de declaração de variáveis do programa. Se estivermos desenvolvendo um programa modularizado, podemos declarar o vetor como uma variável local de um módulo.

Exemplo 1.1: declaração de vetores

1

2

3

int idade[100];

float nota[25];

char nome[80];

No primeiro exemplo, temos a declaração de um vetor chamado idade, que pode armazenar até 100 números inteiros. No segundo exemplo, temos um vetor chamado nota, com capacidade para armazenar até 25 números reais. E, finalmente, no terceiro exemplo, temos um vetor chamado nome, com capacidade de armazenar até 80 caracteres2.

Ao declararmos o vetor, já temos que ter uma previsão de quantos elementos serão armazenados no mesmo. Com isso, o processador saberá quanto de memória precisa ser reservada para armazenar os dados do vetor, ao executar o programa. A quantidade de memória (em bytes) usada para armazenar um vetor pode ser calculada como:

quantidade de memória = tamanho do tipo * tamanho do vetor

O tamanho do tipo indica quantos bytes um determinado tipo de variável utiliza para ser armazenado (vimos este assunto no Volume 1 – Capítulo 3). Ao compilar o programa, a quantidade de memória necessária para armazenar o vetor é alocada. Os vetores têm tamanhos fixos e não podemos armazenar mais elementos do que a quantidade que foi solicitada no momento da declaração do vetor. Por

Atenção

2 Nós já havíamos utilizado vetor de caracteres, já que trabalhamos com variáveis que armazenam uma cadeia de caracteres. No próximo volume, teremos um capítulo dedicado a este assunto.

Page 191: Programação 2 Linguagem C (UFRPE)

11

Programação 2

isso, são chamados de estáticos. A quantidade de elementos não pode aumentar em tempo de execução do programa.

Também é possível declarar um vetor com tamanho parametrizado: usando uma constante. Declaramos uma constante com a diretiva #define, no início do programa, e depois declaramos o vetor com esta constante como tamanho do vetor. Deste modo, podemos alterar o número de elementos do vetor antes de qualquer compilação do programa. Esta é uma maneira simples de administrar o espaço de memória usado pelo programa, e também testar os limites de um vetor.

Exemplo 1.2: Declaração de vetor usando uma constante no local do tamanho do vetor.

1

2

#define TAMANHO 30

int valor[TAMANHO];

No exemplo 1.2, o vetor valor terá capacidade de armazenar 30 elementos (este é o valor da constante TAMANHO).

1.3 Referência a elementos de vetor

Agora que já sabemos como criar os vetores, a partir da sua declaração, vamos aprender como acessar um elemento do vetor. Segue abaixo a sintaxe.

Sintaxe

identificador[indice]

onde:

• identificador: é o nome do vetor que queremos acessar.

• índice: é o índice do elemento do vetor que queremos acessar.

Cada elemento do vetor é referenciado pelo nome do vetor e, entre colchetes, tem-se o índice, que é um número inteiro. O índice irá indicar qual elemento do vetor estamos querendo referenciar. A seguir, são apresentadas algumas atribuições a elementos de um vetor chamado valor, que é composto por 10 elementos do tipo float.

Page 192: Programação 2 Linguagem C (UFRPE)

12

Programação 2

Exemplo 1.3: Acessando os elementos de um vetor

1

2

3

4

5

6

float valor[10]; //declaração do vetor

int x;

x = 3;

valor[1] = 6.6;

valor[x] = 9.9

valor[x+2] = 10.0;

Entre os colchetes, que indicam o índice do vetor que será acessado, podemos ter: um valor (exemplo da linha 4), uma variável (exemplo da linha 5) ou uma expressão (exemplo da linha 6). Devemos ter cuidado quando usamos variáveis e expressões, pois estas devem ser inteiras e devem ter um valor dentro da capacidade de armazenamento do vetor. Ou seja, se o vetor foi declarado com tamanho 10, não podemos tentar acessar o índice 18 do vetor.

Na linha 4, foi atribuído 6.6 ao elemento de índice 1 do vetor valor. Na linha 5, como a variável x tem armazenado 3, então o valor[3], receberá 9.9. Quando temos uma expressão, que é o caso da linha 6, a expressão é resolvida primeiro. Assim, como x = 3, e entre os colchetes temos x+2, o resultado será 5. Dessa forma, valor[5] receberá 10.0. A seguir, temos a situação final do vetor valor, após as atribuições dos valores do exemplo.

Valor 6.6 9.9 10.0

0 1 2 3 4 5 6 7 8 9

Figura 1.2: Situação do vetor valor após atribuições

Viram como é fácil trabalhar com vetor? Em uma única linha, nós criamos um conjunto de variáveis, do tamanho da nossa necessidade. Posteriormente, acessamos cada uma destas variáveis utilizando o nome do vetor e o índice da variável.

Na próxima seção, vamos ver como fazemos para inicializar os elementos de um vetor, no momento da declaração.

Page 193: Programação 2 Linguagem C (UFRPE)

13

Programação 2

1.4 Inicialização de vetores

No momento da declaração de um vetor, também podemos inicializar os seus elementos, fazendo a atribuição de valores aos mesmos. A sintaxe para a inicialização dos elementos de um vetor é a seguinte:

Sintaxe

tipo identificador[tamanho] = {lista de valores};

Onde:

• tipo: é o tipo dos elementos do vetor: int, float, char, etc.

• identificador: é o nome do vetor.

• tamanho: é o tamanho do vetor. Isto é, o número de elementos que o vetor pode armazenar.

• lista de valores: é uma lista, separada por vírgulas, dos valores de cada elemento do vetor. A lista de valores é colocada entre chaves.

Vamos ver a seguir, exemplos de inicialização de vetores.

Exemplo 1.4: Inicialização de vetores

1

2

3

4

int idade[7] = {12, 30, 14, 7, 13, 15, 6};

char vogal[5] = {‘a’, ‘e’, ‘i’, ‘o’, ‘u’};

float nota[5] = {8.4, 6.9, 4.5};

float media[5] = {0};

No exemplo da linha 1, temos o vetor chamado idade e para cada posição do vetor, foi atribuído um valor. Após esta atribuição, o vetor idade ficará assim:

idade 12 30 57 25 18 15 13

0 1 2 3 4 5 6

Figura 1.3: Situação do vetor idade após inicialização

No segundo exemplo, temos um vetor de caracteres, chamado vogal. Quando inicializamos um vetor deste tipo de variável, os valores

Page 194: Programação 2 Linguagem C (UFRPE)

14

Programação 2

devem ser colocados entre apóstrofo. Ao final desta atribuição, o vetor vogal ficará como mostra a figura 1.4.

vogal a e i o u

0 1 2 3 4

Figura 1.4: Situação do vetor idade após inicialização

Na linha 3, temos a inicialização do vetor nota, que é composto por cinco elementos. Notem que, entre as chaves, não temos cinco valores. Temos apenas três. Quando não quisermos inicializar todo o vetor, podemos colocar apenas os valores dos primeiros elementos, e aos demais, será atribuído zero (automaticamente). Vejam na figura 1.5 como ficará o vetor nota, após a sua inicialização.

nota 8.4 6.9 4.5 0.0 0.0

0 1 2 3 4

Figura 1.5: Situação do vetor idade após inicialização

Seguindo o raciocínio do exemplo anterior, quando precisarmos inicializar todos os elementos do vetor com zero, fazemos como mostra o exemplo da linha 4. Colocamos apenas um zero entre as chaves, o primeiro elemento será inicializado com zero, e os demais também. Neste caso, o vetor media ficará como apresentado na figura 1.6.

media 0.0 0.0 0.0 0.0 0.0

0 1 2 3 4

Figura 1.6: Situação do vetor media após inicialização

Opcionalmente, podemos inicializar os elementos do vetor enumerando-os um a um. No exemplo 1.5, a seguir, observem que estas duas inicializações são possíveis:

Page 195: Programação 2 Linguagem C (UFRPE)

15

Programação 2

Exemplo 1.5: Inicialização de vetores

1

2

3

4

5

6

int valor[3] = {7,4,20};

ou

int valor[3];

valor[0] = 7;

valor[1] = 4;

valor[2] = 20;

Na próxima seção, vamos aprender a armazenar, em um vetor, valores que são fornecidos via teclado.

1.5 Leitura de elementos para o vetor

Agora suponham que os valores que vão ser armazenados no vetor sejam fornecidos pelo usuário, via teclado. O que devemos fazer? Devemos utilizar uma estrutura de repetição, para controlar o preenchimento dos dados no vetor, um por um. Assim, podem ocorrer duas situações:

• Nós sabemos quantos elementos o usuário vai digitar;

• Nós não sabemos a quantidade de elementos que o usuário vai digitar.

Vamos ver como tratar cada uma das situações? Quando nós sabemos quantos elementos o usuário vai digitar, poderemos usar uma estrutura de repetição como o for, que irá repetir a leitura dos elementos, na quantidade definida. Vamos ver o Programa Completo 1.1 a seguir: o usuário precisa armazenar 5 elementos em um vetor de inteiros, chamado valor.

Page 196: Programação 2 Linguagem C (UFRPE)

16

Programação 2

Programa Completo 1.1: Ler 5 números inteiros, armazenando-os em um vetor

1

2

3

4

5

6

7

8

9

10

11

main()

{

int valor[5];

int i;

printf(“Cadastro dos elementos do vetor Valor

\n\n”);

for (i=0; i<5; i++)

{ printf(“\n\nElemento %d: “,i+1);

scanf(“%d”,&valor[i]);

}

getche();

}

Comentários sobre o Programa Completo 1.1:

• Linha3: declaração do vetor valor, que tem a capacidade de armazenar 5 números inteiros.

• Linha4: declaração da variável i, que irá controlar o for.

• Linha5: printf para que o usuário saiba que será feito o cadastro dos elementos no vetor.

• Linha6: for que será repetido 5 vezes, fazendo a leitura dos elementos do vetor. Notem que a variável de controle do for, o i, é inicializado com 0. Isso acontece porque o primeiro índice do vetor é 0.

• Linha 7: Abre chaves que inicia a sequência de comandos do for (já que teremos mais de um comando). Nesta linha, também temos o printf para que o usuário saiba qual elemento do vetor está sendo cadastrado no momento. Vejam que neste printf temos a expressão: i+1. O motivo de colocarmos esta expressão no printf é que, como o i começa com zero e vai até 4, não ficaria muito interessante que saísse uma mensagem, na tela, informando que o usuário estaria cadastrando o elemento 0. O correto é dizer que ele está cadastrando o elemento 1. Por

Page 197: Programação 2 Linguagem C (UFRPE)

17

Programação 2

isso, usamos a expressão i+1.

• Linha8: scanf que lê o valor, armazenando no vetor. Notem que estamos usando a variável i, no índice do vetor. Dessa forma, o i vai variando a cada vez que o for é repetido, e assim, os elementos são armazenados em índices diferentes do vetor. Com isso, nenhum elemento irá sobrepor o outro.

• Linha 9: fecha chaves que indica o final da sequência de comandos do for.

• Linha10: comando getche que faz com que a tela de execução do programa fique aberta, e assim podemos ver o resultado do programa.

• Linha 11: fecha chaves, indicando o final do programa principal.

A figura 1.7, apresenta a tela de execução do Programa Completo 1.1.

Figura 1.7: Tela de execução do Programa Completo 1.1

Para facilitar o entendimento, vamos fazer um acompanhamento dos valores das variáveis do Programa Completo 1.1, ao longo da sua execução. Vamos considerar que o usuário está cadastrando os valores apresentados na figura 1.7. A figura 1.8 mostra os valores das variáveis do programa, conforme o programa vai sendo executado.

Page 198: Programação 2 Linguagem C (UFRPE)

18

Programação 2

i i+1 valor

0

1

10

0 1 2 3 4

1

2

10 15

0 1 2 3 4

2

3

10 15 9

0 1 2 3 4

3

4

10 15 9 6

0 1 2 3 4

4

5

10 15 9 6 12

0 1 2 3 4

Figura 1.8: Acompanhamento das variáveis do Programa Completo 1.1

O que fazemos quando não sabemos quantos elementos serão armazenados no vetor? Neste caso, como não sabemos quantas vezes o for deve ser executado, poderemos fazer a leitura dos dados que serão colocados no vetor, usando um do/while, como mostra o Programa Completo 1.2, a seguir. Neste programa, iremos fazer a leitura de uma quantidade indeterminada de números inteiros, armazenando em um vetor.

Page 199: Programação 2 Linguagem C (UFRPE)

19

Programação 2

Programa Completo 1.2: Ler um conjunto de números inteiros, armazenando-os em um vetor.

1

2

3

4

5

6

7

8

9

10

11

12

13

main()

{ int valor[5];

int q, continuar;

q=0;

printf(“Cadastro dos elementos do vetor Valor

\n\n”);

do

{ printf(“\n\nElemento %d: “,q+1);

scanf(“%d”,&valor[q]);

q++;

printf(“\n\nCadastrar outro elemento

(1-sim/2-nao)? “);

scanf(“%d”, &continuar);

} while ((continuar==1) && (q<5));

}

Neste caso, a leitura será finalizada quando o vetor ficar cheio, com cinco elementos, ou quando o usuário decidir que não deseja mais continuar a leitura. Neste último caso, saberemos quantos elementos foram armazenados no vetor através da variável q. É esta variável que indica, também, em qual índice do vetor o elemento deve ser armazenado3.

Comentários sobre o Programa Completo 1.2:

• Linhas2: declaração do vetor valor, que tem a capacidade de armazenar 5 números inteiros.

• Linha3: declaração das variáveis q (que controla a quantidade de elementos que já foram cadastrados no vetor) e continuar (que armazena a resposta do usuário informando se quer cadastrar mais elementos ou não).

• Linha4: inicialização da variável q com 0.

• Linha5: printf para que o usuário saiba que será feito o cadastro

Atenção

3 Quando não sabemos quantos elementos serão cadastrados, temos que estipular um valor para a quantidade de elementos que serão armazenados no vetor. Isso se dá porque temos que saber o tamanho do vetor no momento da sua declaração.

Page 200: Programação 2 Linguagem C (UFRPE)

20

Programação 2

dos elementos no vetor.

• Linha6: do indicando o início da repetição.

• Linha7: Abre chaves que inicia a sequência de comandos do do/while (já que teremos mais de um comando). Nesta linha também temos o printf para que o usuário saiba qual elemento do vetor está sendo cadastrado no momento.

• Linha8: scanf que lê o valor que será armazenado no vetor. Notem que estamos usando a variável q, no índice do vetor.

• Linha 9: incremento da variável q, indicando que mais um elemento foi cadastrado no vetor. Através do valor de q, saberemos se o vetor já está cheio ou não.

• Linha10: prinft que pergunta ao usuário se deseja cadastrar outro elemento no vetor. O usuário pode parar o cadastro dos elemento do vetor, no momento que ele desejar. Nesse caso, o vetor pode ficar com posições sem valores armazenados.

• Linha11: scanf para ler a resposta do usuário.

• Linha 12: fecha chaves do do/while e while com a condição que faz com que a repetição fique sendo executada. Como a condição é formada por duas expressões relacionais, nós colocamos cada expressão relacional entre parênteses e depois colocamos toda a expressão entre parênteses. As expressões estão conectadas pelo operador && (e). Com isso, quando uma das expressões der falso, a repetição para. Vai parar porque o vetor está cheio (q=5) ou porque o usuário desejou parar, respondendo 2 a pergunta se deseja continuar.

• Linha 13: fecha chaves, indicando o final do programa principal.

A figura 1.9, apresenta a tela de execução do Programa Completo 1.2.

Page 201: Programação 2 Linguagem C (UFRPE)

21

Programação 2

Figura 1.9: Tela de execução do Programa Completo 1.2

Vamos acompanhar o valor das variáveis do Programa Completo 1.2? A Figura 1.9 mostra o cadastramento de 3 elementos no vetor. O usuário respondeu que não queria mais cadastrar após dar entrada ao terceiro elemento. A figura 1.10 mostra os valores das variáveis do programa, conforme o programa vai sendo executado.

q q+1 valor

0

1

12

0 1 2 3 4

1

2

12 15

0 1 2 3 4

2

3

12 15 18

0 1 2 3 4

Figura 1.10: Acompanhamento das variáveis do Programa Completo 1.2

Agora que já sabemos colocar informações em um vetor via teclado, vamos ver como apresentar, na tela, os valores armazenados em um vetor.

Page 202: Programação 2 Linguagem C (UFRPE)

22

Programação 2

1.6 Impressão dos elementos de um vetor

Quando desejarmos apresentar os elementos que estão armazenados no vetor, devemos utilizar uma estrutura de repetição, que fará com que cada uma das posições do vetor seja “visitada” e seu conteúdo apresentado. Vale lembrar que, quando declaramos um vetor, indicamos a sua capacidade de armazenamento. Mas durante a execução do programa, pode ser que o usuário não armazene dados suficiente para preencher todas as posições do vetor. Assim, quando formos imprimir os dados de um vetor, precisamos saber quantos elementos têm armazenado no momento da impressão. O Programa Completo 1.3, mostra a leitura e a impressão dos dados armazenados em um vetor.

Programa Completo 1.3: Ler e imprimir um conjunto de números inteiros, armazenando-os em um vetor.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

main()

{ int valor[5];

int q, continuar, i;

q=0;

printf(“Cadastro dos elementos do vetor Valor

\n\n”);

do

{ printf(“\n\nElemento %d: “,q+1);

scanf(“%d”,&valor[q]);

q++;

printf(“\n\nCadastrar outro elemento

(1-sim/2-nao)? “);

scanf(“%d”, &continuar);

} while ((continuar==1) && (q<5));

printf(“\n\nElementos do Vetor: “);

for (i=0; i<q; i++)

printf(“ %d “,valor[i]);

getche();

}

Page 203: Programação 2 Linguagem C (UFRPE)

23

Programação 2

Até a linha 12, o Programa Completo 1.3 é, praticamente, idêntico ao Programa Completo 1.2. A única diferença é que temos, na linha 3, a declaração da variável i, que será usada no for que imprimirá os elementos do vetor. Vamos ver o que está acontecendo nas demais linhas?

• Linha 13: printf para informar que serão apresentados os elementos do vetor. Notem que o texto entre aspas não termina com \n. Isso se dá porque não queremos que o cursor vá para a linha seguinte.

• Linha 14: for que será utilizado para percorrer o vetor, acessando cada uma das posições do vetor. A variável que tem a informação de quantos elementos foram armazenados no vetor é q. Dessa forma, o i do for vai variar de 0 até q-1. Uma vez que se q for 3, a última posição ocupada no vetor é 2.

• Linha15: printf que apresenta o elemento do vetor, na posição de índice i. Este printf também não tem o \n, porque queremos que os elementos do vetor sejam impressos um ao lado do outro. Este é o único comando do for, por isso não houve a necessidade de delimitar com chaves.

• Linha16: getche que evita o fechamento da janela de execução do programa, e assim poderemos ver os elementos do vetor impresso.

• Linha 17: fecha chaves, indicando o final do programa principal.

A figura 1.11 apresenta a tela de execução do programa 1.3. Foram cadastrados os mesmos valores do exemplo anterior.

Page 204: Programação 2 Linguagem C (UFRPE)

24

Programação 2

Figura 1.11: Tela de execução do Programa Completo 1.3

Neste caso, apesar do vetor ter sido declarado com 5 posições, só foram preenchidas 3 posições. Vejam que, após o usuário responder que não quer mais cadastrar, os elementos do vetor são apresentados um ao lado do outro.

Vamos ver outro Programa Completo? Neste programa iremos ler as matrículas e notas dos alunos de uma turma e imprimir as matrículas dos alunos de tiveram nota acima da média das notas da turma.

Programa Completo 1.4

1

2

3

4

5

6

7

8

9

10

main()

{ int mat[10];

float nota[10];

int q, i, continuar;

float soma, media;

soma = 0;

q=0;

do

{ system(“cls”);

printf(“Universidade Aberta do Brasil -

UFRPE\n\n”);

Page 205: Programação 2 Linguagem C (UFRPE)

25

Programação 2

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

printf(“\n\nDados do Alunos %d\n\n”,

q+1);

printf(“\nMatricula: “);

scanf(“%d”,&mat[q]);

printf(“\nNota: “);

scanf(“%f”,&nota[q]);

soma = soma + nota[q];

q++;

printf(“\n\nCadastrar outro(1-sim/2-nao)?

“);

scanf(“%d”, &continuar);

} while ((continuar==1) && (q<10));

media = soma/q;

system(“cls”);

printf(“Universidade Aberta do Brasil - UFRPE

\n\n”);

printf(“Media da turma: %.2f\n\n\n”,media);

printf(“Alunos com nota acima da media da

turma\n\n”);

for (i=0; i<q; i++)

{ if (nota[i]>media)

printf(“%d \n”,mat[i]);

}

printf(“\n\nDigite qualquer tecla para sair

“);

31

32

getche();

}

Comentários sobre o Programa Completo 1.4:

• Linhas 2 a 5: declaração das variáveis do programa. Vejam que precisamos de um vetor para armazenar as matrículas e um outro para armazenar as notas.

Page 206: Programação 2 Linguagem C (UFRPE)

26

Programação 2

• Linhas6e7: inicialização das variáveis soma (que acumula as notas de todos os alunos) e q (que conta quantos elementos foram cadastrados no vetor).

• Linhas8a20: do/while que faz a leitura das matrículas e das notas de cada aluno, armazenando nos respectivos vetores. Neste do/while, o usuário pode parar o cadastro no momento que ele desejar. Para calcularmos a média da turma, temos que somar as notas de todos os alunos e dividir pela quantidade de alunos. Assim, enquanto estivermos no do/while, estamos acumulando as notas de todos os alunos na variável soma.

• Linha 21: ao sair do do/while, a média da turma pode ser calculada.

• Linha22: usa o system(“cls”) para limpar a tela e dar início a tela que irá apresentar os resultados.

• Linha24: printf para apresentar a média da turma.

• Linhas 26 a 29: for para visitar cada posição do vetor que armazena as notas dos alunos. Quando verifica que a nota do aluno é maior que a média da turma (armazenada na variável media), a matrícula do aluno é apresentada.

A figura 1.12 apresenta a tela de execução do programa 1.4, na fase do cadastramento dos dados dos alunos (matrícula e nota).

Figura 1.12: Tela de Execução do Programa Completo 1.4 – Cadastro de Alunos

A figura 1.13 apresenta a tela de execução do programa completo 1.4, na fase do apresentação dos resultados.

Page 207: Programação 2 Linguagem C (UFRPE)

27

Programação 2

Figura 1.13: Tela de Execução do Programa Completo 1.4 – Apresentação dos Resultados

1.7 Tamanho de um vetor e segmentação de memória

Na linguagem C, devemos ter cuidado com os limites de um vetor. Embora na declaração tenhamos que definir o tamanho de um vetor, o C não faz nenhum teste de verificação de acesso a um elemento dentro do vetor ou não.

Por exemplo, se declaramos um vetor como int valor[5], teoricamente, só tem sentido usarmos os elementos valor[0], valor[1], valor[2] , valor[3] e valor[4]. Porém, o C não acusa erro se usarmos valor[12] em algum lugar do programa. Estes testes de limite devem ser feitos dentro do programa, pelo programador.

Este fato se deve à maneira como o C trata os vetores. A memória do computador é um espaço (físico) particionado em porções de 1 byte. Se declararmos um vetor como int valor[3], estamos reservando 12 bytes (3 segmentos de 4 bytes – lembrando que cada int ocupa 4 bytes) de memória para armazenar os seus elementos. O primeiro segmento será reservado para valor[0], o segundo segmento para valor[1] e o terceiro segmento para valor[2]. O segmento inicial é chamado de segmento base, de modo que valor[0] será localizado no segmento base. Quando acessamos o elemento valor[i], o processador acessa o segmento localizado em base+i. Se i for igual a 2, estamos acessando o segmento base+2 ou valor[2] (o último segmento reservado para o vetor). Porém, se i for igual a 7, estamos acessando o segmento base+7 que não foi reservado para os elementos do vetor e que provavelmente está sendo usado por uma outra variável ou contém uma informação inesperada (lixo).

Page 208: Programação 2 Linguagem C (UFRPE)

28

Programação 2

Observem que o acesso a um segmento fora do espaço destinado a um vetor pode destruir informações reservadas de outras variáveis. Estes erros são difíceis de detectar, pois o compilador não gera nenhuma mensagem de erro. Por isso, a solução mais adequada é sempre avaliar os limites de um vetor antes de manipulá-lo. Como feito no Programa Completo 1.2 que vai cadastrando os elementos no vetor e para quando o vetor completa a sua capacidade.

A princípio, este fato poderia parecer um defeito da linguagem, mas na verdade trata-se de um recurso muito poderoso do C. Poder manipular sem restrições todos os segmentos de memória é uma flexibilidade apreciada por programadores mais experientes.

1.8 Passando vetores como parâmetros de funções

Os vetores, assim como as variáveis simples, podem ser usados como argumentos de funções. Veremos como se declara uma função que recebe um vetor como parâmetro e como se chama uma função passando um vetor como parâmetro.

A sintaxe de uma função que recebe um vetor como parâmetro é a seguinte:

Sintaxe

tipo_retorno nome_função(tipo_vetor nome_vetor[])

{

//corpo da função

}

Onde:

• tipo_retorno: é o tipo de retorno da função.

• nome_função: é o nome da função.

• tipo_vetor: é o tipo de dados dos elementos do vetor.

• nome_vetor: é o nome do vetor. Observe que depois do nome do vetor temos o [ e o ], mas não colocamos nada entre eles. Neste caso, não é necessário informar o tamanho do vetor.

Quando formos chamar uma função que recebe um vetor como

Page 209: Programação 2 Linguagem C (UFRPE)

29

Programação 2

parâmetro, usamos a seguinte sintaxe:

Sintaxe

nome_da_função(nome_do_vetor);

Onde:

• nome_da_função: é o nome da função que será chamada.

• nome_do_vetor: é o nome do vetor que queremos passar como parâmetro. Neste caso, indicamos apenas o nome do vetor, sem os colchetes.

O exemplo 1.6, a seguir, apresenta a declaração de uma função que tem um vetor como parâmetro e a chamada da função.

Exemplo 1.6: declaração e chamada de uma função que tem um vetor como parâmetro

1

2

3

4

5

6

7

8

9

10

11

12

float media(float vetor[],float N)

{

//corpo da função

}

main()

{ float valor[30]; // declaração do vetor

float n;

...

med = media(valor, n); // passagem do vetor

para a função

...

}

Atenção: Ao contrário das variáveis comuns, o conteúdo de um vetor pode ser modificado pela função chamada. Isto significa que podemos passar um vetor para uma função e alterar os valores de seus elementos. Isto ocorre porque a passagem de vetores para funções é feita de modo especial dito passagem por endereço. Portanto, devemos ter cuidado ao manipular os elementos de um

Page 210: Programação 2 Linguagem C (UFRPE)

30

Programação 2

vetor dentro de uma função para não modificá-los por descuido.

Atividades e Orientações de Estudos

Vamos fazer um conjunto de exercícios, usando o assunto que acabamos de aprender? Segue abaixo uma lista de exercícios em que os dados serão armazenados em vetores. Vamos começar?

1. Ler um conjunto de números e imprimi-los na ordem inversa da leitura. A quantidade de números também será lida e será no máximo 10.

2. Ler o tamanho e os elementos de dois vetores e, em seguida, caso os vetores tenham o mesmo tamanho, gere e imprima o vetor SOMA, onde seus elementos serão formados pela soma dos elementos de mesmos índices dos dois vetores lidos. Exemplo:

A 1 4 7 2 9

0 1 2 3 4

B 3 5 11 4 8

0 1 2 3 4

Soma 4 9 18 6 17

0 1 2 3 4

3. Ler um vetor de números e imprimir os valores armazenados nas posições PARES e, em seguida, os valores armazenados nas posições ÍMPARES. Exemplo:

V 1 4 7 2 9

0 1 2 3 4

Valores nas posições pares: 1 7 9

Page 211: Programação 2 Linguagem C (UFRPE)

31

Programação 2

Valores nas posições impares: 4 2

4. Ler dois vetores e caso tenham tamanhos iguais, armazene seus elementos alternadamente em um terceiro vetor. Exemplo:

A 1 4 7 2 12

0 1 2 3 4

B 3 5 11 4 15

0 1 2 3 4

Resultante 1 3 4 5 7 11 2 4 12 15

0 1 2 3 4 5 6 7 8 9

5. Ler um vetor de números inteiros e imprimir as posições do maior e do menor elemento do vetor. Assuma que não existem elementos repetidos no vetor. Exemplo:

V 14 13 7 22 9

0 1 2 3 4

O menor elemento se encontra na posição 2

O maior elemento se encontra na posição 3

6. Ler um vetor de números e inverter a ordem dos elementos desse vetor no próprio vetor. Exemplo:

Vetor antes de ser invertido:

V 14 13 7 22 9

0 1 2 3 4

Vetor depois de ser invertido:

Page 212: Programação 2 Linguagem C (UFRPE)

32

Programação 2

V 9 22 7 13 14

0 1 2 3 4

7. Ler dois vetores de números e gerar um terceiro vetor formado pela INTERSECÇÃO dos dois vetores lidos. O resultado da interseção de dois conjuntos é: os elementos que fazem parte dos dois conjuntos. Exemplo:

A 1 4 7 2 12

0 1 2 3 4

B 3 4 2 14 25

0 1 2 3 4

interseccao 4 2

0 1 2 3 4

8. Ler dois vetores de números e gerar um terceiro vetor formado pela DIFERENÇA dos dois vetores lidos. O resultado da diferença de dois conjuntos é: os elementos do conjunto A que não fazem parte do conjunto B. Exemplo:

A 1 4 7 2 12

0 1 2 3 4

B 3 4 2 14 25

0 1 2 3 4

Diferenca 1 7 12

0 1 2 3 4

Page 213: Programação 2 Linguagem C (UFRPE)

33

Programação 2

9. Ler dois vetores de números e gerar um terceiro vetor formado pela UNIÃO dos dois vetores lidos. O resultado da união de dois conjuntos é: todos os elementos que fazem parte dos conjuntos A e B. Exemplo:

A 1 4 7 2 12

0 1 2 3 4

B 3 4 2 14 25

0 1 2 3 4

União 1 4 7 2 12 3 14 25

0 1 2 3 4 5 6 7 8 9

10. Ler um vetor de números e imprimir os números que se repetem nesse vetor. Exemplo:

V 1 4 7 1 2 1 4 25 3 7

0 1 2 3 4 5 6 7 8 9

Os números que se repetem no vetor são: 1 4 7

Conheça Mais

Para ampliar nossos conhecimentos sobre os assuntos tratados neste capítulo, leiam o capítulo que aborda armazenamento em vetores, do livro:

• SCHILDT, Herbert. C Completo e Total. São Paulo: Makron, 1996.

Page 214: Programação 2 Linguagem C (UFRPE)

34

Programação 2

Vamos Revisar?

Vamos lembrar rapidinho o que foi visto neste capítulo? Leia o resumo a seguir, composto com os principais conceitos apresentados.

Vetores: conhecidos como estruturas de dados homogêneas, os vetores são um conjunto de variáveis que armazenam elementos do mesmo tipo.

Índices: para acessar um elemento do vetor, precisamos indicar em que posição do vetor está o elemento.

No momento da declaração dos vetores, precisamos indicar quantos elementos serão armazenados no mesmo.

É de responsabilidade do programador o acesso aos elementos do vetor. Se o programa tentar acessar uma posição que não existe no vetor, o compilador não indicará o erro.

Quando passamos um vetor como parâmetro de uma função, seus valores podem ser alterados

Page 215: Programação 2 Linguagem C (UFRPE)

35

Programação 2

Capítulo 2 – Armazenamento de Dados em Registros

Vamos conversar sobre o assunto?

Neste capítulo, vamos aprender mais uma forma de armazenamento de dados, que são os registros. Nos registros podemos agrupar dados de tipos diferentes. Por conta disto, os registros são chamados de estruturas de dados heterogêneas. Assim como os vetores, os registros vão facilitar o gerenciamento dos dados dos nossos programas, que estão cada vez maiores. Veremos, também, como unir os conceitos de vetores e registros, trabalhando com vetor de registro. Leiam este capítulo com calma e atenção, uma vez que iremos utilizar registros em muitas situações nos nossos programas, certo?

2.1 O que são registros?

Nós já sabemos que um conjunto homogêneo de dados é composto por variáveis do mesmo tipo (vetores). Mas, e se tivermos um conjunto em que os elementos não são do mesmo tipo? Teremos, então, um conjunto heterogêneo de dados, que são chamados de registros. O registro é uma das principais formas de estruturar os dados no programa. O conceito de registro visa facilitar o agrupamento de variáveis de tipos diferentes, mas que possuem uma relação lógica.

Um registro é um conjunto de uma ou mais variáveis, que podem ser de tipos diferentes, agrupadas sobre um único nome. O fato de variáveis agrupadas em um registro poderem ser referenciadas por um único nome, facilita a manipulação dos dados armazenados nestas estruturas. Como exemplo de um registro, imaginem uma estrutura que armazene as diversas informações do boletim de um aluno. O boletim é formado por um conjunto de informações logicamente relacionadas, porém de tipos diferentes, tais como: número de matrícula (inteiro), nome do aluno (caractere), nome da disciplina (caractere), média (real) e situação (caractere), que são subdivisões do registro (elementos de conjunto), também chamadas de campos. Logo, um registro é composto por campos que são partes que especificam cada uma das informações. A figura 2.1 apresenta o boletim de notas de um aluno.

Page 216: Programação 2 Linguagem C (UFRPE)

36

Programação 2

Boletim de Notas

Matricula...: 12345

Nome........: Michel

Disciplina..: Matemática

Média........: 10.0

Situação....: Aprovado

Figura 2.1 Boletim de Notas

Notem que, o boletim é composto por informações de diferentes tipos. No entanto, todas as informações do boletim estão relacionadas ao mesmo aluno. O agrupamento de informações de tipos diferentes, que tem uma relação lógica, facilitará a manipulação de dados.

Nas próximas seções, vamos aprender a declarar e manipular registros.

2.2 Declaração de um Registro

Para declarar uma variável, precisamos informar o seu tipo e dar um nome à mesma. Mas, um registro é formado por várias variáveis de tipos diferentes. Como iremos declarar um registro? Para declarar um registro, é necessário informar quais variáveis, e seus respectivos tipos, fazem parte do registro. Dessa forma, precisamos declarar cada campo do registro, agrupando-os em um novo tipo de dado. A declaração de um registro passa por duas fases: definição de um novo tipo de dado e declaração do registro propriamente dito. Vamos entender melhor isso tudo?

Primeiramente, precisamos definir quais campos fazem parte do registro e criar um novo tipo de dado para o nosso programa. Precisamos criar um novo tipo de dado porque não conseguiríamos representar o tipo de informação que o registro armazena, utilizando os tipos primitivos disponíveis na linguagem: int, float, char, etc. Uma vez que o registro agrupa variáveis de tipos de dados diferentes. Para criar um novo tipo de dado, utilizamos a seguinte sintaxe:

Page 217: Programação 2 Linguagem C (UFRPE)

37

Programação 2

Sintaxe

typedef struct { declaração das variáveis;

} nome_do_tipo;

Onde:

• typedef: indica que um novo tipo de dado será definido.

• struct: indica que o tipo de dado que será definido é um registro, ou seja, um agrupamento de variáveis de tipos de dados diferentes.

• declaração das variáveis: são as variáveis que fazem parte do registro. Neste local, precisamos especificar quais as variáveis irão compor o registro, além do tipo das mesmas. As variáveis são colocadas entre chaves.

• nome_do_tipo: é dado um nome ao novo tipo de dado que está sendo criado. Só depois que o novo tipo de dado é criado, é que o registro poderá ser declarado.

Na sequência, vamos ver a declaração de um registro. Assim como toda variável, ao declarar uma variável que é um registro, precisamos dizer que tipo de dado o registro armazena. Neste caso, iremos dizer que o registro é do tipo de dado que acabamos de definir no typedef. A sintaxe é a seguinte:

Sintaxe

nome_do_tipo nome_do_registro;

Onde:

• nome_do_tipo: é o nome do tipo de dado que definimos no nosso programa, formado pelo agrupamento de várias variáveis.

• nome_do_registro: é o nome da variável registro que está sendo declarada. O nome de um registro segue as regras dos identificadores.

O exemplo 2.1 apresenta a declaração do registro do boletim do aluno:

Page 218: Programação 2 Linguagem C (UFRPE)

38

Programação 2

Exemplo2.1:Definiçãodetipoedeclaraçãoderegistro

1

2

3

4

5

typedef struct { int matricula;

char nome[20], disciplina[20],

situação[10];

float media;

} Tipo_Aluno;

Tipo_Aluno aluno;

Primeiramente, entre as linhas 1 e 4, foi definido o conjunto de variáveis que fazem parte do registro. É nesta parte que está sendo definido um novo tipo de dado.

• Linha 1: com o typedef estamos informando que será definido um novo tipo de dado. O struct indica que este tipo é um agrupamento de variáveis de tipos diferentes, ou seja, um registro. Colocamos o abre chaves e começamos a declarar as variáveis que irão compor o registro. Começamos com a declaração da variável inteira matricula. Se houvesse mais variáveis do tipo int, poderiam ser declaradas nesta mesma linha.

• Linha 2: declaração das variáveis do tipo char: nome, disciplina e situacao.

• Linha 3: declaração da variável media que é do tipo float.

• Linha 4: Após a declaração de todas as variáveis que compõe o registro, podemos fechar a chaves e, em seguida, dar um nome a esse tipo de agrupamento, que acabamos de definir. Neste caso, o tipo foi chamado de Tipo_Aluno. Ao definirmos um tipo de dado no nosso programa, significa que: podemos declarar variáveis dos tipos de dados primitivos (int, float, char, etc), além de variáveis do tipo de dado que nós definimos, neste caso, Tipo_Aluno.

• Linha 5: declaração de uma variável chamada aluno, e o tipo de dado que ela armazena é Tipo_Aluno, ou seja, armazena: matricula, nome, disciplina, situacao e media.

A figura 2.2 mostra a representação gráfica da variável aluno, que é do tipo Tipo_Aluno.

Page 219: Programação 2 Linguagem C (UFRPE)

39

Programação 2

matricula

nome

disciplina

situacao

media

aluno

Figura 2.2: Representação gráfica do registro aluno

Notem que, a variável aluno (que é um registro) é formada pelos campos definidos no Tipo_Aluno.

Como uma variável registro é formada por vários campos, precisamos utilizar uma forma diferenciada para informar qual campo do registro nós estamos querendo acessar. Lembram dos vetores, que precisávamos dizer qual elemento do vetor seria acessado? Com os registros vai acontecer algo parecido. Mas isto, nós vamos aprender na próxima seção.

2.3 Acessando os campos do registro

De acordo com a figura 2.2, a variável aluno é um registro formado por vários campos. Para acessar um campo de um registro, devemos usar a seguinte sintaxe:

Sintaxe

nome_do_registro.campo

Onde:

• nome_do_registro: é o nome da variável registro que queremos acessar.

• Após o nome_do_registro devemos colocar um ponto, que irá separar o nome do registro, do campo que vem logo em seguida.

• campo: é o campo do registro que será acessado.

Page 220: Programação 2 Linguagem C (UFRPE)

40

Programação 2

Pensem da seguinte forma: suponham que queremos acessar o registro aluno, do exemplo 2.1. Ao acessarmos esta variável, ela possui vários campos. Precisamos dizer qual deles será acessado no momento. A seguir, são apresentados exemplos de acesso aos campos do registro aluno. Ao acessar um campo do registro, podemos atribuir valores, como mostra o exemplo 2.2.

Exemplo 2.2: Acesso aos campos de um registro

1

2

3

4

aluno.matricula = 12345;

scanf(“%f”, &aluno.media);

gets(aluno.nome);

printf(“Situacao do aluno: %s”, aluno.situacao);

Na linha 1, estamos acessando o campo matricula do registro aluno. Assim, colocamos o nome do registro, o ponto e o campo que queremos acessar. Com acesso ao campo, fizemos uma atribuição4.

Na linha 2, estamos acessando o campo media do registro aluno. Neste caso, ao invés de atribuir um valor ao campo de registro, estamos fazendo uma leitura via teclado e armazenando o valor digitado no campo media. Como o campo media é do tipo float, colocamos o %f no scanf, indicando que será lido um número real.

Na linha 3, temos o comando de leitura gets, responsável por ler variáveis do tipo char. Neste gets, estamos fazendo uma leitura via teclado e armazenando o valor digitado no campo nome do registro aluno.

Na linha 4, temos um printf que apresenta a situação do aluno. Para isso, acessamos o campo situacao do registro aluno.

Notem que, se tivermos vários alunos em uma turma, precisaremos de várias variáveis registro do tipo Tipo_Aluno, uma para cada aluno. Para fazer isso de forma mais simplificada, devemos juntar os conceitos de vetores e registros e criar um vetor de registro. Vamos aprender como faz isto?

2.4 Vetor de registro

Os vetores são formados por um conjunto de dados do mesmo tipo. No capítulo anterior, utilizamos vetores que armazenavam dados

Saiba Mais

4 O ponto que aparece neste comando, deve ser lido como “campo”. Assim, a leitura do comando da linha 1 seria: aluno no campo matricula recebe 12345.

Page 221: Programação 2 Linguagem C (UFRPE)

41

Programação 2

de tipos primitivos, ou seja, tipos disponíveis na linguagem – int, float, char, etc. Veremos que podemos utilizar como elemento do vetor não apenas um tipo primitivo, mas também os tipos construídos (tipos definido pelo programador), neste caso, os registros. Imaginem que queremos armazenar os boletins dos 50 alunos de uma turma. Para isso, será necessário um registro diferente para cada aluno. Para agrupar todos estes registros, iremos definir um vetor de registro. Como possuímos 50 alunos, podemos criar um vetor no qual cada posição, armazena um Tipo_Aluno.

Para declarar um vetor de registro, precisamos antes definir os elementos do registro, utilizando o typedef struct, e assim, definir um novo tipo de dado que será utilizado no programa. Após definirmos o novo tipo de dado, o vetor poderá ser declarado. Para declararmos um vetor, precisamos informar o tipo de dado que o vetor armazena, damos um nome ao vetor e informamos, entre colchetes, o tamanho do vetor. O exemplo 2.3 apresenta a declaração do vetor de registro alunos:

Exemplo2.3:definiçãodoregistroedeclaraçãodovetorderegistro

1

2

3

4

5

typedef struct { int matricula;

char nome[20], disciplina[20],

situação[10];

float media;

}Tipo_Aluno;

Tipo_Aluno alunos[50];

Neste exemplo, cada uma das 50 posições do vetor alunos irá armazenar todos os dados que compõe o Tipo_Aluno, ou seja: matricula, nome, disciplina, situacao e media. A figura 2.3, a seguir, representa o vetor de registro declarado no exemplo.

alunos

matricula nome disciplina media situacao

matricula nome disciplina media situacao

matricula nome disciplina media situacao

matricula nome disciplina media situacao

0 1 ... 48 49

Figura 2.3: Representação gráfica do vetor de registro aluno

Page 222: Programação 2 Linguagem C (UFRPE)

42

Programação 2

Se apenas com os vetores, já havíamos adquirido uma facilidade na declaração e manipulação de um grande conjunto de variáveis, com os vetores de registros, esta facilidade será aumentada.

Vamos aprender, na próxima seção, como acessamos um campo de um vetor de registro.

2.5 Acessando os campos do vetor de registro

Quando precisamos acessar um elemento do vetor, informamos, entre colchetes, o índice do elemento do vetor que será acessado. Quando queremos acessar um campo do registro, informamos o nome da variável registro, colocamos um ponto e o nome do campo que queremos acessar. Já no caso de um vetor de registro, temos que usar a seguinte sintaxe:

Sintaxe

nome_do_vetor[indice].campo

Onde:

nome_do_vetor: nome do vetor que queremos acessar.

[índice]: índice do vetor que será acessado.

.campo: campo do registro que será acessado.

O exemplo 2.4 apresenta acessos a campos do vetor de registro alunos.

Exemplo 2.4: Acesso aos elementos de um vetor de registro

1

2

3

4

alunos[2].media = 7.5;

alunos[3].matricula = 12345;

gets(alunos[0].nome);

scanf(“%d”,&alunos[2].matricula);

Na linha 1, acessamos o elemento de índice 2 do vetor alunos e atribuímos 7.5 ao campo media. Na linha 2, acessamos o elemento de índice 3 do vetor alunos e atribuímos 12345 ao campo matricula.

Nas linhas 3 e 4, temos acessos através de comandos de entrada

Page 223: Programação 2 Linguagem C (UFRPE)

43

Programação 2

de dados. Na linha 3, temos um gets, que obtém o nome do aluno, via teclado, e armazena no índice 0 do vetor alunos, no campo nome. Na linha 4, temos o scanf que lê a matrícula do aluno, armazenando no índice 2 do vetor alunos, no campo matricula.

2.6 Usando vetor de registro

Vamos fazer um programa completo usando vetor de registro? Este programa será um pouco maior do que os outros programas que já fizemos, e apresentará uma gama de coisas novas. Além do uso de vetor de registro, aprenderemos a mostrar os dados do vetor de registro em forma de tabela. Vamos começar?

Primeiramente, vamos ler e entender o enunciado do Programa Completo 2.1: Faça um programa que cadastre e apresente os dados dos alunos de uma escola. Os dados dos alunos devem ser armazenados em um vetor de registro, com a capacidade de armazenar até 20 alunos. A quantidade de alunos que será cadastrada é desconhecida. No momento do cadastro serão informados os seguintes dados para cada aluno: matrícula, nome, série(1-4) e se tem irmão na escola (1-sim/0-nao). O programa irá calcular o valor da mensalidade do aluno, que depende da série do aluno e se o mesmo tem irmão na escola. Valor da Mensalidade: 1ª Serie: R$110, 2ª Serie: R$130, 3ª Serie: R$160, 4ª Serie: R$170. O aluno que tiver irmão na escola, receberá 20% de desconto no valor da mensalidade. Quando o usuário decidir que não deseja mais cadastrar, o programa apresentará os dados de todos os alunos, em forma de tabela. Para facilitar o entendimento deste enunciado, vejam os exemplos das telas que são apresentadas durante a execução do programa:

Colégio Legal

Cadastro de Aluno

Matricula..: Nome.......: Serie(1-4): Irmao na escola (1-sim/0-nao):

Cadastrar outro aluno (1-sim/0-nao)?

Page 224: Programação 2 Linguagem C (UFRPE)

44

Programação 2

Colégio Legal

Relatório Geral

Matricula Nome Serie Irmao Mensalidade

xx xxxxx x x xx.xx

xx xxxxx x x xx.xx

xx xxxxx x x xx.xx

xx xxxxx x x xx.xx

xx xxxxx x x xx.xx

Tecle enter para sair...

Figura 2.4:Exemplos de telas do programa completo 2.1

A primeira tela representa a operação de cadastramento dos dados dos alunos. Nesta tela, é que serão fornecidos os dados para o cadastramento dos alunos. Como a mensalidade é um dado calculado pelo programa, o usuário não fornecerá este dado no momento do cadastro.

A segunda tela representa a apresentação dos dados de todos os alunos, em forma de tabela (listagem ou relatório). Cada linha da tabela apresentará os dados de um aluno.

Como precisamos armazenar os vários dados de cada um dos alunos da escola, se faz necessário o uso de um vetor de registro.Segue o código do programa completo 2.1, que será comentado posteriormente.

Page 225: Programação 2 Linguagem C (UFRPE)

45

Programação 2

Programa Completo 2.1

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

#include <stdio.h>

main()

{ typedef struct{ int mat, serie, irmao;

char nome[20];

float mens;

} Tipo_Aluno;

Tipo_Aluno alunos[20];

int qa, i, resp;

qa =0;

do

{ system(“cls”);

printf(“Colegio Legal\n”);

printf(“\n\nCadastro de Alunos\n\n”);

printf(“\nMatricula.: “);

scanf(“%d”,&alunos[qa].mat);

printf(“\nNome......: “);

fflush(stdin);

gets(alunos[qa].nome);

printf(“\nSerie(1-4): “);

scanf(“%d”,&alunos[qa].serie);

printf(“\nIrmao na escola(1-sim/0-nao):

“);

scanf(“%d”,&alunos[qa].irmao);

switch(alunos[qa].serie)

24

25

26

27

28

{ case 1: alunos[qa].mens = 110; break;

case 2: alunos[qa].mens = 130; break;

case 3: alunos[qa].mens = 160; break;

case 4: alunos[qa].mens = 170; break;

}

Page 226: Programação 2 Linguagem C (UFRPE)

46

Programação 2

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

if (alunos[qa].irmao == 1)

alunos[qa].mens = alunos[qa].mens*0.8;

qa++;

printf(“\n\nDeseja cadastrar outro aluno(1-

sim/0-nao)? “);

scanf(“%d”,&resp);

}while ((resp == 1) && (qa <20));

system(“cls”);

printf(“Colegio Legal\n”);

printf(“\n\nRelatorio Geral\n”);

printf(“\n________________________________”);

printf(“\nMatricula Nome Serie Irmao

Mensalidade”);

printf(“\n________________________________”);

for(i = 0; i < qa; i++)

printf(“\n%9d %-20s %5d %5d %11.2f”,

alunos[i].mat, alunos[i].nome, alunos[i].serie,

alunos[i].irmao, alunos[i].mens);

printf(“\n_______________________________”);

printf(“\nTecle enter para sair...”);

getche();

}

Comentários sobre o Programa Completo 2.1

• Linha1: inclusão da biblioteca stdio.h devido o uso do comando fflush.

• Linha2: início do programa principal.

• Linhas 3 a 6: definição de um novo tipo de dado, que será chamado de Tipo_Aluno. O Tipo_Aluno é formado pelos dados dos alunos: mat (matrícula), nome, serie, irmao (indica se tem irmão na escola) e mens (mensalidade).

• Linha7: declaração do vetor de registro alunos, com capacidade de armazenar 20 elementos do Tipo_Aluno.

Page 227: Programação 2 Linguagem C (UFRPE)

47

Programação 2

• Linha 8: declaração das variáveis qa (que irá controlar a quantidade de alunos cadastrados no vetor), i (utilizada como variável de controle do for) e resp (utilizada para saber se o usuário deseja continuar cadastrando novos alunos).

• Linha9: inicialização da variável qa com 0;

• Linhas 10 a 34: repetição do tipo do/while que irá controlar o cadastro dos dados dos alunos no vetor de registro. Este do/while irá parar a sua execução se o vetor ficar cheio (20 elementos) ou se o usuário não quiser mais cadastrar.

• Linha11: Cada vez que o do/while é executado, queremos que a tela seja limpa. Para isso, usamos o system(“cls”). Esta linha tem, também, o abre chaves que indica o início da sequência de comandos do do/while.

• Linhas12e13: printf para indicar o nome do colégio (Colégio Legal) e para indicar o que está sendo feito nesta tela (Cadastro de Alunos).

• Linhas14e15: printf informando que o usuário deve digitar a matrícula do aluno e scanf que obtêm a matrícula do aluno, armazenado-a no vetor de registro alunos, na posição qa e no campo mat. Notem que a variável qa iniciou com 0. Na primeira vez que o do/while for executado, os dados dos alunos serão armazenados na posição 0 do vetor. A cada vez que a repetição é executada, a variável qa é incrementada de uma unidade. Assim, os dados de cada aluno serão armazenados em uma posição, diferente, no vetor de registro.

• Linhas16a18: printf informando que o usuário deve digitar o nome do aluno. fflush para limpar o buffer e, em seguida, o gets responsável por ler o nome do aluno, armazenando no vetor de registro alunos, na posição qa e no campo nome.

• Linhas19e20: printf informando que o usuário deve digitar a série do aluno (que pode ser de 1 a 4). scanf responsável por ler a série do aluno, armazenando no vetor de registro alunos, na posição qa e no campo serie.

• Linhas21e22: printf informando que o usuário deve digitar se o aluno tem irmão na escola (digitar 1 se tiver irmão e 0 se não tiver irmão na escola). scanf responsável por ler se o aluno tem irmão na escola, armazenando no vetor de registro alunos, na

Page 228: Programação 2 Linguagem C (UFRPE)

48

Programação 2

posição qa e no campo irmao.

• Linhas23a28: depois de obter todos os dados de um aluno, o programa vai calcular o valor da mensalidade do aluno, verificando a série e se tem irmão na escola. Como cada uma das séries da escola tem um valor diferente de mensalidade, este switch serve para verificar em que série o aluno está matriculado, para atribuir ao campo mens do registro do aluno, o valor da mensalidade correspondente a sua série.

• Linhas29e30: if para verificar se o aluno tem irmão na escola. De acordo com o enunciado, os alunos que tem irmão na escola, recebem uma desconto de 20% na sua mensalidade. Como o if só tem um comando, não foi necessário o uso de chaves.

• Linha 31: neste momento, todo o registro do aluno já foi preenchido. Com isso, fazemos o incremento da variável qa, informando que mais um aluno acabou de ser cadastrado.

• Linhas 32 e 33: printf que pergunta se o usuário deseja continuar cadastrando novos alunos. scanf para ler a resposta do usuário (1 se ele deseja continuar cadastrando e 0 se deseja parar).

• Linha34: fechamento do do/while com a condição que faz a repetição parar. Como mencionado anteriormente, este do/while fica em execução enquanto tem posições disponíveis no vetor ou enquanto o usuário desejar. Nesta linha, termina a fase de cadastramento dos dados dos alunos no vetor de registro.

• Linhas 35 a 47: Esta sequência de comando serve para apresentar os dados dos alunos que foram armazenados no vetor de registro. Por uma questão de organização, estes dados serão apresentados na forma de tabela. Assim, cada linha da tabela corresponderá aos dados de um aluno, ou seja, uma posição do vetor de registro. Para que a tabela fique alinhada, precisamos saber que: a tela tem 80 colunas por 25 linhas. Dessa forma, temos que distribuir as informações de um jeito que não extrapole as 80 colunas da tela. Para entender melhor esta parte do programa, acompanhem os comandos, observando a figura 2.9 (tela de execução do programa).

• Linha35: limpa a tela para darmos início à apresentação dos dados de todos os alunos.

Page 229: Programação 2 Linguagem C (UFRPE)

49

Programação 2

• Linhas36e37: printf para informar o nome do colégio e para informar o que esta tela faz (Relatório Geral).

• Linha38: printf para passar uma linha na tela. Esta linha vai delimitar o cabeçalho da tabela.

• Linha 39: printf que imprime os títulos de cada coluna da tabela. A tabela será composta pelas seguintes colunas: Matricula, Nome, Serie, Irmao e Mensalidade. Os títulos que devemos dar as colunas da tabela são sempre indicados nos enunciados das questões, certo? Sigam esta dica, porque vocês estão começando a aprender a fazer tabelas agora. Este printf é cheio de detalhes, mas vamos ver isso agora, observando a figura 2.5. O resultado deste printf é a linha que está indicada com a seta.

Figura 2.5: Apresentação dos dados em forma de tabela

• Vamos ver quais são os passos para montar o printf da linha 39 (cabeçalhos/títulos das colunas da tabela).

» Para cada coluna da tabela, verifiquem quantas letras tem no seu cabeçalho. Por exemplo, a palavra matrícula, tem 9 letras. Vejam que, na figura 2.5, tem a indicação de quantas letras tem em cada um dos cabeçalhos. A quantidade de letras que tiver o cabeçalho, será a largura da coluna.

» Agora, precisamos verificar se os dados dos alunos vão extrapolar a largura de cada uma das colunas da tabela. Vamos ver uma por uma:

√ Matricula: a coluna que será utilizada para apresentar a matrícula, tem uma largura de 9 espaços (quantidade de letras da palavra matrícula). Vamos considerar que nossas matrículas tem sempre menos que 9 dígitos.

Page 230: Programação 2 Linguagem C (UFRPE)

50

Programação 2

Assim, a largura de 9 espaços para esta coluna, é suficiente.

√ Nome: a palavra nome só tem 4 letras. Vejam que o nome do aluno foi declarado com 20 letras. Assim, se deixarmos a coluna Nome, com largura 4, não será suficiente para apresentar os nomes dos alunos. Quando a quantidade de letras do cabeçalho é menor que o conteúdo que vem na coluna da tabela, devemos completar a coluna com espaços em branco até fazer com que a coluna tenha a largura que precisamos.

√ Série: tem 5 letras. A série do aluno varia entre 1 e 4, dessa forma, a largura da coluna Serie (5 espaços), será suficiente para apresentar o dado.

√ Irmão: também tem 5 letras. A variável que armazena se o aluno tem ou não irmão na escola, varia entre 0 e 1, dessa forma, a largura da coluna Irmao (5 espaços), será suficiente para apresentar o dado.

√ Mensalidade: tem 11 letras. Esta largura é suficiente para apresentar o valor da mensalidade do aluno.

» Agora que já sabemos que apenas a coluna Nome não tem largura suficiente para apresentar os nomes dos alunos, vamos ver quantos espaços em branco nós temos que colocar depois da palavra Nome, para que esta coluna tenha a largura que precisamos. Se o nome do aluno tem até 20 letras e a palavra Nome tem apenas 4 letras, faremos a seguinte conta: 20 – 4 = 16. Assim, depois da palavra Nome, temos que colocar 16 espaços em branco, para que a nossa coluna passe a ter a largura que precisamos (20).

» Por fim, temos que definir um espaçamento para separar uma coluna da outra. Nos nossos exemplos, vamos usar sempre três espaços separando uma coluna da outra. A padronização do espaçamento entre as colunas visa facilitar a programação, já que estamos vendo este assunto agora e o mesmo é cheio de detalhes.

» Agora vamos montar o printf, vejam a figura 2.6. Nós vamos colocando os títulos das colunas da tabela, e entre cada palavra, vamos colocando três espaços em branco,

Page 231: Programação 2 Linguagem C (UFRPE)

51

Programação 2

que foi o espaçamento definido para separar as colunas. Só no caso da coluna nome, que depois que colocamos Nome, devemos dar os 16 espaços em branco para que ela passe a ser uma coluna de largura 20. Mas ainda teríamos que dar mais 3 espaços em branco, que é para separar a coluna nome, da coluna serie.

Figura 2.6: Detalhamento do printf da linha 39

» O printf está pronto! A primeira vista, parece complicado, mas depois vocês estarão fazendo a tabela bem rápido.

• Linha40: printf para passar uma linha na tela. Esta linha vai delimitar o cabeçalho da tabela.

• Linha 41: for para visitar cada uma das posições do vetor e apresentar os dados dos alunos. A variável de controle do for, o i, vai variar de 0 até a ultima posição ocupada do vetor. A variável que tem esta informação é o qa.

• Linha 42: este printf é que vai fazer a montagem das linhas da tabela, apresentado os dados dos alunos que estão armazenados no vetor de registro. Este printf também tem macetes, pois está relacionado com o printf da linha 39. Vamos lá! Lembram que fizemos a contagem para saber a largura de cada coluna da tabela? Vamos precisar desta informação agora.

» Na primeira parte do printf, temos a string de controle (a figura 2.7 faz o detalhamento dessa parte do printf). Sabemos que as colunas da tabela são: matricula( número inteiro e esta coluna deve ter largura 9), nome (vetor de caracteres com até 20 letras), serie (número inteiro e esta coluna tem largura 5), irmão (número inteiro e esta coluna tem largura 5) e mensalidade (número real e esta coluna tem largura 11). Além disso, sabemos que entre cada coluna, nós colocamos três espaços em branco. Com estas informações, vamos montar a string de controle do printf da

Page 232: Programação 2 Linguagem C (UFRPE)

52

Programação 2

linha 42.

Figura 2.7: Detalhamento do printf da linha 42

» Entre o % e a letra que indica o que vai ser impresso (%d, %s ou %f), devemos colocar a largura da coluna. A primeira coluna da tabela é a da matricula, que é um número inteiro e que tem largura 9. Por isso, temos o %9d. Após cada uma das formatações, colocamos três espaços em branco, já que foi o espaçamento definido entre as colunas da tabela. No caso da variável caractere nome do aluno (que é a segunda coluna da tabela) colocamos %-20s (o – é para que o nome do aluno seja alinhado pela esquerda). Nas demais formatações não precisamos colocar o -, só utilizamos em campos caractere.

» Após a string de controle, colocamos as variáveis que serão apresentadas na tela, na ordem em que as colunas foram definidas.

• Linha43: printf para passar uma linha na tela. Esta linha vai fechar a tabela.

• Linha 44: printf que informa que o usuário deve teclar enter para sair.

• Linha 45: getche() que evita que a tela de execução feche antes de vermos os resultados.

• Linha46: fecha chaves do programa principal.

A figura 2.8 apresenta a tela de execução do programa 2.1, na fase do cadastramento dos alunos.

Page 233: Programação 2 Linguagem C (UFRPE)

53

Programação 2

Figura 2.8: Tela de execução do programa completo 2.1 - Cadastro

A figura 2.9 apresenta a tela de execução do programa 2.1, na fase do apresentação dos dados de todos os alunos cadastrados, em forma de tabela.

Figura 2.9: Tela de execução do programa completo 2.1 – Relatório Geral

Viram como esta questão é cheia de detalhes? Mas não se assustem, a explicação precisava ser minuciosa, para que cada linha do programa fosse entendida. Agora precisamos treinar esse tipo de questão. Não percam tempo!

Atividades e Orientações de Estudos

Vamos resolver mais uma lista de exercícios? Esta lista é composta por questões em que se faz necessário o uso de vetor de registro. DICA: sempre coloque as tabelas com os mesmos cabeçalhos propostos nos enunciados (exemplos de telas). Mãos a obra!

1. Uma empresa de turismo deseja um programa que calcule o valor das viagens dos clientes. Serão informados os seguintes

Page 234: Programação 2 Linguagem C (UFRPE)

54

Programação 2

dados: código do cliente, nome, roteiro desejado(1-Brasil, 2-EUA, 3-África), tipo de quarto (1-Standard, 2-Luxo), Se deseja alugar carro(1-sim/0-nao) e a quantidade de dias. A quantidade de clientes é desconhecida. O programa irá calcular o total da viagem usando os valores da tabela abaixo, que variam de acordo com o roteiro escolhido. A diária do quarto de luxo é R$30 mais cara que o valor da diária em um quarto standard. Exemplo: Se a pessoa escolher roteiro 2, em quarto de luxo, a diária irá custar: 320 + 30 = R$ 350.

Roteiro Diária – Hotel Quarto Standard

Diária - Aluguel de carro

1 R$ 170 R$ 50

2 R$ 350 R$ 60

3 R$ 370 R$ 75

Total da Viagem: dias*diáriahotel + dias*diariacarro(se o cliente for alugar carro)

Armazenar os dados em um vetor de registro. Imprimir os dados em forma de tabela. Exemplo das telas:

Viagem Legal – Turismo

Cadastro de Cliente

Codigo: Nome: Roteiro (1-Brasil, 2-EUA, 3-África): Tipo de Quarto (1- Standard, 2-Luxo): Alugar Carro (1-sim/0-nao)? Quantidade de Dias:

Inserir outro (1-sim,0-nao)?

Viagem Legal – Turismo

Relatório Geral

Código Nome Roteiro Quarto Carro Dias Total

xx xxxxx x x x xx xx.xx

xx xxxxx x x x xx xx.xx

xx xxxxx x x x xx xx.xx

Tecle enter para sair...

Page 235: Programação 2 Linguagem C (UFRPE)

55

Programação 2

2. Faça um programa para montar a folha de pagamento dos empregados de uma empresa. Para cada empregado serão lidos os seguintes dados: matricula, nome, cargo(1-Analista de Sistemas/2- programador), sexo(1-mas/2-fem), anos de experiência e quantidade de filhos. O programa irá calcular para cada empregado o seu salário. Sabe-se que:

Cargo Salário Base

1 R$ 2500

2 R$ 1700

O salário será calculado da seguinte forma: Cada cargo tem o salário base. Além do salário base, o empregado recebe os seguintes adicionais: R$ 50, para cada ano de experiência e R$ 40 por cada filho. Portanto, um analista de sistemas com três anos de experiência e dois filhos terá o salário = 2500 + 50*3 + 40*2 = R$ 2730.

Armazenar as informações em um vetor de registros. Imprimir o relatório geral em forma de tabela contendo os dados de cada empregado. A quantidade de empregados da empresa é desconhecida (declarar o vetor com capacidade de armazenar 20 funcionários). Exemplos das telas:

Empresa Legal

Cadastro de Funcionario

Matricula: Nome: Cargo(1-Analista de Sistemas, 2- programador): Sexo(1-mas/2-fem): Anos de experiência: Quantidade de filhos:

Cadastrar outro (1-sim/2-nao)?

Page 236: Programação 2 Linguagem C (UFRPE)

56

Programação 2

Empresa Legal

Listagem Geral

Matricula Nome Cargo Sexo Anos Q. Filho Salário

xx xxxxx x x xx x xxx.xx

xx xxxxx x x xx x xxx.xx

xx xxxxx x x xx x xxx.xx

xx xxxxx x x xx x xxx.xx

Tecle enter para sair...

3. Faça um programa para uma empresa de celular contendo as seguintes operações: cadastro de clientes e listagem geral. Para cada cliente devemos armazenar: código, nome, sexo (1-feminimo/2-masculino), quantidade de ligações, plano que o cliente está associado (1-Dia/2-Noite/3-Fixo/4-Empresarial) e Valor da conta. O programa irá calcular o valor da conta de cada cliente. Sabe-se que, cada plano tem uma tarifa diferenciada, segundo a tabela abaixo:

Plano Valor de 1 ligação

Dia 1.30

Noite 1.60

Fixo 1.25

Empresarial 1.10

Armazenar os dados em um vetor de registro. Após o cadastro dos clientes, apresentar a listagem com os dados de todos os clientes, em forma de tabela. A quantidade de clientes é desconhecida. Declare o vetor com capacidade de receber até 50 clientes.

Exemplos das telas:

Page 237: Programação 2 Linguagem C (UFRPE)

57

Programação 2

Ligue Mais

Cadastro de Cliente

Código: Nome: Sexo(1-fem/2-mas): Quantidade de Ligações: Plano(1-Dia/2-Noite/3-Fixo/4-Empresarial):

Cadastrar outro (1-sim/0-nao)?

Ligue Mais

Listagem Geral

Codigo Nome Sexo Quant. Lig. Plano Total

xx xxxxx x xx x xxx.xx

xx xxxxx x xx x xxx.xx

xx xxxxx x xx x xxx.xx

xx xxxxx x xx x xxx.xx

Tecle enter para sair...

4. Um professor quer um programa para o cálculo da média dos alunos de uma turma. Serão informadas a matrícula, nome (20 caracteres), e as três notas dos alunos. O professor descarta a menor nota do aluno e a media é calculada com as duas maiores notas. Calcular a média e apresentar os resultados em forma de tabela, após o cadastramento. Armazenar os dados em um vetor de registro. A quantidade de alunos é desconhecida, declare o vetor com capacidade de receber até 20 alunos.

Exemplos das Telas:

Universidade Legal

Cadastro de aluno

Matricula: Nome: Nota 1: Nota 2: Nota 3:

Cadastraroutro (1-sim/0-nao)?

Page 238: Programação 2 Linguagem C (UFRPE)

58

Programação 2

Universidade Legal

Relatório Geral

Matricula Nota1 Nota2 Nota3 Media

x xxxxxxxxx x.x x.x x.x x.x

x xxxxxxxxx x.x x.x x.x x.x

x xxxxxxxxx x.x x.x x.x x.x

x xxxxxxxxx x.x x.x x.x x.x

Tecle enter para sair...

5. O MEC quer um programa para fazer um relatório sobre os pólos de educação a distância da UFRPE. Para cada pólo são informados os seguintes dados: código do pólo, cidade, total de alunos, total de tutores, se possui laboratório de informática (1-sim/0-não) e se possui laboratório de ciências (1-sim/0-não). O MEC quer saber quanto deve ser liberado de verba para cada pólo. O calculo será feito da seguinte forma:

• Por cada aluno são liberados: R$ 100

• Por cada tutor são liberados: R$ 500

• Se o pólo tem não tem laboratório de informática são liberados: R$ 20.000

• Se o pólo não tem laboratório de ciências são liberados: R$ 17.000

Ex: um pólo com 150 alunos, com 15 tutores, que tem laboratório de informática, mas não tem laboratório de ciências: Verba = 100 x 150 + 500 x 15 + 17000 = 15000 + 7500 + 17000 = 39500.

Armazenar os dados dos pólos em um vetor de registro. A quantidade de pólos é desconhecida. Declarar o vetor com a capacidade de armazenar até 20 pólos. Após o cadastros dos pólos, apresentar todos os dados dos pólos em forma de tabela.

Exemplos das telas:

Page 239: Programação 2 Linguagem C (UFRPE)

59

Programação 2

Ministério da Educação

Cadastro de Polo

Codigo: Cidade: Quantidade de alunos: Quantidade de tutores: Tem lab. de informatica (1-sim/0-nao)? Tem lab. de ciencias (1-sim/0-nao)?

Cadastrar outro pólo (1-sim,0-nao)?

Ministério da Educação

Listagem Geral

Codigo Cidade Alunos Tutores LI LC Verba Liberada

xx xxxxx xxx xxx x x xxxxx.xx

xx xxxxx xxx xxx x x xxxxx.xx

xx xxxxx xxx xxx x x xxxxx.xx

xx xxxxx xxx xxx x x xxxxx.xx

Tecle enter para sair...

Conheça Mais

Vocês poderão aprender mais sobre registros e vetores de registros lendo os livros:

MONTGOMERY, Eduard. Programando em C: Simples e Prático. São Paulo: Alta Books, 2006.

SCHILDT, Herbert. C Completo e Total. São Paulo: Makron, 1996.

Vamos Revisar?

Nesta seção iremos revisar os principais tópicos vistos neste

Page 240: Programação 2 Linguagem C (UFRPE)

60

Programação 2

capítulo. Vale a pena dar uma lida para verificar como está o nosso aprendizado. Observem o resumo a seguir:

Os registros são um agrupamento de variáveis de tipos diferentes, mas que tem uma relação lógica.

Por ser formado por elementos de diferentes tipos, os registros são chamados de estruturas de dados heterogêneas.

Para declarar uma variável registro, precisamos definir um novo tipo de dado para o programa, utilizando o typedef.

Cada elemento do registro é chamado de campo.

Unindo os conceitos de vetores e de registros, temos os vetores de registro que facilitam a declaração e o manuseio de grandes volumes de dados.

Page 241: Programação 2 Linguagem C (UFRPE)

61

Programação 2

Capítulo 3 – Armazenamento de Dados em Arquivos

Vamos conversar sobre o assunto?

Neste capítulo, vamos aprender a armazenar nossos dados de forma definitiva. Até então, ao terminar a execução de um programa, todos os dados que foram armazenados nas variáveis eram perdidos. Em muitas aplicações isto não pode acontecer. Por exemplo, um professor precisa ter certeza de que todo o trabalho para digitar as notas dos alunos da turma não será perdido quando ele fechar o programa. Com os arquivos, poderemos armazenar os dados e recuperá-los quando necessário. Este capítulo abordará os comandos que nos possibilitarão manipular dados armazenados em um arquivo. Vamos começar?

3.1 O que são arquivos?

Os arquivos são estruturas de dados manipuladas fora do ambiente do programa. Considera-se como ambiente do programa a memória principal, onde nem sempre é conveniente manter certas estruturas de dados. De modo geral, os arquivos são armazenados na memória secundária, como, por exemplo: disco rígido (HD), CD e pendrive.

3.1.1. Como os arquivos são organizados?

A linguagem C utiliza o conceito de fluxo de dados (stream) para manipular os vários tipos de dispositivos de armazenamento e seus diferentes formatos. Os dados podem ser manipulados em dois diferentes tipos de fluxos: fluxos de texto e fluxos binários.

Um fluxo de texto (text stream) é composto por uma sequência de caracteres, que pode ou não ser dividida em linhas, terminadas por um caractere de final de linha. Um fluxo binário (binary stream) é composto por uma sequência de bytes, que são lidos, sem tradução, diretamente do dispositivo externo. A Figura 3.1 ilustra estes dois tipos de fluxos.

Page 242: Programação 2 Linguagem C (UFRPE)

62

Programação 2

Figura 3.1: Fluxo de dados

No fluxo de texto, os dados são armazenados como caracteres sem conversão para a representação binária. Cada um dos caracteres ocupa um byte. O número 12 ocupa dois bytes e o número 113 ocupa 3 bytes. Um caractere em branco foi inserido entre cada um dos números para separá-los, de modo que a função de entrada e saída possa descobrir que são dois números inteiros (12 e 113) e não o número 12113. No fluxo binário, cada número inteiro ocupa 32 bits (4 bytes) e é armazenado na forma binária. Observem que, em arquivos binários, não há necessidade de separar os números já que eles sempre ocupam 32 bits.

Os arquivos binários são utilizados quando queremos armazenar registros completos. Com estes arquivos, poderemos acessar qualquer registro de forma mais rápida. No caso dos arquivos texto, quando queremos encontrar alguma informação, temos que fazer uma varredura sequencial no arquivo, tornando a busca pouco eficiente.

Neste capítulo, será dada ênfase ao armazenamento de dados em arquivos binários. Nas próximas seções, iremos conhecer os comandos para manipular este tipo de arquivo.

3.1.2 Ponteiros

Antes de começarmos a conhecer os comandos de manipulação de arquivos binários, vamos ver um conceito que será utilizado neste capítulo, que é: ponteiro. Um ponteiro é um tipo de variável que armazena um endereço de memória. Nós já vimos variáveis que armazenam números inteiros, números reais e caracteres. Ao trabalhar com arquivos, precisamos saber em qual endereço de memória o arquivo está armazenado. O endereço de memória onde o arquivo

Page 243: Programação 2 Linguagem C (UFRPE)

63

Programação 2

está armazenado será colocado em uma variável que armazena endereço de memória (ponteiro).

Para declarar uma variável que é capaz de armazenar um endereço de memória, usamos a seguinte sintaxe:

Sintaxe

tipo *nome_do_ponteiro;

Onde:

• tipo: tipo de variável que o ponteiro armazena endereço. Podemos dizer que nosso ponteiro armazena o endereço de uma variável inteira, real, caractere, etc. Para este capítulo, estaremos utilizando um ponteiro que vai armazenar o endereço de um arquivo.

• *: o asterisco na frente do nome de uma variável simboliza que a variável que está sendo declarada é um ponteiro.

• nome_do_ponteiro: daremos um nome à nossa variável que armazena endereços.

O exemplo 3.1 apresenta exemplos de declarações de ponteiros que armazenam endereços de memória de arquivos.

Exemplo 3.1: Declaração de ponteiros para arquivos

1

2

FILE *p aluno;

FILE *p produto;

Na linha 1, temos a declaração do ponteiro paluno, que irá armazenar o endereço de um arquivo (FILE). Devemos colocar o FILE em maiúsculo. Na linha 2, temos a declaração de outro ponteiro, pproduto, que armazena o endereço de um FILE.

Quando queremos inicializar uma variável real ou inteira, atribuímos zero às mesmas. Quando precisarmos inicializar um ponteiro, devemos atribuir: NULL. Quando um ponteiro armazena NULL, quer dizer que ele não está armazenando um endereço no momento.

Tenham calma, daqui a pouco o conceito de ponteiros ficará mais claro. Vamos começar a conhecer os comandos de manipulação de arquivos binários e entenderemos melhor onde o conceito de ponteiro será aplicado.

Page 244: Programação 2 Linguagem C (UFRPE)

64

Programação 2

3.2 Comandos para manipular arquivos binários

Como já mencionado, os arquivos binários são utilizados quando queremos armazenar registros. É como se tivéssemos um vetor de registro, só que os dados não são perdidos ao terminar a execução do programa. A figura 3.2 mostra a representação gráfica de um arquivo binário.

Figura 3.2: Representação gráfica de um arquivo binário

O arquivo binário é formado por um conjunto de registros, armazenados um após o outro. As operações realizadas em um arquivo binário dependerão do local onde se encontrar o leitor. Pense no leitor como se fosse a agulha de uma vitrola (Figura 3.3). Para tocar uma música, a agulha passa sobre o disco, fazendo a leitura da música. Dependendo de onde a agulha seja posicionada, é tocada uma música do disco.

Figura:3.3: Vitrola com agulha tocando uma música

O leitor do arquivo passará sobre os registros, fazendo a leitura dos mesmos. Nós podemos colocar o leitor sobre qualquer registro e executar uma operação sobre o mesmo (leitura e/ou gravação). O arquivo tem uma marcação indicando onde ele termina (end of file).

Nas próximas seções, iremos detalhar os comandos para manipular arquivos binários. As operações para a manipulação de arquivo estão na biblioteca stdio.h. Com isso, ao trabalhar com arquivos, devemos

Page 245: Programação 2 Linguagem C (UFRPE)

65

Programação 2

incluir esta biblioteca nos nossos programas.

3.2.1 Declaração de um ponteiro para arquivo

Na linguagem C, as funções que manipulam arquivos trabalham com o conceito de ponteiros para arquivo. Com isso, teremos uma variável que armazenará o endereço de memória onde está armazenado nosso arquivo. Nós vimos na seção 3.2.1 (exemplo 3.1), como fazemos para declarar um ponteiro para um arquivo. Devemos declarar um ponteiro para cada arquivo que formos manipular no nosso programa.

3.2.2 Comando para abrir um arquivo

A maior parte das operações sobre um arquivo (leitura, gravação, etc) só pode ser executada com o arquivo aberto. O comando de abertura do arquivo (fopen) apresenta a seguinte sintaxe:

Sintaxe

ponteiro_arquivo = fopen(“nome_do_arquivo”,

“modo_de_abertura”);

Onde:

• ponteiro_arquivo: ao abrir um arquivo, a função fopen retorna o endereço de memória do arquivo. Por conta disso, devemos atribuir o endereço de memória do arquivo, para um ponteiro. Após o arquivo ser aberto, usaremos este endereço de memória para acessá-lo.

• nome_do_arquivo: determina qual arquivo deverá ser aberto. Neste espaço é colocado o nome do arquivo, da forma que foi salvo no diretório. O comando fopen procura o arquivo que desejamos abrir, no mesmo diretório onde está armazenado o programa executável.

• modo_de_abertura: informa que tipo de uso você vai fazer do arquivo. O modo de abertura indica o que faremos no arquivo: leitura, gravações e alterações. Além disso, o modo de abertura também vai indicar se queremos que um novo arquivo seja criado. A tabela abaixo, apresenta os principais modos de abertura.

Page 246: Programação 2 Linguagem C (UFRPE)

66

Programação 2

Modo Significado

“r+b” Abre um arquivo binário para leitura e escrita. O arquivo deve existir antes de ser aberto. Dessa forma, este modo de abertura só pode ser usado se o arquivo que estamos querendo abrir, já existe no nosso computador.

“w+b” Cria um arquivo binário para leitura e escrita. Se o arquivo não existir, ele será criado. Se já existir, o conteúdo anterior será destruído. Este modo de abertura tem a capacidade de criar novos arquivos. Mas, se solicitarmos que seja aberto um arquivo que já existe, o conteúdo do arquivo será apagado.

“a+b” Acrescenta dados ou cria um arquivo binário para leitura e escrita. Caso o arquivo já exista, novos dados podem ser adicionados, apenas, no final do arquivo. Se o arquivo não existir, um novo arquivo será criado.

O exemplo 3.2, apresenta o uso do fopen.

Exemplo 3.2: Abertura de arquivo

1

2

3

4

5

FILE *paluno, *pprofessor;

paluno = fopen(“alunos.bin”, “w+b”);

pprofessor = fopen(“professores.bin”, “r+b”);

if (pprofessor == NULL)

printf(”Arquivo de professores não existe”);

Na linha 1, temos a declaração de dois ponteiros para armazenar os endereços dos arquivos que iremos abrir logo em seguida.

Na linha 2, temos um fopen que irá abrir o arquivo alunos.bin, utilizando o modo de abertura w+b. Caso o arquivo alunos.bin não exista, ele será criado (com o nome que passamos como parâmetro). Normalmente, usamos o modo de abertura w+b quando executamos o nosso programa pela primeira vez. Neste momento, o arquivo ainda não existe. Dessa forma, desejamos que o mesmo seja criado. Mas, se o arquivo alunos.bin já existir, todo o seu conteúdo será apagado. E, como resultado, teremos o arquivo aberto, mas sem nenhum registro armazenado. Ao abrir o arquivo, o endereço de memória do arquivo será armazenado no ponteiro paluno.

Na linha 3, temos um fopen que abrirá o arquivo professores.bin, utilizando o modo de abertura r+b. Este modo de abertura só é utilizado para arquivos que já existem, pois, diferente do modo de abertura w+b, ele não tem a capacidade de criar um arquivo novo. Se tentarmos abrir um arquivo que não existe, o fopen retornará NULL.

Page 247: Programação 2 Linguagem C (UFRPE)

67

Programação 2

Para saber se um arquivo foi aberto corretamente, podemos fazer um teste como mostra as linhas 4 e 5. Após executar um fopen, verificamos se o ponteiro está com NULL. Caso afirmativo, é porque a abertura não foi executada corretamente.

Uma vez aberto, o arquivo fica disponível para leituras e gravações através da utilização de funções adequadas.

3.2.3 Comando para fechar um arquivo

Após terminar de usar um arquivo, devemos fechá-lo. Para isso, usamos a função fclose, que tem a seguinte sintaxe.

Sintaxe

fclose(ponteiro_arquivo);

Onde:

• ponteiro_arquivo: é o ponteiro que tem armazenado o endereço de memória do arquivo que queremos fechar.

Só podemos fechar arquivos que estão abertos. O exemplo 3.3, apresenta o uso do comando fclose. Vamos utilizar os ponteiros declarados no exemplo anterior.

Exemplo 3.3: Fechamento de arquivo

1

2

fclose(palunos);

fclose(pprofessores);

Na linha 1, fechamos o arquivo que está armazenado no endereço de memória palunos (que é o ponteiro que armazena o endereço do arquivo). Nós só utilizamos o nome do arquivo (o nome que está salvo no diretório), no momento da abertura. Depois de aberto, só utilizamos seu endereço de memória, certo?

3.2.4 Comando para ler um registro armazenado no arquivo

Vamos aprender a ler os dados de um registro armazenado no arquivo? Neste comando, teremos vários detalhes e devemos ter em mente o seguinte:

• A leitura é feita a partir do ponto onde o leitor se encontra. Ao abrir o arquivo, o leitor é posicionado no início do primeiro

Page 248: Programação 2 Linguagem C (UFRPE)

68

Programação 2

registro, como mostra a figura 3.2. À medida que vamos executando leituras, o leitor vai se deslocando. Dessa forma, precisamos ter noção da posição onde o leitor se encontra.

• Nos arquivos binários, SEMPRE fazemos a leitura de um registro completo, independente de quantos campos ele tenha.

• Um arquivo deve armazenar registro do mesmo tipo. Se os registros são do mesmo tipo, cada um deles ocupará o mesmo espaço de memória. Dessa forma, o leitor sempre se deslocará em intervalos regulares. Vamos entender isto melhor, daqui a pouco.

Vamos, primeiro, ver a sintaxe do comando de leitura:

Sintaxe

fread (&registro, numero_de_bytes, quantidade,

ponteiro_arquivo);

Onde:

• &registro: é o registro que armazenará os dados do registro lido do arquivo. É assim, nós pegamos um registro que está no arquivo, e armazenamos no registro passado como parâmetro.

• numero_de_bytes: na verdade, o que o comando de leitura faz é informar que o leitor precisa se deslocar, fazendo a leitura de uma certa quantidade de bytes. A quantidade de bytes que o leitor deve se deslocar é exatamente quantos bytes de memória o registro ocupa. Por exemplo: se o nosso arquivo armazena registros de alunos, composto pelos campos: matricula (int), nota1 (float), nota2 (float) e media (float). Sabe-se que um int ocupa 4 bytes e um float, também, ocupa 4 bytes. Dessa forma, teremos: 4 bytes para a matricula + 4 bytes para a nota1 + 4 bytes para a nota2 + 4 bytes para a media = 16 bytes. Assim, esse registro ocupa 16 bytes (Figura 3.4). É esse o número de bytes que o leitor deverá ler, para recuperar o registro de um aluno, armazenado no arquivo. Existe uma função chamada sizeof que informa quantos bytes ocupa um tipo de dado. Assim, não precisamos estar lembrados de quantos bytes um int ocupa. Além disso, não precisamos fazer as contas para saber quantos bytes o nosso registro ocupa. Para utilizar a função sizeof, precisamos apenas, passar como parâmetro

Page 249: Programação 2 Linguagem C (UFRPE)

69

Programação 2

para a função, que tipo de dado queremos saber quantos bytes ele ocupa. Por exemplo: sizeof(int) ou sizeof(TAluno). No caso de um registro, a função vai fazer as contas de quantos bytes cada um dos campos do registro ocupa, e retorna a soma.

4 bytes 4 bytes 4 bytes 4 bytes

matricula nota1 nota2 media

Figura 3.4: Campos do registro aluno

• quantidade: neste terceiro parâmetro, usaremos SEMPRE 1. Este parâmetro significa quantas vezes a leitura será executada. Nós sempre queremos que seja feita a leitura de um registro por vez. Por isso, sempre utilizaremos 1.

• ponteiro_arquivo: precisamos informar em qual arquivo a leitura será feita. Com isso, passamos o endereço de memória onde o arquivo que será lido está armazenado. Assim, utilizamos o ponteiro que tem o endereço do arquivo.

Agora vamos ver o exemplo 3.4, que apresenta a leitura de um registro do arquivo. Para um melhor entendimento, foram feitas as declarações das variáveis que serão usadas no fread.

Exemplo 3.4: Leitura de um registro do arquivo

1

2

3

4

5

6

7

8

typedef { int matricula;

float nota1, nota2, media;

} TAluno

TAluno aluno;

FILE *paluno;

fread(&aluno, sizeof(TAluno), 1, paluno);

Nas linhas 1 a 3 temos a declaração de um novo tipo de dado, que é o agrupamento dos dados do aluno. Este tipo foi chamado de TAluno. Na linha 5, temos a declaração da variável aluno, que é um

Page 250: Programação 2 Linguagem C (UFRPE)

70

Programação 2

registro do tipo TAluno. Na linha 6 declaramos um ponteiro chamado paluno, que armazena endereço de memória de arquivo.

Na linha 8 é que temos o comando de leitura. Vamos interpretar cada parte do comando. No primeiro parâmetro, temos a variável registro que vai armazenar as informações lidas do arquivo5. Assim, o registro que for lido do arquivo, será armazenado no registro aluno. No segundo parâmetro, precisamos dizer quantos bytes serão lidos. Se iremos ler os dados do registro do aluno, precisamos saber quantos bytes ele ocupa. Para isso, foi usada a função sizeof. Como parâmetro do sizeof foi colocado TAluno, que é um tipo criado no programa e que queremos saber quantos bytes esse tipo de dado ocupa. No terceiro parâmetro, nós sempre usaremos 1. Finalmente, no quarto parâmetro informamos o endereço do arquivo em que será feita a leitura. Neste caso, o endereço do arquivo está armazenado no ponteiro paluno.

Após a leitura de um registro do arquivo, o leitor estará posicionado no início do próximo registro. A Figura 3.5 apresenta a posição do leitor antes e depois da execução do fread.

Figura 3.5: Posição do leitor antes e após a execução de um fread

Agora que já sabemos como fazer para ler um registro que está armazenado no arquivo, vamos aprender a gravar um registro no arquivo.

Atenção

5 Não esquecer de colocar o & na frente da variável.

Page 251: Programação 2 Linguagem C (UFRPE)

71

Programação 2

3.2.5 Comando para gravar um registro no arquivo

Para gravar um registro em um arquivo binário, nós utilizamos o comando fwrite. Este comando é muito parecido com o fread. A diferença é que o fread lê uma sequência de bytes no arquivo, e armazena em um registro (primeiro parâmetro do fread). E o fwrite, pega um registro, e armazena suas informações no arquivo. Vamos ver a sintaxe do fwrite:

Sintaxe

fwrite(&registro, numero_de_bytes, quantidade,

ponteiro_arquivo);

Onde:

• &registro: é o registro que será armazenado no arquivo.

• numero_de_bytes: é a quantidade de bytes que serão gravadas no arquivo. Neste parâmetro, também usaremos o sizeof.

• quantidade: neste terceiro parâmetro, também, usaremos SEMPRE 1. Este parâmetro significa quantas vezes a gravação será executada. Nós sempre queremos que seja feita a gravação de um registro por vez. Por isso, sempre utilizaremos 1.

• ponteiro_arquivo: precisamos informar em qual arquivo a gravação será feita. Assim, utilizamos o ponteiro que tem o endereço do arquivo.

Agora vamos ver o exemplo 3.5, que apresenta a gravação de um registro no arquivo. Para um melhor entendimento, foram feitas as declarações das variáveis que serão usadas no fwrite.

Page 252: Programação 2 Linguagem C (UFRPE)

72

Programação 2

Exemplo 3.5: Leitura de um registro do arquivo

1

2

3

4

5

6

7

8

typedef { int matricula;

float nota1, nota2, media;

} TAluno

TAluno aluno;

FILE *paluno;

fwrite(&aluno, sizeof(TAluno), 1, paluno);

Na linha 8 é que temos o comando de gravação. Vamos interpretar cada parte do comando. No primeiro parâmetro, temos a variável registro que será gravada no arquivo. No segundo parâmetro, precisamos dizer quantos bytes serão gravados. Para isso, foi usada a função sizeof. No terceiro parâmetro, nós sempre usaremos 1. Finalmente, no quarto parâmetro informamos o endereço do arquivo em que será feita a gravação. Neste caso, o endereço do arquivo está armazenado no ponteiro paluno.

Devemos lembrar que o comando de gravação no arquivo (fwrite) é executado na posição onde o leitor se encontra no momento. Se o leitor estiver posicionado no início de um registro e executarmos um fwrite, o registro será gravado sobre o outro. Dessa forma, quando vamos inserir um novo registro no arquivo, devemos posicionar o leitor num ponto do arquivo que não tenha nenhum registro armazenado, ou seja, no final do arquivo. Vamos ver como faz isso?

3.2.6 Comando para posicionar o leitor em um ponto do arquivo

As operações de leitura e gravação são feitas na posição onde o leitor se encontra no momento. Podemos mudar a posição do leitor, colocando-o em um ponto específico do arquivo. Este comando é o fseek. A sintaxe do fseek é a seguinte:

Sintaxe

fseek(ponteiro_arquivo,numero_de_bytes, origem);

Page 253: Programação 2 Linguagem C (UFRPE)

73

Programação 2

Onde:

• ponteiro_arquivo: precisamos informar em qual arquivo o leitor está sendo posicionado.

• numero_de_bytes: é a quantidade de bytes que o leitor irá se deslocar pelo arquivo, até chegar no local desejado.

• origem: determina a partir de onde os número_de_bytes de deslocamento do leitor serão contados. Os possíveis valores são:

Origem Significado

SEEK_SET O deslocamento do leitor será contado a partir do início do arquivo.

SEEK_CUR O deslocamento do leitor será contado a partir da sua posição corrente.

SEEK_END O deslocamento do leitor será contado a partir do final do arquivo.

O exemplo 3.6 apresenta o uso do comando fseek.

Exemplo 3.6: Comando fseek

1

2

fseek(paluno, 0,SEEK_END);

fseek(paluno, 2*sizeof(paluno), SEEK_SET);

No exemplo da linha 1, temos um fseek que será muito utilizado em nossos programas. Neste fseek é solicitado que seja feito o posicionamento do leitor do arquivo de endereço paluno. O deslocamento do leitor será feito iniciando a contagem a partir do fim do arquivo (SEEK_END)6. O número de bytes que o leitor irá se deslocar é 0. Este tipo de fseek é usado quando queremos gravar um novo registro do nosso arquivo. Jogamos o leitor para o fim do arquivo e não deslocamos nenhum byte. Com isso, temos a garantia que o leitor não está sobre nenhum registro. Dessa forma, podemos gravar um novo registro, sem perder registros que já haviam sido gravados no nosso arquivo.

No fseek da linha 2, foi solicitado que o leitor seja posicionado no início do arquivo (SEEK_SET), antes do deslocamento ser efetivado. Notem que, no segundo parâmetro, foi passada uma expressão 2 * o tamanho de um registro. Neste caso, significa que o leitor irá deslocar a quantidade de bytes ocupadas por 2 registros, com isso, irá se posicionar no início do terceiro registro.

Atenção

6 O parâmetro origem, deve ser colocado todo em letra maiúscula.

Page 254: Programação 2 Linguagem C (UFRPE)

74

Programação 2

A figura 3.6 apresenta a posição do leitor após a execução dos fseek do exemplo.

Figura 3.6: Posição do leitor após a execução dos fseek do exemplo 3.6

3.2.7 Comando para posicionar o leitor no início do arquivo

Nós podemos posicionar o leitor no início do arquivo, utilizando o comando rewind. A sua sintaxe é a seguinte:

Sintaxe

rewind(ponteiro_arquivo);

Onde:

• ponteiro_arquivo: é o ponteiro que tem o endereço do arquivo que queremos posicionar o leitor.

O exemplo 3.7 apresenta o uso do comando rewind.

Exemplo 3.7: Uso do comando rewind

1 rewind(paluno);

O comando rewind é utilizado quando precisamos fazer uma varredura por todos os registros do arquivo. A varredura é iniciada colocando o leitor no início do arquivo.

Page 255: Programação 2 Linguagem C (UFRPE)

75

Programação 2

3.2.8Comandoparaverificarsechegouaofinaldoarquivo

Quando fazemos uma varredura no arquivo, não sabemos quantos registros tem armazenados no mesmo. No entanto, precisamos saber o momento de parar de executar a leitura dos registros. O comando feof (end of file) informa se o leitor chegou ao final do arquivo ou não. A sintaxe do feof é a seguinte:

Sintaxe

int feof(ponteiro_arquivo);

Onde:

• int: é o retorno da função. A função feof retorna um número inteiro, que indica se o arquivo terminou ou não. Quando a função retorna zero, significa que ainda não chegou no final do arquivo. Qualquer valor diferente de zero, indica que chegou ao final do arquivo.

• ponteiro_arquivo: é o ponteiro que tem o endereço do arquivo que queremos verificar se chegou ao fim.

O exemplo 3.8 apresenta o uso do comando feof.

Exemplo 3.8: uso do comando feof

1 while (feof(paluno)==0)

Normalmente, o feof é usando como condição de um while, como mostra o exemplo 3.8. Este while será executado enquanto não chegar no final do arquivo.

3.2.9 Comando para remover um arquivo

Quando desejamos apagar um arquivo do diretório, podemos utilizar o comando remove. Este comando só pode ser utilizado em arquivos fechados. A sua sintaxe é a seguinte:

Sintaxe

remove(“nome_do_arquivo”);

Onde:

• nome_do_arquivo: é o nome do arquivo que queremos apagar.

Page 256: Programação 2 Linguagem C (UFRPE)

76

Programação 2

Neste caso, é utilizado o nome do arquivo salvo no diretório do nosso computador.

O exemplo 3.9 apresenta o uso do comando remove.

Exemplo 3.9: uso do comando remove

1 remove(“alunos.bin”);

Neste exemplo, o arquivo alunos.bin será removido do computador.

3.2.10 Comando para renomear um arquivo

Nós podemos renomear um arquivo no diretório do nosso computador. Para isso, utilizamos o comando rename. Este comando, também, só pode ser utilizado em arquivos fechados. A sua sintaxe é a seguinte:

Sintaxe

rename(“nome_do_arquivo”, “novo_nome_do_arquivo”);

Onde:

• nome_do_arquivo: é o nome do arquivo que queremos renomear. Neste caso; é utilizado o nome do arquivo salvo no diretório do nosso computador.

• novo_nome_do_arquivo: é o novo nome para o nosso arquivo.

O exemplo 3.10 apresenta o uso do comando rename.

Exemplo 3.10: uso do comando rename

1 rename(“alunos.bin”, “alunos_temp.bin”);

Neste exemplo, o arquivo alunos.bin, será renomeado para alunos_temp.bin.

3.3 Implementação das operações básicas em um arquivo

Agora é a hora de fazermos o nosso programa completo, que

Page 257: Programação 2 Linguagem C (UFRPE)

77

Programação 2

irá aplicar os comandos de manipulação de arquivo, descritos na seção 3.2. Este programa irá gerenciar os dados dos alunos de uma turma, que serão armazenados em um arquivo. O registro do aluno é composto pela matrícula, nome e média do aluno. O programa implementará as seguintes operações: cadastrar aluno, remover aluno, consultar aluno por matrícula, alterar média do aluno e listagem de todos os alunos.

Mais uma vez, teremos um programa cheio de detalhes, bem maior do que os que fizemos até então. Por isso, o programa completo 3.1 foi desenvolvido de forma modularizada. Para facilitar o entendimento deste programa, que tem quase 200 linhas, o mesmo foi dividido em 8 partes. Vamos começar?

Na primeira parte do programa completo 3.1, teremos as declarações das variáveis globais do programa. Além, de módulos auxiliares, que serão utilizados ao longo do programa, por outros módulos.

Programa Completo 3.1- Parte 1

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

#include <stdio.h>

typedef struct{ int mat;

char nome[20];

float med;

} TAluno;

FILE *paluno;

TAluno aluno_aux, aluno_nulo;

void linha()

{ int i;

for (i=1; i<=80; i++)

printf(“_”);

}

Page 258: Programação 2 Linguagem C (UFRPE)

78

Programação 2

17

18

19

20

21

22

23

24

25

26

27

void cabec()

{ system(“cls”);

printf(“Universidade Federal Rural de

Pernambuco\n”);

linha();

}

void abre_arquivo()

{ paluno = fopen(“aluno.dat”, “r+b”);

if (paluno == NULL)

paluno = fopen(“aluno.dat”, “w+b”);

}

Comentários sobre o Programa Completo 3.1, Parte 1:

• Linha1: inclusão da biblioteca stdio.h devido o uso do comando fflush e comandos de manipulação de arquivo.

• Linhas3a6: definição de um novo tipo de dados – TAluno, que agrupa os dados de um aluno. O tipo TAluno é composto pela matrícula, nome e média do aluno.

• Linha 8: declaração do ponteiro paluno, que armazenará o endereço do arquivo com os registros dos alunos.

• Linha9: declaração de dois registros: aluno_aux e aluno_nulo. O registro aluno_aux, será utilizado quando precisamos ler ou gravar um registro no arquivo. O registro aluno_nulo será utilizado no momento da remoção de um aluno do arquivo. As variáveis declaradas nas linhas 8 e 9 são globais, por isso, podem ser acessadas por todos os módulos do programa.

• Linhas11a15: temos o primeiro módulo do nosso programa. O módulo linha tem como objetivo, passar uma linha na tela. Este módulo será chamado pelos demais módulos do programa.

• Linhas17a21: temos a sequência de comandos do módulo cabec. O módulo cabec faz o cabeçalho das tela. Ao iniciar uma operação do programa (cadastro, remoção, etc), a tela deve ser limpa e precisamos colocar o nome da universidade no topo

Page 259: Programação 2 Linguagem C (UFRPE)

79

Programação 2

da tela. O módulo cabec vai: limpar a tela, colocar o nome da instituição e passar uma linha (fazendo uso do módulo linha).

• Linhas23a27: temos a sequência de comandos do módulo que é responsável por abrir o arquivo dos alunos, e deixá-lo disponível para uso. Vamos entender a lógica deste módulo? Primeiramente, é feita uma tentativa de abrir o arquivo dos alunos – alunos.dat – com o modo de abertura r+b, no comando fopen. Lembrem que o modo de abertura r+b só pode ser utilizado quando o arquivo já existe. O processador vai procurar o arquivo alunos.dat no diretório. Se o arquivo não for encontrado, o ponteiro paluno, ficará com NULL. Mas, se for encontrado, o endereço de memória do arquivo será armazenado no ponteiro paluno. Na sequência (linha 25), temos um if que testa o valor do ponteiro paluno. Se o ponteiro paluno estiver com NULL, significa que o arquivo alunos.dat não existe ainda e precisa ser criado. Se isso acontecer, o comando vinculado ao if é executado. Este comando é um fopen, só que agora utiliza o modo de abertura w+b, que deve ser utilizado para arquivos que não existe. Mas, por que não abrimos o arquivo usando logo o w+b? Vocês devem estar lembrados, que o modo de abertura w+b apaga todos os registros de um arquivo quando ele já existe. Assim, tentamos primeiro abrir o arquivo com r+b (utilizado para arquivos que já existem e abre o arquivo sem apagar os registros). Se der erro, é porque o arquivo não existe. Com isso, tentamos abrir com o modo de abertura w+b.

Vamos agora para a parte 2 do programa completo 3.1. Nesta parte temos o módulo inserir, que é responsável pelo cadastro dos registros dos alunos no arquivo. Para fazer o cadastro de um registro no arquivo binário, devemos obter os dados do aluno, montando o registro que iremos gravar no arquivo. Quando o registro estiver com todas as informações do aluno (mat, nome e media), o mesmo poderá ser gravado no final do arquivo.

Atenção

7 O nome do arquivo que nós passarmos como parâmetro no fopen será utilizado para salvar nosso arquivo no diretório. Por exemplo, após a execução do módulo abre_arquivo, teremos um arquivo chamado alunos.dat no diretório onde está salvo o programa executável. Por convenção, coloque os arquivos de dados sempre com a extensão dat ou bin.

Page 260: Programação 2 Linguagem C (UFRPE)

80

Programação 2

Programa Completo 3.1- Parte 2

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

void inserir()

{ int resp;

do { cabec();

printf(“\n\nCadastrar novo aluno\n\n”);

printf(“\nMatricula: “);

scanf(“%d”, &aluno_aux.mat);

printf(“\nNome.....: “);

fflush(stdin);

gets(aluno_aux.nome);

printf(“\nMedia....: “);

scanf(“%f”, &aluno_aux.med);

fseek(paluno, 0, SEEK_END);

fwrite(&aluno_aux, sizeof(TAluno), 1,

paluno);

printf(“\n\nAluno cadastrado com sucesso!

\n\n”);

printf(“\nDeseja cadastrar outro

(1-sim/0-nao)? “);

scanf(“%d”, &resp);

} while (resp ==1);

}

Comentários sobre o Programa Completo 3.1, Parte 2

• Linha28: início do módulo inserir.

• Linha 29: declaração da variável resp. Esta variável irá armazenar a resposta do usuário, quando for perguntado se ele deseja cadastrar mais alunos.

• Linha 30: início de um do/while. O módulo inserir ficará executando enquanto o usuário desejar cadastrar novos alunos. Nesta linha, também temos a chamada do módulo cabec. Cada vez que um cadastro é feito, a tela vai ser limpa, para iniciar um

Page 261: Programação 2 Linguagem C (UFRPE)

81

Programação 2

novo cadastro.

• Linha31: printf que informa o que esta tela faz – cadastro de alunos.

• Linhas32e33:printf solicitando que seja digitada a matrícula do aluno e scanf que lê esta informação. Os dados do aluno vão sendo colocados no registro aluno_aux.

• Linhas34a36:printf solicitando que seja digitado o nome do aluno, fflush para limpar o buffer de entrada (já que teremos a leitura de uma sequência de caractere) e o gets que lê o nome do aluno e armazena no registro aluno_aux.

• Linhas37e38:printf solicitando que seja digitada a média do aluno e scanf que lê esta informação. Neste momento, o registro aluno_aux acabou de ser todo preenchido com os dados do aluno e já pode ser gravado no arquivo.

• Linha39: para gravar o registro no arquivo, devemos posicionar o leitor no final do arquivo para não correr o risco de fazer a gravação sobre algum outro registro. Para isso, é executado o fseek.

• Linha40: com o leitor posicionado no final do arquivo, podemos executar o fwrite, que vai gravar o conteúdo do registro aluno_aux, no nosso arquivo.

• Linha41: printf para informar que o aluno foi cadastrado com sucesso.

• Linhas 42 e 43: printf para pergunta se o usuário deseja cadastrar outro aluno e scanf que lê a resposta para esta pergunta.

• Linha44: final do do/while, com a condição de parada. O do/while é executado enquanto o usuário estiver respondendo que quer cadastrar mais alunos. Notem que, não precisamos nos preocupar com a capacidade do arquivo. Vamos armazenando quantos registros desejarmos.

• Linha45: fecha chaves que indica o final do módulo inserir.

A figura 3.7 apresenta a tela de execução do programa 3.1, na tela de cadastro de novo aluno.

Page 262: Programação 2 Linguagem C (UFRPE)

82

Programação 2

Figura 3.7: Tela de cadastro de aluno

Vamos ver agora o código de dois módulos que serão utilizados pelos módulos: consultar aluno por matrícula, remover aluno e alterar média do aluno. Quando fazemos uma consulta, alteração ou remoção, precisamos localizar o registro do aluno no arquivo e apresentar o registro para o usuário. Por isso, foi criado um módulo responsável para procurar um registro no arquivo e, outro módulo, responsável por apresentar os dados do registro de um aluno. Vamos lá, entender a parte 3 do nosso programa completo 3.1!

Programa Completo 3.1- Parte 3

46

47

48

49

50

51

52

53

54

55

56

int procura(int matp)

{ int p;

p = 0;

rewind(paluno);

fread(&aluno_aux, sizeof(TAluno), 1, paluno);

while (feof(paluno)==0)

{ if (aluno_aux.mat == matp)

return p;

else

{ fread(&aluno_aux, sizeof(TAluno), 1,

paluno);

p++;

Page 263: Programação 2 Linguagem C (UFRPE)

83

Programação 2

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

}

}

return -1;

}

void mostre(int pos)

{ fseek(paluno, pos*sizeof(TAluno), SEEK_SET);

fread(&aluno_aux, sizeof(TAluno), 1, paluno);

printf(“\n\n”);

linha();

printf(“Matricula Nome Media\n”);

linha();

printf(“%9d %-20s %5.1f\n”, aluno_aux.mat,

aluno_aux.nome, aluno_aux.med);

linha();

}

Comentários sobre o Programa Completo 3.1, Parte 3:

• Linhas46a60: temos a sequência de comandos do módulo procura. O módulo recebe um parâmetro, que é a matrícula do aluno que está sendo procurado. Ao finalizar a sua execução, esse módulo retorna um int que pode ser: -1 (significa que procurou o registro do aluno no arquivo e não achou) ou um número positivo (que significa em qual posição do arquivo o registro foi encontrado). Este módulo possui uma variável local p, que é incrementada cada vez que é feita a leitura de um registro no arquivo. É o valor desta variável que indica em que posição do arquivo o registro foi encontrado. Para localizar o registro de um aluno, com uma dada matrícula, precisamos percorrer todo o arquivo, até encontrar o registro ou até o arquivo chegar ao fim. Para percorrer o arquivo, colocamos o leitor no início do mesmo (usando o rewind – linha 49) e efetuamos vários fread, até que chegue no final do arquivo (while da linha 51). Logo após posicionar o leitor no início do

Page 264: Programação 2 Linguagem C (UFRPE)

84

Programação 2

arquivo, fazemos a leitura do primeiro registro do arquivo, para verificar se não é o final de arquivo (end of file). Lembrem que, assim que um fread é executado, o leitor já fica posicionado no início do próximo registro, pronto para um novo fread. Quando um registro do arquivo tem a mesma matrícula que está sendo procurada, significa que encontramos o aluno. Com isso, já pode ser dado o retorno, indicando a posição onde o registro foi encontrado (linha 52 e 53). Se fizermos a leitura de todos os registros do arquivo e não encontrar nenhum aluno com a matrícula procurada, o módulo retornará -1 (linha 59).

• Linhas62a72: temos a sequência de comandos do módulo mostre. Este módulo recebe como parâmetro a posição do registro que deve ser apresentado, recupera o registro no arquivo e apresenta os dados do registro em forma de tabela. O módulo começa com o posicionamento do leitor no início do registro que deve ser mostrado (linha 63). Notem que, no fseek, no campo que indica o tamanho do deslocamento que o leitor vai dar, é feita a conta: pos*sizeof(TAluno). Vamos entender o porquê desta conta. A variável pos indica em que posição o registro está armazenado no arquivo (se ele é o primeiro, segundo, etc.). Consequentemente, saberemos quantos registros tem armazenados antes do registro que queremos mostrar. E assim, saberemos sobre quantos registros o leitor dever se deslocar, até ser posicionado no início do registro desejado. Com o leitor no ponto certo, podemos fazer a leitura do registro do aluno, armazenando seus dados no registro aluno_aux (linha 64). Após isto, precisamos apenas apresentar os dados do aluno (linhas 65 a 71).

Vamos agora entender o módulo responsável por consultar um aluno através do seu número de matrícula. O módulo consultar vai solicitar que o usuário informe a matrícula do aluno que deseja consultar. Através do uso do módulo procura é descoberta em que posição o registro do aluno se encontra armazenado no arquivo. Se o aluno estiver armazenado no arquivo, seus dados são apresentados, através do uso do módulo mostre. Se o aluno não for encontrado, é apresentada uma mensagem de erro.

Page 265: Programação 2 Linguagem C (UFRPE)

85

Programação 2

Programa Completo 3.1- Parte 4

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

void consultar()

{ int resp, matcon, posicao;

do{ cabec();

printf(“\n\nConsultar Aluno\n\n\n”);

printf(“Matricula do aluno: “);

scanf(“%d”, &matcon);

posicao = procura(matcon);

if (posicao == -1)

printf(“\n\nMatricula nao encontrada!

\n\n”);

else

mostre(posicao);

printf(“\n\nDeseja consultar outro

(1-sim/0-nao)? “);

scanf(“%d”, &resp);

} while (resp == 1);

}

Comentários sobre o Programa Completo 3.1, Parte 4

• Linha73: início do módulo consultar.

• Linha 74: declaração das variáveis locais: resp, matcon (matricula que será consultada) e posicao (armazena em que posição o registro foi localizado).

• Linha 75: início de um do/while. O módulo consultar ficará executando enquanto o usuário desejar consultar alunos. Nesta linha, também temos a chamada o módulo cabec. Cada vez que uma consulta é feita, a tela vai ser limpa, para iniciar uma nova consulta.

• Linha 76: printf que informa o que esta tela faz – consultar aluno.

• Linhas77e78:printf solicitando que seja digitada a matrícula

Page 266: Programação 2 Linguagem C (UFRPE)

86

Programação 2

do aluno que deseja consultar e scanf que lê esta informação.

• Linha79:chamada do módulo procura, passando a matrícula que desejamos consultar como parâmetro. O retorno do módulo procura é armazenado na variável posicao.

• Linhas 80 a 83: if que verifica se a variável posicao tem armazenado -1. Se sim, é porque o aluno não foi encontrado. Com isso, é escrita uma mensagem de erro. Caso posicao não esteja com -1, é porque o aluno foi encontrado e seus dados devem ser apresentados. Para apresentar os dados do aluno, fazemos uma chamada ao módulo mostre, passando a posição onde o aluno foi encontrado, como parâmetro.

• Linhas 84 e 85: printf para perguntar se o usuário deseja consultar outro aluno e scanf que lê a resposta para esta pergunta.

• Linha86: final do do/while, com a condição de parada. O do/while é executado enquanto o usuário estiver respondendo que quer consultar mais alunos.

• Linha87: fecha chaves que indica o final do módulo consultar.

A figura 3.8 apresenta a tela de execução do programa completo 3.1, na tela de consulta aluno por matrícula.

Figura 3.8: Tela de consulta aluno por matrícula

Vamos agora entender o módulo responsável por remover um aluno do arquivo. O módulo da remoção inicia de forma muito similar ao da consulta. Primeiro, é solicitado o número da matrícula do aluno

Page 267: Programação 2 Linguagem C (UFRPE)

87

Programação 2

que será removido, seu registro é localizado e apresentado para que o usuário possa ter certeza que vai remover o registro certo. Na verdade, um registro não é removido do arquivo, o que fazemos é gravar sobre o registro do aluno que queremos remover, um registro com os dados zerados (aluno_nulo). Assim, toda vez que temos um registro com a matrícula igual a zero no arquivo, significa que ele é um registro que foi removido. Se o aluno não for encontrado, é apresentada uma mensagem de erro.

Programa Completo 3.1- Parte 5

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

void remover()

{ int matrem, conf, resp, posicao;

aluno_nulo.mat = 0;

aluno_nulo.med = 0;

do{ cabec();

printf(“\n\nRemover aluno\n\n\n”);

printf(“Matricula: “);

scanf(“%d”, &matrem);

posicao = procura(matrem);

if (posicao == -1)

printf(“\nAluno nao encontrado!!\a”);

else

{ mostre(posicao);

printf(“\n\nDeseja remover o aluno

(1-sim/0-nao)? “);

scanf(“%d”, &conf);

if (conf == 1)

{ fseek(paluno,posicao*sizeof

(TAluno),SEEK_SET);

f w r i t e ( & a l u n o _ n u l o ,

sizeof(TAluno), 1, paluno);

printf(“\n\nAluno removido com

sucesso!”);

}

Page 268: Programação 2 Linguagem C (UFRPE)

88

Programação 2

108

109

110

111

112

113

114

else

printf(“\nRemocao cancelada!”);

}

printf(“\n\n\nDeseja remover outro

(1-sim/0-nao)? “);

scanf(“%d”, &resp);

} while (resp ==1);

}

Comentários sobre o Programa Completo 3.1, Parte 5:

• Linha88: início do módulo remover.

• Linha 89: declaração das variáveis locais: resp, matrem (matricula que será removida), conf (confirmação se deseja remover realmente) e posicao (armazena em que posição o registro foi localizado).

• Linhas 90 e 91: inicialização dos campos do registro aluno_nulo.

• Linha 92: início de um do/while. O módulo remover ficará executando enquanto o usuário desejar remover alunos. Nesta linha, também temos a chamada do módulo cabec. Cada vez que uma remoção é feita, a tela vai ser limpa, para iniciar uma nova remoção.

• Linha 93: printf que informa o que esta tela faz – remover aluno.

• Linhas94e95:printf solicitando que seja digitada a matrícula do aluno que deseja remover e scanf que lê esta informação.

• Linha96:chamada do módulo procura, passando a matrícula que desejamos remover como parâmetro. O retorno do módulo procura é armazenado na variável posicao.

• Linhas 97 a 110: if que verifica se a variável posicao tem armazenado -1. Se sim, é porque o aluno não foi encontrado. Com isso, é escrita uma mensagem de erro. Caso posicao não esteja com -1, é porque o aluno foi encontrado e seus dados devem ser apresentados. Para apresentar os dados do aluno,

Page 269: Programação 2 Linguagem C (UFRPE)

89

Programação 2

fazemos uma chamada ao módulo mostre, passando a posição onde o aluno foi encontrado como parâmetro. Após ver os dados do aluno, o usuário pode desistir de removê-lo. Na linha 102, temos o scanf que lê se o usuário confirma ou não a remoção. A remoção, propriamente dita, é executada nas linhas 104 e 105. Na linha 104 temos o posicionamento do leitor sobre o registro que queremos remover. E, na linha 105, temos a gravação do registro aluno_nulo sobre o registro antigo.

• Linhas 111 e 112: printf para pergunta se o usuário deseja remover outro aluno e scanf que lê a resposta para esta pergunta.

• Linha113: final do do/while, com a condição de parada. O do/while é executado enquanto o usuário estiver respondendo que quer remover mais alunos.

• Linha114: fecha chaves que indica o final do módulo remover.

A figura 3.9 apresenta a tela de execução do programa 3.1, na tela de remoção de aluno.

Figura 3.9: Tela de remoção do registro do aluno

Agora vamos entender o módulo responsável pela alteração da média do aluno. Este módulo é parecido com a remoção. Primeiro, é solicitado o número da matrícula do aluno que será alterado, seu registro é localizado e apresentado para que o usuário possa ter certeza que vai alterar o registro certo. Na alteração, gravamos um registro com a média alterada, sobre o antigo registro do aluno.

Page 270: Programação 2 Linguagem C (UFRPE)

90

Programação 2

Programa Completo 3.1- Parte 6

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

void alterar()

{ int matalt, conf, resp, posicao;

do { cabec();

printf(“\n\nAlterar media do aluno\n\

n\n”);

printf(“Matricula: “);

scanf(“%d”, &matalt);

posicao = procura(matalt);

if (posicao == -1)

printf(“\nAluno,nao encontrado!!\a”);

else

{ mostre(posicao);

printf(“\n\nAlterar a media do

aluno(1-sim/0-nao)? “);

scanf(“%d”, &conf);

if (conf == 1)

{ printf(“\nNova media: “);

scanf(“%f”, &aluno_aux.med);

printf(“\nMedia alterada com sucesso!

\n\n”);

fseek(paluno,posicao*sizeof(TAluno),

SEEK_SET);

fwrite(&aluno_aux,sizeof(TAluno), 1,

paluno);

mostre(posicao);

135

136

137

printf(“\nMedia do aluno alterada com

sucesso!\n”);

}

else

Page 271: Programação 2 Linguagem C (UFRPE)

91

Programação 2

138

139

140

141

142

143

printf(“\n\nAlteracao cancelada!

\n\n”);

}

printf(“\n\nDeseja alterar outro

(1-sim/0-nao)? “);

scanf(“%d”, &resp);

}while (resp ==1);

}

Comentários sobre o Programa Completo 3.1, Parte 6:

• Linha115: início do módulo alterar.

• Linha 116: declaração das variáveis locais: resp, matalt (matricula que será alterada), conf (confirmação se deseja alterar a média do aluno) e posicao (armazena em que posição o registro foi localizado).

• Linha 117: início de um do/while. O módulo alterar ficará executando enquanto o usuário desejar alterar alunos. Nesta linha, também temos a chamada do módulo cabec. Cada vez que uma alteração é feita, a tela vai ser limpa, para iniciar uma nova alteração.

• Linha118: printf que informa o que esta tela faz – alterar média do aluno.

• Linhas119e120:printf solicitando que seja digitada a matrícula do aluno que deseja alterar e scanf que lê esta informação.

• Linha121:chamada do módulo procura, passando a matrícula que desejamos alterar como parâmetro. O retorno do módulo procura é armazenado na variável posicao.

• Linhas 122 a 139: if que verifica se a variável posicao tem armazenado -1. Se sim, é porque o aluno não foi encontrado. Com isso, é escrita uma mensagem de erro. Caso posicao não esteja com -1, é porque o aluno foi encontrado e seus dados devem ser apresentados. Para apresentar os dados do aluno, fazemos uma chamada ao módulo mostre, passando a posição onde o aluno foi encontrado como parâmetro. Após ver os dados do aluno, o usuário pode desistir de alterar a sua média. Na

Page 272: Programação 2 Linguagem C (UFRPE)

92

Programação 2

linha 127, temos o scanf que lê se o usuário confirma ou não a alteração. Se o usuário confirma que quer alterar, é solicitada a nova média do aluno (linha 130). A alteração, propriamente dita, é executada nas linhas 132 e 133. Na linha 132, temos o posicionamento do leitor sobre o registro que queremos alterar. E, na linha 133, temos a gravação do registro alterado sobre o registro antigo. Após os dados serem alterados, o registro do aluno é reapresentado através de uma chamada ao módulo mostre (linha 134).

• Linhas 140 e 141: printf para pergunta se o usuário deseja alterar outro aluno e scanf que lê a resposta para esta pergunta.

• Linha142: final do do/while, com a condição de parada. O do/while é executado enquanto o usuário estiver respondendo que quer alterar mais alunos.

• Linha143: fecha chaves que indica o final do módulo alterar.

A figura 3.10 apresenta a tela de execução do programa completo 3.1, na tela de alteração de média do aluno.

Figura 3.10: Tela de alteração de média do aluno

Veremos, agora, o último módulo do programa, que é a listagem. Este módulo é responsável por apresentar todos dados dos alunos que estão armazenados no arquivo. Os dados serão apresentados em forma de tabela. Devemos lembrar que só iremos apresentar os

Page 273: Programação 2 Linguagem C (UFRPE)

93

Programação 2

registros válidos do arquivo, ou seja, registros com matrícula zerada não devem ser apresentados.

Programa Completo 3.1- Parte 7

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

void listagem()

{ cabec();

printf(“\n\nListagem Geral\n\n\n”);

linha();

printf(“Matricula Nome Media\n”);

linha();

rewind(paluno);

fread(&aluno_aux, sizeof(TAluno), 1, paluno);

while (feof(paluno)==0)

{ if (aluno_aux.mat != 0)

printf(“%9d %-20s %5.1f\n”, aluno_aux.

mat,

aluno_aux.nome, aluno_aux.med);

fread(&aluno_aux, sizeof(TAluno), 1,

paluno);

}

linha();

printf(“tecle enter para voltar ao menu...”);

getche();

}

Comentários sobre o Programa Completo 3.1, Parte 7

• Linha144: início do módulo listagem.

• Linha145: chamada ao módulo cabec, responsável por limpar a tela e escrever o nome da instituição.

• Linha 146: printf que informa o que esta tela faz – listagem geral.

• Linha147: chamada do módulo linha, para iniciar o desenho da tabela.

Page 274: Programação 2 Linguagem C (UFRPE)

94

Programação 2

• Linha148: printf que escreve os cabeçalhos das colunas da tabela.

• Linha149: mais uma chamada ao módulo linha.

• Linha 150: posiciona o leitor no início do arquivo, para que possamos “varrer” o arquivo, visitando todos os registros do arquivo.

• Linha151:Leitura do primeiro registro do arquivo, para verificar se não é o final do arquivo.

• Linhas152a157: while que é executado enquanto não chegar no final do arquivo. Para cada registro lido, é verificado se o mesmo tem a matrícula igual a zero. Se sim, o registro não é apresentado na listagem.

• Linha158: chamada do módulo linha, para fechar a tabela.

• Linha159: printf informando que o usuário deve teclar enter para sair da listagem.

• Linha160: getche para que possamos ver a listagem.

• Linha161: fecha chaves que indica o final do módulo listagem.

A figura 3.11 apresenta a tela de execução do programa completo 3.1, na tela de listagem dos dados de todos os alunos.

Figura 3.11: Tela de listagem de dados de todos os alunos

O programa principal do programa completo 3.1 é apresentado a seguir. É no programa principal que serão feitas as chamadas aos módulos que o usuário deseja executar no momento.

Page 275: Programação 2 Linguagem C (UFRPE)

95

Programação 2

Programa Completo 3.1- Parte 8

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

main()

{ int op;

abre_arquivo();

do{ cabec();

printf(“\n\nOpcoes: \n\n\n”);

printf(“ 1- Cadastrar novo aluno\n\n”);

printf(“ 2- Remover aluno\n\n”);

printf(“ 3- Consultar aluno por

matricula\n\n”);

printf(“ 4- Alterar media do aluno

\n\n”);

printf(“ 5- Listagem geral\n\n”);

printf(“ 0- Sair\n\n”);

linha();

printf(“Informe a opcao desejada: “);

scanf(“%d”, &op);

switch(op)

{ case 1: inserir(); break;

case 2: remover(); break;

case 3: consultar(); break;

case 4: alterar(); break;

case 5: listagem(); break;

case 6: limpar(); break;

case 0: fclose(paluno); break;

184

185

default: printf(“\n\n\aOpcao

invalida!”);

break;

Page 276: Programação 2 Linguagem C (UFRPE)

96

Programação 2

186

187

188

}

} while (op != 0);

}

Comentários sobre o Programa Completo 3.1, Parte 8:

• Linha162: início do programa principal.

• Linha163: declaração da variável local op, que vai armazenar a operação que o usuário deseja executar.

• Linha164: chamada do módulo abre_arquivo, disponibilizando o mesmo para uso.

• Linhas 165 a 187: do/while responsável por ler a operação que o usuário que executar e fazer a chamada do módulo que executará a implementa a operação.

• Linha188: fecha chaves do programa principal.

A figura 3.12 apresenta a tela de execução do programa 3.1, na tela do menu principal, onde é informada a operação que desejamos executar.

Figura 3.12: Tela do menu principal

E assim, terminamos mais um programa completo. Agora, é colocar a mão no teclado e começar a programar, armazenando dados em arquivos.

Page 277: Programação 2 Linguagem C (UFRPE)

97

Programação 2

Atividades e Orientações de Estudos

Temos agora mais uma lista de exercícios para consolidar o nosso entendimento do assunto visto neste capítulo. Se preparem, pois as questões estão maiores. Mas, isso é bom porque vemos que estamos fazendo programas interessantes, não é mesmo?

1. Faça um programa para um shopping contendo as seguintes telas:

Tela de Menu

Shopping Center

Opções: 1 .Cadastrar loja 2. Consultar loja 3. Listagem de todas as lojas 0. Sair

Entre com a opção:

Cadastro

Shopping Center

Cadastro de Loja

Código: Nome: Área: Tipo(1-Confecções, 2-Alimentação, 3-Livros, 4- Serviços):

Cadastrar outra (1-Sim/0-Nao)?

Consulta

Shopping Center

Consultar Loja

Código da loja que deseja consultar:

Código Nome Área Tipo Condomínio

xxx xxxxxxx xx xx xxxx

Consultar outra (1-Sim/0-Nao)?

Page 278: Programação 2 Linguagem C (UFRPE)

98

Programação 2

Relatório Geral

Shopping Center

Listagem Geral

Codigo Nome Área Tipo Condomínio

xxx xxxxxxx xx xx xxxxx

xxx xxxxxxx xx xx xxxxx

xxx xxxxxxx xx xx xxxxx

Tecle enter para voltar ao menu...

• O programa irá armazenar os dados das lojas em um arquivo.

• O programa irá calcular o valor do condomínio de cada loja. O valor do condomínio depende da área e do tipo da loja. Veja tabela abaixo:

Tipo da loja Valor do m²

1 R$ 50

2 R$ 65

3 R$ 80

4 R$ 95

2. Faça um programa para uma Agência de Turismo armazenando os dados em um arquivo. O programa deverá ter as seguintes funções: Cadastrar roteiro, Consultar roteiro, Listagem de todos os roteiros e Simular valor de viagem. A seguir, sugestões de telas.

Tela Principal

Vida Boa Turismo

Opções: 1- Cadastrar roteiro 2- Consultar roteiro 3- Listagem de todos os roteiros 4- Simular viagem 0- Sair

Entre com a opção:

Page 279: Programação 2 Linguagem C (UFRPE)

99

Programação 2

Tela de Cadastro

Vida Boa Turismo

Cadastrar Roteiro

Código: País(1-Brasil, 2-Espanha, -3-Italia): Cidade: Diária de Hotel: R$ Diária Aluguel de Carro: R$

Inserir outro(1-sim,2-não)?

Tela de Remoção de Roteiro

Vida Boa Turismo

Consultar Roteiro

Código do roteiro a ser consultado:

Código País Cidade Diária Hotel Carro

xxx x xxxxxxxx xxx xxxx

Consultar outro (1-Sim/0-Nao)?

Tela de Listagem de todos os roteiros

Vida Boa Turismo

Listagem de todos os roteiros

Código País Cidade Diária Hotel Carro

xxx x xxxxxxxx xxx xxxx

xxx x xxxxxxxx xxx xxxx

xxx x xxxxxxxx xxx xxxx

Página x de x... Tecle enter

Tecle enter para voltar ao menu...

Page 280: Programação 2 Linguagem C (UFRPE)

100

Programação 2

Tela para simular valor de viagem

Vida Boa Turismo

Simular Viagem

Código do roteiro:

Código País Cidade Diária Hotel Carro

xxx x xxxxxxxx xxx xxxx

Quantidade de dias: Alugar carro(1-sim, 2-não)?

Valor total da viagem = R$ xxxxx

Simular outro roteiro(1-sim, 2-não)?

Observações:

• Os dados do roteiro devem ser armazenados em um arquivo. Não pode cadastrar roteiros com códigos repetidos.

• O valor da viagem deve ser calculado com base nos valores do roteiro escolhido; viagem = quantos dias * valor diária hotel + quantos dias * valor diária carro (caso alugue carro).

• Na consulta deve passar o código do roteiro e apresentar os dados do roteiro.

• Na listagem, apresentar os dados de todos os roteiros em forma de tabela.

Conheça Mais

Para melhorar o nosso conhecimento sobre manipulação de arquivos binários, vejam este assunto nos livros:

• LAUREANO, Marcos. Programando em C Para Linux, Unix e Windows. Rio de Janeiro: Brasport, 2005.

• MIZRAHI, Victorine Viviane. Treinamento em Linguagem C – Curso Completo. São Paulo: Makron, 1999.

Page 281: Programação 2 Linguagem C (UFRPE)

101

Programação 2

Vamos revisar?

Vamos fazer uma revisão do assunto que foi visto neste capítulo, lendo o resumo a seguir:

• Os arquivos servem para armazenar nossos dados de forma definitiva.

• Os arquivos binários são adequados para o armazenamento de registros.

• Cada registro que é armazenado no arquivo ocupa a mesma quantidade de memória.

• Toda operação sobre um arquivo será executada no ponto onde o leitor se encontra.

• Com o comando fseek, podemos colocar o leitor sobre o registro que desejamos ler ou gravar.

• Só podemos manipular um arquivo que esteja aberto. Após o uso do arquivo, devemos fechá-lo.

• O arquivo criado pelo programa é salvo no mesmo diretório em que está armazenado o nosso programa executável.

Page 282: Programação 2 Linguagem C (UFRPE)

102

Programação 2

Considerações Finais

Neste volume, tivemos a oportunidade de aprender como armazenar dados em vetores, registros e arquivos. O armazenamento adequado dos dados possibilitou o desenvolvimento de programas com operações mais elaboradas como: cadastro de elementos, remoção, alteração, consultas e listagens. Perceberam o quanto nossos programas evoluíram desde o nosso primeiro programa completo, até hoje? Vejam que todos os conceitos que aprendemos estão sempre em uso nos nossos programas. Isto é bom porque nos acostumamos com a sintaxe dos comandos. Agora, temos apenas mais um módulo para finalizar a nossa caminhada, em busca do aprendizado da linguagem de programação C. Continuem firmes nos estudos! Estamos quase no final! Até o próximo módulo.

Page 283: Programação 2 Linguagem C (UFRPE)

103

Programação 2

Referências

ARAÚJO, Jairo. Dominando a Linguagem C. São Paulo: Ciência Moderna, 2004.

ASCENIO, Ana Fernanda Gomes e CAMPOS, Edilene Aparecida Veneruchi. Fundamentos de Programação de Computadores. São Paulo: Prentice Hall, 2002.

DEITEL, H, M e DEITEL, P. J. Como Programar em C. Rio de Janeiro: LTC, 1999.

LAUREANO, Marcos. Programando em C Para Linux, Unix e Windows. Rio de Janeiro: Brasport, 2005.

MIZRAHI, Victorine Viviane. Treinamento em Linguagem C – Curso Completo. São Paulo: Makron, 1999.

MONTGOMERY, Eduard. Programando em C: Simples e Prático. São Paulo: Alta Books, 2006.

OLIVEIRA, Ulisses. Programando em C – Volume I – Fundamentos. São Paulo: Ciência Moderna, 2004.

SCHILDT, Herbert. C Completo e Total. São Paulo: Makron, 1996.

Page 284: Programação 2 Linguagem C (UFRPE)

104

Programação 2

Conhecendo a Autora

Sou graduada em Ciência da computação pela Universidade Federal de Sergipe. Fiz mestrado e doutorado na Universidade Federal de Pernambuco, desenvolvendo pesquisas nas áreas de Sistemas Distribuídos e Geoprocessamento. Começei a ensinar em 2000, nos cursos de Ciência da Computação e Sistemas de Informação. Desde o início da minha carreira como professora, ministro disciplinas de Programação e tenho uma paixão pela linguagem C. Atualmente, encontrei uma nova paixão: Educação a Distância.