Você está na página 1de 258

1

2
Reitor

Prof. Ms. Stefano Barra Gazzola

Gestão da Educação a Distância

Prof. Ms. Wanderson Gomes de Souza

Design Instrucional e Diagramação

Diógenes Caxin

Isabella de Menezes

Revisão Ortográfica / Gramatical

Erika de Paula Sousa

3
Autor

SIDNEY VERGINIO DA SILVA

Bacharel em Sistemas de Informação (2010) e Pós-Graduado


MBA em Gestão de Tecnologia da Informação (2012), ambos
pelo Centro Universitário do Sul de Minas. Atua na área de
desenvolvimento de sistemas, Auditoria e Segurança de TI.
Professor de minicursos e palestras sobre Segurança de
Sistemas de Informação e Pacote MS Office.

4
SILVA, Sidney Verginio da.

Guia de Estudo – Fundamentos da


programação de computadores. Varginha:
GEaD, UNIS-MG, 2013.

258 p.

I. Título.

5
Sumário

EMENTA DA DISCIPLINA ...............................................................................15

OBJETIVOS GERAIS ..........................................................................................15

OBJETIVOS ESPECÍFICOS ............................................................................16


PALAVRAS-CHAVE: ............................................................................................................... 17
UNIDADE I – INTRODUÇÃO .................................................................................................. 19

META ..........................................................................................................................19

OBJETIVOS DA UNIDADE..............................................................................19

1. INTRODUÇÃO...............................................................................................20

1.1. Definição de algoritmo .......................................................................21

1.1. Algoritmos e programas de computador ................................26

1.2. Estrutura de um algoritmo ................................................................31

1.3. Sintaxe e Semântica ............................................................................33

1.4. APONTAMENTOS PARA A PRÓXIMA UNIDADE ..................35


UNIDADE II – ALGORITMOS COMPUTACIONAIS .................................................................. 37

META ..........................................................................................................................37

OBJETIVOS DA UNIDADE..............................................................................37

2. FUNDAMENTOS DE PROGRAMAÇÃO COM


ALGORITMOS....................................................................................................38

2.1. Tipos de Dados .......................................................................................38

6
2.1.1. Numérico ................................................................................................40

2.1.2. Literal .........................................................................................................40

2.1.3. Lógico .......................................................................................................41

2.2. Variáveis e Constantes........................................................................49

2.2.1. Declaração ............................................................................................53

2.3. Comentários ..............................................................................................60

2.4. Comando de Atribuição .....................................................................61

2.5. Comandos de Entrada e Saída .....................................................66

2.6. Expressões e operadores..................................................................73

2.6.1. Expressões aritméticas ..................................................................75

2.6.2. Expressões lógicas ...........................................................................78

2.7. Estruturas de Controle ........................................................................82

2.7.1. Sequência ..............................................................................................83

2.7.2. Estrutura Condicional ......................................................................85

2.7.3. Estrutura de Repetição ...................................................................93

2.7.3.1. Comando Repita ............................................................................95

2.7.3.2. Comando Enquanto ................................................................. 108

2.7.3.3. Comando Para ............................................................................. 109

2.8. Estruturas de dados........................................................................... 114

2.8.1. Vetores .................................................................................................. 114

7
2.8.2. Matrizes ................................................................................................ 121

APONTAMENTOS PARA A PRÓXIMA UNIDADE............................ 130


UNIDADE III – A LINGUAGEM DE PROGRAMAÇÃO C ......................................................... 132

META ....................................................................................................................... 132

OBJETIVOS DA UNIDADE........................................................................... 132

PRÉ-REQUISITOS............................................................................................. 133

3. INTRODUÇÃO À LINGUAGEM C .................................................... 133

3.1. Primeiras Definições ......................................................................... 134

3.2. Histórico da Linguagem C ............................................................. 142

3.3. Tipos de Dados .................................................................................... 146

3.4. Variáveis e Constantes..................................................................... 148

3.5. Operadores ............................................................................................. 156

3.5.1. Operadores de atribuição.......................................................... 156

3.5.2. Operadores Aritméticos .............................................................. 157

3.5.3. Operadores Lógicos e Relacionais ...................................... 161

3.6. Comandos de entrada e saída ................................................... 163

3.7. Estruturas de Controle ..................................................................... 180

3.7.1. Estruturas Condicionais Simples .......................................... 180

3.7.2. Estruturas Condicionais Compostas................................... 182

3.7.3. Estrutura de Seleção Múltipla ................................................. 186

8
3.7.4. Estruturas de Repetição.............................................................. 189

3.7.5. Outros comandos de controle de fluxo ............................. 195

3.8. Modularização ...................................................................................... 200

3.8.1. Funções ................................................................................................ 202

3.8.2. Passagem de valores para funções .................................... 206

3.9. Estruturas de Dados .......................................................................... 208

3.9.1. Matriz Unidimensional ................................................................. 208

3.9.2. Matrizes Bidimensionais............................................................. 215

3.9.3. Estruturas............................................................................................. 216

3.10. Operações com Arquivos na Linguagem C ................... 223

3.10.1. Definições ....................................................................................... 224

3.10.2. Formas de acesso ..................................................................... 225

3.10.3. Operações com arquivos ...................................................... 231

3.10.4. Estruturas de dados em arquivos..................................... 239


FINALIZANDO ..................................................................................................................... 255
REFERÊNCIAS ..................................................................................................................... 257

9
10
Caro(a) leitor(a),

Certa vez, durante minha graduação, li em um livro que


computadores sabem apenas somar e subtrair. A afirmação, um
tanto estranha, ao longo do curso mostrou-se uma grande
verdade. Afinal de contas, um computador só faz as operações
básicas da matemática: soma, subtração, multiplicação e
divisão. Partindo do princípio que dividir é diminuir, e multiplicar
significa somar várias vezes, pode-se dizer que os
computadores só sabem somar e subtrair.

11
Claro que não devemos levar isso ao pé da letra, mas o exemplo
acima não é totalmente mentira. Mesmo os grandes softwares e
controles extremamente complexos possuem por trás
poderosos computadores capazes de efetuar diversas
operações por segundos, mas sempre, operações binárias (ou
seja, somente somando e subtraindo 0 e 1).

Em cima deste contexto é que apresento a você o Guia de


Estudos da Disciplina de Fundamentos da Programação de
Computadores. Veremos nas próximas páginas deste guia e
nas nossas atividades como se dá a construção de programas
de computador, e ao final do semestre você será capaz de
construir seus próprios programas de computador.

A programação de computadores é parte importante na vida


profissional de um Engenheiro, seja qual for sua área de
atuação. Isso porque diversos sistemas de informação ou
softwares de simulação ou auxílio à construção de modelos
(CAD) utilizam fundamentos de programação para funcionarem.

12
Esta disciplina visa justamente dar a você, aluno, condições de
entender a lógica existente na construção de programas, dando-
lhe condições necessárias para trabalhar com softwares que
exijam conhecimentos em linguagem de programação. Claro
que existem diversas linguagens no mundo, cada uma com sua
aplicação e regras próprias, e seria impossível tratar de todas
elas em um único curso, quanto mais em uma disciplina.
Entretanto, os fundamentos aqui apresentados permitem que
você possa aprender outras linguagens em estudos futuros, pois
embora os comandos e funções sejam diferentes, a lógica na
construção de programas é a mesma.

Como ex-aluno sei que no início tudo isso parecerá um enorme


bicho de sete cabeças e nada fará sentido. Mas garanto que
com empenho e acompanhamento diário de nossas atividades
você dominará todo o conteúdo aqui proposto. Não deixe suas
atividades acumularem, tente sempre sanar suas dúvidas e
procure materiais extras caso precise de maiores explicações. A
Biblioteca Virtual e a internet estão aí para isso.

Sinta-se à vontade para entrar em contato sempre que tiver


dúvidas. Sugestões e exemplos práticos serão sempre muito

13
bem-vindos! Tenho certeza que muitos alunos possuem
experiências que podem contribuir enormemente para nossos
estudos.

Desejo-lhe muito sucesso não somente nesta etapa, mas


também ao longo de todo o curso e de sua vida. Conte comigo!

Grande abraço e mãos à obra!

Prof. Sidney Verginio da Silva

“Algo só é impossível até que alguém duvide

e acabe provando o contrário.”

Albert Einstein

14
EMENTA DA DISCIPLINA

Técnicas de programação de Computadores: algoritmos e


estruturas de dados; técnicas de projeto e desenvolvimento de
algoritmos; tipos de dados: conceituação, formas de
representação, manipulação. Recursos gráficos. Definição e
manipulação de arquivos externos. Elaboração e
implementação de programas em uma linguagem de
programação.

OBJETIVOS GERAIS

Apresentar as principais técnicas utilizadas na programação de


computadores, utilizando, para tanto, o conceito de Algoritmos;

Trabalhar o desenvolvimento de programas na linguagem C,


fornecendo ao aluno conhecimento sobre o desenvolvimento de
programas de computador.

Capacitar o aluno a estruturar, através dos conhecimentos


adquiridos, programas de computador que possam atingir
objetivos propostos na disciplina, contribuindo, assim, para lidar
com estas atividades de programação de computadores em
sua vida profissional.

15
OBJETIVOS ESPECÍFICOS

Conceituar Algoritmos, sua estrutura e formas de apresentação.

Apresentar ao aluno os processos utilizados para construção de


algoritmos computacionais, bem como técnicas para
construção destes algoritmos.

Expor os principais tipos de dados usados na construção de


programas, trabalhando a manipulação dos mesmos.

Fornecer conhecimentos e técnicas para implementação de


programas na linguagem de programação C.

Trabalhar com os diferentes tipos de dados e seu


processamento na linguagem C, bem como as estruturas de
interação com o usuário e fluxos de controle nos programas.

Avaliar o conhecimento adquirido pelo aluno através de fóruns,


atividades práticas e avaliação presencial.

Capacitar o aluno a desenvolver programas de computador que


atinjam objetivos específicos.

16
PALAVRAS-CHAVE:

Algoritmos. Técnicas de Programação. Linguagem de


Programação C.

17
18
UNIDADE I – INTRODUÇÃO

META

Apresentar ao aluno uma visão inicial sobre algoritmos e como


estes podem ser utilizados para descrever tarefas que visem
atingir determinado objetivo.

OBJETIVOS DA UNIDADE

Esperamos que, após o estudo do conteúdo desta unidade,


você seja capaz de:

1. Compreender como se dá o processamento de

dados em computadores – entrada, processamento

e saída;

2. Entender o conceito de Algoritmo, sua estrutura

básica e formas de representação;

19
3. Visualizar a relação existente entre Algoritmos e

programas de computador;

4. Escrever Algoritmos não computacionais.

1. INTRODUÇÃO

O processamento de dados em um computador consiste em


tomar determinados dados (números, textos, datas...), processá -
los conforme determinadas regras e atributos e após este
processamento obter os resultados esperados. Desde a
invenção dos primeiros computadores, tem sido constante a
busca por mecanismos que tornassem o processamento de
dados mais ágil, dinâmico e eficaz.

Como dito na apresentação da disciplina, computadores não


fazem nada senão processar bits (os famosos 0 ou 1); ou seja,
computadores não sabem nada, apenas executam aquilo para
o qual são programados. Portanto, o sucesso de um programa
de computador está justamente na forma como este é
construído, e isso depende unicamente do programador do
software.

20
Antes de tratar sobre formas para escrever programas de
computador, devemos ter em mente que o computador ou
software fará somente o que indicarmos, portanto, é vital que
“digamos” ao computador exatamente o que ele deve fazer para
que o programa execute corretamente a tarefa. Em suma, é
necessário entender primeiramente o que é um Algoritmo para
depois entendermos como ele é importante para a
programação de computadores.

1.1. Definição de algoritmo

Antes de entendermos de fato o que é um algoritmo, imagine


que alguém o pergunte como ligar um computador. Ou então,
algo mais simples: como se coloca um prego na parede? Talvez
você dissesse algo como:

Segurar o prego sobre a parede com a mão esquerda;

Bater com o martelo no prego, com a mão direita;

Verificar se o prego já está no ponto certo;

21
Se não estiver, repetir todos os passos. Se estiver no ponto
certo, parar a ação.

Veja que este exemplo simples mostra, passo a passo, como


resolver determinado problema (colocar o prego na parede).
Para isso, a pessoa deve seguir uma ordem correta de tarefas
(ações).

Pense:

O que aconteceria se você invertesse algum dos


passos? A pessoa conseguiria colocar o prego na
parede? E se a pessoa for canhota? Não correria o risco de
manusear mal o martelo e bater no próprio dedo?

Vejamos agora como seria o algoritmo para “chupar uma bala”:

Exemplo:

Pegar a bala;

22
Com as duas mãos, retirar o papel da bala;

Colocar a bala na boca;

Jogar o papel no lixo.

Este exemplo mostra a “essência” de um Algoritmo, e, por


consequência, de um programa de computador. Lembra
quando dissemos que um computador deve ser informado
exatamente sobre como deve fazer cada ação? É exatamente
essa a função de um algoritmo, informar passo a passo como o
computador deve realizar uma tarefa. Mas isso não serve
somente para programas de computador.

Note que esta sequência de passos é o que se pode chamar de


um algoritmo para atingir a solução de um problema (chupar a
bala). Claro que algoritmos construídos para computadores não
são tão simples e nem apresentados como acima (SANT’ANA,
2010). Entretanto, o conceito da programação é o mesmo
conceito de algoritmos, ou seja, PROGRAMAR É CONSTRUIR
ALGORITMOS.

Sant’ana (2010) cita os conceitos básicos de um algoritmo:

É a descrição, de forma lógica, dos passos a serem executados


no cumprimento de determinada tarefa.

23
Serve como modelo para programas, pois sua linguagem é
intermediária à linguagem humana e às linguagens de
programação, sendo então, uma boa ferramenta na validação
da lógica de tarefas a serem automatizadas.

Como qualquer modelo, um algoritmo é uma abstração da


realidade. A abstração é o processo de identificar as
propriedades relevantes do fenômeno que está sendo
modelado.

Usando o modelo abstrato, podemos nos centrar unicamente


nas propriedades relevantes para nós, dependendo da
finalidade da abstração, e ignorar as irrelevantes.

É a forma pela qual descrevemos soluções de problemas do


nosso mundo, a fim de serem implementadas utilizando os
recursos do mundo computacional. Existem regras básicas na
forma de solucionar os problemas. A partir disso, podemos
então utilizar os recursos de hardware e software disponíveis.

Realize:

Utilizando os exemplos acima, escreva como


seria um algoritmo para trocar o pneu de um carro e outro
algoritmo para escovar os dentes.

24
Existem diversas definições para o termo Algoritmo. Farrer
(1989) já definia como “[...] um conjunto de comandos, que
obedecidos, resultam numa sucessão finita de ações”. Sant’ana
(2010) define algoritmo como sendo “[...] uma sequência finita de
passos que levam à execução de uma tarefa para solução de
um problema”.

Ainda segundo Sant’ana (2010), um algoritmo é como uma


receita ou uma sequência de instruções que atendem um
objetivo específico. Estas instruções devem ser claras e
precisas, pois do contrário, o objetivo não será atingido (como o
caso da troca de ordem das tarefas ao se colocar o prego na
parede).

Resumindo, um algoritmo deve sempre:

Ter início e fim.

Ser escrito em termos de ações não ambíguas e bem definidas.

Ter ações que sigam uma sequência ordenada (SANT’ANA,


2010, p. 13).

25
1.1. Algoritmos e programas de computador

Como dito no item anterior, programar é basicamente construir


algoritmos. Ora, se o algoritmo é uma sequência lógica de
passos que levam à solução de um problema, um programa de
computador nada mais é que a escrita deste algoritmo em uma
determinada linguagem de computador.

A regra é que um algoritmo seja fácil de interpretar e de


codificar. Ele atua como intermediário entre a linguagem
humana e uma linguagem de programação. Sant’ana (2010)
apud Buffoni (2003) descreve algumas formas de se representar
um algoritmo:

Em uma língua (português, inglês), como utilizado nas receitas,


instruções, manuais, etc.

Uma linguagem de programação ( Pascal, Cobol, C , etc.),


utilizada por programadores experientes.

Representações gráficas, como fluxograma, diagramas de


Nassi-Scheniderman , método de Jackson e diagramas de
Warnier-Or.

26
A Figura 1 abaixo apresenta alguns exemplos de se representar
um algoritmo.

Fonte: SANT'ANA (2010, p.15)

Agora veja: existem diversas linguagens para se construir


programas de computador, mas se você tiver o algoritmo
construído, é possível implementá-lo em qualquer linguagem.
Vejamos um exemplo simples: Imagine que um médico queira
calcular a temperatura média aferida em um paciente. Para

27
tanto, ele monitorou a temperatura do paciente em três
momentos, obtendo:

Período da manhã: 37º C

Período da tarde: 40º C

Período da noite: 38º C

Como seria o algoritmo para calcular a média destas


temperaturas?

{Algoritmo Exemplo Temperatura}

Algoritmo

declare temperatura1, temperatura2,


temperatura3: numerico;
declare media: numerico;

leia temperatura1, temperatura2, temperatura3;


media = (temperatura1 + temperatura2 +
temperatura3) /3;
escreva media;

fimalgoritmo

Este mesmo problema seria resolvido da seguinte forma na


linguagem Pascal:

28
Program ExemploTemperatura;
var temperatura1, temperatura2, temperatura3,
media: real;

begin
write ('Digite a primeira temperatura:');
readln (temperatura1);

write ('Digite a segunda temperatura:');


readln (temperatura2);

write ('Digite a terceira temperatura:');


readln (temperatura3);

media = (temperatura1 + temperatura2 +


temperatura3)/3;

write ('Temperatura média do paciente:', media);


end.

Ou mesmo na linguagem Java:

public class MediaTemperatura {


double temperatura1, temperatura2, temperatura3,
media;

double CalculaMedia() {
media = (temperatura1+ temperatura2 +
temperatura3) /3;
return media;
}
}

29
Note que, independentemente da linguagem utilizada para
construir o programa, a construção do primeiro algoritmo foi
base para a criação dos programas nas outras linguagens.
Foram definidos os passos (digitar as 3 temperaturas, somá-las
e então dividir por 3) necessários para resolver o problema
(calcular a média de três temperaturas); uma vez definidos os
passos, podemos implementá-los em qualquer linguagem de
programação.

Portanto, o algoritmo é o ponto de partida


para escrita de um programa em qualquer
linguagem de computador. Um programa
escrito nada mais é do que um algoritmo
implementado em determinada linguagem (Pascal, C, Java, C#,
PHP, etc.).

Uma vez explicado o que é um algoritmo e sua importância em


relação aos programas de computador, vejamos como ele é
estruturado.

30
1.2. Estrutura de um algoritmo

Sant’ana (2010) cita que o desenvolvimento de um algoritmo


deve ser feito considerando a seguinte estrutura básica:

Entrada: São os dados de entrada do algoritmo (como textos e


números).

Processamento: São os procedimentos utilizados para chegar


ao resultado final.

Saída: São os dados já processados, o resultado final .

Realize

Considere o algoritmo criado para calcular a média


de temperatura de um paciente. Quais seriam os

31
dados de entrada? Quais os dados de saída? Qual
processamento foi feito, a partir dos dados de entrada, para se
chegar aos dados de saída?

Como vimos, o algoritmo possui sempre uma sequência de


passos para se atingir um objetivo. É muito importante sempre
construir algoritmos usando expressões e comandos claros,
pois isso permitirá sua compreensão e fará com que seja
facilmente transcrito para uma linguagem de computador. Além
disso, a estrutura acima (entrada, processamento e saída) nos
orienta sobre quais ações estão presentes em um algoritmo, e a
partir disso é possível escrever os comandos de acordo com
esta estrutura.

Em nossos estudos, usaremos sempre uma estrutura padrão


para escrever nossos algoritmos:

Algoritmo

{comandos do algoritmo}

fimalgoritmo

32
As palavras Algoritmo e fimalgoritmo são chamadas palavras-
chave. Estas são palavras que possuem funções próprias dentro
de um algoritmo, devendo ser usadas para ações específicas.
Assim, para iniciar um algoritmo você sempre deverá usar a
palavra-chave Algoritmo e ao finalizar seu código, fimalgoritmo.
Veremos mais sobre palavras-chave adiante.

Atenção!

O esquema apresentado não é uma regra


imutável para a construção de algoritmos. Ao
consultar outras obras, certamente você encontrará diversas
formas de representar um algoritmo. Entretanto, usaremos este
modelo em nossos estudos de forma a padronizar as atividades
e exemplos, pois ele possui um formato que permite melhor
entendimento, além de ser usualmente mais utilizado.

1.3. Sintaxe e Semântica

Antes de continuarmos os estudos sobre construção de


algoritmos, é importante entender dois conceitos fundamentais
de toda linguagem de programação: Sintaxe e Semântica.

33
A sintaxe consiste em um conjunto de regras formais,
que especificam a composição de programas a partir
de letras, dígitos, e outros símbolos. Por exemplo,
regras de sintaxe podem especificar que cada
parênteses aberto em uma expressão aritmética
deve corresponder a um parêntese fechado, e que
dois comandos quaisquer devem ser separados por
um ponto-e-vírgula. As regras de semântica
especificam o “significado” de qualquer programa,
sintaticamente válido, escrito na linguagem.
(SANT’ANA, 2010, p.80)

Em outras palavras, ao construir algoritmos, devemos sempre


ter o cuidado de usar as palavras-chave corretamente, bem
como os comandos e símbolos daquela linguagem (como
parênteses, ponto-e-vírgula, etc.). Erros no uso destes comandos
representam erros de sintaxe. Os erros de semântica estão mais
relacionados à “lógica” do código, como, por exemplo, tentar
abrir um arquivo que não existe ou efetuar cálculos com
números não lidos.

Atenção!

Tenha sempre atenção à correta escrita e ordem


dos comandos para evitar erros de sintaxe e
semântica em seus algoritmos.

34
E esta foi nossa primeira unidade. Vimos o
que são os algoritmos e como é sua estrutura
básica. A partir do que estudamos, você já
pode escrever algoritmos que descrevem
situação reais de seu dia a dia. Devemos sempre lembrar que
um algoritmo deve ser escrito em termos de expressões
simples, claras e objetivas. Um algoritmo pode ser uma
excelente ferramenta para descrever corretamente como
executar determinados passos para se atingir um objetivo.

1.4. APONTAMENTOS PARA A PRÓXIMA UNIDADE

Na próxima unidade veremos como escrever algoritmos para


resolução de problemas utilizando computadores (algoritmos
computacionais). Aprenderemos diversos comandos utilizados
para escrita de programas usando a linguagem de algoritmos.

35
36
UNIDADE II – ALGORITMOS COMPUTACIONAIS

META

Trabalhar com o desenvolvimento de algoritmos


computacionais, escrevendo e implementando programas de
computador usando a linguagem de Algoritmos.

OBJETIVOS DA UNIDADE

Esperamos que, após o estudo do conteúdo desta unidade,


você seja capaz de:

1. Entender a representação de programas de

computador através da linguagem de Algoritmos;

2. Demonstrar conhecimento sobre lógica de

programação;

37
3. Utilizar os principais tipos de dados e estruturas

para elaboração de algoritmos computacionais;

4. Desenvolver, utilizando o programa Visualg, seus

próprios algoritmos.

2. FUNDAMENTOS DE PROGRAMAÇÃO COM


ALGORITMOS

Agora que você conhece bem o que é um algoritmo e sua


estrutura básica, vejamos como estruturá-los e quais os
comandos utilizados para escrever programas de computador.

2.1. Tipos de Dados

Quando desenvolvemos um algoritmo para resolução de um


problema, é importante que tenhamos em mente que tipo de
informação (dados) o algoritmo irá receber, processar e
apresentar como resultados. Por exemplo: ao se criar um
algoritmo para cadastro de telefones (agenda), deve-se ter em

38
mente que informações serão cadastradas, como nome,
telefone, data de aniversário, etc. Ou seja, teremos números
(telefone, data de aniversário) e textos (nome) neste algoritmo,
que deverá ser construído levando em conta esta configuração.

O estudo dos tipos de dados que serão utilizados nos algoritmos


é de suma importância, pois determinará como será a
construção e o tratamentos dos dados no algoritmos. Vejamos
que tipos de dados podem ser utilizados:

Tabela 1: Tipos de dados

Nome Tipo de Valor possível

Numérico Números

Literal Caracteres e conjunto de caracteres


(palavras)

Lógico Valores lógicos (Falso e Verdadeiro)

Fonte: (O autor)

39
2.1.1. Numérico

São valores estritamente numéricos, podendo ser negativos,


positivos, inteiros ou racionais. São exemplos de valores
numéricos:

2.1.2. Literal

São valores representados por caracteres ou cadeia de


caracteres – letras e expressões. Devem sempre vir entre aspas
(“ ”) indicando que se trata de texto. Alguns exemplos:

40
Obs.: Note que um número apresentado entre aspas será
tratado sempre como um texto. Valores numéricos devem vir
sem aspas.

2.1.3. Lógico

São variáveis que podem assumir valores “FALSO” ou


“VERDADEIRO”. Mas para entender este tipo de dados, é preciso
entender o que são proposições.

No desenvolvimento de algoritmos, tal como em lógica


matemática, as proposições são afirmações que fazemos,
como, por exemplo:

O céu é azul.

A frase acima se trata de uma proposição (afirmação)


verdadeira, pois de fato, o céu é azul. Já a afirmação abaixo é
falsa:

O céu é verde.

41
No desenvolvimento de algoritmos, podemos encontrar com
situações parecidas, tais como:

2+3=5

5–1=4

6 + 9 = 20

0–0=1

Enfim, situações que precisamos verificar se são falsas ou


verdadeiras.

A característica básica das proposições é que sua resposta será


sempre SIM ou NÃO. Portanto, “choveu a noite?” é uma
proposição, já “Aonde vamos amanhã?” não é uma proposição,
pois a resposta não será Sim ou Não.

Sobre as proposições, é possível realizar comparações e


operações. A isso chamamos de álgebra de proposições.

 CONJUNÇÃO (E)

A conjunção trata da união de duas ou mais proposições. Para


que a proposição final seja considerada verdadeira, ambas as

42
proposições deverão ser verdadeiras. Caso ao menos uma seja
falsa, a conjunção será falsa. A representação é:

Considere as seguintes proposições:

x = Belo Horizonte é a capital do estado de Mato Grosso

y = São Paulo é a capital do estado de São Paulo

z=2–1=1

a=5+5=9

Fazendo a operação de conjunção, teríamos:

x e y = FALSO, pois x = “Belo Horizonte é a capital do estado de


Mato Grosso” (falso) e y = “São Paulo é a capital do estado de
São Paulo” (verdadeiro). Como a primeira proposição é falsa, a
união de ambas resulta em falso;

43
z e y = VERDADEIRO, pois z = 2 – 1 = 1 (verdadeiro) e y = “São
Paulo é a capital do estado de São Paulo” (verdadeira). Como as
proposições são verdadeiras, a união de ambas resulta em
verdadeiro;

x e a = FALSO, pois x = “Belo Horizonte é a capital do estado de


Mato Grosso” (falso) e a = 5 + 5 = 9 (falso). Como as proposições
são falsas, a união de ambas resulta em falso.

É possível resumir esta condição na seguinte tabela:

Tabela 2: Tabela Verdade Conjunção

Fonte: SANT'ANA (2010)

44
Qual o resultado das conjunções abaixo?

 DISJUNÇÃO (OU)

Na disjunção, a combinação de ao menos uma proposição


verdadeira resulta em verdadeiro. A combinação das
proposições através da conjunção “OU” considera que “ou
temos uma afirmação OU temos outra afirmação”. Em qualquer
caso, basta que uma seja verdadeira para que a união de
ambas resulte em verdadeiro.

Retomemos o exemplo anterior. No caso, a disjunção das


proposições já citadas resultaria em:

x ou y = VERDADEIRO, pois x = “Belo Horizonte é a capital do


estado de Mato Grosso” (falso) ou y = “São Paulo é a capital do
estado de São Paulo” (verdadeiro). Como a segunda proposição
é verdadeira, a união de ambas resulta em verdadeiro;

45
z ou y = VERDADEIRO, pois z = 2 – 1 = 1 (verdadeiro) ou y = “São
Paulo é a capital do estado de São Paulo” (verdadeira). Como as
proposições são verdadeiras, a união de ambas resulta em
verdadeiro;

x ou a = FALSO, pois x = “Belo Horizonte é a capital do estado de


Mato Grosso” (falso) ou a = 5 + 5 = 9 (falso). Neste caso, não
temos nenhuma proposição verdadeira, portanto, a disjunção de
ambas resulta em falso.

É possível resumir esta condição na seguinte tabela:

Tabela 3: Tabela Verdade Disjunção

Fonte: SANT'ANA (2010)

46
Qual o resultado das conjunções abaixo?

 Negação (NÃO)

Dada uma proposição p qualquer, sua negação consiste em


escrever um “não” ou então é “falso que” antes da preposição p.

Vejamos:

não x = resulta em VERDADEIRO, pois não x => “Belo Horizonte


não é a capital do estado de Mato Grosso”, o que é verdadeiro
(poderíamos escrever “É falso que Belo Horizonte é a capital do
estado de Mato Grosso”) .

não z = FALSO, pois não z => 2 – 1 não é 1 (ou é falso que 2 - 1 =


1), o que é falso.

47
não a = VERDADEIRO, pois não a => 5 + 5 não é igual a 9
(estamos negando que 5 + 5 = 9), o que é verdadeiro.

É possível resumir esta condição na seguinte tabela:

Tabela 4: Tabela Verdade Negação

Fonte: SANT'ANA (2010)

Escreva abaixo a negação e o resultado das seguintes


negações:

Assim, podemos ter situações em que uma variável assuma


uma determinada condição, como “verdadeiro” ou “falso”,
servindo de verificação em determinado ponto de seu algoritmo.
Veremos isso com mais exatidão quando tratarmos de
estruturas condicionais.

48
Uma vez que definimos os tipos de dados existentes, agora
devemos entender outro importante conceito em programação:
Variáveis e Constantes.

2.2. Variáveis e Constantes

Voltemos agora às aulas de informática básica... Lembra-se da


Memória RAM (Random Access Memory – Memória de Acesso
Randômico)?

Figura 1: Memória RAM

Fonte: http://compumaxinformatica.com.br/produto/Memoria-RAM-DDR-I-
1GB-533Mhz.html

49
A memória RAM é um tipo de memória para armazenamento
rápido e temporário de dados pelo computador. Nela são
armazenados dados que são utilizados pelos programas em
execução. Ela é volátil, pois ao desligar o computador ou
encerrar o programa, os dados que estavam armazenados são
apagados. Bom, mas o que isso tem a ver?!

Quando criamos programas ou algoritmos, deve-se levar em


consideração que o mesmo trabalhará com diversos dados, que
precisam ser armazenados na memória RAM para que o
computador possa processá-los. Por exemplo, numa soma
simples (5+5 =10), você deve no mínimo reservar uma área de
memória para armazenar o resultado (10), pois do contrário seu
programa não terá como mostrar o resultado.

Assim, quando falamos de VARIÁVEIS, estamos na verdade


falando de um espaço na memória RAM do computador que
ficará reservado para guardar algum dado que será utilizado
pelo nosso programa. Normalmente, este dado só será
conhecido no momento de executar o programa (como no
algoritmo da agenda, onde só saberemos os nomes dos
contatos na hora de cadastrá-los.)

Tomemos como exemplo a soma de 2 números: vamos


representar esta soma através da equação X + Y = Z. O

50
esquema abaixo representa a memória RAM do computador
para executar este cálculo:

Note que reservamos três partes da memória RAM do


computador para armazenar dados referentes à nossa soma.
No momento, não sabemos exatamente quais são estes valores,
pois na hora de executar o programa, cada usuário pode digitar
um valor diferente para X e Y, fazendo com que o valor de Z
também varie em função da soma de X e Y. Por isso damos o
nome de variável, pois é uma área de memória que pode
receber valores diferentes (variáveis) em momentos diferentes.

Veja como ficaria este algoritmo:

{Algoritmo Exemplo Variáveis}

Algoritmo

declare X, Y, Z: numerico;

{desenvolvimento do algoritmo
Fimalgoritmo

51
No exemplo acima, estamos “declarando” (reservando espaço
em memória) 3 variáveis que irão receber apenas números. Ao
longo do programa, criaremos comandos para atribuir valores a
estas variáveis que então passarão a ocupar, com algum valor
numérico, espaço na memória do computador.

O conceito de CONSTANTES é similar ao de variáveis,


entretanto, como diz o nome, ao reservar uma área de memória
para constante, você deverá informar um valor e este será fixo
durante toda a execução do programa. Este conceito é
interessante quando no programa você possui valores fixos que
devem sempre ser utilizados. Por exemplo, no cálculo do
perímetro de uma circunferência:

Veja que neste exemplo não determinamos os valores para as


variáveis “raio” e “circunferência”, pois estes podem variar. No
entanto, “PI” é sempre uma constante, neste caso, com valor
3,14. Independentemente do raio ou tamanho da circunferência,
o valor de PI para o cálculo será sempre o mesmo.

52
2.2.1. Declaração

Como vimos, ao construir um algoritmo, deve-se “reservar” um


espaço de memória para receber os dados desejados durante a
execução do programa. Esta ação é chamada de Declaração
de variáveis. Declarar uma variável significa atribuir um nome a
este local de memória que receberá estes valores. Cada variável
(local da memória) pode ter somente valores do tipo associado
(caractere, numérico ou lógico).

Em algoritmo, a declaração de variáveis e constantes segue a


seguinte notação:

declare lista_de_identificadores nome_do_tipo;

declare: é uma palavra-chave do algoritmo que deve ser


sempre utilizada para declarações.

lista_de_identificadores: são os nomes escolhidos para as


variáveis, que devem estar separadas por vírgula.

nome_do_tipo: é uma das três palavras-chave: numérico, literal


ou lógico que indicam o tipo associado às variáveis. Após o tipo
deve ser inserido o ponto-e-vírgula.

53
Veja um exemplo:

declare NOTA, CODIGO numerico;

TESTE, SIM logico;

NOME, ENDERECO literal;

Note que você pode declarar as variáveis em várias linhas,


devendo apenas usar um comando “declare”. Ao declarar uma
variável ou constante, é muito importante ter atenção aos
nomes utilizados e à forma da escrita, já que a declaração
possui suas próprias regras. Assim, para criar os nomes dos
identificadores, você deve estar atento a:

O nome do identificador (variável) deve, obrigatoriamente, iniciar


com uma letra e os caracteres seguintes, letras ou dígitos, não
sendo permitido o uso de símbolos especiais, como @, . , /, + ,
etc., com exceção do _ ( underscore).

As letras devem ser maiúsculas.

Caracteres com acento são considerados especiais, como por


exemplo: é, á, ó, í, ú, ã, ç, etc. Portanto, nunca os utilize.

Espaços em branco também não são permitidos.

54
Não fazer uso de palavras-chaves, ou seja, palavras que
possuem um significado próprio no algoritmo. Algumas
palavras-chaves (ou palavras reservadas) são: algoritmo,
fimalgoritmo, declare, leia, escreva, se, então, senão,
numérico, literal, lógico, repita, fim repita, interrompa.

É importante que os nomes dos identificadores sejam o mais


significativos possíveis para o contexto do dado que será
armazenado. Por exemplo, se uma variável receberá o nome de
uma pessoa, use como identificador a palavra NOME, assim
como DATA, SALARIO, MEDIA, RESULTADO etc. Veja que estes
nomes indicam por si só que dados elas armazenam.

55
Exercícios

1) Defina “constante” e cite três exemplos. Defina “variável” e


cite também três exemplos.

2) Identifique abaixo que tipo de valores (números, textos ou


Verdadeiro/Falso) podem armazenar as seguintes variáveis:

NOTA literal =

CONFERE logico =

NOTA numerico =

ENDERECO literal =

RUA numerico =

NOME literal =

56
3) Identifique agora se identificadores abaixo são válidos ou
não. Justifique os que você considerar inválidos.

X1E1 =

ENDEREÇO =

RUA =

NOME_FUNCIONÁRIO =

nome_aluno =

_90 =

E:1 =

2/SEMESTRE =

ANO(2012) =

LEIA_NOME =

57
4) Complete a tabela a seguir:

x y xey x ou y nao x (nao y) ou


y
V V
V F
F F
F V

5) Identifique os tipos de constantes abaixo (literal, numérica,


lógica):

a) 21

b) "VERDE"

c) "FALSO"

d) “0,21 * 102”

e) VERDADEIRO

f) - 3,54

58
6) Supondo-se que as variáveis NOME , PROFISSAO, IDADE e
SALARIO serão utilizadas em um algoritmo, para armazenar
respectivamente, o nome, a profissão, a idade e o salário de
uma pessoa, escreva o conjunto de declarações necessário
para criar essas variáveis (SANT'ANA, 2010).

7) Assinale com um X os nomes de variáveis válidos;


justifique os inválidos (SANT'ANA, 2010).

( ) DECLARE

( ) X&Z

( ) ALGORITMO

( ) X123

( ) XY

( ) guarda_chuva

( ) ABC DE

( ) ETC.

( ) FIMALGORITMO

59
2.3. Comentários

Durante a escrita de seu algoritmo, por melhor e maior que seja


o detalhamento e a declaração das variáveis e constantes, faz-
se necessário explicar melhor o funcionamento do mesmo. Mas,
como fazer isso?

É justamente neste ponto que entram os chamados


“comentários”. Como o próprio nome diz, são textos que
colocamos dentro do algoritmo e que não são interpretados
pelo interpretador do código, servindo apenas para explicar
melhor o funcionamento e lógica de determinada parte de seu
algoritmo. Comentários devem sempre ser escritos entre chaves
{ } ou duas barras invertidas //. Qualquer texto escrito dentro
das chaves não é interpretado pelo software. Vejamos um
exemplo:

Algoritmo
declare NUM1, //primeiro número a ser somado
NUM2, //segundo número a ser somado}
SOMA {soma dos dois números} numérico;
{ler os números}
{calcular sua soma}
{escrever a soma}
fimalgoritmo

60
Todos os valores entre chaves são comentários do algoritmo.

2.4. Comando de Atribuição

Um comando é uma determinada ação que desejamos que o


algoritmo cumpra. Peguemos por exemplo uma receita de bolo:
quando na receita lemos “acrescente 3 ovos”, esta ação é um
comando que deve ser feito para que o bolo seja feito
corretamente. Da mesma forma, em algoritmos, usamos
comandos para indicar uma sequência que o algoritmo deve
realizar. Um conjunto de comandos indica a lógica necessária
para que o algoritmo execute determinada tarefa com sucesso.

Um comando básico em algoritmos é a Atribuição. Atribuir


significa “dar um valor” à determinada variável, ou seja, carregá-
la com algum dado. Quando declaramos variáveis, elas são
criadas sem valor, apenas reserva-se espaço na memória do
computador. Ao atribuir um valor, estamos preenchendo este
espaço de memória com algum dado.

61
Atenção

Forma de Atribuição:

variável: é o nome da variável à qual está sendo atribuído o valor;

: é o símbolo de atribuição.

Quando declaramos uma variável, o programa reserva espaço


na memória do computador:

declare X,Y, Z numerico;

A literal;

CONFERE logico;

Resulta em:

X Y Z A CONFERE

Neste momento as variáveis estão vazias, apenas reservam


espaço para receber valores. Para atribuir algum dado a estas

62
variáveis, devemos efetuar o comando de atribuição, da
seguinte forma:

X 29

Y  X+1;

Z  X+Y;

A  “Algoritmo”;

Confere  Verdadeiro;

Após estes comandos, o resultado passa a ser:

Se logo após esta primeira atribuição usássemos o comando X


1, todos os demais valores dependentes de X seriam
alterados, pois atribuímos outro valor à variável X. O resultado
seria, portanto:

63
Lembre-se:

 à esquerda do sinal só é possível haver uma


variável;

 à direita, podemos ter uma variável, ou uma


constante ou uma expressão, desde que todas
sejam do mesmo tipo da variável da esquerda do
sinal ;

 o sinal não tem o sentido de igualdade, mas,


sim de atribuição; por exemplo:

X X + 1;

 como não representa sinal de igualdade, não


poderá ser usado em expressão lógica; não será
aceito, por exemplo ( A B e X > Y ), e sim ( A = B
e X > Y ). (SANT’ANA, 2010)

64
Vejamos outro exemplo prático:

Algoritmo
declare X, Y, Z numérico;
A, B, C literal;
L, M lógico;

X 23.45;
A  “TESTE”;
L Falso;
Y X + 2;
Z X + Y;
M L ou (Y > X);
C  “BEM”;
B A;
B  “A”;
X Z;
fimalgoritmo

Lembrando que a uma variável corresponde uma única posição


na memória, podemos observar que no final deste algoritmo as
variáveis X, Y, Z, A, B, C, L e M estarão valendo, respectivamente,
48.90, 25.45, 48.90, “TESTE”, “A”, “BEM”, Falso e Verdadeiro.

65
Como uma variável armazena apenas um valor de um único
tipo, a atribuição

X  “TESTE”

resultaria em erro, pois X é do tipo numérico, não podendo


receber valores de texto.

2.5. Comandos de Entrada e Saída

De nada adiantaria criar algoritmos para atribuir valores e


efetuar cálculos se não houvesse a interação com usuário. Essa
interação é o grande objetivo dos programas de computador,
pois afinal de contas, estes devem executar ações passadas por
usuários. Da mesma forma, um algoritmo deve sempre efetuar
ações e mostrar aos usuários os resultados obtidos após
execução de comandos. Para isso, existem dois comandos
importantes: comandos de entrada e de saída de dados.

66
 LEIA

Permite a introdução de dados na memória do computador


através do teclado. Sua forma geral é:

leia (lista de variáveis separadas por vírgula),

onde leia é uma palavra-chave e lista de variáveis deve conter


as variáveis citadas no declare.

Algoritmo
declare A, B {dois números quaisquer}
SOMA numerico; {soma dos dois números}
leia (A);
leia (B);
SOMA  A + B;
{escreva a resposta}
fimalgoritmo

Note que ao encontrar o comando leia o algoritmo fará com que


o computador aguarde a entrada dos valores de A e B.

67
 ESCREVA

O comando Escreva permite apresentar na tela os dados


obtidos após determinada operação, ou mesmo mostrar o valor
atual de determinada variável ou constante. Sua forma geral é:

escreva (lista de variáveis e/ou constantes separadas por


vírgula);

onde escreva é uma palavra-chave e a lista de variáveis ou


constantes deve vir separadas por vírgula, entre parênteses e
terminar com o ponto-e-vírgula.

Voltemos ao algoritmo anterior:

Algoritmo
declare A, B {dois números quaisquer}
SOMA numerico; {soma dos dois números}
leia (A);
leia (B);
SOMA  A + B;
escreva (SOMA);{escreva a resposta}
fimalgoritmo

68
Como dito anteriormente, ao encontrar o comando leia o
computador para a execução do algoritmo e aguarda que
valores sejam digitados para A e B. Assim, o usuário que está
usando o programa escrito a partir do algoritmo, não saberá que
o computador está aguardando, não sabendo o que digitar. Da
mesma forma ocorre durante a saída da resposta. Será
mostrado um número sem identificação. Para tanto, é
importante, sempre antes de cada comando leia ou escreva
utilizar frases que instruam ao usuário o que fazer em
determinado momento do algoritmo.

O algoritmo acima resultaria na tela do computador em:

56

11

69
Podemos melhorar o algoritmo anterior reescrevendo-o da
seguinte forma:

Algoritmo {cálculo de média}


declare A, B {dois números}, SOMA {soma de A e
B} numerico;
{leitura dos dados}
escreva (“Digite um Número: ”);
leia (A);
escreva (“Digite outro Número: ”);
leia (B);
SOMA  A + B ;
{saída do resultado}
escreva (“A soma dos dois números é: ”);
escreva (SOMA);
fimalgoritmo

No vídeo do computador, a saída seria:

70
Bem melhor, não?!

Revendo

Caro aluno, neste momento, vimos as 3 operações


básicas de um algoritmo: leitura, escrita e atribuição d e dados
às variáveis. Você já aprendeu a estrutura básica de um
algoritmo, como interagir com o usuário solicitando que ele
entre com dados em seu algoritmo e mostrando dados em tela.
Também já sabe como atribuir os dados digitados a uma
variável. Agora podemos partir para algo ainda mais prático.
Vamos aprender como utilizar um software para colocar nossos
algoritmos em funcionamento.

Realize.

Acesse a nossa Midiateca, na pasta da Disciplina, e baixe o


programa Visualg. Este é um programa que interpreta
algoritmos, executando os resultados através de um painel no
próprio programa ou então através de uma tela em MS-DOS.
Através dele podemos testar os algoritmos que escrevemos em
nossa disciplina.

71
Note que a sintaxe do Visualg difere um pouco da sintaxe que
usamos até o momento neste guia. Entretanto, aprender a
estrutura do Visualg não será difícil para você, que deverá
apenas fazer pequenos ajustes entre o algoritmo escrito e o
algoritmo trabalhado no Visualg.

Figura 2: Interface do Visualg

Fonte: Obra do autor

72
Realize

Acesse a Midiateca e assista ao vídeo sobre como


utilizar o Visualg.

Vamos agora aprender alguns comandos mais avançados em


algoritmos.

2.6. Expressões e operadores

Uma das grandes vantagens na construção de programas de


computador é poder realizar cálculos que seriam extremamente
demorados de se fazer a mão. A automatização de tarefas é
uma grande vantagem dos softwares. E para dar sentido à
construção de algoritmos melhor elaborados, vamos aprender
um pouco mais sobre expressões e operadores.

Uma expressão é a combinação de uma ou mais constantes


e/ou variáveis (neste caso operandos) com um ou mais
operadores (como símbolos matemáticos ou funções
predefinidas).

73
As constantes e/ou variáveis podem ser de qualquer tipo
(numérico, lógico ou literal), mas devem obedecer à
compatibilidade, ou seja, em uma expressão devemos ter
operadores e operandos de um único tipo. Portanto, em um
algoritmo, teremos sempre expressões numéricas OU literais OU
lógicas; nunca os três tipos em uma única expressão.

74
2.6.1. Expressões aritméticas

São aqueles que executam operações matemáticas. Os


operadores básicos são:

Tabela 5: Operadores Aritméticos Básicos

Fonte: Obra do autor

São exemplos de expressões aritméticas:

75
Tabela 6: Expressões Aritméticas

Fonte: Adaptado de FARRER (1989)

Algumas regras importantes:

1) Não se deve omitir o operador de multiplicação, o que é


comum nas expressões matemáticas, isso para evitar
confusão quanto aos nomes de variáveis. Em uma
expressão do tipo AB + C, como saber se AB é uma
variável ou a multiplicação dos conteúdos das variáveis A
e B? Neste caso, a forma correta poderia ser A * B + C.

76
2) As expressões aritméticas possuem ordem de

prioridade, tal como na matemática:

Tabela 7: Prioridade nas operações

Fonte: Obra do autor

Para alterar a ordem de resolução de uma expressão, tal como


na Matemática, devemos utilizar os parênteses – não são
utilizados chaves ou colchetes. Vários níveis de parênteses
podem ser utilizados para alterar a hierarquia na resolução da
expressão:

A  5 + 3 * 2 {resulta em 16}

A  (5+3) * 1 {resulta em 8}

77
Veja que o uso de parênteses altera o resultado da expressão.

Qual o resultado das seguintes expressões?


(5+3) + (5 + (2-2))

(0+1) * (0*0) + (20 / (1*2))

Implemente a operação abaixo no Visualg. Utilize o comando


leia e escreva para atribuir valores às variáveis e visualizar os
resultados:

A – B x (C+D) / ( (E-1) – F) + G

2.6.2. Expressões lógicas

Por vezes, a execução de determinada ação no algoritmo é


condicionada a determinada situação. Por exemplo, o algoritmo
pode executar diferentes ações para diferentes valores digitados
pelo usuário. Para verificar esta condição, usamos uma
expressão lógica. Uma expressão lógica é aquela cujos
operadores são lógicos e cujos operandos são relações e/ou

78
variáveis do tipo lógico (FARRER, 1989). A Tabela abaixo
apresenta os tipos de operadores existentes:

Tabela 8: Operadores Lógicos

Fonte: Obra do autor

79
Portanto, uma expressão de relação (lógica) é uma comparação
realizada entre dois valores do mesmo tipo básico. Estes valores
são representados por constantes, variáveis ou expressões
aritméticas. Vejamos alguns exemplos:

Veja que para cada uma das expressões acima, o programa


retornará um valor lógico, que pode ser falso ou verdadeiro.

Vamos para outro exemplo prático:

Dadas as variáveis:

A, B, SOMA e NOME, vamos atribuir valores e verificar os


resultados após as expressões.

Algoritmo
declare A, B, SOMA numerico;
NOME literal;

escreva (“Digite um Número para A: ”);


leia (A);
escreva (“Digite um Número para B: ”);
leia (B);

80
escreva (“Digite um nome para CLIENTE: ”);
leia (NOME);

SOMA  A + B ;

escreval (“A é maior que B:”, A > B);


escreval (“B é maior que A:”, B < B);
escreval (“A é diferente de B:”, A <> B);
escreval (“O nome é João:”, NOME = “Joao”);
escreval (“A SOMA de A e B é maior que B:”,
SOMA > B);
escreval (“A SOMA é: ”, SOMA);
escreval (“O nome é: ”, NOME);
fimalgoritmo

Implemente este algoritmo no Visualg e teste os


resultados!

Veja que apareceu neste algoritmo um novo


comando: escreval. Pesquise sobre este comando e
descubra qual a sua função no algoritmo.

81
Note que este algoritmo possui um alinhamento dos
comandos; os comandos dentro da estrutura
algoritmo – fimalgoritmo possuem um
deslocamento maior a partir da margem da página. A isso
chamamos de indentação. Pesquise o que significa esse termo
e qual sua importância. Dê exemplos de programas bem
indentados e mal indentados.

2.7. Estruturas de Controle

Neste tópico abordaremos as estruturas de controle nos


algoritmos. Veremos como elas permitem construir algoritmos
mais refinados e com maior controle por parte do usuário.

Para entender a importância de uma estrutura de controle,


pensemos o seguinte: imagine que você criou um algoritmo que
num determinado momento peça ao usuário para entrar com
um número que será usado como divisor de outro número. O
que aconteceria se o usuário digitasse “0”? Certamente teríamos
um erro no programa, pois não existe divisão por 0. Como evitar
isso? Ou então, o seu algoritmo precisa ler diversos números de
forma repetida. Teríamos que escrever o mesmo trecho de

82
código várias vezes? Para isso usamos as estruturas de controle
que veremos a seguir.

2.7.1. Sequência

Nos algoritmos trabalhados até o momento, vimos que os


comandos utilizados são todos sequenciais, ou seja, o programa
lê o algoritmo linha por linha, a partir do comando Algoritmo e
executa as ações indicadas, até encontrar o comando
fimalgoritmo. Uma vez executado um comando, não é possível
executá-lo novamente. Para que isso aconteça, o algoritmo
deveria ser executado todo novamente. A isso chamamos de
estrutura sequencial, pois os comandos são executados em
uma sequência linear:

Algoritmo
declare {variáveis}
comando 1;
comando 2;
.
.
comando n;
fimalgoritmo

83
Entretanto, em várias ocasiões precisamos que um determinado
comando seja executado mais de uma vez, ou então, seja
“pulado” para o próximo comando:

Algoritmo
declare {variáveis}
comando 1;
comando 2;
comando 3;
comando 4;
comando 5;
.
.
comando n;
fimalgoritmo

Neste algoritmo, os comandos 1 e 2 devem ser repetidos


novamente ao fim do comando 2, ao passo que ao fim do
comando 3 deve-se ir diretamente para o comando 5, sem
executar o comando 4. Vejamos como realizar estas ações.

84
2.7.2. Estrutura Condicional

As estruturas condicionais permitem escolher o grupo de ações


a serem executadas quando determinada condição é atendida.
Esta condição geralmente é verificada através de uma
expressão lógica (lembra-se dela?), que, uma vez atendida ou
não, pode levar à execução de diferentes comandos.
Lembrando o exemplo citado anteriormente, deveríamos criar
uma estrutura condicional para evitar que o usuário digite 0 na
leitura de um número.

 Estrutura Condicional Simples

A estrutura condicional simples tem a seguinte forma:

se [condição]
entao [comando ou]
[bloco de comandos]
fimse

onde se, entao e fimse são palavras-chave e condição é uma


expressão lógica.

85
Para cada se corresponde um único então e um
único fimse.

Uma estrutura condicional simples teria a seguinte notação:

Nas estruturas condicionais, os comandos escritos após entao


são executados SE e SOMENTE SE a expressão lógica for
VERDADEIRA. Caso a expressão seja falsa, os comandos dentro
da estrutura SE são ignorados.

86
Vejamos:

Algoritmo
declare DIVISOR,RESULT, DIVIDENDO real;
DIVIDENDO = 10
escreva (“Digite um Número para o Divisor: ”);
leia (DIVISOR);

se (DIVISOR > 0)
então RESULT = DIVIDENDO / DIVISOR;
escreva (“O Resultado é: ”, RESULT);
fimse

se (DIVISOR <= 0)
então escreva (“Não é possível dividir por
0”);
fimse

Vamos entender melhor o algoritmo?

Ao executar o algoritmo, o computador começa a ler cada


instrução, até que o usuário digite um número. Neste momento,
o próximo comando é justamente uma estrutura de seleção
com uma expressão lógica (DIVISOR > 0 ?). Aqui o computador
verifica se o número digitado é maior que 0. Caso seja
verdadeiro, então o valor contido na variável DIVIDENDO é
divido pelo valor digitado pelo usuário (DIVIDENDO/DIVISOR) e

87
armazenado na variável RESULT. Daí então é escrito na tela o
resultado do cálculo – o valor da variável RESULT.

Caso o número digitado seja 0, a avaliação da expressão


DIVISOR> 0 resultará em FALSO, e a primeira estrutura SE é
ignorada. Continuando a execução do algoritmo, encontramos
outra estrutura SE, onde a expressão DIVISOR <= 0 é avaliada.
Neste caso, o resultado é VERDADEIRO, pois o usuário digitou 0.
Assim, é executado o comando escreva contendo a mensagem
que não é possível dividir por 0. O comando fimalgoritmo
encerra a execução do programa.

Crie um algoritmo que leia 2 números A e B. Se A for


maior do que B, o algoritmo deve escrever “A maior
que B”, caso contrário, o algoritmo deve escrever “B
maior que A”. Em último caso, o algoritmo deve escrever “A e B
são iguais”.

 Estrutura Condicional Composta

Podemos dizer que uma estrutura condicional composta reúne


duas ou mais estruturas condicionais simples num único bloco

88
de comandos. Ela permite executar um comando (ou uma
sequência de comandos) se a condição é verdadeira. Se a
condição for falsa, são executados outros blocos de comandos.

se [condição]
entao [comando ou]
[bloco de comandos]
senao [comando ou]
[bloco de comandos]
fimse

onde:

se, então, senão e fimse são palavras-chave e condição é uma


expressão lógica.

Para cada SE corresponde um único então, um único senão e


um único fimse.

Escreva um algoritmo que leia as notas do primeiro


e do segundo semestre (notas possíveis: 0 a 50
pontos por semestre) e calcule a média deste aluno.
Caso o aluno tenha 60 pontos ou mais ele está aprovado, caso
contrário, está reprovado.

89
Algoritmo
declare NOTA1,NOTA2, MEDIA numerico;

escreva (“Digite a nota do 1. semestre: ”);


leia (NOTA1);
escreva (“Digite a nota do 2. semestre: ”);
leia (NOTA2);

MEDIA = (NOTA1+NOTA2)/2

se (MEDIA >= 60)


entao escreva (“O aluno está aprovado. Média
é: ”,MEDIA);
senao escreva (“O aluno está reprovado. Média
é: ”,MEDIA);
fimse
fimalgoritmo

Como funciona?

O algoritmo é executado normalmente (recebendo as notas dos


alunos e calculando a média) até que ele encontra o comando
SE. Neste ponto é verificado o valor contido na variável MEDIA.
Caso seja maior ou igual a 60 pontos, a execução passa para o
primeiro então, escrevendo a mensagem que o aluno está
aprovado. Caso contrário, é executado o segundo comando,

90
então, escrevendo que o aluno está reprovado. Note que não há
como o algoritmo “fugir” desta condição. Se a média for maior
ou igual que 60 pontos, é executada uma ação. Caso a média
seja menor a 60 pontos, é executada outra ação complementar.

Vamos exercitar mais um pouco.

Considere o seguinte trecho de algoritmo:

Algoritmo
.
.
se A2 <= B3
então TESTE <- verdadeiro
senao TESTE <- falso
fimse
C <- TESTE
.
.
fimalgoritmo

91
1) (FARRER, 1989) Ao fim da execução do algoritmo, o valor
armazenado em C será FALSO se:

A. ( ) A2 < B3

B. ( ) A2 <= B3

C. ( ) A2 >= B3

D. ( ) A2 > B3

E. ( ) A2 = B3

2) Crie um algoritmo que leia um número qualquer. Caso o


número seja PAR, exiba o número e escreva “Este número é
par”. Caso contrário, exiba o número e escreva “Este número
é impar”.

3) Altere o algoritmo do item anterior para calcular se o


número é maior do que 0.

92
2.7.3. Estrutura de Repetição

As estruturas de repetição permitem que um comando ou


sequência de comandos seja executada repetidamente até que
determinada condição aconteça. Chamamos esta condição de
Condição de Parada, pois ela determinará até quanto os
comandos serão repetidos. Note que esta condição envolve
também um comando ou expressão lógico que deve ser
analisado.

Imagine um algoritmo que leia o nome de um aluno, suas notas


semestrais e calcule sua média:

Algoritmo
declare N1, N2, MEDIA numerico;
NOMEALUNO literal;
leia NOMEALUNO;
leia N1;
leia N2;
MEDIA <- (N1+N2)/2;
escreva (NOMEALUNO, MEDIA);
fimalgoritmo

93
Pois bem, o que fazer caso seja necessário efetuar este
algoritmo para dois alunos? Duplicar os comandos? Vejamos:

Algoritmo
declare N1, N2, MEDIA numerico;
NOMEALUNO literal;
NOTA1, NOTA2, MEDIA2 numerico;
NOMEALUNO2 literal;

leia NOMEALUNO;
leia N1;
leia N2;
MEDIA <- (N1+N2)/2;
escreva (NOMEALUNO, MEDIA);
leia NOMEALUNO2;
leia NOTA1;
leia NOTA2;
MEDIA2 <- (N1+N2)/2;
escreva (NOMEALUNO2, MEDIA2);
fimalgoritmo
fimalgoritmo

Note que repetimos os comandos de leitura e escrita para cada


aluno. Além disso, propositalmente, dobramos o número de
variáveis. Se fosse necessário efetuar este cálculo para 200

94
alunos, o algoritmo teria uma estrutura enorme, concorda? Por
isso usamos os comandos de repetição.

Podemos ter 3 tipos de estruturas de repetição: com interrupção


no início, interrupção no meio e interrupção no fim da estrutura.

2.7.3.1. Comando Repita

O comando REPITA executa uma sequência de comandos até


que determinada condição seja atendida. Esta condição pode
estar no início, meio ou fim do comando. Veja:

 Interrupção no Início

Neste caso, logo no início da estrutura de repetição é realizado


um teste. Caso o teste seja FALSO, a estrutura é executada, caso
contrário, o fluxo é desviado. Assim, pode ser que nem mesmo
uma vez esta estrutura seja executada – isso pode ocorrer
quando a expressão lógica for Verdadeira.

95
Estrutura:

repita
se [condição]
então interrompa;
fimse
[comando ou]
[bloco de comandos]
fimrepita

Repita, fimrepita e interrompa são palavras-chave. Condição é


uma expressão lógica que, se verdadeira, determina a
interrupção do processo de repetição.

Retomemos o algoritmo anterior. Podemos, por exemplo, limitar


a execução do algoritmo quando o número de alunos lidos for
igual a 100. Mas para isso teríamos que contar a quantidade de
alunos já lidos. Aqui entra um novo conceito de variável, que
verifica a quantidade de vezes que a estrutura foi repetida.
Usualmente chamamos esta de variável CONTADORA. O
primeiro aluno lido começa com a variável CONTADOR com o
valor 1. A cada novo aluno esta variável é incrementada em 1.

96
Veja como ficaria o algoritmo reescrito:

Algoritmo
declare N1, N2, MEDIA, CONTADOR real;
NOMEALUNO literal;
{Inicializando o valor de contador}
CONTADOR <- 1;
repita
se (CONTADOR > 100)
entao interrompa;
fimse
leia (NOMEALUNO, N1, N2);
MEDIA <- (N1+N2)/2;
escreva (NOMEALUNO, MEDIA);
{Incrementa o contador}
CONTADOR <- CONTADOR+1;
fimrepita
fimalgoritmo

A variável CONTADOR é inicializada com valor 1. Na estrutura


condicional, seu valor é checado, e como é menor que 100, o
algoritmo passa para os próximos comandos dentro da
estrutura REPITA. Ao fim, a variável CONTADOR é incrementada
(adicionada mais 1), passando, então, ao valor de 2. Novamente
a execução volta para o comando SE, e como a variável ainda é
menor que 100, toda a estrutura é repetida. O comando só é

97
interrompido quando a variável possui valor 101. Neste caso,
como ela possui valor maior que 100, o teste resulta em
VERDADEIRO e o comando entao interrompa é executado,
encerrando a repetição.

Veja que temos aqui uma estrutura de repetição que será


interrompida quando calcular a média de 100 alunos. Para
alterar a quantidade de alunos, deve-se apenas alterar a
condição de parada, ou seja, o valor da variável CONTADOR na
estrutura condicional (SE).

Outro ponto importante é o uso de variáveis chamadas


acumuladores. Ascencio, Campos (2012) ilustram bem o uso
destas variáveis: devem ser utilizadas quando a realização de
um cálculo precisa do resultado final a cada iteração. Em outras
palavras, o cálculo final só estará completo ao fim da estrutura
de repetição. Neste caso, o acumulador deve sempre ser
iniciado com valor 0 para cálculos de adição e com valor 1 para
cálculos de multiplicação.

Vejamos:

Algoritmo
declare SOMA, NUM, CONTADOR real;
{Inicializando valores}
CONTADOR <- 1;
SOMA <- 0;

98
repita
se (CONTADOR > 5)
então interrompa;
fimse
escreva (“Digite um número:” );
leia (NUM);
SOMA <- SOMA + NUM;
{Incrementa o contador}
CONTADOR <- CONTADOR+1;
fimrepita
escreva (“Soma:”, SOMA);
fimalgoritmo

Note que a variável SOMA possui o valor 0, e ao digitar qualquer


número, este é adicionado ao valor da variável SOMA. Na
próxima repetição, ao digitar um novo número, este é somado à
variável SOMA – que passa então a possuir um novo valor. Ao
fim do algoritmo, a variável SOMA terá o valor de todos os
números digitados pelo usuário.

Execute este algoritmo no Visualg e veja os resultados.


Atribua diferentes valores para cada número digitado.

99
Vejamos outro exemplo, unindo agora a definição de contadores
e somadores:

Algoritmo
declare MAIOR, NUM, SOMA, CONTADOR real;
{Inicializando valores}
CONTADOR <- 1;
MAIOR <- 0;
SOMA <- 0;
repita
se (CONTADOR > 5)
entao interrompa;
fimse
escreva (“Digite um número:” );
leia (NUM);
se (NUM > 5)
entao MAIOR <- MAIOR + 1;
fimse
CONTADOR <- CONTADOR+1;
fimrepita
escreval (“Quantidade de números lidos:”,
CONTADOR-1);
escreval (“Quantidade de números maiores que 5”,
MAIOR);

fimalgoritmo

Como ficaria a memória do computador durante a execução


deste algoritmo?

100
Tabela 9: Valores durante a execução do algoritmo

Fonte: Adaptado de ASCENCIO; CAMPOS (2012)

 Interrupção no Meio

A interrupção no meio, como o nome já diz, interrompe a


execução do algoritmo durante a estrutura de repetição. É útil
quando não sabemos ao certo quantas repetições deverão ser
feitas, por isso, a repetição pode ser encerrada a qualquer
momento, ao contrário do exemplo de alunos, que só seria
interrompida quando chegasse ao aluno 101.

101
Forma geral:

repita
[comando ou]
[bloco de comandos]
se [condição]
então interrompa;
fimse
[comando ou]
[bloco de comandos]
fimrepita

Retomando o exemplo da leitura de notas dos alunos: imagine


que agora você queira interromper a repetição a qualquer
momento. Sabemos que para interromper uma estrutura de
repetição devemos inserir uma expressão lógica que, quando
verdadeira, interrompa a execução. E qual seria esta expressão?
Podemos criar uma regra que, ao usuário digitar uma
determinada palavra no nome do aluno, a estrutura seja
interrompida.

102
Vejamos:

Algoritmo
declare N1, N2, MEDIA numerico;
{não precisamos mais da variável CONTADOR}
NOMEALUNO literal;
repita
leia (NOMEALUNO);
se (NOMEALUNO = “CANCELAR”)
entao interrompa;
fimse
leia (N1, N2);
MEDIA <-(N1+N2)/2;
escreva (NOMEALUNO, MEDIA);
fimrepita
fimalgoritmo

Vamos refletir sobre o trecho em azul:

Após declarar as variáveis, a execução do algoritmo inicia o


comando repita lendo o nome do aluno. Imagine que aqui você
digita “João”. Como este nome é diferente de “CANCELAR”, o
algoritmo ignora o comando entao interrompa e passa a
executar os comandos seguintes. Ao fim, escreve o nome do
aluno e sua média. Novamente volta ao início do comando
repita e lê outro nome de aluno, para depois suas notas e

103
cálculo da média. Estes comandos são executados até que
você digite a palavra “CANCELAR”. Ao ler esta palavra, o
comando SE retorna o valor VERDADEIRO (pois é igual a
Cancelar), desviando, assim, o fluxo para o comando entao
interrompa e para o fim da estrutura de repetição. Veja que esta
estrutura pode ser repetida n vezes, até que alguém digite o
valor “Cancelar”.

Que tal deixar o algoritmo mais refinado para o


usuário? Insira um comando de escrita informando
ao usuário que para interromper a leitura dos
nomes e notas, ele deve digitar “Cancelar” no nome
do aluno. Implemente no Visualg e veja os resultados!

 Interrupção no Fim

Vimos até agora estruturas de repetição que podem ser


interrompidas no meio ou no fim do algoritmo. A estrutura da
interrupção no fim faz com que a repetição seja executada no
mínimo 1 vez – já que o algoritmo executará toda a estrutura de
repetição para somente ao final verificar se deve ou não repetir
novamente.

104
Veja a sintaxe deste comando:

repita
[comando ou]
[bloco de comandos]
se [condição]
entao interrompa;
fimse
ate fimrepita

A repetição no fim é útil quando deixamos para o usuário a


escolha pela repetição dos comandos.

Algoritmo
declare N1, N2, MEDIA real;
{não precisamos mais da variável CONTADOR}
NOMEALUNO, OPCAO literal;
repita
escreva (“Digite o nome do aluno: ”);
leia (NOMEALUNO);
escreval (“Digite as notas semestrais do
aluno: ”);
leia N1;
leia N2;

MEDIA <-(N1+N2)/2;
escreval (NOMEALUNO, MEDIA);

105
escreval (“ “);
escreval (“Deseja repetir para outro aluno?
Sim/Nao ”);
leia (OPCAO);
se ( (OPCAO = “NAO”) ou (OPCAO = “nao”) )
entao interrompa;
fimse
fimrepita

Note que este algoritmo executa primeiro a leitura do nome e


notas de um aluno para só depois solicitar ao usuário a opção
de repetir a execução. Dentro da estrutura SE colocamos uma
expressão que avalia se o usuário digita a palavra ‘Nao’ – como
ele pode digitar em caracteres maiúsculos ou minúsculos,
devemos criar uma expressão que contemple ambas as
opções.

Outro exemplo:

Algoritmo
declare NUMERO numerico;
NUMERO <- 0;
repita
escreva (NUMERO);
NUMERO <- NUMERO + 1;
se (NUMERO > 100)
então interrompa;

106
fimse
fimrepita
fimalgoritmo

Do trecho em azul pode-se ter o seguinte entendimento:

 Criamos uma variável numérica chamada NUMERO, que

é inicializada com o valor 0;

 O primeiro comando dentro da estrutura REPITA escreve

este número na tela;

 Após isso a variável NUMERO é incrementada (adiciona-

se 1);

 Temos, então, uma estrutura de seleção simples (SE) que

verifica o valor da variável NUMERO. Como é menor do que 100,

a execução não é desviada para o comando interrompa.

 Novamente volta-se ao comando escreva. Neste ponto, a

variável NUMERO possui valor 2, que é escrito na tela. O

próximo comando incrementa a variável, que passa a assumir o

valor 3. O comando SE verifica este valor e desvia o fluxo para

fora do comando interrompa, pois ainda é menor que 100.

107
 Esta sequência é executada até que o valor de NUMERO

seja 100. Este valor é escrito na tela e acrescido de 1 – passando

a valer 101. A estrutura condicional verifica este valor, como é

maior do que 100, desvia o fluxo para o comando entao

interrompa, que faz com que o algoritmo passe para o

comando fimrepita e depois fimalgoritmo.

2.7.3.2. Comando Enquanto

O comando Enquanto é similar ao comando repita com


interrupção no início:

enquanto [condição] faca


[comando ou]
[bloco de comandos]
fimenquanto

Enquanto, faca e fimenquanto são palavras-chave. Condição é


uma expressão lógica que enquanto for VERDADEIRA, fará com
que os comandos dentro do bloco sejam executados.

108
Algoritmo
declare NUMERO numerico;
NUMERO <- 0;
enquanto (NUMERO <= 100) faca;
escreva (NUMERO);
NUMERO <- NUMERO + 1;
fimenquanto
fimalgoritmo

Veja que o uso do comando enquanto eliminou a necessidade


de criar uma estrutura SE dentro do bloco de repetição, além do
que, este comando avalia logo no início se a estrutura deve ou
não ser repetida.

2.7.3.3. Comando Para

O comando para possui uma estrutura maior, devendo utilizar


mais variáveis para seu controle. Tal como enquanto, ele
executa os comandos e a cada repetição verifica uma condição
declarara em sua estrutura, até que se atinja um valor

109
predeterminado. Geralmente é utilizado quando sabemos
exatamente a quantidade de repetições dos comandos.

Sintaxe:

para [variável] de [Num1] ate [Num2] passo [Num3]


faca
[comando ou]
[bloco de comandos]
fimpara

[variável] - Variável de controle tipo numérico (contador). Esta


variável “contará” a quantidade de vezes que o comando para
foi executado;

[Num1] - Valor numérico que representa o estado inicial do


contador – número inicial da contagem;

[Num2] - Valor numérico que representa o estado final do


contador – número final da contagem;

[Num3] – É o incremento do contador, ou seja, a soma que o


contador receberá a cada repetição da estrutura.

110
Algoritmo
declare NUMERO numerico;
para NUMERO de 0 ate 100 passo 1 faca
escreva (NUMERO);
fimpara
fimalgoritmo

O algoritmo escreve o valor 0 na tela. Após isso, volta ao início


do comando para, incrementa a variável NUMERO em 1 e
escreve novamente seu valor. Isso é repetido até que a variável
NUMERO possua o valor 100, quando será escrita novamente
na tela e então o comando de repetição é encerrado.

Teste estes exemplos no Visualg e veja os


resultados!

111
Revendo

Caro aluno, notou a importância das estruturas de repetição na


construção de algoritmos? Viu como estas estruturas permitem
um melhor refinamento e aumentam nossas possibilidades?!
Além disso, o uso em conjunto destas estruturas permite criar
algoritmos para as mais diversas necessidades. Um ponto
importante é que não existe uma regra para uso destas
estruturas. Cada uma deve ser utilizada de acordo com sua
preferência e necessidade pontual para resolver determinado
problema através de um algoritmo.

112
Vamos realizar alguns exercícios para revisão.

a) Crie um algoritmo que leia um número qualquer e


adicione o valor 10 a este número. Caso a soma destes
números seja menor que 100, o algoritmo deve ler outro
número e acrescentar ao valor desta soma. O algoritmo
deve ser finalizado assim que a soma seja maior que 100,
quando o algoritmo mostra a mensagem “Você chegou a
100”.

b) Crie um algoritmo que receba as 3 notas de um aluno e


calcule sua média. Caso o aluno tenha mais que 60
pontos, escreva Aprovado. Se a média do aluno for entre
40 a 60 pontos, escreva que o aluno está de recuperação.
Caso contrário, o aluno está reprovado. Caso o aluno
esteja em recuperação, deverá ser informado quantos
pontos são necessários para que ele atinja a média de
aprovação. (ASCENCIO; CAMPOS, 2012)

c) Faça um programa que leia dois números e escreva o


maior (ASCENCIO; CAMPOS, 2012)

113
2.8. Estruturas de dados

Sabemos que uma variável reserva uma posição de memória


que utilizamos para armazenar dados. Em algum momento será
preciso armazenar vários dados do mesmo tipo ao mesmo
tempo. Poderíamos criar uma variável para cada dado, como
NOTA1, NOTA2... NOTAn. A depender da quantidade de dados, o
código seria inviável. Para isso existem estruturas de dados mais
completas, capazes de armazenar uma quantidade maior de
dados usando uma única referência de memória. São
chamadas estruturas compostas homogêneas, e dividem-se em
unidimensionais (Vetores) e Multidimensionais (Matrizes).

2.8.1. Vetores

Um vetor é uma estrutura de dados homogênea que contém


elementos do mesmo tipo (como textos ou números) e que são
referenciados com um único nome. Quando usamos vetores, o
programa reserva na memória RAM do computador vários
espaços de memória que conterão dados do mesmo tipo.

Sintaxe:

114
declare NOME_VARIAVEL: vetor [LI .. LF] de tipo;

NOME_VARIAVEL : Nome da variável homogênea.

Vetor: É uma palavra-chave que indica tratar-se de uma


estrutura unidimensional;

[LI .. LF]: LI é o limite inferior e LF o limite superior (final do


vetor).

Tipo: Pode ser numérico, lógico ou literal.

O número de elementos (dados) de um vetor é dado por: LF – LI


+ 1. Assim, as posições do vetor são identificadas a partir de LI,
com incrementos unitários até LF. Graficamente, um vetor teria a
seguinte estrutura:

Exemplo de declaração de um vetor:

declare NOME: vetor [1..5] de literal;

115
Visualmente:

NOME

Cada posição do vetor é chamada de elemento e é tratada


como se fosse uma variável simples. Caso queira referenciar
algum elemento do vetor, utiliza-se o nome do vetor e a
identificação do elemento (índice) entre colchetes. Esta notação
é usada tanto para atribuir quanto para ler dados do vetor:

NOME [4] <- “Jéssica”

Este comando teria o seguinte efeito no vetor:

NOME

116
De forma similar, os comandos abaixo:

NOME [4] <- “Maria”

NOME [1] <- “Jéssica”

Resultariam em:

NOME

E para leitura do vetor, os comandos utilizados seriam:

escreval (NOME [1]);

escreval (NOME [2]);

escreval (NOME [3]);

escreval (NOME [4]);

escreval (NOME [5]);

117
O resultado na tela seria:

Jéssica

Maria

As posições 2 e 3 do vetor não possuem nenhum dado


armazenado, por isso é apresentado um espaço em branco na
tela. Da mesma forma, o comando escreva (NOME[6]) resultaria
em erro de execução do algoritmo, pois a posição 6 do vetor
não existe.

Vejamos como trabalhar com vetores.

Escreva um algoritmo que armazene as 5 notas de


um aluno. Ao final, exiba o total de pontos do aluno.

Algoritmo
declare TOTAL: real;
NOTAS: vetor [1..5] de real;
escreval (“Digite a Nota 1 do aluno: ”);

118
leia (NOTAS[1]);
escreval (“Digite a Nota 2 do aluno: ”);
leia (NOTAS[2]);
escreval (“Digite a Nota 3 do aluno: ”);
leia (NOTAS[3]);
escreval (“Digite a Nota 4 do aluno: ”);
leia (NOTAS[4]);
escreval (“Digite a Nota 5 do aluno: ”);
leia (NOTAS[5]);

TOTAL <- NOTAS[1] + NOTAS[2] + NOTAS[3] +


NOTAS[4] + NOTAS[5]
Escreva (“Total de pontos:”, TOTAL);
fimalgoritmo

Embora não esteja errado, este algoritmo está um tanto


cansativo, não?! Veja como criamos um comando para cada
posição do vetor. Imagine, então, fazer isso para um vetor de 80
posições. Neste ponto, as estruturas de repetição já estudadas
nos auxiliam muito.

Como dito, o índice (posição) de um vetor é referenciado através


de um número crescente (de 1 até o limite do vetor). Ora, para
percorrer todas as posições de um vetor, podemos então usar
uma estrutura que leia a primeira posição do vetor e repita esse
procedimento para cada posição seguinte, até o seu limite.

119
Utilizando estruturas de repetição com vetores.

Algoritmo
declare TOTAL, CONTADOR inteiro;
NOTAS : vetor [1..5] de inteiro;
CONTADOR <-1;
TOTAL <- 0;
{a variável contador será responsável pelo índice do
vetor}

para CONTADOR de 1 ate 5 passo 1 faca


escreva (“Digite a Nota”, CONTADOR, “ do
aluno: ”);
leia (NOTAS[CONTADOR]);
TOTAL <- TOTAL + NOTAS[CONTADOR];
fimpara
escreva (“Total de pontos:”, TOTAL);
fimalgoritmo

Bem mais prático não? Usamos uma variável de contador para


percorrer as posições do vetor (de 1 até 5), usando a estrutura
de repetição para. A cada repetição (volta), o valor lido é
armazenado na posição respectiva do vetor e somado à variável
TOTAL. Ao fim da repetição exibimos o total de pontos.

120
Implemente este algoritmo no Visualg. Altere a
contagem da repetição para 6 e veja o que acontece
na execução do programa.

2.8.2. Matrizes

Ainda dentro de estruturas homogêneas, temos o conceito de


MATRIZ, que nada mais é do que uma variável composta
multidimensional, formada por uma sequência de variáveis do
mesmo tipo, com o mesmo identificador e alocadas
sequencialmente na memória (ASCENCIO, CAMPOS, 2012).
Cada campo é referenciado por um índice que o identifica na
estrutura – tal como os vetores. A diferença é que a matriz
possui mais que uma dimensão, ou seja, possui uma estrutura
composta por linhas e colunas, tal como uma tabela.

Sintaxe de uma matriz:

declare NOME_VARIAVEL: vetor [LI 1 .. LF 1, LI 2 .. LF 2] de tipo;

121
NOME_VARIAVEL é o nome que será dado à sua variável
heterogênea (matriz);

[LI1 .. LF1, LI2 .. LF2]: LI1 é o limite inferior e LF1 o limite superior
(final), LI2 é o limite inferior e LF2 o limite superior (final).

Tipo: Pode ser numérico, lógico ou literal.

Vamos entender melhor o conceito de matriz. Para tanto,


imagine uma tabela que armazene o nome e endereço dos
funcionários de uma empresa:

Desprezando o cabeçalho (Nome, Endereço), temos uma tabela


de 5 linhas por 2 colunas, ou 5 x 2. Assim, em que posição está o

122
nome “Sidney”? Ora, na linha 2 e coluna 1, em outras palavras, 2
x 1 (não entenda o x como multiplicação). Da mesma forma, o
nome Paula está na posição 1 x 1 (linha 1, coluna 1). Portanto,
esta tabela possui as posições:

Note que a posição 5 x 1 representa a última linha e primeira


coluna da tabela, já a posição 1 x 2 representa a primeira linha e
última coluna da tabela. Em algoritmos, essa tabela seria
representada através de uma matriz da seguinte forma:

declare MATRIZ: vetor [1..5, 1..2]de literal;


resultando em uma estrutura multidimensional:

123
Veja que cada campo é referenciado por um índice, composto
pelo número da linha e da coluna que o dado ocupa na
estrutura. Portanto, ao referenciar dados em uma matriz,
usamos sempre a notação NOME_DA_VARIAVEL
[linha:coluna].

Para atribuir o nome “João” e seu endereço na linha 3,


usaríamos a seguinte notação:

MATRIZ [3,1] <- “João”;

MATRIZ [3,2] <- “Avenida S. João, 53”;

124
Resultando em:

Vejamos um exemplo mais prático:

Exemplo de Estrutura Homogênea Bidimensional


(Matriz)

Algoritmo
declare MATRIZ: vetor [1..4,1..2]de literal;
leia (MATRIZ[1,1]);
leia (MATRIZ[1,2]);
leia (MATRIZ[2,1]);
leia (MATRIZ[2,2]);
leia (MATRIZ[3,1]);

125
leia (MATRIZ[3,2]);
leia (MATRIZ[4,1]);
leia (MATRIZ[4,2]);

escreval (“Escrita dos dados:”);

{código para escrita da matriz}


Fimalgoritmo

Complete o código acima para escrever os dados


lidos pelo algoritmo.

Veja que, tal como nos vetores, esta programação é


extremamente cansativa e não otimiza o código. Novamente
teremos que utilizar estruturas de repetição para percorrer a
matriz. Só que desta vez usaremos 2 variáveis: uma
representado as posições de linhas e outra para as posições de
coluna. Além disso, uma estrutura será responsável por “andar”
pelas linhas e outra pelas colunas. Veja:

126
Veja que a primeira estrutura de repetição inicia a contagem do
número de linhas, já a segunda estrutura logo em seguida inicia
a contagem do número de colunas. Assim, antes do comando
escreva (“Digite um número”), os contadores estão na posição
1:1 (linha 1 e coluna 1). Logo após o usuário terminar a
digitação do número, o comando para incrementa somente a
variável coluna; assim, os contadores passam a ter o valor 1:2
(linha 1 e coluna 2). Daí então é lido o segundo número. Como

127
a variável coluna chegou ao limite do comando para (2), a
estrutura de repetição é encerrada e volta ao primeiro comando
para, que agora, incrementa a variável linha, que passa a ter o
valor 2. Novamente, a segunda estrutura de repetição é iniciada,
e os contadores passam a ter o valor 2:1. A segunda estrutura lê
os números para esta posição e para a posição 2:2. Ao final,
como a variável coluna chegou a seu limite, a estrutura é
encerrada. Mas agora a variável linha também chegou ao limite
do comando para (2), portanto, esta estrutura também é
encerrada, passando para o próximo comando – escreval
(“Escrita da Matriz”). Note que o segundo bloco, para escrita
dos números da matriz, funciona de forma similar à leitura dos
números.

Exercícios

1) Crie um algoritmo (e depois no Visualg) que contenha um


vetor de 100 posições e atribua a estas posições somente
números pares, começando do 0.

128
2) Escreva um algoritmo que leia 20 números inteiros, calcule
e mostre a soma dos mesmos. Mostre também quantos
destes números são pares e quantos são ímpares.
Implemente também no Visualg.

3) Crie um programa que pergunte ao usuário quantas linhas


e quantas colunas ele deseja que a matriz tenha. Após isso ,
peça ao usuário que digite os números para a matriz e
mostre o resultado em tela.

4) Escreva e implemente um algoritmo que crie uma matriz


de dimensões 10 x 10, atribuindo a todas as posições desta
matriz somente o número 10.

129
Chegamos ao final de nossa segunda unidade,
querido aluno. Vimos que os algoritmos são
importantes ferramentas para a elaboração de
programas de computador. Aprendemos como é a estrutura de
um algoritmo, os dados utilizados e as principais operações que
podemos realizar. Tudo isso é de grande importância para
entendermos como construir programas de computador
utilizando efetivas linguagens de programação.

APONTAMENTOS PARA A PRÓXIMA UNIDADE

Na próxima unidade veremos como escrever programas de


computador utilizando a linguagem C.

130
131
UNIDADE III – A LINGUAGEM DE
PROGRAMAÇÃO C

META

Nesta unidade, veremos como desenvolver programas de


computador na linguagem de programação C.

OBJETIVOS DA UNIDADE

Esperamos que, após o estudo desta unidade, você seja capaz


de:

1. Compreender como ocorre a escrita, compilação e

execução de um programa;

2. Utilizar adequadamente os comandos, tipos de

dados e estruturas da linguagem C;

132
3. Solucionar os problemas e exercícios propostos

neste capítulo;

4. Criar programas na linguagem C.

PRÉ-REQUISITOS

Para se ter um bom aproveitamento dos estudos desta unidade,


é importante que você tenha compreendido bem os conceitos
trabalhados no capítulo anterior, quando tratamos de algoritmos
e suas estruturas de dados.

3. INTRODUÇÃO À LINGUAGEM C

Vimos até agora como construir algoritmos para a resolução de


problemas. Uma vez construído o algoritmo, ele serve de
protótipo para a construção de programas – basta que seja
traduzido para alguma linguagem de programação.

Os conhecimentos obtidos até agora permitem que você, aluno,


esteja apto a escrever qualquer solução para um problema em

133
linguagem de algoritmo. Uma vez escrito o algoritmo, podemos
“traduzi-lo” para qualquer linguagem de programação. É isso
que trataremos nesta unidade: a escrita de programas utilizando
a linguagem C.

Mas, antes, devemos fazer uma revisão sobre os fundamentos


de linguagens de programação.

3.1. Primeiras Definições

Uma linguagem de programação nada mais é do que a forma


pela qual indicamos as tarefas que um computador deve
realizar para resolver problemas, tal como num algoritmo. A
diferença é que, numa linguagem, usamos palavras e regras de
sintaxe específicas para aquela linguagem.

Ou seja, todos os algoritmos trabalhados neste guia podem ser


traduzidos em programas de computador utilizando qualquer
linguagem. Notadamente, o algoritmo escrito em linguagem
Pascal terá comandos e estrutura diferentes que o mesmo
algoritmo escrito na linguagem Java. Entretanto, ambos terão
como resultado a resolução do problema que foi resolvido
através do algoritmo.

134
As linguagens de programação possuem conjuntos de símbolos
e regras de sintaxe que permitem a construção de comandos
que descrevem de forma precisa ações compreensíveis e
executáveis para o computador.

As linguagens de programação são, em outras palavras,


algoritmos escritos de uma forma que o computador possa
interpretá-los, ou seja, programas computacionais. Para isso, os
comandos devem ser transcritos para uma linguagem que o
computador consiga compreender. Em verdade, os

135
computadores só podem executar algoritmos expressos em
linguagem de máquina¸ que são um conjunto de instruções
capazes de ativar diretamente os dispositivos eletrônicos do
computador, fazendo com que este realize as operações
necessárias para atingir o objetivo final do programa (FARRER,
1989).

Sobre a linguagem de máquina:

 É diferente para cada tipo de computador,

dependendo de sua arquitetura;

 é extremamente rudimentar, ou seja, todas as

operações (inclusive as mais simples) devem ser expressas

em termos de registros, acumuladores e outros dispositivos

de máquina;

 é totalmente expressa em forma numérica, usando o

sistema de numeração binário (0 e 1) ou hexadecimal.

Portanto, escrever programas de computador em Linguagem de


Máquina é uma tarefa de difícil aprendizado e pouco expressiva.
Por isso, foram desenvolvidas outras linguagens, denominadas
“Linguagens de Programação”, que funcionam como uma

136
alternativa entre a comunicação ser humano x computador
(FARRER, 1989). Assim como em algoritmos, uma linguagem de
programação possui suas próprias regras de sintaxe e
semântica.

Você verá que escrever programas na linguagem C assemelha -


se muito ao que vimos em algoritmos, a diferença é que uma
linguagem é a notação formal de um algoritmo que será
executado pelo computador.

 Tipos de Linguagens de Programação

Existem diversos tipos de linguagens de computador, cada uma


com suas características e objetivos, tal como abaixo:

137
Por mais avançados que sejam, os computadores são capazes
de executar somente programas em Linguagem de Máquina, ou
seja, executam instruções utilizando circuitos elétricos e
comandos binários (0 e 1). Entretanto, a maioria dos programas
são construídos em linguagens de alto nível, legíveis ao ser
humano, como Delphi, C#, Java.

Mas como os computadores, que só entendem comandos em 0


ou 1, executam programas escritos em linguagem quase
humana? Através da tradução das linguagens de alto nível em
comandos de linguagem de máquina.

Veja como isso acontece:

Figura 3: Tradução de um programa de alto nível para


linguagem de máquina

Fonte: SANT'ANA (2010)

138
Primeiro o computador traduz o código-fonte para o código-
objeto. Isso acontece em tempo de execução, caso a linguagem
use um interpretador (traduz e executa uma instrução por vez).
Caso a linguagem utilize um compilador, as instruções são
traduzidas antes que se inicie a execução do programa
(FARRER, 1989).

O mesmo Farrer (1989) nos dá as seguintes definições para este


processo:

 Código-fonte: não é executável diretamente pelo

processador. Permite apenas que o programador consiga

construir o programa utilizando uma forma legível ao ser

humano.

 Compilador: programa que traduz todo o código-fonte

de programas escritos numa linguagem de alto nível em código-

objeto antes da execução do programa;

 Código-objeto: é o código produzido pelo compilador

que é uma forma intermediária, similar à linguagem de máquina

do computador. Este é representado em números binários, mas

não é executável diretamente pelo processador, pois,

geralmente, o código-objeto referencia partes de programa que

139
não estão necessariamente definidas no mesmo arquivo que o

gerou, como por exemplo, arquivos de bibliotecas de sub-

rotinas.

 Editor de ligação (ou link-editor): é um programa que

reúne módulos (trechos de programas) compilados e arquivos

de dados para criar um programa executável.

Para finalizar este tópico, Sant'ana (2010) traz alguns critérios


para escrever um programa de qualidade:

 Integridade: os resultados gerados pelo

processamento do programa devem estar corretos, levando em

consideração as entradas realizadas; caso contrário, o

programa simplesmente não tem sentido;

 Clareza: tem a ver com a facilidade de leitura do

programa. Um programa escrito com clareza permite que outro

programador entenda sua lógica sem muito esforço. Isso é

interessante para o próprio autor do programa, pois muitas

140
vezes um programador precisa entender o programa após certo

tempo sem contato com ele;

 Simplicidade: Utilizar de clareza e precisão na

construção de um programa para torná-lo de fácil entendimento

e com estrutura mais simples;

 Eficiência: Refere-se à velocidade do processamento

dos dados e correta utilização da memória do computador.

Espera-se que um programa tenha desempenho suficiente para

atender às necessidades do problema e do usuário, utilizando

os recursos de memória do computador de forma eficaz. Vemos

isso em programas extremamente “pesados” que exigem até

computadores com maior poder de processamento. Quem

nunca se irritou quando ao fazer uma operação em um

programa e o mesmo “travou” o computador todo?

 Modularidade: É o particionamento do programa em

módulos (partes) menores bem identificáveis e com funções

específicas. Isso faz com que o conjunto desses módulos e a

141
interação entre eles permita a resolução do problema de forma

mais simples e clara – veremos isso mais adiante;

 Generalidade: É interessante que um programa seja

tão genérico quanto possível, ou seja, sua construção, dentro do

possível, deve permitir a reutilização de seus componentes em

outros projetos. A modularização possui importante papel neste

quesito.

3.2. Histórico da Linguagem C

A Linguagem C surgiu do desenvolvimento de uma linguagem


mais antiga, denominada BCPL, desenvolvida por Martin
Richards, que influenciou uma linguagem chamada B. Na
década de 1970, a linguagem B influenciou o desenvolvimento
da linguagem C, criada por Dennis Ritchie. A linguagem C
inicialmente era fornecida com o sistema operacional UNIX,
mas, com a popularização dos microcomputadores, muitas
implementações passaram a ser escritas na linguagem C, o que
curiosamente era aceito em computadores de diferentes
arquiteturas e sistemas operacionais. Em 1983, devido a
discrepâncias entre os programas criados, a American National

142
Standards Institute – ANSI, criou um comitê para padronização
da linguagem C, chegando assim a uma obra que abrangia um
padrão de forma da linguagem C. (SCHILDT, 1997)

De lá para cá, temos visto uma grande utilização e evolução da


linguagem C, que serviu como base para criação de outras
linguagens mais avançadas de programação, como C#, Java e
até mesmo PHP (linguagem de programação para web com
sintaxe muito próxima à linguagem C).

Vejamos a estrutura básica de um programa em C:

/* Exemplo - Um programa bem simples */


#include <stdio.h> //Biblioteca - entrada e saída vídeo
#include <conio.h>
main (void)
{
puts ("Bem vindo a linguagem C");
puts ("Tecle algo para sair...");
getch();
}

Este programa apresenta na tela o texto “Bem-vindo à


linguagem C”. Na primeira linha, temos uma biblioteca chamada
#include <stdio.h>, que faz a inclusão de algumas funções de
biblioteca utilizadas para ler e escrever.

143
Note que dentro da função main encontra-se o corpo principal
do programa. A função main deve existir em todo programa C,
pois é a partir dela que o programa em C começa a ser
executado.

A palavra void antes de main e entre parênteses significa que a


função main não retorna nenhum valor e nem espera valores
(veremos detalhes mais adiante). Dentro do corpo principal está
sendo usado um comando para escrever palavras: puts, e
dentro dele o valor que deve ser escrito. Esta função puts tem
seu protótipo definido dentro do arquivo de cabeçalho stdio.h,
por isso a necessidade de fazer a inclusão desta biblioteca
neste programa (SANT’ANA, 2008). Utilizar comandos sem
importar a biblioteca correspondente resulta em erros de
compilação.

Também é possível inserir comentários em C; como em


qualquer outra linguagem, os comentários não são compilados
nem executados, portanto, podem ser escritos em qualquer
parte do programa e ajudam a deixar o código mais claro para
quem o lê.

Comentários em C seguem a seguinte sintaxe:

 Para comentários de apenas uma linha, usamos 2

barras invertidas: //

144
 Comentários com mais de uma linha devem ser

depois de */ , e encerrados com */.

Exemplo:
// isto é um comentário

*/ este também é um comentário */

Todo este capítulo foi escrito levando em consideração padrão


estipulado pela ANSI para a linguagem C, já que se trata de um
padrão internacional.

Desde já, vamos começar a trabalhar na prática.


Acesse a Midiateca, baixe e instale o programa Dev
C++; é com ele que escreveremos e executaremos nossos
programas em C.

145
3.3. Tipos de Dados

A linguagem C nos oferece 5 tipos básicos de dados: caractere,


inteiro, ponto flutuante (decimais), ponto flutuante de precisão
dupla e sem valor (respectivamente, char, int, float, double e
void). A partir destes, é possível criar outros tipos de dados.
Cada um destes tipos possui variações no tamanho de dados
possíveis de armazenamento, conforme a tabela abaixo:

146
Tabela 10: Tipos de dados e valores suportados

Fonte: SCHILDT, 1997.

147
As palavras signed e unsigned são chamados modificadores,
pois modificam o tipo básico do dado. O uso do modificador
signed faz com que o tipo aceite apenas valores positivos, já
unsigned aceita valores positivos e negativos. O uso de cada
tipo varia de acordo com a necessidade do programa,
entretanto, é interessante definir o mais exatamente possível o
tipo de dado para otimizar a execução do programa e o uso de
memória RAM do computador.

3.4. Variáveis e Constantes

VARIÁVEIS

Como vimos em “algoritmos”, antes de se escrever um


programa, precisamos declarar as variáveis, ou seja, alocar
espaços de memória do computador e referenciar estes
espaços através de identificadores.

Na linguagem C, os nomes válidos para identificadores seguem


o mesmo padrão já visto para algoritmos: o primeiro caractere
deve ser uma letra ou sublinhado e os seguintes caracteres
devem ser letras, números ou sublinhados.

148
O uso de identificadores em C possui 3 importantes
características:

 Identificadores possuem tamanho limitado de

caracteres (geralmente 31). Assim, em uma variável cujo nome

ultrapasse este limite, os caracteres que extrapolarem o limite

de 31 serão ignorados;

 Letras maiúsculas e minúsculas são diferenciadas.

Assim, NOME, Nome e nome são identificadores diferentes em

C;

 Os nomes utilizados não podem ser os mesmos de

palavras-chave e/ou funções nativas da Linguagem C. Assim,

não é possível usar uma variável chamada int, por exemplo.

As variáveis em C são declaradas da seguinte forma:

tipo lista_de_variaveis;

Alguns exemplos:

int a, b, x;

149
short int Numero, numero;

double Preco;

Um importante aspecto da linguagem C é que esta é uma


linguagem modular, ou seja, é construída através de pequenos
“blocos” de comandos chamados módulos ou funções. Estes,
podem estar em diversas partes do programa e possuem suas
variáveis e comandos próprios. Assim, podemos dizer que uma
variável pode ser declarada em 3 locais distintos, definido,
assim, seu comportamento.

 Variável Local

É criada dentro de um bloco específico do programa, sendo


“visível” somente por este bloco. Um bloco, na linguagem C,
sempre é escrito entre chaves ( { } ).

Veja:

void divisao ()
{
int a, b;
double resultado;
}

150
Caso tentemos atribuir um valor às variáveis a, b ou resultado
em outro trecho do código, teríamos um erro de execução, pois
o programa só “enxerga” estas variáveis dentro deste bloco.

 Parâmetro Formal

São parâmetros (dados/valores) passados para uma função


que utiliza parâmetros. Estes são tratados como variáveis locais
da função e sua declaração é feita depois do nome da função e
dentro dos parênteses.

/* Parâmetro formal */
#include <stdio.h>
void EscreveCaracter (char c)
{
putchar (c);
}
main ()
{
EscreveCaracter ('a');
}

No exemplo acima, a variável c é um parâmetro formal, que


recebe um valor quando a função EscreveCaracter é utilizada

151
em outra parte do programa. Veremos isso com mais detalhes
adiante. O comando putchar escreve um caractere na tela.

 Variáveis Globais

São variáveis declaradas no início do código e disponíveis no


programa inteiro; assim, qualquer bloco do programa pode
acessá-las sem erro. Estas variáveis devem ser declaradas fora
de todas as funções e no começo do programa principal.

/* Variável global */
#include <stdio.h>

char c; /* Declaração da variável global */


main ()
{
c = 'B';
putchar (c);
}

Embora prático, o uso de variáveis globais deve ser evitado, pois


estas ocupam espaço na memória durante toda a execução do
programa, além de que pode ocorrer de algumas serem
utilizadas poucas vezes durante a execução do programa. Para
isso, é interessante o uso de funções, pois estas permitem

152
melhor organização e estruturação de programas em C.
Veremos mais a respeito de funções nas páginas seguintes.

CONSTANTES

Como diz o nome, são variáveis que não podem ter seu valor
modificado durante a execução do programa. O valor inicial
deve ser atribuído no momento da inicialização (declaração) da
variável.

Sintaxe:

const tipo nome_identificador ;

const é uma palavra-chave que informa ao compilador tratar-se


de uma constante;

tipo é um dos tipos predefinidos da linguagem C (int, float, etc.);

nome_identificador é o nome da constante.

Veja o exemplo:

/* Constante */
#include <stdio.h>

153
const int valor = 10; /* Declaração da constante
*/
main ()
{
c = valor/10;
print (c); /*comando para escrever valores
numéricos*/
}

Vamos revisar um pouco sobre variáveis e


constantes.

1) Assinale com um X os identificadores válidos em C.


Justifique os que você achar inválidos.

( ) Valor

( ) Salario-Liquido

( ) B248

( ) X2_( )

( ) Nota Aluno

154
( ) A1B2C3

()3x4

( ) KM/H

( ) NomeDaEmpresa

( ) Sala215

2) Um programa deverá efetuar a leitura e escrita do nome de


um cliente, sua idade, endereço e data de aniversário.
Escreva como seria a declaração de variáveis em C para este
programa.

155
3.5. Operadores

Vejamos agora os principais operadores da linguagem C. Como


já vimos, operadores são símbolos que permitem efetuar
operações com dados.

3.5.1. Operadores de atribuição

Para atribuir valores a variáveis e constantes, usamos uma


notação bem simples:

Nome_variavel = expressão ou valor;

Nome_variavel é o nome do identificador

= é o sinal de atribuição (não confunda com sinal de


igualdade!);

expressão ou valor é a expressão ou valor que será atribuído à


variável.

156
É possível realizar atribuições múltiplas na linguagem C,
atribuindo o mesmo valor a muitas variáveis utilizando apenas
uma linha de comando:

x = y = z = a = 0;

Neste exemplo, as variáveis x, y, z e a recebem o valor 0.

3.5.2. Operadores Aritméticos

São os operadores que permitem realizar cálculos aritméticos:

Tabela 11: Operadores em C

Fonte: SCHILDT, 1997.

157
Alguns exemplos:

int A, B;
A = 5;
B = 2;

printf(“%d”, A + B); /* mostrará o resultado 7*/


printf(“%d”, A - B); /* mostrará o resultado 3*/
printf(“%d”, A / B); /* mostrará o resultado 2*/
printf(“%d”, A % B); /* mostrará o resultado 1, ou
seja, resto da divisão inteira*/

Há de se fazer uma observação importante sobre incremento e


decremento na linguagem C. Estes operadores realizam
operações diferentes dependendo do momento em que são
utilizados junto às variáveis. Por exemplo:

x = 10;

y = ++ x;

Tanto x quanto y passam a ter o valor 11. Já o comando

x = 10;

y = x++;

faz com que y tenha o valor 10 e x recebe o valor 11. Qual a


diferença?

158
O fato é que no primeiro exemplo, o operador de incremento
(++) foi atribuído antes da variável x, portanto, o programa
aumenta em 1 o valor de x e só depois atribui a y. No segundo
caso ocorre o contrário, primeiro o valor de x (10) é atribuído a y
e somente depois o valor de x é incrementado.

Devemos lembrar que a ordem de precedência para executar


as operações segue a mesma lógica já vista em Algoritmos:

Tabela 12: Prioridade nas operações

Fonte: Obra do autor

159
Para alterar a ordem de execução de uma operação, devemos
utilizar parênteses, tal como vimos em algoritmos:

int A, B;
A = 5;
B = 2;

printf(“%d”, A + B / 2); /resulta em 6*/


printf(“%d”, (A + B) / 2); /* resulta em 1, resto
da divisão de 7 por 2*/

A linguagem C permite ainda abreviações em atribuições.


Portanto,

X + = 10

é o mesmo que X = X + 10

Implemente todos os exemplos acima no Visualg e


verifique os resultados.

160
3.5.3. Operadores Lógicos e Relacionais

Podemos ainda criar operações de comparação de variáveis e


constantes – a estas damos o nome de relacionais. Toda
operação relacional resulta em um valor (Verdadeiro ou Falso),
que pode ser utilizado para outras operações; para estas damos
o nome de operações lógicas.

A linguagem C interpreta o valor 0 como Falso e qualquer valor


diferente de 0 como Verdadeiro. Assim, em expressões
relacionais, temos sempre como resultado os valores 0 (falso)
ou diferente de 0 (verdadeiro).

Os operadores relacionais são:

Tabela 13: Operadores Relacionais

Fonte: Obra do autor

161
Tabela 14: Operadores Lógicos

Fonte: Obra do autor

Relembrando...

Lembra-se das operações lógicas vistas em


Algoritmos? Reveja este item para entender melhor as
operações lógicas em C.

Considerando as variáveis x = 10, y = 2 e z = 3, escreva o


resultado das seguintes expressões:

a) ++ x – z

b) x < 2 && 10 > 5

c) x / y

d) x % y

162
e) X + Y

f) 5*x + z - (y/y) + x

g) x > x

h) z != x

i) ! ( y == z)

3.6. Comandos de entrada e saída

Para caracteres, usamos o comandos getchar () para entrada e


putchar () para escrita. Quando tratamos de strings (palavras),
usa-se os comandos gets() para ler uma string e puts() para
escrever a string na tela. Há ainda os comandos scanf () e printf
() para entrada e saída formatada, respectivamente. Veremos
estes dois últimos logo adiante.

A função getchar () espera até que seja digitado um caractere


no teclado, então mostra este caractere e sai do processo de
entrada de dados. Já a função putchar () escreve um caractere
a partir da posição corrente do cursor.

163
/* Exemplo - Programa que lê caracteres e os escreve na
tela em maiúsculo ou minúsculo */
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
main (void)
{
char ch;
printf ("Entre com algum texto - Digite um
ponto para sair. \n");
do{
ch = getchar();
if (islower(ch))
ch = toupper (ch);
else ch = tolower (ch);
putchar (ch);
} while (ch!= '.');
}

Declaramos inicialmente uma variável chamada ch do tipo


caractere. O comando printf() exibe uma mensagem na tela.
Temos, depois, o comando do..while, uma estrutura de
repetição que veremos adiante. Esta estrutura repete a leitura de
caracteres através do comando getchar() e armazena o valor
lido na variável ch. Depois, o conteúdo desta variável é escrito

164
na tela através do comando putchar(). O programa só é
encerrado quando o usuário digita um ponto.

Ao executar este programa, você perceberá que após digitar o


caractere deverá pressionar <ENTER> para executar os
próximos comandos. Isso porque o comando getchar()
armazena o valor em um buffer de memória até que o comando
<ENTER> seja pressionado. Para tonar isto mais interativo,
temos a opção de utilizar os comandos getch() ou getche().
Estes executam a mesma ação do getchar(), entretanto, estas
funções esperam que algum caractere seja digitado na tela,
retornando imediatamente. A diferença é que getch() retorna
sem exibir o caractere na tela, já getche() exibe o caractere
antes de retornar. Vejamos o exemplo anterior com estes
comandos.

/* Exemplo - Programa que lê caracteres e os escreve na


tela em maiúsculo ou minúsculo */
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
main (void)
{
char ch;
printf ("Entre com algum texto - Digite um ponto
para sair. \n");
do{

165
ch = getch();
if (islower(ch))
ch = toupper (ch);
else ch = tolower (ch);
putchar (ch);
} while (ch!= '.');
}

Implemente os exemplos acima e veja os resultados. Alterne


entre os comandos getche() e getch().

STRINGS

Para leitura e exibição de strings, utilizamos os comandos gets()


e puts(), respectivamente.

A função gets () lê um string de caracteres digitado pelo teclado


até que seja pressionado <ENTER>. O caractere representado
por <ENTER> não fará parte do string, em seu lugar é colocado
o caractere de fim de cadeia ('\0'). Já puts () escreve um string
na tela seguido por uma nova linha ('\n'). A função puts() é uma
alternativa interessante ao comando printf(), pois é executado
mais rapidamente. Entretanto, puts() só pode ler strings, nunca
números.

166
Vejamos:

/* Programa que lê um nome e escreve uma mensagem com o


nome digitado. */
#include <stdio.h>
#include <conio.h>

main ()
{
char nome[20];
puts ("\n Escreva seu nome:"); /* \n pulo uma
linha */
gets (nome);
printf ("Oi, %s", nome);
getch();
}

ENTRADA E SAÍDA FORMATADA

Um interessante recurso na escrita e leitura de dados é entrada


e saída formatada. Isso permite que os dados sejam lidos e
escritos nos formatos desejados, aumentando, assim, o controle
e eficiência do programa.

167
 Printf()

Sua sintaxe é printf (“série de controle”, lista de argumentos),


onde a série de controle é uma série de caracteres que indicam
como o dado será mostrado, e lista de argumentos são os
dados que serão exibidos conforme a formatação.

O comando printf() permite uma série de formatos:

Tabela 15: Comandos de formato printf()

Fonte: Adaptado de SHILDT (1997)

168
Portanto, imagine que num determinado programa você tenha
uma variável X do tipo double com valor 10,546454. Pode-se
escrevê-la de vários formatos, variando apenas o formato
desejado através do comando printf():

printf(“%4.2f”, X); → exibe o valor 10.54 (4.2 significa exibir o


número de ponto flutuante (f) com 4 dígitos, sendo 2 reservados
para a parte decimal);

printf(“%3.1f”, X); → exibe o valor 10.5 (3.1 significa exibir o


número de ponto flutuante (f) com 3 dígitos, sendo 1 reservado
para a parte decimal);

Veja como funciona:

/* Exemplo de Programa com saída formatada */


#include <stdio.h>
#include <conio.h>
main (void)
{
printf ("\n%-5.2f", 123.234);
printf ("\n%5.2f", 3.234);
printf ("\n%10s", "Oi");
printf ("\n%5.7s", "1234567890");
getch()
}

169
123.23

3.23

Oi

1234567

 A constante de barra invertida '\n' significa nova

linha (new line);

 O formato "%-5.2f" indica que o número em ponto

flutuante (f) deve ser apresentado com, no mínimo, 5 caracteres,

2 dígitos para a parte fracionária do número e deve ser

justificado à esquerda (-).

 O formato "%10s" indica que a string deve ser

apresentada 10 espaços justificado à direita.

170
 Já o formato "%5.7s" indica que a string deve ser

apresentada com pelo menos 5 caracteres e não mais que 7

caracteres (SANT’ANA, 2008).

Os valores que acompanham os códigos de formatação (como


5.2, 10, etc.) são chamados de especificadores de precisão, isso
porque delimitam a quantidade mínima e/ou máxima de
caracteres que serão mostrados em vídeo. Como dito, %10.4f
exibe um número com pelo menos 10 dígitos sendo 4 casas
decimais. Se aplicados a números inteiros, como %3.8d,
identificam a quantidade mínima e máxima de dígitos para o
número – caso o número seja menor, será completado com 0.
No caso de strings, %4.7s exibe uma string de no mínimo 4
caracteres e no máximo 7 caracteres.

/* Outro Exemplo com saída formatada */


#include <stdio.h>
#include <conio.h>
main ()
{
printf ("%.4f\n", 123.1234567);
printf ("%3.8d\n", 1000);
printf ("%10.16s\n", "Esse é um teste
simples");
getch();
}

171
A saída deste programa será:

123,1235 (há o arredondamento do número);

00001000 (acréscimo de 0 para conter 8 dígitos);

Esse é um teste (limite de 16 caracteres).

 Scanf()

Esta é uma rotina de entrada de dados geral. Permite a leitura


de qualquer tipo de dados e converte esta leitura no tipo de
dado interno. Funciona de forma parecida ao comando printf().
Sua sintaxe é:

scanf(“formato”, &variável); onde “formato” são os caracteres


que determinam como o dado será armazenado e variável é
justamente a variável que armazenará o dado. Notadamente, o
formato adotado no comando scanf() deve ser do mesmo tipo
da variável. Usamos o caractere & para atribuir o valor lido à
variável em questão.

A esta função podemos atribuir os seguintes formatos:

172
Tabela 16: Especificadores de formato de scanf()

Fonte: Adaptado de SHILDT (1997)

/* Exemplo de uso da função scanf */


#include <stdio.h>
main ()
{
char nome[20];
int idade;
printf ("Digite um nome: ");
scanf ("%s", nome);

173
printf ("\nDigite a idade: ");
scanf ("%d", &idade);
printf ("\n\n%s, você tem %d anos.\n", nome,
idade);
getch();
}

Veja que usamos novamente o comando \n para inserir uma


quebra de linha. O símbolo & serve para atribuir o valor lido à
variável, no caso, &idade atribui à variável idade o valor lido
pela função scanf(), este valor é armazenado como um número
inteiro.

Como dito, ao ler uma string, o comando scanf armazena em


um buffer o conteúdo digitado pelo usuário e armazena também
a tecla utilizada para encerrar a entrada de dados (geralmente o
<ENTER>). Por isso é importante que:

 O buffer seja esvaziado após a leitura e atribuição

do valor à variável. Para isso, usa-se o comando

%*c – o caractere * informa que o buffer deve ser

esvaziado;

 Como sempre armazena o caractere de

encerramento de entrada, devemos, ao declarar

174
uma variável do tipo string, informar um campo a

mais para “guardar” este caractere. Assim, caso sua

variável “confere”, armazene somente os valores

SIM ou NÃO; devemos declará-la com 4 campos:

char confere[4]. Ao digitar um valor, seria

armazenado na memória do computador:

Outro ponto importante da função scanf() é que ao utilizá-la


para leitura de strings, a função efetua a leitura até que se
encontre um espaço em branco. Ou seja, a frase “Isso é um
teste”, ao ser lida pela função, armazenaria na variável somente
o valor “Isso”, pois logo após aparece um espaço em branco.
Para resolver este problema, frases devem ser lidas utilizando o
comando gets(), que lê todos os caracteres digitados até que se
digite <ENTER>.

Vamos realizar alguns exercícios para fixar o

175
conteúdo:

1) Descreva o que faz cada uma das funções abaixo. Dê


exemplos de uso das mesmas. (SANT’ANA, 2008)

getch() :

getchar() :

putchar():

getche():

gets() :

puts():

2) Crie um programa em C que leia dois números inteiros


e apresente o resultado de sua soma, subtração,
multiplicação e divisão.

176
3) Escreva um programa em C para apresentar os valores
abaixo:

Inteiro = 10

Caractere = A

Float = 99.99

String = Linguagem C

4) Qual o valor das variáveis x, y e z depois da seguinte


sequência de operações?

int x, y , z;

x=y=10;

z= ++x;

y++;

x = x + y -(z--);

177
5) Implemente o programa abaixo. Explique com suas
palavras o funcionamento deste programa em C.

#include <stdio.h>
#include <conio.h>

main(void)
{
int i, j;
printf("\nEntre com dois números inteiros: ");
scanf("%d%d", &i, &j);
printf("\n%d == %d eh %d\n", i, j, i==j);
printf("\n%d != %d eh %d\n", i, j, i!=j);
printf("\n%d <= %d eh %d\n", i, j, i<=j);
printf("\n%d >= %d eh %d\n", i, j, i>=j);
printf("\n%d < %d eh %d\n", i, j, i<j);
printf("\n%d > %d eh %d\n", i, j, i>j);
getch();
}

178
6) As expressões abaixo são falsas ou verdadeiras? Após
isso, implemente estas expressões em um programa e
confira o resultado.

((10>5) || (5>10))

(!(5==6) && (5!=6) && ((2>1) || (5<=4)))

7) Implemente o programa abaixo. Caso o resultado

esteja incorreto, corrija o programa para que seja


escrito o valor corretamente.

#include <stdio.h>

#include <conio.h>

main (void)

int num = 10;


float f;

f = num/4;

179
printf ("%f",f);

getch();

3.7. Estruturas de Controle

Vimos nos capítulos sobre algoritmos que as estruturas de


controle permitem desviar o fluxo de execução de um programa,
dependendo de condições que são ou não atendidas. Podem,
ainda, efetuar a repetição de uma sequência de comandos. Em
C não é diferente. Veremos agora importantes estruturas de
controle da Linguagem C.

3.7.1. Estruturas Condicionais Simples

São estruturas que contêm expressões que, quando avaliadas,


desviam o fluxo do programa para um ou mais comandos. Uma
estrutura condicional simples possui a seguinte estrutura:

if (expressão) comando;

else comando;

180
if e else são palavras-chave e comando é um comando ou
bloco de comandos (entre chaves { }). A expressão será avaliada
como Falsa (se retornar 0) ou Verdadeira (retorno diferente de
0). Caso a expressão seja Verdadeira, os comandos são
executados. Caso contrário, os comandos são ignorados ou
então se executa os comandos dentro após o else. Este
comando else é opcional.

/* Exemplo do Comando de seleção simples */


#include <stdio.h>
#include <conio.h>

main (void)
{
int num;
printf ("Digite um numero entre 0 e 10: ");
scanf ("%d",&num);

if (num==10)/* verifica se o número é igual a


10*/
{
printf ("\n\nVoce acertou!\n");
printf ("O numero e igual a 10.");
}
else printf ("\n Voce errou! O numero era
10.");
getch();
}

181
No programa acima, após digitar um número qualquer, o
comando if(num==10) verifica se o número digitado pelo
usuário é igual a 10. Caso seja, o bloco de comandos logo após
é executado, daí então são mostradas na tela duas mensagens.
Caso o número seja diferente de 10, o comando if desvia o fluxo
automaticamente para o comando else, que executa o
comando printf, exibindo a mensagem de erro na tela.

3.7.2. Estruturas Condicionais Compostas

Podemos ter dentro de um mesmo if outros comandos if – a


isso chamamos de aninhamento. Em tese, alguns compiladores
permitem até 15 comandos if aninhados. Um comando else
refere-se sempre ao if mais próximo e dentro do mesmo bloco:

if (i)
{
if (j) comando 1;
if (k) commando 2; /* este if está associado ao
else logo abaixo */
else commando 3 /* este else está associado ao
if do comando 2 */
}

182
else comando 4 /* este else está associado ao if
(i) */

O último else não está associado ao if (j), pois este não está no
mesmo bloco, ao contrário, está associado ao if (i) que está fora
do bloco e é o mais próximo. O else dentro do bloco está
associado ao if (k) que é o if mais próximo.

Veja um exemplo mais prático de estrutura condicional


composta.

/* Exemplo do Comando de seleção composta */


#include <stdio.h>
#include <conio.h>
main (void)
{
int num;
printf ("Digite um numero entre 0 e 10: ");
scanf ("%d",&num);

if (num==5)/* verifica se o número é igual a


5*/
{
printf ("\n\nVoce acertou!\n");
printf ("O numero e igual a 5.");
}

183
else
{
printf (“\n Você errou!”);

if (num > 5)
printf ("\n O número digitado é muito
alto");
else
printf ("\n O número digitado é muito
baixo");
getch();
}

Neste programa acima, o comando if(num==5) verifica se o


número digitado pelo usuário é igual a 5. Caso seja, o bloco de
comandos logo após é executado, e são mostradas na tela duas
mensagens. Caso o número seja diferente de 5, o comando if
desvia o fluxo automaticamente para o comando else, que
executa o comando printf, exibindo a mensagem de erro na
tela. Sabendo que o número lido não é 5, temos após o else um
novo if, que verifica se o número digitado é maior que 5, caso
seja, é mostrada a mensagem de que o número digitado é alto.
Caso não seja, o fluxo desvia para o else logo abaixo, exibindo,
então, a mensagem que o número é muito baixo.

184
Como dito, é possível criar vários comandos if-else dentro de
uma estrutura if-else. As condições são sempre avaliadas de
cima para baixo. Tão logo uma condição verdadeira seja
encontrada, os comandos associados a ela são executados e
todo o fluxo é desviado para fora. Caso nenhum teste resulte em
verdadeiro, o último comando else é executado. Veja:

/* Programa de números mágicos */

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

main (void)
{
int magic; // número mágico
int palpite; // palpite do usuário

magic = rand(); /* a função rand escolhe um número


inteiro aleatório e atribui a variável magic */

printf ("Adivinhe o numero magico: ");


scanf("%d", &palpite);

if (palpite == magic)
{
printf("**** Voce acertou!! ***");
printf("%d é o número magico!",
magic);
}
else
if (palpite > magic)
printf ("Errado, palpite muito alto!");
else
printf ("Errado, palpite muito baixo!");

getch(); /*cria uma pausa na tela e aguarda


digitação de algum caractere para encerrar */

185
}

Embora comum, este procedimento pode tornar o código um


pouco confuso. Para isso existe outra estrutura, chamada de
seleção múltipla, que veremos agora.

3.7.3. Estrutura de Seleção Múltipla

A linguagem C possui um comando de seleção múltipla –


chamado switch, que testa o valor de uma constante ou
variável contra uma série de constantes inteiras ou caracteres.
Assim que o valor verdadeiro é encontrado, os comandos
associados àquela constante são executados. Caso nenhuma
condição verdadeira seja encontrada, o fluxo é desviado para
outro comando – default –, ou para o fim da estrutura. Vejamos
a estrutura do comando switch:

switch (expressão){
case (valor 1):
sequência de comandos;
case (valor 1):
sequência de comandos;
.

186
.
.
default:
sequência de comandos;

Um exemplo prático:

/* Exemplo comando SWITCH */


#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
main (void)
{
int numero;
printf("Digite um numero entre 1 e 5: ");
scanf ("%i", &numero);

switch (numero){
case 1:
printf("\n%s", "Numero digitado --> UM.");
break;

case 2:
printf("\n%s", "Numero digitado --> DOIS.");
break;

case 3:
printf("\n%s", "Numero digitado --> TRES.");
break;

case 4:
printf("\n%s", "Numero digitado -->
QUATRO.");
break;

case 5:
printf("\n%s", "Numero digitado --> CINCO.");
break;

187
default:
puts("\nVoce nao digitou nenhum valor entre 1
e 5.");
}
puts ("\n\nTecle algo para sair..");
getch();
}

Vamos entender o programa acima...

O usuário deve digitar um número entre 1 e 5, que é


armazenado na variável numero. O comando switch analisa o
valor desta variável comparando-o com os valores contidos em
cada comando case. Supondo que o usuário tenha digitado o
valor 5, o comando switch faz as seguintes comparações:

Verifica se o conteúdo da variável ‘numero’ (5) é igual a ...

case 2 = falso;

case 3 = falso;

case 4 = falso;

case 5 = VERDADEIRO, daí então são executados os comandos


após este comando, até que seja encontrado o comando break.

188
Caso o usuário digite 0, todos os testes acima são feitos. Como
todos retornam FALSO, o programa executa então os comandos
contidos após o comando default. Em verdade, default
funciona como um “escape”, pois geralmente colocamos junto a
ele comandos que devem ser executados caso nenhuma
condição seja atendida.

3.7.4. Estruturas de Repetição

Já vimos que os comandos de repetição (também chamados


de laços de repetição) permitem que um conjunto de comandos
seja repetido até que determinada condição seja satisfeita.
Vejamos agora os laços de repetição existentes em C.

 O laço for

A forma geral do laço for é:

for (inicialização; condição; incremento) comandos;


sendo que for é a palavra-chave da estrutura, inicialização
geralmente é o valor inicial da variável de contagem do laço ( a
variável contador, lembra-se?); condição é uma expressão

189
relacional que determina quando a repetição cessará;
incremento define como a variável contadora será alterada a
cada repetição da estrutura. Logo em seguida, temos os
comandos que devem ser executados na repetição.

Um exemplo de escrita dos números de 1 a 100 na tela:

#include <stdio.h>
#include <conio.h>

main (void)
{
int x;
for (x=1; x<=1000; x++)
printf (“%d ”, x);
getch();
}

Agora veja este exemplo:

#include <stdio.h>
#include <conio.h>

main (void)
{
int x, z;
for (x=100; x !=65 ; x = x- 5)
{
z = x * x;
printf(“O quadrado de %d eh %d”, x,z);
}
getch();
}

190
Veja que neste laço ocorre o contrário do primeiro laço: aqui, a
variável x é inicializada com 100, e decrementada de 5 em 5 até
que atinja o valor 65. A cada repetição, é escrito o quadrado do
valor atual de x na repetição. Implemente no Dec-C++ e veja o
resultado.

E o que acontece no laço abaixo??

x=10;
for (y=10; y != x; ++y)
printf(“%d”, y);
printf (“%d ”, y); // apenas este comando será
executado
}

Apenas o último comando será executado, pois o teste lógico


retornará o valor Falso, já que neste caso y=10, e a condição do
laço deve ser y diferente de x. Assim, o laço nunca será
executado, pois x = y. Apenas o comando final, fora da estrutura
será escrito, e teremos na tela o valor de y (10) impresso na tela.

 O laço while

Nesta estrutura, temos uma validação também no início do laço,


que pode ser interrompida a qualquer momento. No comando
for, a estrutura será repetida uma quantidade determinada de

191
vezes, ao passo que na estrutura while, esta repetição pode ser
interrompida a qualquer momento. Sua sintaxe é:

while (condição)

comandos;

onde while é a palavra-chave, condição é a expressão lógica a


ser avaliada, cujo resultado deve ser diferente de 0, e comandos
são todos aqueles que devem ser executados na repetição.
Caso haja mais de um comando, estes devem vir entre chaves
({ }).

/* Exemplo de repeticao while */


#include <stdio.h>
#include <conio.h>
main (void)
{
char ch;
while (ch != 'f')
{
ch = getche ();
puts (“Tecla errada para sair \n”;)
}
puts ("\nFim");
getch();
}

192
O programa acima lê uma tecla digitada pelo usuário e exibe
uma mensagem até que o usuário digite a tecla “f”, quando
finalmente é exibida a mensagem “Fim”.

 O laço do-while

Ao contrário das estruturas de repetição anteriores, o laço do-


while testa a condição de repetição no fim. A sintaxe é:

do {

comando ;

} while (condição);

onde a condição é qualquer expressão lógica cujo resultado é


um valor diferente de zero, comandos são os comandos a
serem executados na estrutura, e do- while são as palavras-
chave.

193
/* Exemplo de repeticao do-while */

#include <stdio.h>

#include <conio.h>

main (void)

int i = 1;

do {

printf ("%4d", i);

i++;

while (i <= 100);

getch();

Note que a estrutura acima escreve os números de 1 a 100, mas


somente verifica se a variável i chegou ao valor 100 após a
escrita; ou seja, neste exemplo os comandos serão executados
ao menos uma vez.

194
3.7.5. Outros comandos de controle de fluxo

Existem ainda outros comandos que podem controlar o fluxo ou


desviar de comandos quando utilizados. Vejamos:

Comando return

Este comando obriga o programa a retornar a execução de uma


determinada função ou estrutura. Se o programa está
executando alguma função (veremos isso adiante) e encontra o
comando return, o programa retornará ao ponto em que foi
chamada a função.

Sintaxe:

return expressão;

195
/* Exemplo de desvio usando return */
#include <stdio.h>
#include <conio.h>
int menos (int a, int b)
{
return (a - b);
}

main (void)
{
int x, y;
puts ("\nDigite dois inteiros separados por
espaco: ");
scanf ("%d%d", &x, &y);
printf ("%d menos %d e' igual a %d\n\n", x, y,
menos (x, y));
getch();
}

Comando break

O comando break, como vimos, permite terminar um case


(teste) da instrução switch, ou, ainda, terminar uma estrutura de
repetição evitando o teste de condição de interrupção. Veja na
próxima página um exemplo:

196
/* Exemplo de desvio usando comando break */
#include <stdio.h>
#include <conio.h>
main ()
{
int t = 1;
for (;;)
/* aqui não declaramos nenhuma condição para o laço
for. Isso faria com que o laço executasse
indefinidamente */
{
if (t > 100)
break;
printf ("%4d", t++);
}
getch();
}

Veja que o laço for não possui os comandos que determinam a


quantidade de vezes nem o teste lógico para determinar o fim
da repetição, o que faria a estrutura ser repetida indefinidamente
– chamamos isso de laço infinito. Ao contrário, há um teste
lógico que verifica se a variável t chegou ao valor 100, caso isso
tenha acontecido, o comando break interrompe imediatamente
a execução do laço for.

197
Comando continue

O Comando continue funciona de forma contrária ao comando


break, pois obriga a próxima interação do laço de repetição,
pulando qualquer código intermediário. Para o laço for, o
comando continue faz com que a condição e o incremento
sejam executados.

/* Exemplo de desvio usando comando continue */


#include <stdio.h>
#include <string.h>
#include <conio.h>
main (void)
{
char s[80];
int i;
printf ("\nDigite um nome completo: ");
fgets (s, 79, stdin);
for (i = 0; i != strlen (s); i++)
{
if (s[i] == ' ')
continue;
putchar (s[i]);
}
}

198
Este programa solicita que o usuário digite um nome completo.
Este nome é armazenado numa variável chamada s. Logo
depois, o comando for escreve este nome – usamos o comando
for, pois cada letra é uma posição da variável s –, tal como os
vetores que vimos em algoritmos. No entanto, caso a estrutura
encontre no nome um espaço em branco, este será. O uso do
comando continue força o laço a ir para o próximo passo,
“pulando”, assim, a escrita do espaço. Implemente este
programa e veja o resultado.

Vamos realizar algumas atividades para fixar o


conteúdo visto até agora.

1) Crie um programa que leia um determinado número e


verifique se este é par ou ímpar. Escreva na tela o resultado
desta análise.

2) Uma loja necessita criar um controle de tamanhos de roupas.


Para isso, informou ao analista que o programa deveria ler o
número da etiqueta que representa o tamanho da peça. Caso o
número esteja entre 1 a 4, significa “P”. Caso o tamanho esteja

199
entre 5 e 7, significa “M”. Acima de 7 até 10 o tamanho será G.
Desenvolva este programa na linguagem usando a estrutura de
seleção composta (switch).

3) Escreva um programa que leia um nome. Se o nome for


digitado em maiúsculo, o programa deverá escrevê-lo em
minúsculo, e vice-versa.

4) Escreva um programa que leia um número entre 0 e 100.


Caso o número lido seja menor que 50, o programa deverá
escrever seus antecessores iniciando no número chegar ao 0.
Caso o número seja maior que 50, o programa deve escrever
seus sucessores até chegar a 100. Se o número digitado for 50,
o programa deverá escrever a mensagem “Metade de 100!”.

3.8. Modularização

Um interessante aspecto da linguagem C é que ela é


estruturada e modularizada, ou seja, permite que criemos dentro
do programa “blocos” de comandos que executam tarefas

200
específicas. Imagine, por exemplo, um programa que calcule o
reajuste de um funcionário. Para cada salário digitado você
deveria escrever os comandos que efetuam o cálculo:

#include <stdio.h>
#include <conio.h>

main (void)
{
float salario, novoSalario;
char opcao;

puts ("Digite o salario atual: ");


scanf("%f", &salario);
novoSalario = salario + (salario * 0.1);
printf ("Novo salario: %3.2f", novoSalario);

printf("\n\nDeseja continuar? ");


opcao = getche();
if (opcao == 's')
{
puts ("\n\nDigite o salario atual: ");
scanf("%f", &salario);
novoSalario = salario + (salario * 0.1);
printf ("\n\nNovo salario: %3.2f",
novoSalario);

printf("\n\nDeseja continuar? S/N ");


opcao = getche();
if (opcao == 's')
{
puts ("\n\nDigite o salario atual: ");
scanf("%f", &salario);

201
novoSalario = salario + (salario *
0.1);
printf ("\n\nNovo salario: %3.2f",
novoSalario);
}
else printf ("\n\nFim do programa");
}

else printf ("\n\nFim do programa");


printf("\n\nTecle algo para sair... ");
getch ();
}

Veja que o programa acima efetua o cálculo de apenas 3


funcionários e ainda assim ficou extenso. Caso fosse preciso
calcular de 1.000 funcionários, deveríamos digitar os comandos
1.000 vezes??? Para isso, além das estruturas de repetição para
diminuir o tamanho dos códigos, usamos as funções, que são
escritas apenas uma vez e “chamadas” em qualquer parte do
código quando preciso.

3.8.1. Funções

Uma função, na linguagem C, é um bloco de construção


responsável por efetuar uma tarefa específica. Ou ainda, “[...] é
um conjunto de instruções desenhadas para cumprir uma tarefa

202
particular e agrupadas numa unidade com um nome para
referenciá-la” (MIZRAHI, 2008).

A grande vantagem no uso de funções é que elas dividem


grandes tarefas (como o código todo) em tarefas menores,
permitindo, assim, trabalhar em problemas específicos. Além
disso, as funções muitas vezes executam comandos sem que,
no entanto, tenhamos necessariamente que conhecer tais
comandos. Um exemplo é a função printf(), que usamos sem
conhecer como ela funciona internamente.

A forma geral de uma função é:

tipo nome_da_funcao (lista_de_parametros)


{
comandos da função
}

Tipo é um dos tipos básicos predefinidos em C, como char,


Inteiro, Double, etc.

Nome_da_funcao é o nome de sua função. Este nome será


utilizado toda vez que usarmos (chamarmos) a função. Dentro
da função, temos os comandos que dão corpo à função.

Imagine que você tenha um programa que deve ler um número


e retornar o seu quadrado. Entre a leitura e a escrita do

203
resultado, deve-se desenhar uma linha. Vejamos como
implementar este programa usando funções:

//Exemplo de função
#include <stdio.h>
#include <conio.h>

void linha ( )
{
int cont;
for (cont = 0; cont <=50; cont ++)
printf ("%s", "-");
}

int quadrado (int numero)


{
return numero * numero;
}

main (void)
{
int resultado, num_lido;
printf("Digite um numero qualquer: ");
scanf("%d", &num_lido);
linha ();
resultado = quadrado (num_lido);
printf ("\n O quadrado do numero lido e: %d",
resultado);
getch();
}

204
Implemente este programa no Dev-C++ e veja o
resultado. Note que podemos incluir as funções
em qualquer momento. Faça um teste: inclua a
função linha() antes do comando getch() e veja o que acontece!

No programa acima, temos a função linha() que não recebe


parâmetro algum – entre parentes não há nada. Esta função
apenas escreve na tela 50 vezes o caractere “ – “, criando, assim,
uma linha na tela. Mude os parâmetros do laço for e veja o
resultado. Já a função quadrado() precisa de um parâmetro
que deve ser passado no momento em que ela é chamada (no
caso, o valor que consta na variável num_lido). Este valor é
usado dentro da função para calcular o seu quadrado. O
comando return, como já vimos, volta à execução do programa
de onde a função foi chamada, retornando o valor da
multiplicação do número. Este valor é armazenado na variável
“resultado”. Após isso temos, então, a escrita do resultado na
tela.

Lembra-se do programa que calculava o reajuste de salário?


Veja como podemos melhorá-lo usando funções. Não se
esqueça de implementar o exemplo abaixo no Dev-C++.

205
3.8.2. Passagem de valores para funções

Quando dividimos o programa em partes, devemos ter especial


atenção na declaração de variáveis. Isso porque uma
determinada variável pode estar disponível apenas dentro de
uma função (bloco) ou no programa inteiro.

Chamamos de variáveis globais aquelas que são declaradas no


início do programa, podendo ser acessadas em qualquer parte
do mesmo. Devem ser declaradas logo no início do programa e
fora de todos os blocos.

Já as variáveis locais são aquelas declaradas dentro de um


bloco específico. Ela só pode ser acessada dentro deste bloco.
Ao tentar atribuir valor ou ler esta variável em outra parte do
sistema, ocorrerá um erro.

Vimos isso no item 3.4, quando tratamos de


variáveis. Para saber mais, leia novamente este
item do guia.

206
Por uma questão de otimização de código,
estruturação do programa e até mesmo economia
de memória, é importante tentar sempre utilizar
blocos de comandos com variáveis locais. Isso evita que
variáveis que talvez nem sejam utilizadas ocupem um endereço
de memória. Programadores experientes dividem seus
programas em vários módulos ou blocos e criam uma
verdadeira documentação dos mesmos. Isso permite utilizar
estes blocos em desenvolvimento de programas futuros.

207
3.9. Estruturas de Dados

Tal como já visto em Algoritmos, podemos utilizar estruturas


mais organizadas para armazenar dados na memória do
computador. Em C, as estruturas principais são: Matrizes
(Unidimensional e Bidimensional) e Estruturas.

3.9.1. Matriz Unidimensional

Lembra-se da definição de vetores vista em Algoritmos?

Relembre!

Uma matriz unidimensional homogênea (vetor) é


uma estrutura de dados que contém elementos do mesmo tipo
(como textos ou números) e que são referenciados com um
único nome. Quando usamos vetores, o programa reserva na
memória RAM do computador vários espaços de memória que
conterão dados do mesmo tipo.

208
Sintaxe:

main ()
{
int NOTAS[5];
}

Quando declaramos uma matriz unidimensional (vetor) estamos


reservando um espaço contínuo na memória do computador,
que armazenará o mesmo tipo de dado e será acessado pelo
mesmo identificador. No caso de vetores e matrizes em C, o
endereço mais baixo na memória corresponde ao primeiro
elemento da estrutura e o mais alto corresponde ao último
elemento.

Importante!!!

Na linguagem C, todas as matrizes e vetores


começam com índice 0 (em algoritmos iniciam
com 1). Portanto, quando declaramos o vetor anterior, estamos
definindo na memória os dados:

209
NOTAS 

Este vetor teria como índices:

NOTAS [0];

NOTAS [1];

NOTAS [2];

NOTAS [3];

NOTAS [4];

/* Exemplo de Matriz Unidimensional (Vetor) */


#include <stdio.h>
#include <conio.h>
main (void)
{
int Indice, Vetor[100];
for (Indice = 100; Indice > 0; Indice--)
Vetor [Indice-1] = Indice;

for (Indice = 1; Indice <= 100; Indice++)


printf ("%4d", Vetor [Indice-1]);
getch();
}

210
Neste exemplo, usamos um laço de repetição para atribuir
valores ao vetor. Note que o valor inicial de índice é 100 e
atribuímos este valor à posição 99 do vetor (Indice-1), pois a
posição 100 do vetor não existe. Ao chegar ao valor 1, a posição
do vetor é 0 (Vetor[índice-1] é o mesmo que Vetor[0]). Então, é
atribuída a esta posição o número 1.

No próximo laço temos a escrita do vetor, iniciando na posição


0 (Vetor[Indice-1]) até a posição 99, mostrando na tela os
números de 1 a 100.

Importante: não confunda as posições do vetor


com os valores armazenados. Isso porque, no
exemplo acima, a posição 99 do vetor armazena o
número 100, a posição 50 armazena o número 51,
e assim sucessivamente, até a posição 0 armazenar o número 1.

 Strings

É importante ainda atentar para a questão de Strings em C. Uma


string nada mais é do que uma matriz de caracteres individuais
que, juntos, podem formar palavras. Toda String termina com
um caractere de fim de cadeia '\0' (o caractere nulo). Por isso,
devemos sempre declarar uma string com um caractere a mais

211
do que o necessário para o programa. Por exemplo, para uma
palavra de 10 posições, devemos declará-la com 11 posições.

char s [11]; /* índices de (0 - 10) */

Na linguagem C, existem funções que servem para manipular


valores de Strings:

Fonte: SANT'ANA (2008)

Veja que as strings não podem ser manipuladas diretamente,


apenas através de funções. Portanto, para ler e armazenar um
valor numa variável String, o comando abaixo está incorreto:

char s [11]; /* índices de (0 - 10) */


s = “Teste”;

212
O correto seria:

char s [11]; /* índices de (0 - 10) */


strcpy(s, “Teste”);

Sant’ana (2008) apresenta um exemplo completo sobre o uso


das funções para manipulações de String em C:

/* Exemplo de Funcoes para strings em C */


#include <stdio.h>
#include <string.h>
#include <conio.h>

main (void)
{
char nome1[40], nome2[40];
printf ("\nDigite um nome : ");
fgets (nome1, 39, stdin);

printf ("Digite outro nome : ");


fgets (nome2, 39, stdin);

puts ("\n**** TESTE DA FUNCAO strlen ");


printf ("Tamanho do primeiro nome : %d", strlen
(nome1));
printf ("\nTamanho do segundo nome : %d", strlen
(nome2));

puts ("\n\n**** TESTE DA FUNCAO strcmp ");


if (!strcmp (nome1, nome2))
puts ("Os nomes sao iguais");
else
puts ("Os nomes sao diferentes");

puts ("\n\n**** TESTE DA FUNCAO strcpy ");


strcpy (nome1, "Universidade ");
printf ("Novo nome: %s ", nome1);

213
puts ("\n\n**** TESTE DA FUNCAO strcat ");
strcat (nome1, nome2);
printf ("Nomes concatenados : %s ", nome1);

puts ("\n\n**** TESTE DA FUNCAO strchr ");


if (strchr (nome2, 'a'))
puts ("Existe 'a' no segundo nome");
else
puts ("Nao existe 'a' no segundo nome");

puts ("\n**** TESTE DA FUNCAO strstr ");

if (strstr (nome2, "ana"))


puts ("Existe \"ana\" no segundo nome");
else
puts ("Nao existe \"ana\" no segundo nome");
getch();
}

A função strcmp retorna:

• 0 (zero) se s1 e s2 são iguais;

• < 0 se s1 é alfabeticamente menor que s2;

• >0 se s1 é alfabeticamente maior que s2. (SANT’ANA, 2008)

Implemente e teste o programa acima.

214
3.9.2. Matrizes Bidimensionais

São estruturas que armazenam valores em 2 dimensões, tal


como uma tabela, onde temos linhas e colunas. Devem ser
referências por 2 índices, indicando a linha e coluna atual do
valor. Sua sintaxe é:

tipo nome [l][c];

Tipo: dado que será armazenado: inteiro, float, etc.;

nome é o nome de sua variável (identificador); e

[l][c] são os índices, informando a quantidade de linhas [ l ] e


colunas [ c ] de sua matriz.

/* Exemplo de Matriz Bidimensional */


#include <stdio.h>
#include <conio.h>
main (void)
{
int IndiceL, IndiceC, Matriz[3][4];
for (IndiceL = 0; IndiceL < 3; IndiceL++)
for (IndiceC = 0; IndiceC < 4; IndiceC++)
Matriz [IndiceL][IndiceC] = IndiceL *
IndiceC;

215
for (IndiceL = 0; IndiceL < 3; IndiceL++)
for (IndiceC = 0; IndiceC < 4; IndiceC++)
printf ("%4d", Matriz [IndiceL][IndiceC]);
getch ();
}

O programa acima cria uma matriz 3 x 4 e a cada posição


armazena o valor da multiplicação de seus índices. Depois, são
escritos na tela os valores armazenados na matriz.

Podemos ainda informar valores individuais a cada posição da


matriz. Chamamos isso de inicialização:

int Valores[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


char Teste[5] = {‘a’, ‘b’, ‘c’, ‘d’, ‘e’};

3.9.3. Estruturas

Vimos até agora estruturas chamadas homogêneas, pois


armazenam apenas o mesmo tipo de dados em seu interior.
Entretanto, a linguagem C permite que tenhamos uma coleção
de variáveis de diferentes tipos, relacionadas por apenas um

216
nome. A isso chamamos de Estruturas ou Registros. Uma
Estrutura possui elementos logicamente relacionados, porém,
de diferentes tipos, aumentando, assim, as possibilidades para
armazenamento de dados no programa.

Sua sintaxe é:

struct nome {
tipo nome_da_variavel;
tipo nome_da_variavel;
tipo nome_da_variavel;
...
} variaveis_estruturas;

onde:

struct é a palavra-chave que usamos para informar ao


compilador que está sendo criado um modelo de estrutura; tipo
é um dos tipos definidos de dados, e nome da variável é o
nome de cada identificador que fará parte da estrutura. Veja um
exemplo de definição de estrutura:

struct endereco
{
char nome [20];
char rua [40];
char cidade [20];
char estado[2];

217
signed int CEP [8];
};

Estamos criando uma estrutura que armazenará 4 variáveis do


tipo char: nome, rua, cidade, estado, e uma variável armazenará
inteiros positivos: CEP.

Na execução do programa, podemos criar variáveis do tipo


estrutura, tal como criamos variáveis de outro tipos. Imagine
criar uma estrutura do tipo endereço para armazenar endereços
de clientes:

Poderíamos ainda criar variáveis referentes à estrutura no


momento da declaração da mesma:

218
struct endereco
{
char nome [20];
char rua [40];
char cidade [20];
char estado[2];
signed int CEP [8];
}; Endereco_clientes; Endereco_Fornecedores;

Neste exemplo, usamos um laço de repetição para atribuir,


estamos criando uma estrutura e ao mesmo tempo criando 2
variáveis para armazenar dados tal como a estrutura criada. As
variáveis são Endereco_clientes e Endereco_Fornecedores.

Para atribuir valores a cada campo da estrutura, usamos o


comando ponto ( . ). Importante notar que, para atribuir valores
aos campos do tipo char, devemos sempre usar o comando
strcpy (). Assim, para atribuir um endereço a um cliente,
usaríamos os seguintes comandos:

strcpy (Endereco_clientes.nome, “Sidney Verginio da


Silva”);
strcpy (Endereco_clientes.rua, “Coronel José Alves,
256”);
strcpy (Endereco_clientes.cidade, “Varginha);
strcpy (Endereco_clientes.estado, “MG”);

219
Endereco_clientes.CEP = 37010540;

Para efetuar a leitura ou escrita de algum dado a partir do


teclado/monitor, podemos usar os comandos de E/S, já vistos
da linguagem C:

gets (Endereco_clientes.nome);
gets (Endereco_clientes.rua);
scanf (%d, Endereco_clientes.CEP);

E para escrita dos dados na tela:

printf (“%s”, Endereco_clientes.nome);


printf (“%s”, Endereco_clientes.rua);
printf (“%d”, Endereco_clientes.CEP);

Ainda é possível armazenar estruturas em variáveis


homogêneas (vetores); basta, para isso, declarar um vetor do
tipo da estrutura definida anteriormente:

struct endereco matriz [100];

Esta declaração define um vetor de índices de 0 a 99, cujos


elementos são do tipo estrutura registro. Em cada índice, será

220
armazenada uma estrutura contendo todos os dados definidos
na estrutura endereco. Para acessar um estrutura específica,
deve-se indexar o nome da estrutura. Por exemplo, para se
imprimir o código de CEP da estrutura 3:

printf ("%s", matriz [2].cep);

Lembrando que, em C, os índices das matrizes iniciam-se


sempre com o valor 0.

Vamos realizar alguns exercícios para fixar o


conteúdo:

1) Escreva um programa que leia 5 números, armazene-os


em um vetor e depois exiba: a média dos valores lidos, a
soma dos valores lidos, o menor e o maior valor.

221
2) Escreva um programa que crie uma matriz 3 x 3 e atribua o
número 3 a todas as posições das diagonais desta matriz.

3) Uma escola deseja criar um sistema que armazene o


código, nome completo e idade de seus alunos. Implemente
um programa em C para resolver este problema.

4) Depois de resolvida a questão 3, altere o programa para


que a escola possa armazenar os dados de 100 alunos. Faça
o teste armazenando e exibindo os dados de 5 alunos.

5) Crie um programa que leia um número inteiro. Este


programa deve ter uma função capaz de informar se o
número é par ou ímpar. Se for par, a função deve exibir a
mensagem “PAR”, seguido do símbolo +. Caso contrário, a
função escreve a mensagem “ÍMPAR” seguido do símbolo - .

222
3.10. Operações com Arquivos na Linguagem C

Vimos até agora como realizar operações de leitura, escrita e


manipulação de dados usando apenas a memória RAM do
computador. Mas, caso seu programa estivesse rodando e
houvesse um erro ou acabasse a energia do computador, os
dados seriam perdidos. Por isso, é importante sempre trabalhar
com armazenamento físico dos dados. Isso possibilita gravar os
dados em um arquivo e acessá-lo sempre que preciso.

A linguagem C permite que criemos arquivos físicos,


armazenados no HD do computador. Isso aumenta ainda mais
as possibilidades do programa, pois além de gravar os dados
em um arquivo do computador, podemos ler, alterar e excluir
estes dados a qualquer momento. Um programa capaz de
efetuar estas tarefas é chamado de CRUD – Create, Restore,
Update and Delete – Criar, Restaurar, Atualizar e Deletar.
Veremos agora as principais funções de manipulação de
arquivos em C.

É importante que você tenha mais atenção a partir


de agora, pois iremos trabalhar com comandos e
funções mais avançadas da linguagem C. Em caso
de dúvida, não deixe de entrar em contato comigo!

223
3.10.1. Definições

Usamos a biblioteca <stdio.h> para manipular arquivos. Esta


biblioteca fornece diversas funções para trabalharmos com
arquivos. Para tanto, usamos variáveis do tipo FILE, que
referenciam o endereço de memória que foi alocado para
“apontar” para o arquivo. Para melhor atendimento,
chamaremos este endereço de memória de “ponteiro”. Um
ponteiro de arquivo une o sistema de entrada/saída do
computador (teclado) com um buffer (espaço de memória). O
ponteiro não aponta diretamente para o arquivo em disco, mas
contém informações sobre o arquivo, incluindo nome, status
(aberto ou fechado) e posição atual sobre o arquivo. Define-se
uma variável ponteiro de arquivo usando o seguinte comando:

FILE *arq;

Com este comando, estamos usando uma variável chamada


“arq” que aponta (refere-se) a um arquivo físico.

A linguagem C permite gravar binários ou de texto. Para facilitar


nossa aprendizagem, trabalharemos somente com arquivos do
tipo texto.

224
3.10.2. Formas de acesso

Para trabalhar com um arquivo, devemos antes de tudo abri-lo.


Usamos a função fopen(), que abre o arquivo e devolve o
ponteiro a ele associado:

FILE *arquivo;

fopen(nome_do_arquivo, mode_de_abertura );

Arquivo é a variável que armazenará o endereço inicial de


memória ocupado por um arquivo. Caso o arquivo não possa
ser aberto, esta variável recebe o valor NULL;

nome_do_arquivo representa o nome do arquivo que se deseja


abrir, podendo incluir até o caminho do arquivo no sistema
operacional (por ex. C:\Usuario\Meus documentos);

modo_de_abertura representa como o arquivo será aberto. Os


modos de abertura são:

225
Tabela 17: Modos de abertura de arquivos
Fonte: Adaptado de ASCENCIO, CAMPOS (2012)

A utilização de cada modo de abertura varia de acordo com as


necessidades do programa. Assim, não convém abrir um
arquivo em modo de leitura e escrita (r+) se a intenção é apenas
exibir dados para o usuário.

Vejamos um exemplo:

FILE *arquivo;
arquivo = fopen(“arquivo.txt”, “w”);

Neste caso, a função fopen() cria um arquivo chamado


“arquivo.txt”, onde poderão ser realizadas operações de escrita e

226
leitura de dados, pois usamos o modo de abertura “w”. Quando
usamos uma função fopen() para abrir um arquivo no modo
escrita (w e w+), podem ocorrer duas situações:

 Se o arquivo não existe, ele é criado;

 Se o arquivo já existir, ele será sobreposto por um novo

arquivo vazio.

Como dito, a função fopen() devolverá à variável arquivo um


endereço de memória ocupado pelo arquivo, caso a operação
tenha sido realizada com sucesso. Caso contrário, ela retornará
o valor NULL. Por isso, é importante realizar um teste para
verificar se o arquivo foi criado/aberto corretamente:

#include <stdio.h>
#include <conio.h>

main (void)
{
FILE *arquivo;
arquivo = fopen (“arquivo.txt”, “w”);
if (arquivo == NULL)
printf (“\n Ocorreu um erro, o arquivo não
foi aberto.”);
else

227
{
/*os demais comandos do programa só serão
executados
se o arquivo foi aberto corretamente. */
}
getch();
}

Note que o comando fopen() apenas cria o arquivo, geralmente


no mesmo diretório onde o programa é compilado e salvo como
executável. Para alterar o caminho ou mesmo criar uma
estrutura de pastas, devemos utilizar a função system() da
biblioteca <stdlib.h>. Essa função envia uma string para o
processador, que, por sua vez, executa as ações da mesma
forma que as linhas de comando do sistema operacional (como
no prompt do MS-DOS no Windows). Com a função system()
podemos criar pastas, listar o conteúdo de uma pasta, renomear
e copiar arquivos, etc.

#include <stdio.h>
main (void)
{
system (“md C:\\exemplo\\teste”);
getch();
}

228
Usamos neste exemplo a função system() para criar um
diretório (pasta) no disco C. Para isso, passamos através dela
uma string que utiliza o comando md, padrão do Windows para
criação de pastas. Para não confundir o compilador com
caracteres de controle, usamos duas barras invertidas ( \\ ) para
indicar o caminho das pastas.

Após trabalhar com o arquivo, devemos fechá-lo para evitar


erros no mesmo. A função que fecha um arquivo é fclose():

int fclose(FILE *arquivo);

onde arquivo é a referência para o arquivo, que foi obtida


quando o mesmo foi aberto. Veja que quando executada, a
função fclose() retorna um número inteiro. Caso este número
seja igual a zero, significa que o arquivo foi fechado
corretamente, caso contrário, houve um erro em seu
fechamento.

#include <stdio.h>
#include <conio.h>

main(void)
{

229
FILE *arquivo;
int resposta;
arquivo = fopen("arquivo.txt", "w");
if (arquivo == NULL)
printf ("Erro na abertura do arquivo!\n\n");
else
{
printf ("Sucesso na abertura do
arquivo!\n\n");
resposta = fclose(arquivo);
if (resposta ==0)
printf ("\n\nSucesso no fechamento do
arquivo!");
else
printf ("\n\nErro no fechamento do
arquivo!");
}
getch();
}

A função fopen() abriu o arquivo “arquivo.txt” no modo escrita,


associando-o à variável arquivo. Veja que criamos um teste que
verifica se o arquivo foi aberto corretamente. Caso o retorno seja
NULL, é exibida a mensagem de erro. Caso contrário, podemos
realizar normalmente as operações de escrita. A função fclose()

230
usa o endereço guardado na variável arquivo para fechar o
arquivo “arquivo.txt”, armazenando o resultado desta operação
na variável resposta. Caso este resultado seja igual a 0
(resposta == 0), o arquivo foi fechado corretamente. Como já
dissemos, é importante decidir corretamente o modo de
abertura do arquivo e, principalmente, deixá-lo aberto o menor
tempo possível, já que um erro na execução do programa pode
danificar arquivos abertos.

3.10.3. Operações com arquivos

Podemos utilizar a função ferror() para verificar se ocorreu


algum erro durante a operação com arquivos. Sua sintaxe é:

int ferror (*arq);

Esta função devolve um número inteiro e deve ser usada logo


depois da chamada de qualquer outra função de manipulação
de arquivo. Se o valor retornado for 0, a operação foi realizada
corretamente. Caso contrário, ocorreu algum erro. Ao longo dos
demais exemplos, veremos como utilizar esta função.

231
 Gravando Caracteres em Arquivos

Usamos a função fputc() para escrever um caractere em um


arquivo:

#include <stdio.h>
#include <conio.h>
main (void)
{
FILE *arquivo;
char carac;
arquivo = fopen("caractere.dat", "a");

if (arquivo = NULL)
printf ("Erro na abertura. \n\n");
else
{
printf ("\nDigite um caractere: ");
scanf("%c*c", &carac);
while (carac != 'f')
{
fputc(carac, arquivo);
if (ferror(arquivo))
printf ("Erro na gravacao do
arquivo\n");

else
{
printf ("\nGravacao realizada com
sucesso!");
printf ("\nDigite outro
caractere");
scanf("%c*c", &carac);
}
}
}

232
fclose(arquivo);
getch();
}

Este programa recebe um caractere qualquer, armazenando-o


na variável c. A estrutura de repetição permite que se digite
inúmeros caracteres, até que o usuário digite “f”, finalizando o
programa. A cada leitura, a função fputc() grava o caractere lido
no arquivo referenciado pela variável arquivo. A função ferror()
verifica se o caractere foi gravado corretamente. Por fim, ao final
do programa, o arquivo é fechado através da função fclose().

 Lendo Caracteres de Arquivos

Usamos a função fgetc() para ler um caractere de um arquivo.


Caso a função seja bem sucedida, retornará o caractere lido,
que pode ser armazenado numa variável do tipo char. Caso
contrário, a função devolve o valor EOF (End Of File – Fim de
arquivo).

#include <stdio.h>
#include <conio.h>

main (void)
{
FILE *arquivo;

233
char c;
arquivo = fopen("caractere.txt", "r");
if (arquivo = NULL)
printf ("Erro na abertura. \n\n");
else
{
do
{
c = fgetc (arquivo);
if (ferror(arquivo))
printf ("Erro na leitura do
caractere\n");

else
{
if (!feof(arquivo))
{
printf ("\nLeitura realizada com
sucesso!");
printf ("Caractere lido: %c",
c);
}
}
} while (!feof(arquivo));
}
fclose(arquivo);
getch();
}

Note que existe neste programa uma estrutura de repetição do-


while que permite a leitura dos caracteres gravados no arquivo,
acessado por meio da variável arquivo. A função fgetc() lê um
caractere do arquivo e armazena-o na variável c. A cada leitura,

234
a função ferror() verifica se a leitura foi feita corretamente. Logo
após, temos a função feof(), que verifica se o fim do arquivo foi
encontrado. Isso é necessário para que não seja exibido o
caractere de fim de arquivo. Essa estrutura se repete até que
seja detectado o fim de arquivo, novamente através de nova
função feof(). Por fim, o arquivo é fechado e o programa é
encerrado.

 Gravação de Cadeiras de Caracteres em Arquivos

Veremos agora como gravar cadeias de caracteres em arquivos.


Estes comandos são úteis para armazenar palavras inteiras em
arquivos.

Usamos o comando fputs() para gravar uma cadeia de


caracteres em um arquivo. Vejamos um exemplo:

#include <conio.h>
#include <stdio.h>
#include <string.h>

main (void)
{
FILE *p;

235
char cadeia [30];
p = fopen ("cadeias.txt", "a");
if (p == NULL)
printf("\nErro de abertura!");

else
{
printf("\nDigite uma cadeia de caracteres -
\"fim\" para encerrar: ");
gets(cadeia);
while (strcmp (cadeia, "fim") != 0)
{
fputs (cadeia, p);
if (ferror (p))
printf("\nErro na gravação da
cadeia");
else
printf("\nGravacao realizada com
sucesso!");
printf ("\n\nDigite outra cadeia: ");
gets (cadeia);
}
}
fclose(p);
printf ("\n\nTecle algo para sair ");
getch ();
}

236
O programa solicita que seja digitada uma cadeia de caracteres,
lê esta cadeia e armazena na variável cadeia. A estrutura de
repetição permite que sejam digitadas várias cadeias. A
repetição é encerrada quando se digita a palavra “fim” – por isso
o comando strcmp(cadeia, "fim"), que compara o valor da
variável cadeia ao valor “fim”. Caso esta comparação seja
verdadeira – ou seja, igual a 0 –, a estrutura de repetição é
encerrada. A cada repetição, a função puts() grava a cadeia de
caracteres digitada no arquivo referenciado pela variável p.
Novamente usamos a função ferror() para verificar se a
gravação foi feita com sucesso, e, no fim, o arquivo é fechado.

 Leitura de Cadeiras de Caracteres em Arquivos

Para ler cadeias de caracteres de um arquivo, usamos a função


fgets(). Esta cadeia é formada por todos os caracteres
existentes, da posição atual do ponteiro do arquivo até a marca
de nova linha ou até a quantidade máxima de caracteres,
determinada por tamanho – 1.

Vejamos outro exemplo prático.

#include <stdio.h>

237
#include <conio.h>

main (void)
{
FILE *p;
char cadeia [5];
p = fopen ("cadeias.txt", "r");
if (p == NULL)
printf ("\nErro na abertura do arquivo.");

else
{
while (!feof(p))
{
fgets(cadeia, 5,p);
if (ferror(p))
printf ("\nErro na leitura da cadeia!");
else
{
printf ("\nLeitura realizada com
sucesso! - Cadeia lida: %s\n", cadeia);
}
}
}
fclose(p);
printf ("\nTecle algo para sair");
getch();
}

238
Mais uma vez temos uma estrutura de repetição que permite ler
todas as cadeias de caracteres gravadas em arquivo. A função
fgets() lê uma cadeia de 5 caracteres armazenados no arquivo
referenciado por p, armazenando os caracteres na variável
cadeia (note que estamos lendo os caracteres de 5 em 5.
Aumente ou diminua este valor para ver o resultado).

Esta função efetua a leitura até atingir 5 caracteres ou até


encontrar uma marca de nova linha. Note como usamos
novamente a função ferror() para verificar erros. A estrutura é
encerrada quando chegamos ao fim do arquivo, condição que é
verificada no comando feof() do comando while. E, por fim,
usamos a função feof() para fechar o arquivo.

3.10.4. Estruturas de dados em arquivos

Vimos que a linguagem C fornece meios de armazenar


diferentes tipos de dados referenciando uma única variável,
através de estruturas ( struct). No entanto, estas estruturas não
podem ser armazenadas em arquivos, já que estes armazenam
apenas uma sequência de caracteres ou de bytes. No entanto,
podemos ler parte do conteúdo de um arquivo e armazenar em

239
uma variável, ou, ainda, armazenar o conteúdo destas variáveis
diretamente no arquivo.

Para isso, usamos a função fwrite(), que escreve em arquivo


qualquer tipo de dado, não somente caracteres. Sua sintaxe é:

int fwrite (*mem, qtd_bytes, cont, FILE *arq);

onde:

mem é a variável que armazena o conteúdo a ser gravado no


arquivo;

qtd_bytes representa o total de bytes que será escrito no


arquivo;

cont representa o número de blocos de tamanho de qtd_bytes


que serão escritos no arquivo;

arq é a referência para o arquivo onde as informações serão


escritas.

Caso a gravação seja bem-sucedida, a função fwrite() retorna o


número de gravações realizadas no arquivo, que deve ser o
mesmo valor da variável cont. Caso contrário, a função retorna
um valor menor que o valor de cont.

240
Veja um exemplo prático.

//Exemplo de gravacao de estruturas em arquivo

#include <stdio.h>
#include <conio.h>

main (void)
{
struct cliente{
int numero;
char nome [20];
};

FILE *cli;
struct cliente c;
cli = fopen("clientes.txt", "w");
if (cli == NULL)
printf ("\nErro na abertura do arquivo");
else
{
printf ("\nDigite o numero do cliente a ser
incluído: ");
scanf("%d", &c.numero);
printf ("\nDigite o nome do cliente a ser
incluído: ");

241
scanf("%s", &c.nome);
fwrite(&c, sizeof(struct cliente), 1, cli);
if (ferror(cli))
printf ("\nErro na gravação");
else
printf ("\n\nGravacao realizada com
sucesso!");
fclose(cli);
}
getch();
}

Analisemos com atenção este programa:

Criamos uma estrutura chamada cliente, que armazenará 2


tipos de dados: código e nome do cliente. Criamos então uma
variável c para referenciar esta estrutura. Novamente, temos a
função fopen() que abre o arquivo e a função ferror(), que
verifica se a abertura do mesmo foi feita com sucesso. Logo
depois, temos a leitura de dois valores: o número do cliente,
armazenado na variável que representa o código na estrutura
(c.numero), e logo após foi lido o nome do cliente, armazenado
então na variável que representa o nome do cliente na estrutura
(c.nome). Assim, a estrutura representada pela variável c ficou
totalmente preenchida. Usamos, então, a função fwrite() para

242
gravar o conteúdo da estrutura armazenada na variável c no
arquivo referenciado pela variável cli. As funções ferror() e
fclose() já são conhecidas.

Importante: Na função fwrite() temos:

&c, é a variável que contém os dados a serem


gravados no arquivo;

sizeof (struct cliente) – é o tamanho do bloco que será gravado,


ou seja, o tamanho é o mesmo tamanho ocupado pela variável
c – estrutura cliente;

1 representa a quantidade de blocos do tamanho sizeof (struct


cliente) que serão gravados, ou seja, apenas uma gravação por
vez;

cli é a variável que referencia o arquivo físico aberto


(ASCENCIO; CAMPOS, 2012);

Uma vez efetuada a gravação dos dados no arquivo, podemos


efetuar a leitura a partir do mesmo. Neste caso, usamos a
função fread(), que possui a seguinte sintaxe:

int fread (*mem, qtd_bytes, cont, FILE *arq);

243
onde:

mem é a variável que vai receber o conteúdo do arquivo lido;

qtd_bytes representa o tamanho do bloco, em bytes, que será


lido do arquivo;

cont representa o número de blocos (o mesmo informado no


parâmetro qtd_bytes) que serão lidos a partir do arquivo;

arq é a referência para o arquivo que será lido.

Caso a função fread() seja executada com sucesso, retornará


um valor igual ao número de leituras realizadas (igual ao
parâmetro cont informado). Caso ocorra algum erro ou quando
o fim do arquivo for encontrado, o valor retornado será menor
que o valor de cont.

Vejamos agora como efetuar a leitura dos dados gravados no


programa anterior:

//Exemplo de leitura de estruturas a partir de um


arquivo
#include <stdio.h>
#include <conio.h>
main (void)
{
FILE *cli;
struct cliente{

244
int numero;
char nome [20];
};
struct cliente c;
cli = fopen("clientes.txt", "r");
if (cli == NULL)
printf ("\nErro na abertura do arquivo");
else
{
fread(&c, sizeof(struct cliente),1,cli);
if (cli == NULL)
printf ("\nErro na leitura do arquivo");
else
printf ("\n\nLeitura do arquivo realizada
com sucesso!");
while (!feof(cli))
{
printf ("\n\nNumero do cliente lido: %d",
c.numero);
printf ("\n\nNome do cliente lido: %s",
c.nome);
fread(&c, sizeof(struct cliente),1,cli);
if (ferror(cli))
printf("\n\nErro na leitura do
arquivo.");
else
printf ("\n\nLeitura realizada com
sucesso!");

245
}
fclose(cli);
}
printf ("\n\nTecle algo para sair!");
getch();
}

Neste programa, o arquivo clientes.txt foi aberto e seu endereço


foi atribuído à variável cli, sendo que no momento da abertura o
cursor do arquivo foi posicionado no byte zero do arquivo, ou
seja, seu início. A função fread() efetua a leitura dos dados do
arquivo, percorrendo a quantidade de bytes informada na
função – esta quantidade é a mesma do tamanho da estrutura
cliente. Isso movimentou ou cursor a mesma quantidade bytes.
Por exemplo, a variável c, que é do tipo struct cliente ocupa 22
bytes – 2 para o número e 20 para o nome. Logo, o cursor do
arquivo sai da posição 0 e termina na posição 21.

A estrutura de repetição permite ler todos os dados do arquivo,


que são armazenados na variável c. Em seguida, o conteúdo
armazenado na variável c é exibido através da função printf().
Essa leitura e escrita só é encerrada quando encontrado o fim
do arquivo, através da função feof(). Logo em seguida, o arquivo
é fechado.

246
Na função fread(), temos:

&c, é a variável que receberá os dados lidos do


arquivo;

sizeof (struct cliente) – é o tamanho do bloco de leitura, ou seja,


o tamanho ocupado por variáveis do tipo struct cliente;

1 representa a quantidade de blocos do tamanho sizeof (struct


cliente) que serão lidos;

cli é a variável que referencia o arquivo físico que será feita a


leitura (ASCENCIO; CAMPOS, 2012);

 Cursores em arquivos

Vimos que um arquivo também possui um cursor, que nada


mais é do que um ponteiro que indica a partir de que posição
do arquivo uma operação será executada. Quando um arquivo é
aberto, seu cursor aponta para a posição 0, ou seja, o primeiro
byte do arquivo. Caso usemos o comando fread(), o cursor se
movimentará à quantidade de bytes indicados na função.

247
Em alguns momentos, devemos reposicionar este cursor.
Imagine que você tenha um programa que efetue, num único
código, escrita e leitura de dados. Como o arquivo não será
fechado, é possível que você esteja lendo um arquivo a partir de
seu fim, ou ainda, que você grave dados sobre outros já
existentes. Por isso devemos usar comandos de reposicionar
cursores em arquivos. Os comandos utilizados são: rewind() e
fseek().

A função rewind() reposiciona o cursor de volta ao início do


arquivo. Sua sintaxe é:

rewind (FILE *arq);

Veja:

#include <stdio.h>
#include <conio.h>
main (void)
{
FILE *cli;
struct cliente{
int numero;
char nome [20];
};
struct cliente c;
cli = fopen("clientes.txt", "r");
if (cli == NULL)
printf ("\nErro na abertura do arquivo");
else

248
{
fread(&c, sizeof(struct cliente),1,cli);
if (ferror(cli))
printf("\n\Erro na leitura");
else
{
printf ("\n\nLeiura realizada com
sucesso");
printf ("\n\nNumero do cliente lido:
%d", c.numero);
printf ("\n\nNome do cliente lido: %s",
c.nome);
rewind(cli);
printf ("\n\nCursor reposicionado no
inicio ->");
fread(&c, sizeof(struct
cliente),1,cli);
if (ferror(cli))
printf("\n\nErro na leitura do
arquivo.");
else
{
printf ("\n\nLeitura realizada com
sucesso!");
printf ("\n\nNumero do cliente
lido: %d", c.numero);
printf ("\n\nNome do cliente lido:
%s", c.nome);
}
}
fclose(cli);
}
getch();
}

249
Note que eliminamos a estrutura de repetição while(). Após as
primeiras leituras, reposicionamos o cursor no início do arquivo,
efetuando nova leitura dos dados. Por isso os dados são
exibidos de forma repetida, pois foram lidos novamente. Após
isso, o arquivo é fechado.

Além disso, podemos posicionar o cursor em uma posição


específica do arquivo. A função fseek() efetua este serviço sem
que tenhamos que abrir e fechar o arquivo novamente. Sua
sintaxe é:

fseek(FILE *arq, qtd_bytes, posicao);

onde: arq é o arquivo que será percorrido pela função fseek();

qtd_bytes representa a quantidade de bytes que o cursor será


movimentado a partir da posição;

posicao representa o ponto a partir do qual a movimentação


será executada, podendo assumir os valores:

 SEEK_SET: permite a movimentação de qtd_bytes a

partir da posição inicial do arquivo;

250
 SEEK_CUR: permite a movimentação de qtd_bytes

no arquivo a partir do ponto atual do cursor;

 SEEK_SET: permite a movimentação de qtd_bytes a

partir da posição final do arquivo.

 Outras operações com arquivos

Ainda podemos usar funções para renomear e apagar arquivos:

int remove (char *nome_arq);

nome_arq representa o nome do arquivo que será removido.


Caso a função seja executada com sucesso, será devolvido o
número 0. Caso contrário, será devolvido outro valor. Importante
que, antes de apagar o arquivo, ele deve ser fechado.

int rename (char *nome_atual, char *nome_novo);

nome_atual indica o nome físico atual do arquivo, e


nome_novo será o novo nome do arquivo físico.

251
Exemplos:

A) Renomeando um arquivo:

#include <stdio.h>
#include <conio.h>
main (void)
{
int x;
FILE *arq;

arq = fopen ("cliente.txt", "a");


fclose(arq);

x = rename ("cliente.txt", "dados.txt");


if (x == 0)
printf ("Sucesso na troca do nome");
else
printf ("Erro na troca do nome");

fclose(arq);
getch();
}

252
B) Apagando um arquivo:

#include <stdio.h>

#include <conio.h>

main (void)

int x;

x = remove (“cliente.txt”);

if (x == 0)

printf (“Arquivo removido com sucesso);

else

printf (“Erro na remocao do arquivo”);

getch();

Implemente no Dev-C++ os programas acima.


Veja como ocorrem as gravações e leituras dos
arquivos. Veja também, na pasta onde você sala
seus programas em C, como os arquivos .txt criados são
modificados após a execução dos comandos rename e
remove.

253
Acesse a Midiateca e baixe o arquivo em C
contendo um programa completo para
manipulação de arquivos.

Vimos neste capítulo como é a construção de um programa em


uma linguagem de programação de alto nível. A linguagem C
permite criar diversos programas com muitas funcionalidades.
Por ser estruturada, possibilita criar muitas funções e módulos
que facilitam o desenvolvimento e manutenção do código.
Vimos ainda como manipular dados usando matrizes,
estruturas, e principalmente arquivos, cujos dados podem ser
lidos e armazenados em qualquer momento. Mesmo que o
programa seja encerrado e executado em outro momento, os
dados não são perdidos, pois ficam registrados em um arquivo
físico, e não na memória volátil (RAM) do computador. Essa ,
sem dúvida, é uma das grandes vantagens na construção de
programas de computador: a criação, edição, consulta e
exclusão de dados.

254
FINALIZANDO

Caro aluno,

Chegamos ao fim de nossa jornada. Ao longo deste guia, vimos


as principais técnicas de programação de computadores, desde
a elaboração de algoritmos simples até à construção de
programas inteiros e complexos na linguagem C.

Procure implementar todos os exercícios e exemplos aqui


propostos. Altere os comandos, mude funções, aumente as
possibilidade de seus programas. Inove e crie novos programas
com novas funcionalidades. Aos poucos você estará
desenvolvendo aplicações para resolver problemas de seu dia a
dia.

Claro que este assunto não se esgota aqui, já que existem


diferentes tipos de linguagem de programação, cada uma com
sua finalidade específica, bem como diferentes formas de
desenvolver programas. O conteúdo apresentado nesta
disciplina permite que, a partir de agora, você explore com
sabedoria o universo da linguagem de programação e busque
entender ainda mais o funcionamento de um programa.

Tenho certeza que a partir de agora você não verá os softwares


da mesma forma. Enquanto outros olham programas e veem

255
apenas botões, ícones e textos, você agora é capaz de enxergar
variáveis, funções, vetores, estruturas de dados...

Foi um prazer estar contigo ao longo deste semestre. Desejo-


lhe, querido aluno, muito sucesso em toda a sua vida.

Um grande abraço!

Prof. Sidney Verginio da Silva

Julho de 2013.

256
REFERÊNCIAS

ASCENCIO, Ana Fernanda Gomes; CAMPOS, Edilene Aparecida


Veneruchi de. Fundamentos da programação de
computadores: algoritmos, Pascal, C/C++ e Java. 3. ed. São
Paulo: Pearson Prentice Hall, 2012.

FARRER, Harry, et al . Algoritmos estruturados - Programação


estruturada de computadores. Rio de Janeiro: LTC, 1989.

FORBELLONE, André Luiz Villar. Lógica de programação: a


construção de algoritmos e estruturas de dados. 3. ed. São
Paulo: Makron Books, 2005.

MIZRAHI, Victorine Viviane. Treinamento em Linguagem C.


2.ed. São Paulo: Pearson Prentice Hall, 2008.

257
SALVETTI, Dirceu Douglas; BARBOSA, Lisbete Madsen.
Algoritmos. São Paulo: Makron Books, 1998.

SANT’ANA, Tomás Dias. Guia de Estudos - Princípios de


Desenvolvimento de Algoritmos. Varginha: GEaD - UNIS/MG,
2010.

SANT’ ANA, Tomás Dias. Guia de Estudos - Linguagem e


Técnicas de Programação II. Varginha: GEaD-UNIS/MG, 2008.

SCHILDT, Herbert. C, Completo e Total. 3.ed. São Paulo:


Pearson Makron Books, 1997.

258

Você também pode gostar