You are on page 1of 81

Universidade São Francisco

Centro de Ciências Exatas e Tecnológicas


Câmpus Itatiba

Algoritmos e Linguagem
de Programação C

Autores:
Thales Coelho Borges Lima
Márcio Henrique Zuchini
Fábio Alexandre G. Casotti
Débora Pretti Ronconi
Algoritmos e Linguagem de Programação
i

1. Sistema de Computadores.........................................................................................2
1.1 Arquitetura Típica: Hardware e Software..................................................................2
1.2 Componentes básicos de um computador...................................................................3
1.2.1 Memórias.................................................................................................................................3
1.2.1.1 Memória ROM.................................................................................................................3
1.2.1.2 Memória RAM.................................................................................................................4
1.2.2 Dispositivos de Entrada e Saída...............................................................................................4
1.2.3 Unidade Aritmética e Lógica..................................................................................................4
1.2.4 Unidade de Controle................................................................................................................4
1.3 Processador...................................................................................................................5
1.3.1 A família PC............................................................................................................................5
1.3.2 O exterior de um micro............................................................................................................6
1.4 Bits, Bytes e Palavras...................................................................................................6
1.5 Sistemas de Numeração................................................................................................7
1.5.1 Sistema Binário........................................................................................................................7
1.5.1.1 Conversão do sistema binário para o sistema decimal.....................................................8
1.5.1.2 Conversão do sistema decimal para o sistema binário.....................................................8
1.5.2 Sistema octal de numeração.....................................................................................................9
1.5.2.1 Conversão do sistema octal para o decimal......................................................................9
1.5.2.2 Conversão do sistema octal para o binário.......................................................................9
1.5.2.3 Conversão do sistema binário para octal..........................................................................9
1.5.2.4 Conversão do sistema decimal para octal.......................................................................10
1.5.3 Sistema Hexadecimal.............................................................................................................10
1.5.3.1 Conversão do sistema hexadecimal para o decimal.......................................................11
1.5.3.2 Conversão do sistema hexadecimal para o binário........................................................11
1.5.3.3 Conversão do sistema binário para o hexadecimal........................................................11
1.5.3.4 Conversão do sistema decimal para o hexadecimal.......................................................11
2. Algoritmos e Programas.........................................................................................12
3. Dados e Tipos de Dados..........................................................................................20
3.1 Dados Numéricos.........................................................................................................20
3.2 Dados não-numéricos.................................................................................................20
3.3 Código ASCII..............................................................................................................21
3.4 Operadores para manipulação de dados...................................................................21
3.4.1 Operadores Aritméticos.........................................................................................................21
3.4.2 Operadores de Relação...........................................................................................................22
3.4.3 Operadores Lógicos................................................................................................................22
3.5 Variáveis......................................................................................................................23
3.5.1 Identificadores.......................................................................................................................23
3.6 Constantes....................................................................................................................24
3.7 Operação de atribuição...............................................................................................24
3.7.1 Expressões..............................................................................................................................24
3.7.1.1 Prioridade dos operadores em uma expressão ..............................................................25
3.8 Funções Embutidas.....................................................................................................25
3.9 Comandos de Entrada e Saída...................................................................................26
3.9.1 Comando LEIA......................................................................................................................26
3.9.2 Comando ESCREVA.............................................................................................................26
4. Estruturas de Decisão.............................................................................................28
4.1 Bloco de Comandos.....................................................................................................30
4.2 Comandos Ses Aninhados ( Encaixados ).................................................................31
Algoritmos e Linguagem de Programação
ii

5. Estruturas de Repetição ( Laços )..........................................................................34


5.1 Comando Para.............................................................................................................34
5.2 Comando Enquanto....................................................................................................36
5.3 Comando Faça-Enquanto...........................................................................................36
5.4 Laços Aninhados.........................................................................................................37
6. Conjunto Homogêneos (Vetores e Matrizes).........................................................39
6.1 Vetor ( Conjunto Unidimensional ) .........................................................................39
6.1.1 Aplicações de vetores............................................................................................................39
6.2 Matrizes ( Conjuntos Bidimensionais ).....................................................................41
6.3 Conjuntos com mais de duas Dimensões...................................................................41
7. Fundamentos de C..................................................................................................43
7.1 Variáveis .....................................................................................................................43
7.2 Tipos de Dados ......................................................................................................44
7.2.1 Modificadores de tipos...........................................................................................................44
7.2.2 Declaração de Variáveis.........................................................................................................45
7.3 Constantes....................................................................................................................45
7.4 Inicialização de variáveis em C.................................................................................46
7.5 Operadores..................................................................................................................46
7.5.1 Operadores Aritméticos .......................................................................................................46
7.5.2 Operadores de Incremento e Decremento.............................................................................47
7.5.3 Operadores Relacionais.........................................................................................................47
7.5.4 Operadores Lógicos................................................................................................................48
7.5.5 Operador de Atribuição.........................................................................................................48
7.6 Expressões....................................................................................................................48
7.6.1 Conversão de tipos em expressões.........................................................................................48
7.6.2 Casts........................................................................................................................................49
7.7 Comandos de Entrada e Saída...................................................................................49
7.7.1 Entrada de dados....................................................................................................................49
7.7.2 Saída de dados........................................................................................................................50
7.8 Chaves e Comentários.................................................................................................50
8. Comandos de Controle de Fluxo ...........................................................................50
8.1 Comandos de Decisão.................................................................................................51
8.1.1 Comando if ............................................................................................................................51
8.1.2 Comando if-else.....................................................................................................................51
8.1.3 Comandos if aninhados..........................................................................................................52
8.1.4 O comando if-else-if..............................................................................................................52
8.1.5 Comando switch.....................................................................................................................53
8.2 Comandos de Repetição..............................................................................................53
8.2.1 Comando for...........................................................................................................................54
8.2.1.1 Variações do comando for..............................................................................................55
8.2.1.2 Laço for infinito..............................................................................................................55
8.2.2 Comando while.......................................................................................................................55
8.2.3 Comando do-while.................................................................................................................56
8.3 Interrupção de Laços..................................................................................................56
8.3.1 Break.......................................................................................................................................56
8.3.2 Continue.................................................................................................................................56
8.3.3 Rótulos e goto.........................................................................................................................57
Algoritmos e Linguagem de Programação
iii

9. Vetores e Matrizes...................................................................................................57
9.1 Matriz de uma dimensão - Vetores............................................................................57
9.2 Matriz com Duas Dimensões......................................................................................58
9.3 Cadeia ( Strings ).........................................................................................................58
9.3.1 Lendo uma string ...................................................................................................................59
9.3.2 Exibindo uma string...............................................................................................................59
9.3.3 Funções para manipulação de strings em C..........................................................................59
9.3.3.1 Função strcpy()................................................................................................................59
9.3.3.2 Função strcat().................................................................................................................60
9.3.3.3 Função strcmp()...............................................................................................................60
9.3.3.4 Função strlen().................................................................................................................60
10. Funções e estrutura de um Programa em C........................................................61
10.1 Regra de escopo das funções....................................................................................62
10.1.1 Variáveis Locais...................................................................................................................62
10.1.2 Variáveis globais..................................................................................................................63
10.1.3 Parâmetros formais...............................................................................................................63
10.2 Funções que retornam valores.................................................................................64
10.2.1 Valores de Retorno...............................................................................................................64
10.3 Argumentos das Funções..........................................................................................65
10.3.1 Chamada por Valor e Chamada por Referência..................................................................65
10.3.1.1 Como criar uma chamada por referência em C............................................................66
10.4 Protótipos de Funções...............................................................................................66
11. Ponteiros................................................................................................................66
11.1 Operadores de Ponteiros..........................................................................................67
11.2 Aritmética com ponteiros..........................................................................................67
11.3 Ponteiros e vetores.....................................................................................................67
11.4 Passando vetores e matrizes para dentro de uma função em C.............................68
12. Arquivos.................................................................................................................69
12.1 Operações com Arquivos em Disco em C................................................................69
12.1.1 Leitura e Gravação em Alto Nível.......................................................................................69
12.1.2 Arquivos Texto e Binário.....................................................................................................69
12.1.3 Abrindo um Arquivo em Disco............................................................................................69
12.1.4 Escrevendo em um arquivo..................................................................................................70
12.1.5 Fechando um arquivo...........................................................................................................70
12.1.6 Lendo Dados de um Arquivo...............................................................................................71
12.1.7 Fim de Arquivo....................................................................................................................72
12.1.8 Gravando uma cadeia de caracteres ( bytes )......................................................................72
12.1.9 Lendo uma cadeia de caracteres ( bytes ) em um arquivo..................................................72
12.1.9.1 Enviando uma string para a impressora........................................................................73
12.1.10 Gravando um arquivo de forma Formatada.......................................................................73
12.1.11 Lendo um arquivo Formatado............................................................................................73
12.1.12 Lendo e Gravando Registros em um Arquivo...................................................................74
12.1.12.1 Gravando estruturas.....................................................................................................74
12.1.13 Gravando vetores ...............................................................................................................75
12.1.14 Lendo estruturas de um arquivo.........................................................................................75
Algoritmos e Linguagem de Programação
iv
Algoritmos e Linguagem de Programação
1

Algoritmos
Algoritmos e Linguagem de Programação
2

1. Sistema de Computadores

1.1 Arquitetura Típica: Hardware e Software


Um sistema de computador é formado por um conjunto de componentes físicos,
denominado hardware e de um conjunto de programas necessários para o
funcionamento da parte física, que recebe o nome de software. O termo inglês
“Hardware” significa equipamento. Entende-se como Hardware toda a parte física do
equipamento, como exemplo:
- Fonte de Alimentação
- Teclado
- Monitor de Vídeo
- CPU
- Controladoras
- Driver
- Winchester, etc...
Sem o software o hardware não possui nenhuma utilidade, pois sem os programas
o usuário não possui acesso aos recursos oferecidos pelo computador. Pode-se dividir
o software em duas categorias:
- Aplicativos Específicos
- Aplicativos Básicos
Como aplicativos específicos pode-se citar: editores de texto, folhas de pagamento,
planilhas, controle de estoque, etc. O software básico tem a função de
operacionalizar o computador, de modo a deixar o equipamento pronto para receber o
software aplicativo.
Como exemplo de software básicos pode-se citar: o firmware, os sistemas
operacionais, os programas utilitários e as ferramentas de programação.
O firmware é um conjunto de programas internos, gravados em memória ROM,
necessários para executar tarefas como: inicialização do computador, transferência do
sistema operacional do disquete ou winchester para a memória principal e testes para
verificar o correto funcionamento do equipamento, antes de liberá-lo para a operação.
Também é conhecido pelo nome de BIOS (sistema básico de entrada e saída).
O sistema operacional é o programa que faz a interface entre o usuário e a
máquina. Ao ser carregado, o sistema operacional coloca a disposição do operador,
uma série de comandos úteis para a realização de tarefas básicas como:
- Exame e manuseio dos arquivos armazenados em disco,
- Utilização básica do monitor, teclado, impressora, etc...
Os programas utilitários, embora façam parte do sistema operacional, realiza
muitas funções básicas, tais como:
- Copiar arquivos,
- Formatar disquetes e winchester,
- Criar e editar textos,
- Informar a capacidade armazenada em discos.
Algoritmos e Linguagem de Programação
3

As ferramentas de programação têm a função de transformar o programa criado


pelo usuário em uma série de comandos em linguagem de máquina, que é a forma que
o computador entende. São chamados de compiladores e interpretadores.

1.2 Componentes básicos de um computador


Todos os tipos de computadores, desde microcomputadores até mainframes,
consiste de um sistema interconectado composto de quatro componentes básicos: a
memória, a unidade de controle, a unidade aritmética e lógica e os dispositivos de
entrada e saída de dados.

1.2.1 Memórias
São dispositivos para o armazenamento de dados. É a parte do computador onde os
programas e dados são armazenados. A memória é dividida em memória interna ou
principal e memória externa. Os programas e dados a serem executados pelo
computador, residem na memória principal.
A memória principal é constituída de unidades básicas e de mesmo tamanho,
denominada de palavras, sendo que cada palavra tem um endereço correspondente,
para que possa ser acessada de forma única. Cada palavra pode armazenar um pedaço
de informação. As palavras de uma memória contém o mesmo número de bits, que é
a unidade básica. Um bit ( dígito binário ) pode conter o valor 0 ou 1.
A memória externa é constituída de dispositivos capazes de armazenar os
programas, mesmo que o computador não esteja ligado. O custo de memórias
externas é bem menor se comparado com o custo da memória principal, e sua
capacidade de armazenamento é bem superior ao da memória principal. Como
exemplo de memórias externas, podemos citar: os discos rígidos (winchester), os
discos flexíveis (disquetes), as fitas magnéticas, etc.

1.2.1.1 Memória ROM


A sigla ROM significa READ ONLY MEMORY, ou seja, memória apenas para a
leitura. É apenas lida e nunca para ser gravada. Já sai da fábrica com o seu conteúdo
armazenado.
São memórias não-voláteis, isto é, o seu conteúdo não é perdido quando o
computador é desligado. É usada para manter os programas necessários no instante de
inicialização do computador. Por exemplo, quando o computador é ligado, pode-se
observar na tela, uma contagem de memória, um acesso aos drives e a carga do
Sistema Operacional. Tudo isso é realizado por um programa denominado BIOS
(Sistema Básico de Entrada e Saída) que está armazenado na memória ROM.
Existe outros tipos de memória ROM:
- PROM: Programable ROM. Permite um armazenamento das informações pelo
próprio usuário, porém feito de forma definitiva. Após a programação a PROM se
transforma em uma ROM. A forma de armazenamento de dados em uma PROM é
feita aplicando níveis de tensão conveniente na localidade onde se deseja armazenar o
dado. Esta programação é definitiva não sendo possível nenhuma alteração.
- EPROM: Erasable Programable ROM. Permite a programação de forma
semelhante às PROM, com a vantagem de poderem ser apagadas normalmente,
mediante banho de ultravioleta efetuado através de uma pequena janela existente em
seu encapsulamento.
- EAROM: Electrically Alterable ROM e EEPROM: Electrically Erasable
Programable ROM. Diferenciam da EPROM na forma de apagamento, sendo
apagadas eletricamente e não por luz ultravioleta.
Algoritmos e Linguagem de Programação
4

1.2.1.2 Memória RAM


A sigla RAM significa RANDOM ACCESS MEMORY (memória de acesso
aleatório). Este tipo de memória pode ser usada tanto para leitura quanto para escrita.
É nela que estão armazenadas as instruções a serem executadas pelo processador, bem
como os dados a serem processados. É uma memória volátil; o seu conteúdo é
perdido no momento que a máquina é desligada. Isto não que dizer que os programas
serão perdidos, pois eles ficam armazenados permanentemente no disco e são
copiados para a memória RAM quando forem usados.
Tipos de memória RAM:
- DRAM - Dynamic RAM. É usada em grande quantidade nos micros. Por
exemplo, um computador com 8 MBytes de memória, todos esses 8 Mbytes são
formados por DRAM . São lentas, mas em compensação são baratas e compactas.
- SRAM - Static RAM. É mais veloz que a DRAM. Nas modernas placas de CPU,
usa-se uma pequena quantidade de memória SRAM para acelerar o desempenho da
DRAM. A SRAM é chamada de memória cache.
- VRAM - Video RAM. É um tipo especial de DRAM apropriada para as placas
de vídeo. Pode ser acessada por dois circuitos simultaneamente.

1.2.2 Dispositivos de Entrada e Saída


São todos os dispositivos usados pelo computador para receber e enviar dados. Os
dispositivos de entrada fornecem o meio pelo qual os dados são enviados para o
computador para que possam ser processados. Já os dispositivos de saída são
necessários para que possamos obter os resultados após o processamento. Existe uma
grande variedade de dispositivos de entrada e saída. Como exemplo, podemos citar os
mais comuns: teclado, mouse, caneta ótica , scanner, como equipamentos de entrada
de dados e monitor, impressora, plotter, como dispositivos de saída de dados.

1.2.3 Unidade Aritmética e Lógica


Onde todos os cálculos são realizados. Estes cálculos podem ser operações
aritméticas como adição, multiplicação, subtração e divisão ou operações lógicas
como comparação de dois valores para verificar qual é o maior.

1.2.4 Unidade de Controle


Controla as ações de todos os dispositivos mencionados acima, ou seja, gerencia
todas as operações do computador Controla todas as instruções que estão na memória
principal, faz com que os dispositivos de entrada leiam os dados, transfere os dados
da memória principal para a unidade aritmética e lógica, onde são executados os
cálculos, e passa os resultados para os dispositivos de saída . A unidade de controle e
a unidade aritmética e lógica formam a Unidade Central de Processamento (UCP) ou
seja, o processador. A Figura 1.A mostra os componentes básicos de um
computador.
Algoritmos e Linguagem de Programação
5

Figura 1.A

1.3 Processador
O processador é a parte do computador que tem a função de executar os programas
(conjunto de instruções). São de responsabilidade do processador:
- Ler e escrever informações na memória;
- Reconhecer e executar um conjunto de comandos ou instruções;
- Informar a todas as partes do computador o que deve ser feito a cada momento.
É o componente mais importante de um micro. É um chip que realiza todo o
controle do computador: comanda a leitura/escrita de dados nos discos, lê e grava
dados na memória, executa programas, recebe dados de dispositivos como o mouse e
teclado, e transmite dados para dispositivos como impressoras e vídeo.
O microprocessador executa diversas operações matemáticas como: adição,
subtração, multiplicação, divisão e operações lógicas como: OR, AND e NOT.
Também realiza comparações entre dois números para saber qual é o maior, menor ou
se são iguais. Executa decisões em função de comparação. Além de operações
numéricas, podem ser realizadas operações com caracteres, como exemplo, procurar
uma palavra em um texto, trocar todas as ocorrências de um caracter por outro e
outras operações comuns em processamento de texto.
O usuário não comanda diretamente o microprocessador, e sim os programas. Os
programas contém as instruções que são executadas pelo microprocessador.

1.3.1 A família PC
Em 1981, a IBM lançou o 1º Computador pessoal IBM-PC (Personal Computer)
que possuía um microprocessador INTEL 8088 de 4,77 MHz e 64 kbytes de
memória. Mais tarde, a IBM acoplou um disco rígido de 10 Mbytes e passou a
chamá-lo de IBM PC XT (Extended Technology).
Após a INTEL lançou o microprocessador 80286 que passou a ser utilizado no
IBM PC AT (Advanced Technology) com 8 Mhz. Era 6 vezes mais veloz que o 8088.
Em seguida surgiram microprocessadores 80386, 80486 e o PENTIUM.
Algoritmos e Linguagem de Programação
6

1.3.2 O exterior de um micro


Todos os micros, do ponto de visto externo são parecidos. É impossível dizer
antecipadamente as características principais como: microprocessador, quantidade de
memória e capacidade do disco rígido.. Externamente, pode-se observar os módulos:
- Gabinete
- Teclado
- Monitor
- Mouse
- Impressora
- Scanner
- Joystick
- Caixas de Som e Microfones
Sem dúvida que a parte mais importante de um micro é a que fica no interior do
gabinete. Na parte frontal do gabinete pode-se observar os drives (para leitura e
escritas em disquetes) e unidade de CD-ROM, além de diversas chaves e leds. Na
parte traseira do gabinete, encontra-se diversas conexões para ligar dispositivos como
teclado, impressora, monitor, mouse, etc, e a tomada para ligar o computador à rede
elétrica.
Primeiramente, os micros PC eram produzidos apenas pela IBM. Em seguida,
surgiram os “clones” do IBM PC, que eram computadores compatíveis com o IBM
PC, mas produzidos por outros fabricantes. Em qualquer tipo de PC, o
microprocessador fica localizado em uma placa denominada de PLACA DE CPU.
Uma grande característica dos processadores da INTEL é a compatibilidade. Assim
todos os programas escritos para rodar no IBM PC XT rodam no 80286 ao
PENTIUM.

1.4 Bits, Bytes e Palavras


O computador tem a capacidade de manipular dados. Os dados dentro de um
computador são constituídos por um conjunto de zeros e uns, tanto para representar
um caracter ( como exemplo, uma letra ) quanto um número. A menor e fundamental
unidade capaz de armazenar um valor 0 ou 1 em um computador é chamada de bit
( binary digit ). Um bit é capaz de armazenar um valor 0 ou um valor 1 em um dado
instante de tempo. Os bits 0 e 1 podem representar ligado ou desligado, verdadeiro ou
falso.
Os bits individualmente não representam muita informação, mas um conjunto de
bits formamos algo significativo. Um conjunto de 8 bits constituímos uma unidade
denominada de byte. Os bytes são as principais unidades práticas de dados em um
computador. Como exemplo, a capacidade de memória ou a capacidade de
armazenamento de um disco rígido, são medidas em bytes.
Portanto, podemos concluir que um byte é constituído por 8 bits e é a principal
unidade de dados e um bit é a menor unidade de dados.
Embora podemos acessar os bits de um byte, os computadores foram projetados
para trabalhar com dados na forma de bytes ou conjunto de bytes.
Um byte é um conjunto de 8 zeros e uns. Desta forma temos 256 possíveis
combinações que um byte pode tomar. Exemplo:
Algoritmos e Linguagem de Programação
7

0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0
.
.
.
1 1 1 1 1 1 1 1

Os bytes são representações de caracteres ou um número.


Palavra é um conjunto de bytes. Exemplo, palavra de 2 bytes ou seja 16 bits.
Computadores de 8, 16, 32 ou 64 bits significa a quantidade de bits que o computador
pode manusear de uma só vez.
Para conhecer e entender o funcionamento interno de um computador, precisamos
conhecer o sistema numérico que o computador utiliza: sistema binário. Como é
muito difícil interpretar um conjunto de bits, utilizamos outras formas abreviadas para
representar o conjunto de bits, ou seja, outros sistemas de numeração. Os sistemas de
numeração mais utilizados são: octal ou hexadecimal.

1.5 Sistemas de Numeração


Existem diversos sistemas numéricos, dentre os quais podemos citar: o sistema
decimal, o binário, o octal e o hexadecimal. O sistema decimal é o que mais
utilizamos no dia a dia. Trata-se de um sistema que possui 10 algarismos, com os
quais podemos formar qualquer número.
Podemos representar os números e realizar as mesmas operações aritméticas em
qualquer sistema de numeração.
Os sistemas binário, octal e hexa, são muito utilizados na área de eletrônica digital
e computação.

1.5.1 Sistema Binário


O sistema binário é composto de apenas 2 algarismos: o 0 e o 1. A quantidade zero
é representada pelo algarismo 0 e a quantidade um pelo algarismo 1. E para
representarmos a quantidade dois?.
Procedemos da mesma forma que no sistema de numeração decimal, para
representar a quantidade dez. Com não existe um algarismo para representar esta
quantidade, associamos o algarismo 1 com o algarismo 0. O algarismo 1 significa que
temos uma dezena (grupo de dez unidades) e o 0 nenhuma unidade. Portanto, no
sistema binário, para representar a quantidade 2, associamos o algarismo 1 com o 0.
O algarismo 1 significa que temos um grupo de dois elementos e o 0 um grupo de
nenhuma unidade, formando o número 2. Assim:

Decimal Binário
0 0
1 1
2 10
3 11
Algoritmos e Linguagem de Programação
8

4 100
5 101
6 110

1.5.1.1 Conversão do sistema binário para o sistema decimal


A conversão de um número binário para decimal é necessário, pois é difícil saber a
quantidade que este número binário representa. Seja o número 1101010101. Que
quantidade este número representa?
Seja o número decimal 345. Este número significa:
3x100 + 4x10 + 5x1 = 345 ou 3x102 + 4x101 + 5x100 = 345
Observa-se que a base deste sistema é o número 10. A base do sistema binário é dois.
Utilizando o mesmo procedimento acima, podemos converter um número binário
para o seu equivalente em decimal. Seja o número binário 110 ( que corresponde ao
número 6 em decimal ):
1x22 + 1x21 + 0x20 = 6. Assim, o número 110 na base dois, corresponde ao número 6
na base dez.

1.5.1.2 Conversão do sistema decimal para o sistema binário


Para converter um número na base decimal para seu correspondente em binário,
dividimos o número na base 10 e os respectivos quocientes por 2 até que o quociente
seja igual a 1. O último quociente será o algarismo mais significativo do número
binário. Os outros algarismos são os restos das sucessivas divisões e correspondem ao
número binário. Assim, se quisermos converter o número decimal 49 para o seu
correspondente na base dois:

4 9  _ 2__
1 24
1º resto: 1

2 4  _ 2__
0 12
2º resto: 0

1 2  _ 2__
0 6
3º resto: 0

6  _ 2__
0 3
4º resto: 0

3  _ 2__
1 1
5º resto: 1

Assim, o número 49 em binário é dado por 110001. Para verificar vamos converter o
número binário 11001 para a base 10:
Algoritmos e Linguagem de Programação
9

1x25 + 1x24 + 0x23 + 0x22 + 0x21 + 1x20 = 49

1.5.2 Sistema octal de numeração


Este sistema contém oito algarismos: 0, 1, 2, 3, ..., 7. Para representarmos a
quantidade 8 agimos da mesma forma vista anteriormente. Juntamos o algarismo 1
com o algarismo 0, que significa um grupo de oito e zero unidade. A tabela abaixo
mostra a seqüência de números em octal:

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

1.5.2.1 Conversão do sistema octal para o decimal


Para fazer a conversão de um número em octal para um número decimal, usamos
os conceitos básicos de formação de um número. Exemplo: vamos converter o
número 245 em octal para o seu correspondente em decimal. O número 245 em octal
pode ser escrito como:
2x82 + 4x81 + 5x80 = 165 em decimal

1.5.2.2 Conversão do sistema octal para o binário


Para converter um número em octal para o seu correspondente em binário, basta
transformar cada algarismo em octal no seu correspondente em binário. Assim, o
número 34 em octal a 11100 em binário, pois o algarismo 3 em binário é 11 e o
número 4 é 100.

1.5.2.3 Conversão do sistema binário para octal


Para converter um número binário em octal, basta separarmos o número binário
em grupos de 3 a partir da direita e cada grupo é convertido diretamente para um
número em octal. Seja o número 11011110 em binário. Separando-o em grupos de 3,
temos:
11 011 e 110
que resulta no número 336 em octal.
Algoritmos e Linguagem de Programação
10

1.5.2.4 Conversão do sistema decimal para octal


Existem dois métodos para fazermos esta conversão. O primeiro método é análogo
à conversão do sistema decimal para binário, só que efetuamos a divisão por 8, pois o
sistema é octal. Exemplo: converter o número 120 em decimal para octal.

1 20 _ 8__
0 15 _ 8__
7 1
Portanto, 120 em decimal corresponde a 170 em octal.
O outro método consiste em converter o número decimal para binário e depois
para octal.

1.5.3 Sistema Hexadecimal


Este sistema possui 16 algarismos. São eles:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E e F. O Algarismo A representa a quantidade
10, O algarismo B representa o a quantidade 11 e assim sucessivamente, até o
algarismo F que representa a quantidade 15. Para representarmos a quantidade 16,
utilizamos o mesmo conceito de formação de um número; colocamos o algarismo 1
seguido do algarismo 0, que representa um grupo de dezesseis e zero unidades. A
seqüência de numeração hexadecimal é dada por:

Decimal Hexadecimal
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 A
11 B
12 C
13 D
14 E
15 F
16 10
17 11
18 12
19 13
20 14

Este sistema é muito usado em microprocessadores e mapeamento de memórias


de computadores com palavras de 4, 8 e 16 bits.
Algoritmos e Linguagem de Programação
11

1.5.3.1 Conversão do sistema hexadecimal para o decimal


A regra de conversão é análoga aos outros sistemas. Seja o número A124 em
hexadecimal. Para convertê-lo para decimal, basta multiplicarmos cada algarismo do
número hexa, por potências de 16. Portanto:
Ax163 + 1x162 + 2x161 + 4x160 = 41.252 em decimal.

1.5.3.2 Conversão do sistema hexadecimal para o binário


Esta conversão é análoga ao sistema octal para o binário, só que precisamos de 4
algarismos binários para representar um algarismo hexadecimal. Como exemplo, seja
o número CA2 em hexadecimal. Em binário:

C: 1100 A: 1010 2: 0010. Portanto o número em binário é representado por


110010100010 em binário.

1.5.3.3 Conversão do sistema binário para o hexadecimal


Basta separarmos o número binário em grupos de 4 algarismos da direita para a
esquerda. Assim, convertendo o número 101011000001 em binário para decimal
resulta em: 1010 1100 0001 = AC1 em hexadecimal

1.5.3.4 Conversão do sistema decimal para o hexadecimal


Existem dois métodos. O primeiro consiste em dividir sucessivas vezes o número
em decimal por 16, como nas transformações anteriores. Exemplo; converter o
número 1000 em decimal para hexadecimal.

1000 _16__
8 62 _16__
14 3
Portanto o número é 3E8, pois 14 corresponde a E em hexadecimal.
O segundo método consiste em converter o número para binário e depois para
hexadecimal.
Algoritmos e Linguagem de Programação
12

2. Algoritmos e Programas

2.1. Programas

A forma de se comunicar com um computador chama-se


programa e a única linguagem que o computador entende é a
linguagem de máquina.
Um programa é um conjunto de instruções que dirigem a UCP
na execução de uma determinada tarefa. Um programa pode ser
escrito utilizando uma linguagem de programação, tal como:
Pascal, C, Fortran, Cobol, Clipper, etc. Um programa escrito em
uma linguagem de programação, é denominado programa fonte,
que está escrito de uma forma mais adequada à compreensão
humana. Para que este programa possa ser compreendido pelo
computador, é necessário traduzi-lo para uma linguagem que o
computador possa compreender. Portanto, uma linguagem de
programação, é um tradutor, que converte um programa escrito em
uma forma semelhante à linguagem humana para um conjunto de
instruções que possam ser executadas pelo computador
(linguagem de máquina).
Os tradutores podem ser divididos em duas categorias
básicas: compiladores e interpretadores. Os interpretadores
executam uma instrução por vez, e se não tiver erro, converte
para linguagem de máquina para finalmente executá-la. Segue,
então para a próxima instrução, repetindo o processo até que a
última instrução seja executada. O compilador lê a primeira
instrução do programa e a converte para a linguagem de máquina
e, em vez de executá-la, segue para a próxima instrução repetindo
o processo até que a última instrução seja atingida. Se não houver
erros, o compilador gera um programa denominado programa
objeto. Este programa não pode ser executado até que sejam
agregadas ao programa objeto, rotinas que permitem a execução.
Esta tarefa é feita por um programa denominado linkeditor que cria
o programa executável que pode ser executado diretamente pelo
computador. Assim, o programa escrito em uma linguagem de
programação é compilado gerando o programa objeto e após, o
Algoritmos e Linguagem de Programação
13

programa objeto é linkado gerando o programa executável. A figura


2.1 ilustra as etapas do programa no computador:

figura 2.1

2.2. Algoritmos

Um trabalho de programação pode se tornar muito mais fácil


se for dividido em partes menos complexas. Um problema a ser
solucionado pelo computador pode ser separado em duas fases:
1ª) Fase da resolução do problema
2ª) Fase de implementação do problema
A primeira fase se refere na elaboração de um algoritmo para
solucionar o problema. Só então, após a elaboração do algoritmo é
que devemos passar para a fase de implementação do algoritmo
em alguma linguagem de programação.
Uma vez que temos um algoritmo bem elaborado, sua
codificação para alguma linguagem de programação é basicamente
direta.
Os computadores apenas executam o que passamos para ele
e não o que desejamos que eles façam. Assim, as instruções a
serem executadas não devem ser ambíguas. Muito cuidado deve
ser tomado para garantir que o computador siga pelo único
caminho correto, e como resultado, as respostas corretas.
Escrevendo um algoritmo antes de elaborarmos o programa,
podemos obter uma formulação mais correta do problema,
evitando assim, possíveis erros.
Portanto, algoritmo pode ser definido como:
- Seqüência ordenada, sem ambigüidade, de instruções que
levam à solução de um dado problemas. A figura 2.2 mostra as
fases de implementação de um problema pelo computador.
Algoritmos e Linguagem de Programação
14

Fase de Resolução do Problema


Problema

Solução em
Forma de
Passo Difícil Algoritmo

Fase de
Implementação
Programa de
Computador

figura 2.2

A utilização do algoritmo é bastante comum. Como exemplo,


podemos citar: as indicações para se chegar a uma determinada
rua, constituem um algoritmo para encontrar este rua; uma receita
para se fazer um bolo ou um esquema para se montar um
brinquedo constituem exemplos de algoritmos, pois todos possuem
uma seqüência de ações a serem cumpridas para atingir o objetivo.
O algoritmo destina-se a resolver um determinado problema;
estabelece um conjunto de regras a ser seguida, com o objetivo de
alcançar o resultado final e como conseqüência solucionar o
problema. Como exemplo, seja a seqüência de números: 1, 5, 9, 13,
17, .... Para determinamos o próximo elemento desta série,
devemos determinar a regra de formação desta seqüência. Para
tal, observamos que o próximo número é a soma do anterior com 4.
Portanto, este somatório constitui a regra de formação de qualquer
número desta série.
Para ilustrar, vamos elaborar um algoritmo bastante usado
em nosso cotidiano: trocar uma lâmpada queimada. Este algoritmo
pode ser expresso em dois passos:
• retirar a lâmpada queimada
• colocar a nova lâmpada
Podemos observar que cada passo do algoritmo para trocar
uma lâmpada, possuem diversos detalhes, Como exemplo, o
primeiro passo para retirar a lâmpada queimada pode ser
expandido para os seguintes passos:
• pegar a escada
• posicionar a escada embaixo da lâmpada a ser trocada
• subir na escada até que a alcançar a lâmpada queimada
• retirar a lâmpada queimada
O passo “colocar a nova lâmpada” pode ser divido nas
seguintes tarefas:
• pegar uma lâmpada nova
• colocar a nova lâmpada no soquete
Algoritmos e Linguagem de Programação
15

• descer da escada
• guardar a escada
Observamos que o algoritmo para trocar uma lâmpada
queimada passou de 2 para oito passos, após o detalhamento de
cada passo do primeiro algoritmo. Analisando o segundo algoritmo,
vemos que ele constitue de uma seqüência de instruções mais
detalhadas para a execução da tarefa. Portanto, conclui-se que o
algoritmo deve ser formado por um conjunto de passos simples e
bem definidos de forma que possa ser entendido diretamente pelo
agente que irá executá-lo. Suponhamos que o agente seja um
computador. Como o computador não tem conhecimento prévio, o
conjunto de passos de um algoritmo devem estar bem detalhados
de forma que o computador possa reconhece-los e executá-los e
produzir os resultados esperados.

2.2.1. Obstáculos na elaboração de um algoritmo


• Complexidade do Problema
• Legibilidade: constitui na capacidade de compreensão do
algoritmo. Quanto mais legível for um algoritmo, menor será a sua
complexidade.
• Portabilidade: devemos projetar um algoritmo em uma
linguagem (em uma notação) de forma que possa ser entendido e
convertido diretamente para qualquer linguagem de programação.
• Método cartesiano: consiste em dividir o problema em partes
menores e tratar cada parte individualmente, tornando-o mais
simples e mais específico. Se cada parte não estiver bem
compreendida, esta deve novamente ser dividida. Este
procedimento de divisão das partes do problema deve continuar
até que cada parte possa ser facilmente compreendida e
elaborada.
• Planejamento Reverso: partindo do produto final, vamos
separá-lo até obtermos os componentes básicos que o constitue.
No nosso caso, a partir das informações de saída, determinamos os
componentes de entrada e suas transformações.

2.2.2. Propriedades de um Algoritmo:


• Os passos ( ou seja, as instruções ) de um algoritmo devem ser
simples e não devem produzir ambigüidades.
• A ordem de execução dos passos devem ser obedecidas e deve
estar bem definida.
• Todo algoritmo deve ter uma seqüência finita de passos.
Os métodos para a elaboração de um algoritmo, inicia-se com
uma solução genérica do problema e em seguida, passamos para
um nível de detalhamento do algoritmo.
O algoritmo deve ser escrito de forma que possa ser
compreendido pelo agente que irá executá-lo. Portanto, para que o
computador possa executar um determinado algoritmo, é
necessário que este esteja limitado a um conjunto de instruções
que possam ser compreendidas pelo computador.
Algoritmos e Linguagem de Programação
16

Os algoritmos a serem solucionados pelo computador, devem


possuir uma notação específica, para que possam ser codificados
diretamente para qualquer linguagem de programação.

2.2.3. Métodos para a construção de algoritmos


• Ler atentamente o enunciado do problema.
• A partir do enunciado, obter os dados de entrada, ou seja,
quais são os dados a serem fornecidos.
• Obter as informações de saída a partir do enunciado do
problema, ou seja, os resultados finais ou o objetivo do algoritmo.
• Determinar quais são as funções a serem desenvolvidas para
transformar os dados de entrada nas respostas desejadas. Nesta
etapa, elaboramos um layout do algoritmo, pois a partir dos
requisitos especificados, determinamos a seqüência de ações. Aqui
podemos utilizar nesta fase o método cartesiano ou o planejamento
reverso.
• Construir o algoritmo definitivo
• Testar o algoritmo. Consiste em executar os passos do
algoritmo, verificando os resultados e detectar possíveis erros.
Aqui, rastreamos o algoritmo analisando cada instrução deste.

2.2.4. Descrição de Algoritmos


O desenvolvimento de um algoritmo adequado é o primeiro
passo na preparação de um programa de computador para uma
dada aplicação. Um algoritmo bem descrito é facilmente convertido
para uma linguagem de programação. Existe algumas formas para
a descrição de algoritmos.

2.2.4.1. Descrição Narrativa


Consiste na especificação dos passos de um algoritmo em
linguagem natural. A descrição de um algoritmo em linguagem
natural resulta em instruções imprecisas, levando a interpretações
erradas das instruções pelo computador.
Um comando descrito em linguagem natural, muitas vezes
está omitindo uma série de passos a serem executados, que nem
sempre são fáceis de implementar. A narração é muito importante
para descrever comentários, esclarecendo trechos do programa.
Portanto, mesmo não sendo o método mais adequado para
implementar um algoritmo, a descrição narrativa deve ser usada
como método complementar na especificação de determinados
trechos do programa que não são fáceis de serem compreendidos.

2.2.4.2. Fluxograma
Consiste em uma descrição gráfica do algoritmo. Um
fluxograma mostra a lógica do algoritmo, enfatiza os passos
individuais e suas interconexões.
O fluxograma possui 4 símbolos para representar as
instruções básicas:
Algoritmos e Linguagem de Programação
17

representa um cálculo

entrada de dados

uma decisão

saída de dados

Início
Figura 2.3

O fluxograma é composto por um conjunto desses símbolos


interligados por linhas, mostrando a ordem de execução das
operações. A figura 2.4 mostra um exemplo de fluxograma.
Algoritmos e Linguagem de Programação
18

Início

nota1, nota2

média =
(nota1+nota2)
2

média>=5?

média média
"Reprovado" "Aprovado"

Fim
Figura 2.4

O fluxograma não permite especificar claramente muito dos


comandos básicos que uma linguagem de programação
implementa. Também pode ocasionar maus hábitos no
desenvolvimento de programas. O fluxograma tem como
vantagem, uma melhor visualização da lógica do programa, pelo
fato de ser uma ferramenta gráfica, mas obscurece a estrutura do
programa.

2.2.4.3. Linguagem Algorítmica


Consiste em uma forma de descrição do algoritmo bastante
similar às linguagens de programação. A passagem do algoritmo
expresso neste tipo de descrição para uma linguagem de
programação é quase direta. A seguir é mostrado um algoritmo na
forma de linguagem algorítmica.

Início
[ Declaração de variáveis ]
[ Comandos ]
Fim
Algoritmos e Linguagem de Programação
19

A seguir é mostrado um exemplo de algoritmo na forma de


linguagem algorítmica.

Exemplo:
Início
N1,N2,M: real [ declaração das variáveis ]
leia( N1, N2 ) [ lê os dados que são atribuídos às
variáveis N1 e N2 ]
M = ( N1 + N2 )/2 [ avalia a expressão e atribui o
resultado à variável M ]
escreva( "Média: ", M ) [ exibe o resultado, imprimindo a
constante "Média: " e
o valor da variável M ]
Fim

Obs: Os comandos obedecem a seqüência estabelecida e são


executados na ordem em que foram colocados.
Algoritmos e Linguagem de Programação
20

3. Dados e Tipos de Dados

O objetivo principal de qualquer computador é a manipulação de dados ou


informações. Como exemplo de dados básicos que podem ser tratados pelo
computador, podemos citar:
• Notas de alunos de um curso
• Vendas de uma loja
• Listagem dos alunos aprovados no vestibular
Os dados podem ser numéricos e não-numéricos. Os diferentes tipos de dados são
tratados de forma diferentes pelo computador.

3.1 Dados Numéricos

Os dados numéricos podem ser representados de duas formas distintas:


• Inteiro: correspondem aos números inteiros da aritmética. Não possuem
componentes decimais ou fracionários e podem assumir valores positivos ou
negativos. Como exemplo, de dados inteiros, podemos citar: 25, -1243,2344, etc...

Reais: são os números com componentes decimais. As frações são armazenadas



na forma decimal. Os números reais também podem assumir valores positivos ou
negativos. Exemplos: -23.4, 78.2434, 234.123, etc.
Os dados numéricos, possuem um certo limite com relação ao número máximo de
dígitos que podem conter, que varia de máquina para máquina.
Para representar números muito grandes ou muito pequenos, utilizamos uma
notação especial que possui uma certa quantidade de dígitos de precisão seguido pela
magnitude do número como potência de 10. Como exemplo, o número
3823392338922323 pode ser representado como 3.8234 x 1015 .
A estes números chamamos de números em ponto flutuante que nada mais é que
uma notação especial para números reais.

3.2 Dados não-numéricos

• Caracter: corresponde ao conjunto dos caracteres da tabela ASCII, isto é, letras


(A,...,Z,a,...,z), dígitos (0,...,9) e caracteres especiais (branco, @,%,&,^,...). Como
exemplo de dados do tipo caracter, podemos citar:
'A', 'M', '1', '#'. . .
Os dados do tipo caracter são geralmente delimitados por apóstrofos em muitas
linguagens de programação.

• Cadeia ( ou string ): corresponde a uma seqüência de caracteres, que podem


conter letras, dígitos e/ou caracteres especiais. As cadeias de caracteres também
possuem caracteres delimitadores para indicar o início e o fim da cadeia. Assim,
como exemplos1:

1Para diferenciar valores do tipo caracter com o tipo cadeia, usaremos apóstrofos
( ' ) para delimitar o tipo caracter e aspas ( " ) para cadeia.
Algoritmos e Linguagem de Programação
21

"UNIVERSIDADE SAO FRANCISCO"


"12$^&78qwqe GHGHGj "

• Dados lógicos ou booleanos: Este tipo de dado pode assumir dois valores:
verdadeiro ou falso.
Resumindo, podemos classificar os tipos de dados como:

3.3 Código ASCII

American Standard Code for Information Interchange. Foi desenvolvido em 1963


e posteriormente, em 1968, gerou o atual código ASCII. Os códigos são usados para
especificar os caracteres através de um conjunto de bits. Como um bit pode assumir
os valores 0 ou 1, a quantidade de bits usadas num código, determina o número de
combinações possíveis e, consequentemente, a quantidade de caracteres codificáveis,
dada pela fórmula 2n = nº de caracteres, onde n é o número de bits. O código ASCII é
um código alfanumérico, isto é, é capaz de representar dígitos, letras e alguns
caracteres especiais.

3.4 Operadores para manipulação de dados

Existem operadores específicos para cada tipo de dado. Um operador é um símbolo


que manda o computador executar determinadas manipulações matemáticas ou
lógicas. Os operadores podem ser classificados em três categorias básicas:
aritméticos, de relação e lógicos.

3.4.1 Operadores Aritméticos

Os operadores matemáticos básicos são:

Operador Ação
- subtração e o menos unário
+ adição
* multiplicação
/ divisão
Algoritmos e Linguagem de Programação
22

% módulo

Estes operadores são operadores binários, pois envolvem dois elementos. São
aplicados a tipos de dados numéricos. Se somarmos dois números do tipo real ,
teremos como resultado um número real. O mesmo comentário vale para os números
inteiros. Devemos ter cuidado com relação a operação de divisão de números inteiros
pois, se o resultado não for um número inteiro, o resultado será truncado ou
arredondado. Como exemplo, seja a divisão de dois números inteiros: 8/5. O
resultado é 1.6. Como este número não é um número inteiro, o resultado final será 1
(se for truncado) ou 2 ( se for arredondado ).
Se misturarmos tipos diferentes de operandos em operações numéricas, o resultado
será sempre expresso como o tipo do maior operando. Assim, se multiplicarmos um
número inteiro com um número real, o resultado será um número do tipo real, pois o
computador reserva mais espaço para alocar um número real.
O operador módulo é aplicado somente a dados numéricos do tipo inteiro e dá
como resultado, o resto de uma divisão de dois números.

3.4.2 Operadores de Relação

Refere-se às relações que os valores podem ter uns com os outros. São usados para
fazer comparações entre dois valores (operadores binários). Podem ser aplicados a
qualquer tipo de dado básico. O resultado de uma operação relacional é um resultado
booleano: verdadeiro ou falso. Os símbolos que representam os operadores
relacionais são:

Operador Ação
> Maior que
>= Maior ou igual
< Menor
<= Menor ou igual
== Igual a
!= Diferente

3.4.3 Operadores Lógicos

Se refere na maneira que as relações podem estar conectadas. São operadores


conectivos. Os operadores lógicos são E, OU e NÃO. O resultado também é um valor
lógico de acordo com a tabela abaixo ( tabela-verdade ):

A B AEB A OU B NÃO A
V V V V F
V F F V F
F V F V V
F F F F V

Onde V indica verdadeiro e F falso. O operador NÃO é um operador de negação e


inverte o valor. Se for verdadeiro, o resultado será falso e vice-versa. O operador E
retorna verdadeiro se e somente se, todos os valores comparados forem verdadeiros.
Do contrário o resultado será falso. O operador OU retorna um resultado verdadeiro
Algoritmos e Linguagem de Programação
23

se um apenas um dos valores for verdadeiro. O resultado será falso se e somente se,
todos os valores forem falsos.

3.5 Variáveis

É um espaço de memória reservado para armazenar um certo tipo de dado, e a cada


instante de tempo, pode conter valores diferentes do mesmo tipo. É conhecida no
programa por um nome (identificador). Portanto, um identificador é um nome usado
dentro de um programa para se fazer referência a uma variável.
Uma variável pode receber diversos valores diferentes, mas num dado instante,
pode conter somente um valor. A utilização de variáveis em programas de
computador permite a especificação de uma fórmula geral dentro do programa.
Como exemplo, seja um retângulo cujos lados são representados por a e b.

b
A área do triângulo é definida por: c = a * b. Podemos definir três variáveis para
representar os dois lados (a e b) e a área do retângulo (c) e atribuir diversos valores
aos lados para obter a área correspondente.

3.5.1 Identificadores

Os identificadores são os nomes das variáveis. Assim. a, b e c são identificadores.


É interessante darmos nomes significativos às variáveis para uma melhor
compreensão do programa e para prevenir erros. No exemplo acima, o mais correto
seria dar nomes às variáveis de base, altura para os lados e area_retangulo para a
área.
Podemos usar quantos caracteres quisermos para um nome de variável, mas
devemos obedecer alguns critérios:
• O primeiro caracter deve ser uma letra. A linguagem de programação C, admite
utilizar o caracter sublinhado ( _ ) como primeiro caracter.
• Os demais caracteres podem ser letras, dígitos e alguns caracteres especiais, que
dependem da linguagem de programação.
• As linguagens de programação possuem algumas palavras reservadas e não
podemos dar nomes às variáveis idênticos a essas palavras.
• Não é permitido utilizar o caracter branco (espaço) fazendo parte do nome da
variável.

Como exemplo de identificadores válidos, podemos citar: teste, nome_funcionario,


mat1q234, ... . São exemplos de nomes de variáveis inválidos: 3arquivo, teste três,
etc...
As variáveis devem ser de um dado tipo: inteiro, real, caracter, cadeia, e lógico.
Uma variável definida como sendo de um determinado tipo de dado, somente pode
assumir valores deste tipo. Assim, uma variável inteira, somente poderá conter
valores inteiros.
Algoritmos e Linguagem de Programação
24

3.6 Constantes
São valores fixos que não podem ser alterados no programa. As constantes podem
ser de qualquer tipo de dado. A forma como são representadas no programa e no
algoritmo, dependem de seu tipo. As constantes do tipo caracter e cadeia são
representadas utilizando delimitadores. A seguir, temos alguns exemplos:

Tipo de Dado Exemplos de Constantes


inteiro 12, -2344, 8432
real 123.23, 3.4x103
caracter 'a', '%'
cadeia "entre com o nome", "teste do resultado"

3.7 Operação de atribuição

Esta operação é utilizada para atribuir um valor a uma variável. Na notação


algorítmica, vamos representar o operador de atribuição pelo símbolo = . Cada
linguagem de programação possui um determinado símbolo para representar o
operador de atribuição.
Como exemplo de uma operação de atribuição:
A = 3
que indica que o valor 3 está sendo atribuído à variável A.
A operação de atribuição é considerada uma operação destrutiva, pois qualquer
valor que a variável possuía antes é substituído pelo novo valor atribuído. Portanto,
após a seqüência de operações:
A = 3
A = -5
A = 18
o valor contido na variável A será 18 e os valores anteriores não existem mais.

3.7.1 Expressões

Uma expressão é uma combinação de variáveis, constantes e operadores.


Corresponde ao lado direito do comando de atribuição, ou seja, o que está após o
operador de atribuição. O resultado de uma expressão é o valor que será atribuído à
variável indicada.
A atribuição de um único valor a uma variável, é um caso particular de uma
expressão, onde esta contém apenas uma constante. Portanto, a forma geral do
comando de atribuição é dada por:
variável = expressão

Exemplo:
A = 5+10*12-4/2
Primeiramente, o valor da expressão é avaliado e o resultado é então atribuído à
variável A.
Algoritmos e Linguagem de Programação
25

A expressão também pode conter variáveis, sendo que os valores contidos nestas
variáveis devem ser previamente atribuídos. Portanto:
C = 12
D = 32
A = C + D * 19
As variáveis contidas na expressão são substituídas pelos seus valores. A expressão
C+D*19 corresponde na verdade a 12+32*19.

Observação importante: qualquer variável utilizada em uma expressão deve ter


seu valor previamente atribuído no momento que estiver sendo utilizada. Exemplo:
C = 10
A = C + D
D = 12
O exemplo acima levaria a uma avaliação errada da expressão C+D pois, no
momento que esta expressão está sendo avaliada, o valor da variável D não é
conhecido. Portanto, é responsabilidade do programador evitar este tipo de erro.
A própria variável que recebe o valor resultante em uma expressão ( lado esquerdo
do comando de atribuição ) pode fazer parte da expressão. Exemplo:
X = 0
X = X + 1
Esta expressão é avaliada da mesma forma que qualquer expressão. Assim, o valor
de X, que primeiramente recebe 0, é somado com a constante 1 na expressão X+1. O
resultado desta expressão é então atribuído à variável X, que terá 1 como valor final.

3.7.1.1 Prioridade dos operadores em uma expressão

Existem critérios de prioridade quando uma expressão estiver sendo avaliada.


Operadores com maior prioridade são processados primeiramente. Se existir dois
operadores com o mesmo nível de prioridade, o que estiver mais a esquerda na
expressão, é processado antes. Abaixo, temos a relação de prioridade dos operadores
matemáticos:

mais alta - menos unário


/,*
mais baixa +,-

Portanto, na expressão 8+12*3, o termo 12*3 é processado primeiramente. O


resultado 36 é adicionado a 8, resultando 44.
Seja agora, uma expressão com dois operadores de mesma prioridade: 12*4/3. A
multiplicação é executada antes da divisão, pois está mais a esquerda na expressão
que a divisão.
Para alterar a prioridade dos operadores em uma expressão, é necessário colocar
entre parênteses o termo que desejamos que seja executado primeiro. Portanto, se na
expressão 8+12*3, quisermos que a adição seja executada antes da multiplicação,
basta colocarmos o termo 8+12 entre parênteses. Assim temos (8+12)*3, que resulta
no valor 60.

3.8 Funções Embutidas


Algoritmos e Linguagem de Programação
26

As linguagens de programação possuem uma série de funções embutidas, usadas


para auxiliar na execução de cálculos que necessitam mais do que o conjunto
convencional de operadores. A variedade destas funções dependem da linguagem de
programação. Exemplo de algumas funções que são implementadas pela maioria das
linguagens de programação:

Função Significado da função


abs(x) valor absoluta da variável x
sqrt(x) raiz quadrada de x
log(x) logaritmo neperiano
sin(x) seno de x
cos(x) cosseno de x
tan(x) tangente de x
exp(x) exponencial de x: ex
trunc(x) trunca o valor de x
round(x) arredonda o valor de x

3.9 Comandos de Entrada e Saída

Os comandos de entrada são usados para fornecer valores para o programa e os


comandos de saída são usados para exibir os resultados após a execução de um
programa. As linguagens de programação fornecem comandos para executar as
operações de entrada e saída

3.9.1 Comando LEIA

O comando leia é o comando de entrada utilizado na notação algorítmica, e que


permite ler valores de algum dispositivo de entrada (geralmente o teclado) atribuindo-
os, às variáveis indicadas. A forma geral do comando de entrada é dado por:

LEIA( lista de variáveis )

Onde lista de variáveis é o conjunto de variáveis às quais os valores de entrada são


atribuídos As variáveis devem estar separadas por vírgula. Exemplo:
LEIA( a, b, c, d, q )
onde a, b, c, d e q são as variáveis.

3.9.2 Comando ESCREVA

É o comando utilizado no algoritmo para exibir os dados. O comando escreva,


está associado a dispositivos de saída de dados, como por exemplo, o vídeo e a
impressora. A forma geral do comando escreva é:

ESCREVA ( lista de saída )


Algoritmos e Linguagem de Programação
27

Onde a lista de saída pode exibir o valor de uma variável, o resultado de alguma
expressão, ou o valor de uma constante. Por exemplo:
N1 = 8.34
N2 = 9.12
N3 = 7.34
MEDIA = ( N1 + N2 + N3 ) / 3
ESCREVA ( " A média é: ", media )
↓ ↓
constante variável

Ou:

ESCREVA( N1+N2+N3 )

expressão

Para exibir algum valor constante, devemos utilizar caracteres delimitadores. A


expressão quando utilizada no comando de saída ( escreva ), é avaliado
primeiramente, exibindo apenas o resultado desta expressão.
Algoritmos e Linguagem de Programação
28

4. Estruturas de Decisão
Até o momento, vimos como executar um algoritmo executando
suas instruções seqüencialmente, ou seja, da primeira instrução até
a última do algoritmo. O computador tem a habilidade de tomar
decisões e determinar quais ações serão executadas durante a
execução de um programa.
As estruturas de decisão, tornam possível selecionar uma ação
de um conjunto de alternativas que foram especificadas, podendo
então mudar o curso de execução de um programa.
A Unidade Aritmética e Lógica é a parte do computador onde
as instruções aritméticas e lógicas são executadas. A parte lógica,
permite selecionar uma determinada ação de um conjunto de
possíveis opções, possibilitando a elaboração do comando de
decisão nas linguagens de programação.
O comando de decisão é especificado em uma expressão lógica
que retorna um valor booleano ( verdadeiro ou falso ). Como
exemplo, sejam duas variáveis numéricas A e B cujos valores são
diferentes e queremos determinar qual variável contém o maior
valor. A figura 4.1 mostra a estrutura de um comando de decisão
através de um fluxograma:

S N
A>B

"A é o Maior", "B é o Maior",


A B

figura 4.1

A condição A > B é uma expressão lógica cujo resultado é um


valor booleano. Se o valor de A for maior que o valor de B, o
resultado será o valor VERDADEIRO e o conteúdo da variável A será
impressa. Do contrário, ou seja, se o valor de A for menor ou igual a
B, o resultado desta expressão lógica será FALSO e o valor de B será
exibido.
Como exemplo, assuma que A tenha o valor 20 e B o valor 12.
Como 20 é maior que 12, a expressão lógica A>B dá como
resultado um valor VERDADEIRO e o número 20 será impresso pelo
Algoritmos e Linguagem de Programação
29

computador. Suponhamos agora, que o valor de A seja 14 e B


tenha o valor 23. Neste caso, o resultado da expressão lógica será
FALSO e o computador exibe o valor contido em B, que no caso é o
número 23. Através do fluxograma na figura 4.1, observamos as
duas possíveis opções que o computador pode tomar, dependendo
do resultado avaliado na expressão lógica.
A escolha de uma ação é determinada após avaliar uma
condição, que nada mais é que uma expressão lógica que nos dá
como resultado um valor lógico. A forma geral do comando de
decisão em linguagem algorítmica é dada por:

SE ( condição ) ENTÃO
comando 1
SENÃO
comando 2

Se a condição for verdadeira, o comando 1 será executado e o


comando 2 será ignorado. Do contrário, o computador executará o
comando 2, ignorando o comando 1. Portanto, dependendo do
resultado da condição, a execução do programa segue um
determinado fluxo, ignorando as demais alternativas.
O exemplo anterior, que compara os valores contidos em A e B,
em notação algorítmica ficaria:
início
a,b: inteiro
leia( a, b )
se ( a>b ) então
escreva( “ O maior valor é o que está contido em A
sendo “, A)
senão
escreva( “ O maior valor é o que está contido em B
sendo “, B)
fim.

A parte do comando de decisão SENÃO é opcional, resultando em


um comando de decisão simplificado, cuja forma geral é dada por:

SE ( condição ) ENTÃO
comando 1

O comando 1 apenas será executado se o resultado da condição


for VERDADEIRA. Como exemplo:

início
c: caracter
leia( c )
se (c = = ‘a’)
ESCREVA ( “Você pressionou a tecla a” )
fim.
Algoritmos e Linguagem de Programação
30

Se o a tecla a for pressionada, o computador exibe a mensagem


“Você pressionou a tecla a”, pois a expressão lógica (c == ‘a’)
nos dá um resultado VERDADEIRO. Se a tecla pressionada for qualquer
uma que não seja o caracter a, este programa não fará
absolutamente nada.

4.1 Bloco de Comandos


Um bloco de comandos nada mais é que um conjunto de
comandos delimitados por um determinado símbolo. Na linguagem
algorítmica vamos delimitar o bloco de comandos pelos símbolos {
indicando o início do bloco e } para indicar o final do bloco.
Podemos ter um conjunto de instruções sob um comando de
decisão. Assim a forma geral do comando ficaria:

SE ( condição ) ENTÃO
{
comando 1.1
comando 1.2
comando 1.3
.
.
.
}
SENÃO
{
comando 2.1
comando 2.2
comando 2.3
.
.
.
}

Portanto, se a condição for VERDADEIRA, o primeiro bloco de


comandos será executado. Do contrário, o segundo bloco de
comandos será executado. Isto se faz necessário, pois se não
utilizarmos o conjunto de instruções como um bloco de comandos,
apenas a primeira instrução estaria sob o comando de decisão,
estando as demais instruções independentes do comando de
decisão. O exemplo abaixo mostra como seria a execução dos
comandos, sem utilizar os delimitadores de bloco de comandos:

SE ( condição ) ENTÃO
comando 1
comando 2
comando 3
Algoritmos e Linguagem de Programação
31

Apenas o comando 1 é dependente da condição. Os demais


comandos, independente do resultado da condição, serão
executados pelo computador. Portanto, devemos delimitar um
conjunto de comandos através de símbolos que indiquem o início e
fim, para indicar ao compilador que este conjunto deve ser
interpretado como um bloco de comandos.

4.2 Comandos Ses Aninhados ( Encaixados )


Em algumas aplicações, um comando a ser executado dentro de
um comando SE, pode ser um outro comando SE. Dizemos então que
o comando interno SE, está aninhado. O exemplo abaixo mostra
uma utilização de comandos SES encaixados:

INÍCIO
c: inteiro
leia ( c )
se ( c >= 0 ) então
se ( c <= 9 ) então
escreva ( “Você digitou um número entre 0 e 9”)

FIM.

O algoritmo abaixo mostra um outro exemplo utilizando comando


SE encaixado; imprimir o maior valor dentre três números.

INÍCIO
maior_valor, n1, n2, n3: inteiro
se ( n1 > n2 ) então
se ( n1 > n3 ) então
maior_valor = n1
senão
maior_valor = n3
senão
se ( n2 > n3 ) então
maior_valor = n2
senão
maior_valor = n3
escreva (“O maior valor é: “,maior_valor
FIM

Observação: este tipo de estrutura pode causar confusões. É


importante que a parte SENÃO tenha a mesma paragrafação do SE.
Uma falta de cuidado pode levar a ambigüidades. Considere o
exemplo:

SE ( condição 1 ) ENTÃO
SE ( condição 2 ) ENTÃO
comando 1
SENÃO
Algoritmos e Linguagem de Programação
32

comando 2

Em que situação o comando 2 será executado? Quando a condição


1 for falsa ou quando a condição 2 for falsa? Não está claro se o
SENÃO se refere ao primeiro ou ao segundo SE. Este problema pode
existir em qualquer linguagem de programação que implemente a
estrutura de decisão e pode ser solucionada através de regras
específicas da linguagem. Na notação algorítmica solucionamos
este problema através da indentação. Os comandos que devem
ser executados de acordo com uma condição ficam deslocados a
direita, mostrando que estes comandos são dependentes. Como
exemplo, considere um algoritmo que leia o nome e o salário bruto
de um funcionário de uma determinada empresa e calcule o salário
líquido. Se o salário for menor ou igual a Cr$ 2.000,00, o desconto
será de 15%. Se o salário for maior que Cr$ 2.000,00 mas menor ou
igual a Cr$ 4.000,00, o desconto será de 25%. Acima de Cr$
4.000,00, o desconto será de 35%. O salário líquido é o salário
bruto menos o desconto.

INÍCIO
nome: cadeia
salário_bruto, salário_líquido: real
leia ( nome, salário_bruto )
se ( salário_bruto <= 2.000 ) então
salário_líquido = salário_bruto - salário_bruto * 0.15
senão
se ( salário_bruto <= 4.000 ) então
salário_líquido = salário_bruto - salário_bruto *
0.25
senão
salário_líquido = salário_bruto - salário_bruto *
0.35
escreva ( “NOME: “, nome )
escreva ( “SALÁRIO LÍQUIDO: “, salário_líquido )
FIM.

Podemos ter diversos comandos de decisão encaixados conforme


mostra o trecho a seguir:

se (condição 1) então
se (condição 2) então
se (condição 3) então
se (condição 4) então
comando 1
senão
comando 2
senão
comando 3
senão
Algoritmos e Linguagem de Programação
33

comando 4
senão
comando 5

O comando 1 somente será executado se todas as condições


forem verdadeiras. O comando 2 é executado se as condições 1, 2
e 3 forem verdadeiras e 4 falsa; o comando 3 se 1 e 2 forem
verdadeiras e 3 falsa; o comando 4 se a condição 1 for verdadeira e
2 for falsa e finalmente, o comando 5 somente será executado de a
condição 1 for falsa.
Algoritmos e Linguagem de Programação
34

5. Estruturas de Repetição ( Laços )

As Estruturas de Repetição são usadas quando uma


instrução ou um conjunto de instruções deve ser executado
diversas vezes. É uma construção básica oferecida pela maioria das
linguagens de programação. Como exemplo, o cálculo do fatorial de
um número N é dado por N!. O fatorial de N é calculado como o
produto de Nx(N-1)x(N-2)x...x2x1, que nada mais é que uma série
de multiplicações sucessivas, onde o multiplicador é reduzido de 1
antes de cada multiplicação.
Existem dois tipos de comandos de repetição: o comando de
repetição condicional, que fica repetindo a execução de um
comando ou conjunto de comandos até que a condição, que é uma
expressão booleana, retorne um valor falso; e o comando de
repetição contado, que repete a execução um número fixo de
vezes. Na notação algorítmica serão apresentadas três estruturas
de comandos de repetição, implementadas na maioria das
linguagens de programação.

5.1 Comando Para


A forma geral do comando Para, na notação algorítmica é:

Para(inicialização; condição;incremento)
comando

A inicialização é um comando de atribuição que o compilador


usa para estabelecer o valor inicial da variável de controle do laço.
A condição, é uma expressão booleana que testa a variável de
controle do laço com algum valor, para determinar quando o laço
se encerrará. O incremento define a maneira como a variável de
controle será alterada a cada repetição. O laço Para, executa o
comando se a condição for verdadeira. Se a condição for falsa, o
comando de repetição é ignorado.
O exemplo a seguir imprime os números de 1 a 100 na tela,
usando o comando de repetição Para.

Início
a: inteiro
Para(a=1;a<=100;a=a+1)
Escreva(a)
Fim

Este programa atribui inicialmente, o valor 1 à variável a. Em


seguida, o valor contido em a é comparado com o número 100.
Como a condição é verdadeira, o comando escreva é executado
exibindo o número 1. Após, o valor da variável a é incrementado
Algoritmos e Linguagem de Programação
35

em uma unidade e a condição é novamente testada. Se for


verdadeira o comando escreva é novamente executado, exibindo
agora, o número 2. Este processo se repete até que o valor contido
na variável a seja igual a 100. Neste exemplo, a é a variável de
controle do laço.
O comando de repetição Para, não precisa sempre fluir para
frente. Pode-se criar um fluxo de repetição decrescente, onde o
valor da variável de controle é decrementado até que a condição
retorne um valor falso. Como exemplo:

Início
a: inteiro
Para(a=100;a>=1;a=a-1)
Escreva(a)
Fim

A forma como a variável será incrementada ou


decrementada, não precisa ser de uma unidade. O comando de
atribuição da parte incremento, mostra de quanto em quanto, a
variável será incrementada ou decrementada. Com exemplo:

Início
a: inteiro
Para(a=0;a<=100;a=a+5)
Escreva(a)
Fim

No exemplo acima, o valor de a é incrementado de 5 em 5,


ou seja, a variável de controle do laço conterá os seguintes valores:
0, 5, 10, 15, 20,...,100. Como foi mencionado anteriormente, pode-
se repetir a execução de um conjunto de comandos. Para que todos
estes comandos possam estar dentro de um comando de repetição,
é necessário que estejam na forma de bloco de comandos, usando
os símbolos { para indicar início do bloco e } para indicar o término
do bloco de comandos, conforme mostra o exemplo a seguir:

Início
a,b: inteiro
Para(a=1;a<=100;a=a+1)
{
b= a*a
Escreva(a)
Escreva(b)
}
Fim
Algoritmos e Linguagem de Programação
36

5.2 Comando Enquanto


O segundo comando de repetição existente em linguagem
algorítmica e na maioria das linguagens de programação é o
comando Enquanto. A forma geral em notação algorítmica é:

enquanto (condição) {
comando
}
Enquanto a condição for verdadeira, o comando será
executado. O laço somente termina quando o resultado da
condição tornar falsa. Assim, como no laço Para, a condição é uma
expressão booleana que retorna um valor verdadeiro ou falso, após
ser avaliada.
Para este comando de repetição, deve haver pelo menos um
comando a ser executado, que altere o valor da condição para falso
pois, do contrário, o comando ficará executando infinitamente.
Exemplo:

Início
a: inteiro
a=1
Enquanto(a<=10){
Escreva (a)
a=a+1
}
Fim

A variável a deve ser inicializada, para que possa saber o


valor que está sendo comparado ao número 10. Se a não fosse
inicializado, o valor seria um número desconhecido e, se fosse
maior que 10, o comando de repetição jamais seria executado.
Observa-se o comando “a=a+1”. Este comando é necessário para
alterar o valor da variável a pois, caso contrário, o comando ficaria
repetindo para sempre, e a execução do programa nunca se
encerraria.

5.3 Comando Faça-Enquanto


Os comandos de repetição Para e Enquanto, sempre testam
a condição no começo do laço, e executam os comandos apenas se
o resultado desta condição for verdadeira. O comando Faça-
Enquanto é um comando de repetição condicional que testa a
condição ao final do laço. Como conseqüência, os comandos dentro
do laço são executados pelo menos uma vez. A forma geral do
comando Faça-Enquanto em notação algorítmica é:

faça {
comando
} enquanto (condição)
Algoritmos e Linguagem de Programação
37

Assim como no laço Enquanto, é necessário um comando que


torne a condição falsa pois, do contrário, o comando de repetição
Faça-Enquanto ficará executando indefinidamente. Como
exemplo:

Início
a:inteiro
a=1
Faça {
Escreva(a)
a=a+1
} Enquanto(a<=10)
Fim

Este exemplo, imprime os números de 1 a 10 na tela do


computador.

5.4 Laços Aninhados


Quando um laço está dentro de um outro laço, dizemos que o
laço interno está aninhado ao laço externo. Pode-se usar quaisquer
comando de repetição aninhado. Seja o exemplo:

Para(a=1;a<10;a=a+1)
Enquanto(a != 5)
comando

Conforme o exemplo, o comando Enquanto está aninhado ao


comando Para. A seguir são mostrados outros exemplos de laços
aninhados:

Exemplo 1:

Enquanto(c<10)
Para(i=0; i<10;i=i+3)
comando

Exemplo 2:

Para(i=1; i<=3;i=i+1)
Para(j=1; j<=4;j=j+1)
comando

Exemplo 3:

Faça{
Para(i=0; i<3;i=i+1)
comando
Algoritmos e Linguagem de Programação
38

c=c+1
} Enquanto( c<3)

Para se determinar o número de iterações, basta multiplicar


quantas vezes o laço interno se repete com o número de vezes que
o laço externo se repete. Assim, com relação ao exemplo 2, o
comando se repetirá 3x4 = 12 vezes, pois para cada valor da
variável de controle i (1,2 e 3), a variável j assume os valores 1,2,3
e 4.
Algoritmos e Linguagem de Programação
39

6. Conjunto Homogêneos (Vetores e Matrizes)


As linguagens de programação permitem criar diversos tipos
de estruturas de dados. Um conjunto homogêneo é uma estrutura
de dados que possibilita agrupar variáveis do mesmo tipo de dados,
sendo todas elas referenciadas por um mesmo nome.

6.1 Vetor ( Conjunto Unidimensional )

Uma variável pode conter um valor simples, tal como um


número inteiro ou real, um caracter ou uma cadeia. Um vetor é
definido como um conjunto que contém um número fixo de
elementos do mesmo tipo de dados ( homogêneos ): inteiro, real,
caracter, booleano, cadeia. O vetor possui apenas uma dimensão.
Um vetor é um conjunto de variáveis de um mesmo tipo,
associadas a um único nome. Portanto, temos diversos valores
referenciados pelo mesmo nome. Para selecionar um elemento
deste conjunto, fazemos o uso de um índice. O índice é um número
inteiro2 ou uma variável inteira, que indica a posição de um
elemento no vetor. A forma geral de declaração de um vetor em
linguagem algorítmica é:

nome_ da_variável: vetor de [número_de_elementos] de


tipo_de_dado

Considere os exemplos a seguir de declaração de vetores:

notas_da_turma: vetor de [10] de real. A variável notas_da_turma,


é um conjunto de 10 números reais.
nome: vetor de [30] de caracteres: nome é um vetor de 30
caracteres.
Para acessar um elemento específico do vetor utiliza-se o
índice que pode assumir valores de 1 até o número máximo de
elementos do vetor3. A forma geral é definida como:
nome_da_variável[índice]
Exemplo: a variável notas_da_turma[5] indica a quinta nota.

6.1.1 Aplicações de vetores

1. Seja uma classe de 5 alunos. Deseja-se obter a média da classe e


imprimir o nome do aluno cuja nota seja superior a média. Para
resolver este problema, precisamos declarar 5 variáveis para alocar
as notas dos alunos e mais 5 variáveis para os nomes, além da

2 Algumas linguagens (como C, Pascal ) admite o índice definido como sendo do tipo caracter.
3 Em C, o primeiro elemento de um vetor é referenciado pelo índice 0. Portanto os valores que o
índice pode ter vai de 0 até número máximo de elementos - 1.
Algoritmos e Linguagem de Programação
40

variável que conterá a média da classe. O seguinte algoritmo


mostra a solução deste problema.

Início
nome1, nome2, nome3, nome4, nome5: cadeia
media, nota1, nota2, nota3, nota4, nota5: real
leia( nome1, nota1, nome2, nota2, nome3, nota3, nome4, nota4,
nome5, nota5 )
media = (nota1+ nota2+ nota3+ nota4+ nota5)/5
se ( nota1 >= media ) então
escreva( nome1 )
se ( nota2 >= media ) então
escreva( nome2 )
se ( nota3 >= media ) então
escreva( nome3 )
se ( nota4 >= media ) então
escreva( nome4 )
se ( nota5 >= media ) então
escreva( nome5 )
fim.
Observe que este algoritmo só é válido para uma classe com 5
alunos. Como ficaria o algoritmo para uma classe com 100 alunos?
Utilizando a mesma abordagem teríamos que declara 100 variáveis
para os nomes dos alunos e mais 100 para as respectivas notas,
além dos 100 comandos de decisão. Portanto, devemos associar as
notas e os nomes dos alunos a um conjunto referenciado pôr
apenas um nome, que nada mais é do que dois vetores: um
contendo os nomes e o outro com as notas. O algoritmo acima
usando vetor ficará:
Início
nome: vetor de [5] de cadeia
nota: vetor de [5] de real
media, soma: real
i : inteiro
soma = 0
para i de 1 até 5, passo 1, faça
{
leia ( nome[i], nota[i] )
soma = soma + nota[i]
}
media = soma/5.0
para i de 1 até 5, passo 1, faça
se ( nota[i] > media ) então
escreva( nota[i] )
fim.
Com este algoritmo, podemos trabalhar com uma classe com
qualquer número de alunos, mudando apenas o valor final da
variável de controle de fluxo.
Algoritmos e Linguagem de Programação
41

6.2 Matrizes ( Conjuntos Bidimensionais )

É um conjunto com duas dimensões. Assim, como em


vetores, os elementos são de um mesmo tipo de dados. Para
referenciarmos um elemento da matriz, utilizamos dois índices: o
primeiro para especificar a linha e o segundo, a coluna. A forma
geral de declaração de uma matriz bidimensional em notação
algorítmica é:

nome_da_matriz: matriz[número_de_linhas][número_de_colunas]
de tipo_de_dados

Exemplo de declaração de matrizes:

tabela: matriz[5][7] de inteiro: corresponde a uma matriz 5x7 de números inteiros


carac: matriz[3][5] de caracteres: corresponde a uma matriz 3 pôr 5 de caracteres

Para realizar uma operação sobre todos os elementos de uma matriz, devemos
usar dois comandos de repetição: um associado às linhas e o outro às colunas. O
exemplo abaixo, mostra como ler valores de entrada e atribuir à matriz.
início
mat: matriz[4][6] de inteiro
linha, coluna: inteiro
para linha de 1 até 4, passo 1, faça
para coluna de 1 até 6, passo 1, faça
leia( mat[linha][coluna] )
fim.

6.3 Conjuntos com mais de duas Dimensões

Podemos ter conjuntos com várias dimensões. Para cada dimensão é


necessário um índice. Portanto, se tivermos um conjunto tridimensional, são
necessários três índices para acessar um elemento deste conjunto. A forma geral de
declaração, em linguagem algorítmica, de um conjunto com n-dimensões, onde N é
um número inteiro é definido como:

nome_da_variável: conjunto[número1][número2][número3]...[númeroN] de tipo

Como exemplo de um conjunto com 3 dimensões:


arquivo: conjunto[5][10][12] de inteiro.
arquivo pode ser entendido como tendo 5 matrizes 10x12. Para atribuir valores a este
conjunto, devemos usar 3 comando de repetição; um para cada índice. Generalizando,
se tivermos que atribuir valores a um conjunto n-dimensional, teremos que usar n
laços.
Algoritmos e Linguagem de Programação
42

Linguagem de
Programação
C
Algoritmos e Linguagem de Programação
43

Linguagem de Programação C
7. Fundamentos de C
Um programa em C, consiste de um conjunto de uma ou mais funções que
especificam as operações que devem ser realizadas. Todo programa em C inicia-se
chamando uma função especial denominada main(). Esta função marca o início de
um programa C, ou seja, o programa começará a ser executado a partir desta função.
Portanto, todo programa em C, deve ter uma função main() de onde outras funções
podem ser chamadas. Estas outras funções podem ser funções escritas pelo próprio
programador ou funções contidas em bibliotecas da linguagem.
O caracter abre-chave "{", marca o início da função main() e o caracter fecha-
chave "}", indica o término da função. Assim, todas as instruções devem estar
delimitadas pelas chaves e são executadas na ordem que estão escritas no programa.
Quando o compilador chega ao final da função main(), termina-se a execução do
programa.
Todas as instruções em C, são finalizadas pelo caracter ponto-e-vírgula ";". O
ponto-e-vírgula é um terminador de comandos
Abaixo, tem-se a forma geral de um programa em C:

main()
{ /* Início do Programa */
comando 1;
comando 2;
.
.
.
comando n;
}/* Término do Programa */

A linguagem C é sensível ao caso, isto é, letras minúsculas e maiúsculas são


tratadas como caracteres diferentes. Assim, as palavras varia, VARIA e Varia, são
entendidas de forma diferentes pelo compilador C.
O comentário em C, é delimitado pelos símbolos /*, indicando início do
comentário e */ para o término do comentário. Tudo que estiver dentro destes
marcadores, serão ignorados pelo compilador C.

7.1 Variáveis
Variáveis, são objetos de dados básicos manipulados pelo programa. para dar
nomes às variáveis em C, deve-se obedecer alguns critérios:
• O primeiro caracter dever ser sempre uma letra ou o caracter sublinhado "_".
• Os demais caracteres podem ser letras, números ou o caracter sublinhado.
• Como C é uma linguagem sensível ao caso, nomes de variáveis com letras
maiúsculas serão diferentes de nomes com letras minúsculas. Assim, cont e CONT,
são nomes de variáveis diferentes.
• Os nomes de variáveis não podem ser iguais a nomes de palavras reservadas e
também não podem ser iguais a nomes de funções ou rotinas pertencentes às
bibliotecas padrões.
Algoritmos e Linguagem de Programação
44

• Apenas um certo numero de caracteres do nome de variáveis são significativos.


Este número depende do compilador C usado. Assim, se apenas os 8 primeiros
caracteres forem significativos, os nomes de variáveis nome_123 e nome_12345, não
serão distinguidos pelo compilador C utilizado4.

7.2 Tipos de Dados


Existe 5 tipos de dados básicos em C:

Tipo Descrição Bytes Escala


char caracter 1 -128 a 127
int inteiro 2 -32768 a 32767
float real 4 3.4E-38 a 3.4E+38
double real 8 1.7E-308 a 1.7E+308
void sem valor 0 sem valor

7.2.1 Modificadores de tipos


Os tipos de dados básicos, com exceção do tipo void, podem estar precedidos
por modificadores que servem para alterar a escala dos tipos básicos. São eles:
signed, unsigned, short, long. Os modificadores são aplicados aos tipos básicos char
e int. O modificador long pode ser aplicado ao tipo de dado double. A tabela abaixo
mostra as combinações possíveis dos tipos básicos com os modificadores.
O modificador signed, indica número com sinal. Como as declarações default
dos tipos de dados char e int, são com sinal, a utilização deste modificador torna-se
redundante. O modificador unsigned informa que o número deve ser interpretado
com um número sem sinal. Assim, se aplicarmos o tipo unsigned nos tipos char e int
a escala se altera.
O modificador long aumenta o número de bytes do tipo int . O tipo int é
representado em dois bytes. Se utilizarmos o modificador long antes de int, o
número de bytes será 4, aumentando a escala. Em alguns computadores, o tipo int é
representado em 4 bytes. Se usarmos o modificador short, este tipo será representado
em dois bytes.
A tabela abaixo, mostra uma combinação dos tipos de dados int e char com os
modificadores.

Tipo Escala
signed char -128 a 127
unsigned char 0 a 255
signed int -32768 a 32767
unsigned int 0 a 65535
long int -2147483648 a 2147483647
short int -32768 a 32767

4O compilador C padrão admite no máximo 8 caracteres significativos e o compilador Borland C


permite até 32 caracteres significativos para nome de variáveis.
Algoritmos e Linguagem de Programação
45

7.2.2 Declaração de Variáveis


Todas as variáveis devem ser declaradas antes de serem usadas. A forma geral
de declaração de uma variável é dada por :
tipo_de_ dado variáveis;
Consiste em especificar o tipo e em seguida uma lista contendo as variáveis
deste tipo separadas por vírgula. Exemplos:
int num;
float r1, r2, r3, r4;
char carac1;
unsigned int n1,n2;
long int n3;
Onde declarar as variáveis:
1. Fora de todas as funções incluindo a função main(). As variáveis que forem
declaradas fora de todas as funções são denominadas de variáveis globais e podem
ser usadas em qualquer parte do programa; todas as funções a enxergam.
2. Dentro das funções. Neste caso as variáveis são consideradas variáveis locais e
podem ser utilizadas somente dentro da função onde foram declaradas.
3. Como parâmetros de uma função. São usadas para receber as informações que são
passadas para dentro de uma função e funcionam como variáveis locais5.

Dentro de uma função, as variáveis são geralmente declaradas após o caracter


{. Exemplo de declaração de variáveis:

int a;
main()
{
int b;
float f;
char c1, c2;
double d1;
}

A variável "a" declarada fora da função main() é considerada uma variável


global e pode ser usada dentro de main(). As demais variáveis declaradas dentro de
main(), são consideradas variáveis locais e só podem ser utilizadas apenas dentro da
função main().
As variáveis globais não podem ter o mesmo nome que variáveis locais, ao
passo que os nomes de variáveis locais podem ter o mesmo nome em funções
diferentes, uma vez que estas variáveis são vistas apenas dentro da função que foram
declaradas.

7.3 Constantes
São valores fixos que não podem ser alterados no programa. As constantes
podem ser de qualquer tipo de dado básico.
Uma constante do tipo caracter ( char ) é um único caracter escrito entre
apóstrofos, como exemplo 'a', '1', etc. Uma constante do tipo inteira é um número na
escala descrita nas tabelas acima. Uma constante do tipo long int deve ser escrita
terminada com a letra L. Assim, como exemplo, 1233L. Um número do tipo float

5Este assunto será abordado com maiores detalhes na parte referente a funções.
Algoritmos e Linguagem de Programação
46

ou double possui o ponto decimal. Exemplo de constantes decimais: 12.23, 23.34.


Uma constante em ponto flutuante é escrita como 1.23e-4 ou 1.23E-4 e é presumida
ser do tipo double.
Em C, existe constantes octais e hexadecimais. Para indicar que uma constante
é octal, esta deve ser precedida com o caracter 0 ( zero ) e para representar uma
constante hexadecimal, deve-se colocar os caracteres 0x ou 0X antes do número.
Exemplo, o número 0132 é um número na base oito e 0x123A é um número
hexadecimal.
As constantes do tipo cadeias de caracteres é uma seqüência de 0 ou mais
caracteres e são delimitadas por aspas, Assim, "Nome do funcionário", é um
exemplo de uma constante cadeia. Toda constante do tipo cadeia é terminada com o
caracter nulo '\0'. Portanto para armazenar uma cadeia deve-se alocar mais um byte
para guardar o caracter \0 que indica o fim da cadeia.
Cuidado! Seja o seguinte exemplo: "a". Esta constante é do tipo cadeia de
caracteres pois está delimitada por aspas e é diferente da constante 'a', que é uma
constante do tipo caracter.

7.4 Inicialização de variáveis em C


As variáveis em C, podem ser inicializadas quando forem declaradas. Basta
apenas colocar um sinal de igual e um valor constante após o nome da variável.
A forma geral de inicialização é:
tipo nome_variável = valor_constante;

Exemplos:
int a = 100;
float f1 = 12.0, f2 = 13.0, f3;
char b = ‘B’;

7.5 Operadores
São símbolos que informam ao compilador executar determinadas
manipulações matemáticas, relacionais e lógicas. C é um linguagem rica em
operadores ( cerca de 40 ).

7.5.1 Operadores Aritméticos


A linguagem C possui operadores matemáticos binários e unários. A tabela
abaixo mostra os operadores aritméticos:

Operador Ação
- subtração e menos unário
+ adição
* multiplicação
/ divisão
% resto da divisão ( módulo )
Algoritmos e Linguagem de Programação
47

A expressão a%b, produz o resto da divisão de a por b. O operador módulo é


aplicado somente a valores inteiros ( int ) e não pode ser aplicados a valores float e
double. Os operadores *, / e % têm a mesma prioridade que é maior que os
operadores + e -. O menos unário, tem prioridade maior que os demais operadores.
Quando a divisão é aplicada a números inteiros, o resto é truncado. Assim,
10/3 resulta em 3.

7.5.2 Operadores de Incremento e Decremento


A linguagem C oferece dois operadores não comuns em outras linguagens de
programação, para incrementar e decrementar o valor de variáveis em uma unidade.
Assim, o operador de incremento soma1 à variável, ao passo que o operador de
decremento subtrai de 1 unidade. Portanto:
x++ corresponde a x = x + 1
x-- corresponde a x = x - 1
Estes operadores podem ser pré-fixados (antes da variável) ou pós-fixados
(após a variável). Exemplo: x++ ou ++x. Nos dois casos a variável x será
incrementada mas com a seguinte diferença: no primeiro caso, o valor de x é usado e
depois é que será incrementado. No segundo caso, o valor de x é primeiramente
incrementado e seu novo valor é então usado.
Sejam as seguintes expressões:
b = 10;
a = b++;
Após a expressão a = b++ ser avaliada, os valores contidos nas variáveis a, e b são 10
e 11, respectivamente.
Considere agora:
b = 10;
a = ++b;
Os valores finais de a e b agora valem 11 e 11, respectivamente.
Estes operadores podem ser aplicados somente a variáveis, não sendo possível
utilizá-lo em expressões. Como exemplo, uma expressão do tipo a = (c+d)++ está
errada.

7.5.3 Operadores Relacionais


Se refere às relações entre dois valores. Uma expressão booleana compara
dois valores retornando um resultado lógico: verdadeiro ou falso. Em C, verdadeiro é
qualquer valor diferente de 0, enquanto falso é zero. Uma expressão booleana,
retornará 1, se for verdadeira e 0 se for falsa. A tabela a seguir mostra os símbolos
que representam os operadores de relação em C

Operador Ação
> maior
>= maior ou igual
< menor
<= menor ou igual
== igual
!= diferente
Algoritmos e Linguagem de Programação
48

7.5.4 Operadores Lógicos


Se refere como as relações estão conectadas. Os operadores lógicos são:

Operador Ação
&& E
|| OU
! NEGAÇÃO

A linguagem C, permite combinar várias operações em uma expressão,


conforme o exemplo:
10 > 4 && !(3<2+4) | | 6 <= 3
Os operadores relacionais e lógicos tem precedência menor que os operadores
aritméticos. Portanto, C avalia a expressão 12>5*7 como se fosse 12>(5*7), que dará
um resultado falso (0)
A tabela a seguir, mostra a prioridade dos operadores relacionais e lógicos.

Maior !
> >= < <=
= = !=
&&
Menor ||

7.5.5 Operador de Atribuição


O símbolo que representa o operador de atribuição em C, é o sinal de igual:
“=”. A linguagem C, permite a utilização deste operador em expressões que
envolvem outros tipos de operadores. Como exemplo:

if ( (sq=x*x) < 0 )

Primeiramente, C atribui o valor de x*x à variável sq. Após, o valor atribuído a


sq é testado com 0. Os parênteses são necessários porque a prioridade do operador de
atribuição é menor que o operador relacional. Se não estiver entre parênteses,
primeiramente seria calculado o produto x*x , em seguida, este valor seria comparado
com o valor 0. Se for menor, indica que a expressão lógica é verdadeira e portanto, sq
recebe o valor 1. Se a expressão for falsa, sq receberá o valor 0

7.6 Expressões
Uma expressão é um conjunto de operandos (constantes e variáveis) e
operadores. É a parte que está a direita do operador de atribuição. A expressão será
avaliada e resultará em um valor que será atribuído a uma variável (parte esquerda do
comando de atribuição).

7.6.1 Conversão de tipos em expressões


Se em uma expressão tiver variáveis e constantes de tipos diferentes, C as
converte para o mesmo tipo. Todos os operandos serão convertidos para o tipo do
maior operando, uma operação por vez, conforme as seguintes regras:
Algoritmos e Linguagem de Programação
49

1. Todo char e short int é convertido para int e todo float é convertido
para double.
2. Para todos os pares de operandos, ocorre o seguinte: se o maior dos
operandos for long double, o outro será convertido para long double, se for double
o outro operando será double, se for float o outro será float.
Após ser aplicada a regra de conversão, cada par de operandos será do mesmo
tipo.

7.6.2 Casts
É uma construção que força uma expressão ser de um dado tipo. A forma geral
é:
(tipo) expressão

Onde tipo é um tipo de dado. Por exemplo: seja i uma variável inteira e quiser
transformar um resultado para double. Portanto: (double) i/3. O cast é considerado
um operador unário.
Os casts podem ser muito úteis. Como exemplo, suponha que se deseja usar um
número inteiro para controle de um loop, mas que a execução de um cálculo com este
inteiro, seja um número decimal.
Observação: Seja x uma variável inteira. Se fizermos (float) (x/3), o
computador executará a divisão de inteiros ( portanto truncando o resultado) e este
resultado será convertido para float. Exemplo:
Seja x uma variável inteira e f uma variável do tipo float.
x = 10;
f = (float) (x/3).
A variável f, conterá o valor 3 e não o valor 3.333..., como era de se esperar.

7.7 Comandos de Entrada e Saída


São os comandos que possibilitam fornecer valores para dentro do programa e
para exibir os resultados do programa.

7.7.1 Entrada de dados


Para fornecer dados para o programa. A função scanf() implementa o
comando de entrada de dados. Esta função é implementada em todos compiladores C.
Forma geral:
scanf(“expressão de controle”, lista de variáveis );

A expressão de controle é basicamente constituída por códigos de formatação


relativos às variáveis que irão receber os valores de entrada. A lista de variáveis,
consiste dos endereços das variáveis. C oferece um operador de endereço denotado
por & que retorna o endereço da variável, ou seja, sua localização de memória (um
número inteiro sem sinal).
Para cada código de formatação deve ter um endereço de variável correspondente.
Exemplo:
int c;
float f;
scanf(“%d %f”, &c, &f);
Algoritmos e Linguagem de Programação
50

7.7.2 Saída de dados


A linguagem C, utiliza a função printf() para enviar dados para o console. A
forma geral do comando printf() é:

printf(“Expressão de controle”, lista de argumentos)

A expressão de controle contém caracteres que serão exibidos na tela,


comandos de formatação que indicam o formato que os argumentos devem ser
impressos, ou ambos.
Printf() é uma função da biblioteca padrão de Ce pode receber um número
variável de argumentos. Os argumentos devem estar separados por vírgula. Exemplo:
printf(“Os números são: %d e %d”, 2,3)
Os códigos de formatação básicos são:

Código Significado
%d Exibir um número inteiro
%f Exibir um número float no formato decimal
%e Exibir um float em notação de pto flutuante
%ld Exibir um inteiro longo
%lf Exibir um double no formato decimal
%le Exibir um double em pto flutuante
%c Exibir um caracter
%s Exibir uma cadeia
%o Exibir um número em octal
%x Exibir um número em hexadecimal
%u Exibir um número inteiro sem sinal

7.8 Chaves e Comentários


Um bloco é um conjunto de comandos conectados que aparecem entre chaves. Um
comentário em C é delimitado pelos símbolos /* indicando início do comentário e */
indicando o término do comentário. Duas barras //, indica um comentário de linha, ou
seja, tudo que estiver depois de // na mesma linha, estará comentado.

8. Comandos de Controle de Fluxo

Os comandos de controle de fluxo são a essência de qualquer linguagem de


programação, pois governam o fluxo de execução de um programa. Os comandos de
controle de fluxo são divididos em três categorias. A primeira são os comandos de
decisão. A segunda são os comandos de repetição e a terceira o comando de desvio
incondicional ( goto ).
Um comando pode consistir em: um comando simples, um bloco de comandos
ou nenhum comando ( comando vazio ).
Algoritmos e Linguagem de Programação
51

8.1 Comandos de Decisão


Os comandos de decisão possibilitam desviar a seqüência de execução de um
programa, de acordo com o resultado de uma condição, que nada mais é que uma
expressão booleana.

8.1.1 Comando if
Instrui ao computador executar um comando baseado na avaliação de uma
expressão booleana. Se o resultado da expressão for verdadeiro o comando será
executado, caso contrário o comando será ignorado. A forma geral do comando if é:

if ( expressão booleana )
comando;

Se tiver mais de um comando a ser executado dentro do if (bloco de comandos), a


forma geral do comando if é agora dada por:

if ( expressão booleana ) {
comando 1;
comando 2;
comando 3;
.
.
.
comando N;
} /* end if */

8.1.2 Comando if-else


O comando else associado ao comando if executará um comando se o resultado
da expressão booleana for falsa. A forma geral é dada por:

if ( expressão booleana )
comando 1;
else
comando 2;

Se o comando for um bloco de comandos a forma geral do comando if-else é


dada por:

if ( expressão booleana ) {
comando 1;
comando 2;
comando 3;
.
.
.
comando N;
Algoritmos e Linguagem de Programação
52

} else {
comando 1;
comando 2;
comando 3;
.
.
.
comando N;

} /* end else */

8.1.3 Comandos if aninhados


Um if aninhado é um comando if que é um comando de um outro if ou else. A
maior dificuldade com relação a esta estrutura, é dizer que else está associado com
qual if. A linguagem C utiliza uma regra bastante simples para saber com que if o else
está relacionado: o else está ligado ao if mais próximo que ainda não tenha um
comando else associado a ele.
Exemplo:
if (x >= 1)
if ( y = = 1 )
printf(“ Valor igual a um”);
else
printf(“ Valor maior que um”);

O comando else estará associado ao if ( y = = 1 ) pois é o comando if mais próximo.


Se desejar que o else esteja associado ao comando de decisão if ( x >= 1 ), deve-se
usar as chaves para anular a regra de associação da linguagem, conforme mostra o
exemplo:
if ( x >= 1 ) {
if ( y = = 1 )
printf(“ Valor igual a um”);
} else {
printf(“ Valor maior que um”);
} /* end if */

8.1.4 O comando if-else-if


Forma geral:
if (condição 1)
comando 1;
else if ( condição 2 )
comando 2;
else if ( condição 3 )
comando 3;
.
.
.
else
Algoritmos e Linguagem de Programação
53

comando N;

Este comando é avaliado de cima para baixo. Assim que uma condição é
verdadeira, o comando será executado e o resto do comando será ignorado. Se
nenhuma das condições for verdadeira, o comando associado ao último else será
executado.

8.1.5 Comando switch


O comando switch é usado no lugar do comando if-else-if. O valor de uma
variável é testado sucessivamente com relação a uma lista de constantes do tipo
inteiro ou caracter. Quando o valor da variável coincidir com uma constante, os
comandos associados a esta constante serão executados. A forma geral do comando
switch é:

switch ( variável ) {
case constante 1:
seqüência de comandos;
break;
case constante 2:
seqüência de comandos;
break;
case constante 3:
seqüência de comandos;
break;
.
.
.
default:
seqüência de comandos;
} /* end switch */

O comando default, é opcional e somente será executado se o valor da variável


não coincidir com nenhuma das constantes. Quando encontrar alguma coincidência,
os comandos associados serão executados até encontrar o comando break.
Características do comando switch:
• Só é possível fazer comparações de igualdades
• Não pode haver duas constantes case com valores iguais no mesmo switch.
O comando break é opcional dentro do comando switch; é utilizado para
terminar a seqüência de comandos que está associado ao case que coincide com o
valor da constante. Se o break for omitido, a execução continuará até achar o próximo
break ou chegar ao final do comando switch.

8.2 Comandos de Repetição


Os comandos de repetição são usados para executar um comando ou bloco de
comandos diversas vezes. Os comandos de repetição em C são: for, while e o do-
while.
Algoritmos e Linguagem de Programação
54

8.2.1 Comando for


A forma geral do comando for é dada por:

for ( inicialização; condição; incremento )


comando;

Na forma simplificada, a inicialização é um comando de atribuição usado para


atribuir o valor inicial à variável de controle do fluxo. A condição é uma expressão
lógica que verifica se a variável de controle atingiu um determinado valor final, de
forma que o comando for termine. O incremento determina a forma que a variável de
controle será alterada cada vez que o comando de repetição for executado. As três
partes são separadas por ponto-e-vírgula. Se a condição for verdadeira, o laço for
continuará sendo executado. Quando a condição for falsa, o laço é terminado.
Exemplo:

main() {
int x;
for ( x=1 ; x<=10; x++ )
printf(“X: %d”,x );
} /* end main */

Primeiramente, o valor 1 é atribuído à variável x. Como x é menor que 10, o


programa executa a instrução printf(). Após, o valor de x é incrementado de 1 unidade
e um teste é feito para verificar se ainda é menor que o valor constante 10. Se for
( condição verdadeira ), o comando printf() é novamente executado. O processo se
repete até que x seja maior que 10.
Pode-se criar um laço for que seja decrementado. Exemplo:
main() {
int x;
for ( x=10 ; x>0; x-- )
printf(“X: %d”,x );
} /* end main */

A forma como a variável de controle de fluxo é alterada pode ser qualquer tipo
de comando de atribuição. Exemplo:
main() {
int x;
for ( x=0 ; x<=100; x=x+5 )
printf(“X: %d”,x );
} /* end main */

Para executar diversos comandos dentro de um laço for, deve-se colocá-los


como se fosse um bloco de comandos, ou seja entre chaves. A forma geral é:

for ( inicialização; condição; incremento ) {


comando 1;
comando 2;
comando 3;
} /* end for */
Algoritmos e Linguagem de Programação
55

8.2.1.1 Variações do comando for


Uma das variações é o uso de duas ou mais variáveis de controle, conforme
mostra o exemplo:

main() {
int x,y;
for ( x=0, y=0 ; x+y <100; x++, y++ )
printf(“X+Y: %d”,x+y );
} /* end main */

As inicializações, bem como as formas como as variáveis de controle são


alteradas, são separadas por vírgula.
Uma outra variação do comando for, é que ele não exige que todas as partes da
definição do comando estejam presentes. Por exemplo.

for ( x=0; x!=100; )


scanf(“%d”, &x);

Este trecho de programa ficará repetindo até que o número 100 seja digitado.
Cada vez que o laço se repete, o valor de x é testado, mas nunca será incrementado.
Quando o número 100 for digitado, a expressão booleana será falsa e o laço termina.

8.2.1.2 Laço for infinito


Se nenhuma das três opções do laço for forem colocadas, pode-se elaborar um
comando de repetição infinito. Exemplo:

for(;;)
comando 1;

Para sair de um laço for infinito, utiliza-se o comando break, que ocasiona o
término do laço.

8.2.2 Comando while


Uma outra forma de comando de repetição que a linguagem C possui é o
comando while. A forma geral deste comando é:

while ( condição )
comando;

Primeiramente, a condição é testada. Se o resultado da condição for verdadeiro


o comando será executado. Se tivermos mais de um comando dentro do laço while
deve-se usar os caracteres chaves para delimitá-los como um bloco de comandos, da
mesma forma apresentada para o laço for. Exemplo:

while ( condição ) {
comando1;
comando2;
comando3;
Algoritmos e Linguagem de Programação
56

.
.
.
comandoN;
}

8.2.3 Comando do-while


O comando do-while é um outro comando de repetição disponível em C. É um
laço cuja condição é testada no final. A forma geral deste comando é dada por:

do {
comando 1;
comando 2;
.
.
.
comando n;
} while ( condição )

As chaves não são necessárias quando tiver apenas um comando a ser executado
dentro do do-while. São utilizadas para aumentar a legibilidade do código.

8.3 Interrupção de Laços


São usados para interromper a execução de um laço ou de
alguma repetição do laço.

8.3.1 Break
O comando break, além de ser usado no comando switch, é utilizado para
suspender a execução de um loop, ignorando o teste condicional. Quando encontrar
um comando break dentro de um laço, este será imediatamente encerrado, passando a
executar o comando que estiver após deste comando de repetição, conforme o
exemplo:

main()
{
int a;
for(a=0;a<1000;a++) {
printf(“%d”, a);
if (a = = 30 )
break;
} /* end for */

8.3.2 Continue
O comando continue não encerra a execução do laço, mas força a execução da
próxima repetição, ignorando todos os comandos que estiverem depois. Seja o
exemplo:
main()
Algoritmos e Linguagem de Programação
57

{
int x;
for(x=0;x<=200;x++) {
if(x%3==0)
continue;
printf(“%d”, x);
}
}
Se x for um múltiplo de 3, o comando continue será executado, passando para a
próxima iteração, ignorando o comando printf.

8.3.3 Rótulos e goto


Apesar de não existir nenhuma situação de programação que requeira o uso do
comando goto, ele pode ser usado em certas situações, como por exemplo, substituir
vários níveis de aninhamentos. O uso do comando goto pode tornar um programa
confuso e difícil de entendê-lo.
O comando goto faz uso de um rótulo. Um rótulo é um identificador seguido
pelo caracter “:”. O rótulo deve estar na mesma função do comando goto que o
utiliza. Exemplo:
z=10;
rot:
z++;
if ( z<100) goto rot;

9. Vetores e Matrizes
É um conjunto de variáveis do mesmo tipo de dados ( homogêneas )
referenciadas pelo mesmo nome. São diferenciadas através de um número
denominado de índice, ou seja, o índice é utilizado para acessar um elemento da
matriz. Uma matriz ou um vetor, consiste de alocações adjacentes de memória. Uma
matriz pode ter uma ou mais dimensões. Uma matriz de uma dimensão é denominada
de vetor.

9.1 Matriz de uma dimensão - Vetores

Forma geral de declaração de um vetor é:

tipo_de_dados nome_da_variável[tamanho];

Onde o tipo_de_dados determina o tipo de dado dos elementos do vetor. O


nome_da_variável é o nome do vetor e o tamanho se refere à quantidade de elementos
do vetor. O exemplo:
int mat[26];
declara uma variável denominada mat capaz de guardar até 20 valores do tipo
inteiro. É alocada memória para conter 26 números inteiros.
Para referenciar um elemento particular do vetor, utiliza-se um índice, que é um
número usado para especificar a posição do elemento no vetor. Em C, o primeiro
elemento do vetor é referenciado com o índice zero. Portanto, os 26 elementos são
mat[0] à mat[25]. O índice pode ser uma variável inteira ou caracter.
Algoritmos e Linguagem de Programação
58

O trecho de programa a seguir, ilustra a utilização de vetor.

main()
{
int vet[10], i;
for( i=0;i<10;i++)
vet[i] = i*2;
}

Para determinar a quantidade de bytes que é alocado a um vetor, faz-se:


Quantidade de bytes = sizeof(tipo_de_dados) * tamanho do vetor.

Observação: A linguagem C não verifica os limites de uma matriz e nada


impede que este limite seja ultrapassado, podendo ocasionar erros de lógica do
programa. É responsabilidade do programador assegurar estes tipos de erros. A
linguagem C não fornece a verificação de matrizes pois ocasionaria um aumento no
tempo de execução do programa, e C foi projetado para substituir em muitas situações
a linguagem Assembly.

9.2 Matriz com Duas Dimensões


A linguagem C permite definir matrizes com várias dimensões. Uma matriz
bidimensional é uma matriz de matrizes unidimensionais. A forma de declarar uma
matriz bidimensional é definida por:

tipo_de_dado nome_da_matriz[número_de_linhas][número_de_colunas];

O exemplo a seguir define uma matriz contendo 20 linhas e 30 colunas. Todos


os elementos são do tipo inteiro.
int mat[20][30];

Uma matriz utiliza dois índices. O primeiro indica a linha e o segundo a coluna.
Portanto, para referenciar um elemento de uma matriz em C, basta usar o nome da
matriz seguido pelos índices relativos à linha e coluna. O elemento na linha 1, coluna
1 é acessado como: nome_da_matriz[0][0].

Para determinar o tamanho de uma matriz em bytes, basta usar a fórmula


abaixo:
número de bytes = número de linhas x número de colunas x
sizeof(tipo_de_dados). Do exemplo acima, há um total de 20x30x2=1200 bytes
alocados na memória.

Podemos definir uma matriz com mais de duas dimensões. A forma geral é
dada por:

tipo_de_dado nome_da_variável[tam1][tam2]...[tamN];

9.3 Cadeia ( Strings )


O tipo de dado cadeia é um vetor de caracteres em C terminada com um zero
especificado pelo caracter nulo (‘\0’). Portanto, devemos sempre declarar uma
Algoritmos e Linguagem de Programação
59

variável do tipo cadeia contendo um caracter a mais para armazenar o ‘\0’. O


exemplo a seguir, mostra como declarar uma string em C.
char nome[21];
A string nome pode conter uma constante do tipo cadeia com até 20 caracteres.
O o 21º caracter é reservado para armazenar o ‘\0’ indicando o fim da cadeia.
Não é necessário acrescentar o ‘\0’ ao final de uma string após atribuir um valor
a variável do tipo cadeia. A linguagem C, faz isto automaticamente.

9.3.1 Lendo uma string


A função scanf() é bastante limitada para leitura de strings. Como scanf() utiliza
o caracter espaço para indicar o término de uma entrada, fica complicado entrar com
uma constante do tipo cadeia que contenha caracteres espaços, ou seja, um texto com
várias palavras.
A forma mais conveniente de leitura de uma string, é através do uso da função
gets(). A forma geral desta função é:

gets( nome_da_variável );

Basta apenas colocar entre parênteses o nome da string. Esta função lê os


caracteres de um dispositivo de entrada (o default é o teclado) até que seja digitado
um <ENTER>. A função gets() não verifica o limite máximo de caracteres a ser
alocado.
É responsabilidade do programador assegurar que o limite de caracteres de uma
string, não seja ultrapassado.

9.3.2 Exibindo uma string


Pode-se usar a função printf() com o código de formatação ‘%s’ ou usar uma
função específica para imprimir uma string por vez: puts(). A forma geral desta
função é dada por:

puts( nome_da_variável ) ou puts (“constante do tipo cadeia”);

9.3.3 Funções para manipulação de strings em C


A linguagem C não permite atribuir uma constante cadeia a uma variável do
tipo string através da operação de atribuição. Para fazermos esta operação e outras
manipulações com strings, utilizamos funções disponíveis nas bibliotecas padrões C . 6

9.3.3.1 Função strcpy()


Forma geral desta função:
strcpy( destino, fonte );
O parâmetro destino é o nome da variável que receberá o valor contido em
fonte, que pode ser uma outra variável ou uma constante cadeia. Exemplo:

#include<stdio.h>
#include<string.h>

6 Para usar as funções de manipulação de strings, devemos incluir a cabeçalho string.h que contém
os protótipos destas funções.
Algoritmos e Linguagem de Programação
60

main() {
char str[10],str1[10];
strcpy(str, “teste”);
strcpy(str1, str);
}
Este trecho de programa, primeiramente, copia a cadeia constante “teste” para a
variável str. Também coloca ao final de teste o caracter ‘\0’. O segundo comando
strcpy, copia o valor contido na strin str para a string str1.

9.3.3.2 Função strcat()


Esta função é utilizada para concatenar duas strings. A forma geral é:
strcat( string1, string2 );
Strcat concatena o valor contido em string2 na variável string1. Como exemplo:

#include<stdio.h>
#include<string.h>
main() {
char str1[10], str2[10];
strcpy(str1, “teste1”);
strcpy(str2, “teste2”);
strcat(str1, str2);
}

Ao final deste programa o valor contido em str1 será “teste1teste2”.

9.3.3.3 Função strcmp()


É utilizada para comparar os valores contidos em duas strings. Esta função
retorna 0 se as strings forem iguais. A forma geral desta função é:
strcmp( string1, string2);
Se string1 for lexicograficamente maior que string2, a função strcmp()
retornará um número positivo, do contrário, será retornado um número negativo.

#include<stdio.h>
#include<string.h>
main() {
char str1[10];
gets(str1);
if ( !strcmp( str1, “senha”) );
printf(“senha correta”);
}

9.3.3.4 Função strlen()


Esta função retorna o número de caracteres de uma string ( não conta o ‘\0’ ). A
forma geral desta função é:
strlen(string);

Exemplo:
#include<stdio.h>
Algoritmos e Linguagem de Programação
61

#include<string.h>
main() {
char str1[10];
strcpy( str1, “teste”);
printf(“%d”, strlen(str1));
}
Neste exemplo, será exibido o número 5, que é o número de caracteres contidos
em str1.

10. Funções e estrutura de um Programa em C


Um problema computacional pode ser dividido em partes menores tornando a
implementação mais simples. Desta forma, cada tarefa pode ser desenvolvida pôr um
determinado programador. Utiliza-se funções e procedimentos também quando uma
parte do programa é executada diversas vezes, evitando assim escrever o mesmo
código de programa toda vez que for necessário usá-lo dentro do programa.
A linguagem C consiste de diversas pequenas funções as quais podemos citar:
printf(), scanf(), sin(), cos(). Uma função é uma sub-rotina que contém alguns
comandos e que executa alguma tarefa específica. Cada função tem um nome, um
tipo e pode conter uma lista de argumentos que a função receberá. Os argumentos são
os valores que serão passados para dentro da função A forma geral de uma função em
C é:

tipo nome_da-função( lista_de_parâmetros )


{
corpo da função: conjunto de comandos dentro da função
}

tipo: Especifica o tipo valor que a função deve retornar para o programa
principal. Uma função não necessita retornar um valor se for o caso. Como exemplo
já visto, fizemos o uso da função main() que não retorna valor. Exemplo: a função
getch() retorna um caracter digitado pelo teclado.
A lista_de_parâmetros é uma lista de nomes de variáveis e seus respectivos
tipos de dados, que receberão os argumentos quando a função for chamada dentro do
programa principal. Uma função não precisa necessariamente conter parâmetros.
Exemplo de função sem parâmetros:

void imprime(); // Protótipo da função


void main() {
imprime();
}
void imprime() {
printf (“Universidade São Francisco”);
}

Exemplo de uma função que contém parâmetros:

void main() {
int num1, num2;
scanf(“%d %d”, &num1, &num2);
soma_num(num1, num2);
Algoritmos e Linguagem de Programação
62

}
void soma_num(int n1, int n2) {
int total;
total = n1+n2;
printf( “Total: %d”, total);
}

No exemplo a função soma_num recebe dois números inteiros como


argumentos que são atribuídos à n1 e n2 para serem usados dentro da função . 7

Quando uma função é chamada a execução do programa é interrompida


temporariamente sendo passada para dentro da função chamada. Após o término de
execução desta função, a execução volta para o comando imediatamente a seguir ao
comando que chamou a função. A figura a seguir ilustra uma chamada a uma função.

main(){ func1()
comando1; comando1
comando2; ;
comando3; comando2
func1();
comando5;
func2()
comando6;
func2(); comando1
comando7; ;
} comando2

10.1 Regra de escopo das funções


As regras de escopo de uma linguagem, ditam se uma determinada parte do
programa Tem ou não acesso a outro trecho de códigos ou dados.
Em C, cada função é um conjunto de comandos, ou seja um trecho de código
que é particular da função e não pode ser acessado por outra função, a não ser pela
chamada à função.
Existem três tipos de variáveis: variáveis locais, variáveis globais e parâmetros
formais. As regras de escopo determinam como as outras partes do programa podem
acessar cada um desses tipos.

10.1.1 Variáveis Locais


São as variáveis declaradas dentro de uma função. As variáveis locais podem
ser utilizadas apenas pelos comandos que estão dentro da função onde as variáveis
foram declaradas. As variáveis locais não são conhecidas fora da função e seu escopo
é limitado à função que foram declaradas. As variáveis locais existem apenas durante
a execução do bloco de código na qual estão declaradas, isto é, uma variável local é
criada durante a execução da função e destruído no término de execução da função.
Exemplo:

main(){
func1();
func2();
7As variáveis n1 e n2 são variáveis locas à função soma_num(), pois somente
poderão ser usadas dentro desta função.
Algoritmos e Linguagem de Programação
63

}
func1(){
int a;
a = 10;
}
func2(){
int a=10;
printf(“%d”, a);
}

A variável a é declarada dentro das funções func1() e func2(). Mas a variável a


da função func1() não é a mesma da função func2(), pois cada variável é conhecida
apenas dentro da função que foram declaradas.

10.1.2 Variáveis globais


As variáveis globais são conhecidas em todo o programa e podem ser usadas
dentro de qualquer função. As variáveis globais mantém os valores durante toda a
execução do programa. Para criar uma variável global, deve-se declará-la fora de
qualquer função. Exemplo:
int a;
main(){
a= 10;
func1();
}
func1(){
printf(“A: %d”, a);
}

Se uma variável global e uma local tiverem o mesmo nome, todas referências a
essa variável dentro da função na qual a variável local foi declarada dirão respeito à
variável local e não terá efeito sobre a variável global.
As variáveis globais são úteis quando se usa os mesmos dados nas várias
funções do programa. Deve-se evitar o uso de variáveis globais desnecessárias:
1. pôr ocupar espaço na memória durante toda a execução do programa e não
apenas quando são necessárias ( como as variáveis locais ).
2. Pode levar a erros imprevisíveis, pôr não conhecer as causas de possíveis
efeitos colaterais.
3. As funções ficam menos generalizadas.

10.1.3 Parâmetros formais


Se uma função utiliza argumentos, então devem ser declaradas variáveis para
receber os valores dos argumentos. Essas variáveis são chamadas de parâmetros
formais da função. Os parâmetros se comportam como uma variável local à função.
A declaração dessas variáveis ocorrem dentro dos parêntesis da função,
precedida pelo tipo de dados. Exemplo:
main(){
int a, b;
a=10;
b=20;
Algoritmos e Linguagem de Programação
64

soma(a,b);
}
soma( int n1, int n2){
printf(“Soma: %d”, n1+n2);
}
Alguns compiladores C aceitam um outro tipo de declaração dos parâmetros da
função, conforme mostra o exemplo a seguir:

soma(n1,n2)
int n1,n2;
{ // Início da função
printf(“Soma: %d”, n1+n2);
}// Término da função.

A figura abaixo ilustra os tipos de variáveis dentro de um programa C.

int var_global;

main(){
int a,b;
}

func1( int f1){


int f11;
}

func2(){
int f2;
}

10.2 Funções que retornam valores


As funções que não retornam valores são conhecidas na notação algorítmica
pelo nome de procedimentos. São funções procedurais e não produz nenhum valor.
As funções que não retornam valores, são declaradas do tipo void, e não precisam
especificar nenhum valor de retorno.
Existem duas formas pelas quais uma função termina sua execução e volta para
o trecho do programa que a invocou: primeiramente executa todos os comandos de
uma função até o ultimo e encerra a execução da função, voltando ao trecho
chamador, ou seja, quando encontra o caracter fecha-chave “}” indicando o término
da função. A segunda maneira é através do uso do comando return. Pode-se usar o
comando return sem nenhum valor associado a ele.
Uma função pode conter diversos comandos return.

10.2.1 Valores de Retorno


Ao especificar um tipo para uma função, esta pode devolver um valor do
mesmo tipo da função, através do comando return. Como exemplos deste tipo de
função, temos em C: sin(), cos(), etc.. Definindo uma função que retorna um valor.
Algoritmos e Linguagem de Programação
65

void main() {
double, num,c;
printf(“Entre com um número: “);
scanf(“%lf”, &num);
c=cubo(num);
printf(“O Cubo é: %lf”, c);
}// end main
double cubo(double n){
double c;
c= n*n*n;
return(c);
} // end cubo

10.3 Argumentos das Funções


Os parâmetros das funções devem ser do mesmo tipo que os argumentos
utilizados nas chamadas das funções. Se os tipos de dados não forem o mesmo, o
compilador pode não emitir uma mensagem de erro e como conseqüência resultar em
valores não previstos.

10.3.1 Chamada por Valor e Chamada por Referência


Os argumentos podem ser passados para dentro de uma função de duas formas.
A primeira é conhecida por Chamada por Valor, que copia o valor do argumento para
dentro do parâmetro da função. Portanto, as alterações feitas nos parâmetros dentro da
função, não terão nenhum efeito nas variáveis usadas na chamada da função.
Exemplo:

main(){
int n1=10;
printf(“%d”, quadrado(n1));
printf(“%d”, n1);
} // end main
quadrado( int n2) {
n2 = n2*n2;
return(n2);
} // end quadrado

A linguagem C copia o valor de n1 que é 10 para o parâmetro n2. Quando a


multiplicação ocorrer, apenas o valor de n2 será alterado. A variável n1 ainda terá o
valor 10 após terminar a execução da função quadrado(). A linguagem C, utiliza o
método de passagem por valor para passar os argumentos. Assim as variáveis cujos
valores são passados para dentro da função, não são alteradas após a execução da
função.
A segunda forma de passar argumentos para uma função é a chamada por
referência. A chamada por referência, copia o endereço de um argumento para o
parâmetro. Dentro da função, o endereço é usado para acessar o argumento real
usado na chamada da função. Portanto, as alterações que forem feitas nos parâmetros
dentro da função afetarão as variáveis usadas como argumentos.
Algoritmos e Linguagem de Programação
66

10.3.1.1 Como criar uma chamada por referência em C


Os parâmetros de uma função são definidos como ponteiros do mesmo tipo das
variáveis que são passadas para dentro da função. Ao invés de passar o valor da
variável para dentro da função, é passado o endereço da variável, utilizando o
operador de endereço &. O exemplo a seguir ilustra uma passagem por referência.

main(){
int a,b;
a=10;
b=20;
printf(“A: %d B: %d”, a,b); // Imprime os valores 10 e 20 respectivamente
troca(&a,&b);
printf(“A: %d B: %d”, a,b); // Imprime os valores 20 e 10 respectivamente
}
troca(int *n1, int *n2){
int aux;
aux = *n1;
*n1 = *n2;
*n2 = aux;
}

10.4 Protótipos de Funções


É a declaração do tipo da função e o número e os tipos de parâmetros da
função. Como resultado, a linguagem C estabelece uma verificação muito forte de
tipo e exibirá mensagens de erros toda vez que chamar uma função com argumentos
de tipos diferentes daqueles declarados na função.

11. Ponteiros
Um ponteiro é uma variável que contém um endereço de memória, ou seja, o
endereço de uma outra variável na memória. Se uma variável contiver o endereço de
uma outra variável, pode-se dizer que uma aponta para a outra, conforme ilustra a
figura a seguir.

Endereço de memória Variável na memória

1000 1003

1001

1002

1003

1004

Uma variável do tipo ponteiro é declarada como:


tipo *nome_variável;
Onde tipo é qualquer tipo de dado em C. O tipo define para qual o tipo de variável o
ponteiro aponta. Exemplo:

char *p; Declara ponteiro para caracteres.


Algoritmos e Linguagem de Programação
67

int *i; Declara ponteiro para inteiros.

11.1 Operadores de Ponteiros


Os operadores para ponteiro são * e &, onde & é o operador de endereço que
devolve o endereço de memória do operando, como foi usado na função scanf().
Exemplo:
endr = &valor; A variável ponteiro endr, recebe o endereço de memória da
variável valor e não o seu conteúdo. Portanto, suponha que a variável valor esteja no
endereço 1.000 na memória. Após a atribuição, a variável endr receberá o valor 1.000
e não o conteúdo da variável valor.
O operador * é o complemento de &. Devolve o valor da variável localizada no
endereço. Exemplo:

main() {
int *end_cont, cont, valor;
cont = 256; // Atribui a constante 256 à variável cont
end_cont = &cont; // Atribui o endereço de cont à variável end_cont
valor = *end-cont; // Atribui o valor contido na variável end_cont
}

O endereço contido em end_cont é o endereço da variável cont e o conteúdo


que a variável valor recebe, nada mais é que o valor contido em cont.
Podemos atribuir um valor de uma variável ponteiro para outra variável
ponteiro:

main(){
int *p1,*p2, val;
val = 200;
p1 = &val;
p2 = p1;
}

11.2 Aritmética com ponteiros


Pode-se usar apenas duas operações aritméticas com ponteiros: + e -. Exemplo:
suponha que p seja uma variável ponteiro do tipo inteiro com valor 1000. Após a
expressão p1 = p1+1, o conteúdo de p1 será 1002 e não 1001, pois cada vez que o
valor de p1 é incrementado, ele aponta para o próximo inteiro. O mesmo vale para
decrementos. Portanto, toda vez que um ponteiro é incrementado, ele aponta para o
próximo elemento de seu tipo base. Exemplo:

11.3 Ponteiros e vetores


Existe um relacionamento muito próximo entre ponteiros e vetores. Exemplo:

main(){
char str[100], *s;
s = str;
}
Algoritmos e Linguagem de Programação
68

O ponteiro s, recebe o endereço do primeiro elemento do vetor str. Em C, o


nome do vetor sem índice é o endereço do primeiro elemento do vetor. Em outras
palavras, o nome do vetor é um ponteiro para este vetor. Do exemplo acima, para
acessar o 4º elemento do vetor poderia escrever de duas formas: str[3] ou *(p+3).

11.4 Passando vetores e matrizes para dentro de uma função em C


Quando se usa um vetor ou matriz como argumento de uma função, é passado
apenas o endereço do vetor ( lembrando que o nome de um vetor é o próprio endereço
) e não todos os elementos do vetor. Existe três formas de declarar o parâmetro que
irá receber uma matriz:

1. Declarando-o como matriz. Exemplo:


main(){
int t[10],i;
for (i=0;i<10;i++)
t[i] = i;
impr(t);
}
impr(int vet[10]){
int i;
for (i=0;i<10;i++)
printf(“%d”, vet[i]);
}
Embora vet seja declarado como um vetor de 10 elementos inteiros, C converte
vet para um ponteiro inteiro, porque nenhum parâmetro pode receber toda a matriz.

2. Especificando como um vetor ou matriz sem tamanho. Exemplo:


impr(int vet[]){
int i;
for (i=0;i<10;i++)
printf(“%d”, vet[i]);
}

3. Forma de ponteiro. Exemplo:


impr(int *vet){
int i;
for (i=0;i<10;i++)
printf(“%d”, *(vet+i));}
Retornado ponteiros em funções
Para construir uma função que retorne um ponteiro de qualquer tipo, o tipo base
da função deve ser um ponteiro. Exemplo de declaração de uma função que retorna
um ponteiro para char.
char * mat(void);
Para retornar um vetor ou matriz de uma função, deve declará-la como sendo
um ponteiro do mesmo tipo do vetor.
Algoritmos e Linguagem de Programação
69

12. Arquivos

Um arquivo é uma coleção de bytes armazenados permanentemente em algum


dispositivo de memória secundária como disquete, winchester, fita magnética, cd-
rom, etc.
Todo arquivo contém um único nome, através do qual o referenciamos.
Consiste em um conjunto de componentes arranjados em forma de sequência, onde
cada elemento só pode ser acessado após a leitura sucessiva de todos os elementos
anteriores, a partir do primeiro. Uma sequência é um arranjo (vetor) de elementos de
forma que eles mantenham entre si uma relação de posição.
Pode-se fazer uma analogia do arquivo com uma fita cassete contendo várias
músicas. Cada música é um elemento do arquivo. Para ouvir a segunda música, tem
necessariamente que passar pela primeira, mesmo que não queira escutá-la. Da
mesma forma é com arquivos. Se quiser acessar o segundo elemento, tem que passar
pelo primeiro.
Todo arquivo tem uma marca especial para indicar o seu fim. (Fim de Arquivo -
EOF).
Como exemplo, temos um cadastro de todos os funcionários de uma empresa.
De tempos em tempos, o número de funcionário pode variar. Portanto, um arquivo
um número de elementos variáveis. Outros exemplos seriam, a descrição dos
materiais em estoque, de candidatos a vestibular, de alunos de um curso, etc.

12.1 Operações com Arquivos em Disco em C


C possui uma biblioteca de funções para trabalhar com arquivos.

12.1.1 Leitura e Gravação em Alto Nível


Existe 4 modos para acessar arquivos em C:
1. Os dados são lidos e escritos caracter por caracter.
2. São lidos e escritos como uma cadeia de caracteres, ou seja, um conjunto de
bytes
3. São lidos e escritos no modo formatado
4. No formato registro. É um grupo de dados de tamanho fixo. É usado para
armazenar dados com elementos similares como vetores, registros, matrizes.

12.1.2 Arquivos Texto e Binário


Se refere a forma como um arquivo será aberto: no modo texto ou binário. Um
arquivo no modo texto é interpretado como um conjunto de caracteres agrupados por
linha. cada linha é separada pelo caracter nova linha ou LF ( código ASCII 10 ). Ao
final. possui uma indicação de fim de arquivo. Um arquivo no modo binário se difere
do modo texto, em dois aspectos: não possui a indicação de fim de arquivo e um
número é armazenado no arquivo do tipo texto, como uma sequência de caracteres,
enquanto que no modo binário, são guardados como estão na memória.

12.1.3 Abrindo um Arquivo em Disco


Para usarmos um arquivo em disco, o sistema operacional e o programa devem
conter as mesmas informações a respeito do arquivo. Primeiramente, deve-se declarar
um ponteiro do tipo FILE.
Algoritmos e Linguagem de Programação
70

FILE *fp;

Para abrir um arquivo em disco, utiliza-se a função fopen(). Esta função retorna
um ponteiro do tipo FILE que aponta para a localização na memória da estrutura
FILE. Forma de declaração:

ponteiro_para_FILE = fopen(“nome_do_arquivo”, “modo_de_operação”);

Exemplo:
fp = fopen(“func.dat”, “w”);
func.dat é o nome do arquivo que será manipulado. As informações sobre o
arquivo serão armazenadas na variável fp. A string “w”, informa o tipo de abertura,
que é para a gravação de dados no arquivo. Existe outros tipos de abertura:
- “r” Abrir um arquivo do tipo texto para leitura. O arquivo deve existir em
disco.
- “a” Abrir um arquivo texto para a gravação. Os dados serão adicionados no
final do arquivo existente. Se o arquivo não existir em disco, este é então criado.
- “w” Abrir um arquivo texto para a gravação. Se arquivo existir, ele será
destruído e novamente criado. O conteúdo anteriormente armazenado será destruído.
Se o arquivo não existir, ele será criado.
“r+” Abrir um arquivo texto para leitura e gravação. O arquivo deve existir e
pode ser atualizado
“a+” Abrir um arquivo texto para atualizações e para adicionar novos dados no
arquivo existente. Se não existir, cria-se um novo arquivo.
“rb” Abrir um arquivo no modo binário para a leitura.
“wb” Abrir um arquivo binário para a gravação
“ab” Abrir um arquivo binário para a gravação de novos dados
Outros modos: “rb+”, “wb+” “ab+”.

12.1.4 Escrevendo em um arquivo


Após a função fopen(), pode-se escrever dados em um arquivo. Para escrever
um único caracter utiliza-se a função putc() (similar à putchar() que escreve um
caracter no console). Forma:
putc( caracter, ponteiro_para_file );

12.1.5 Fechando um arquivo


Após a manipulação do arquivo, deve-se fechá-lo. Em C, para fechar um
arquivo, usa-se a função fclose(). Forma:
fclose( ponteiro_para_FILE );
Quando envia um caracter para ser armazenado em um arquivo, este é
armazenado temporariamente em um buffer ( área de memória ), ao invés de ser
escrito no disco imediatamente. Quando o buffer estiver totalmente preenchido, o seu
conteúdo é copiado de uma vez no arquivo.

Exemplo: O programa a seguir, lê um caracter e armazena-o no arquivo, até que


seja digitado o caracter <ENTER>.

#include<stdio.h>
Algoritmos e Linguagem de Programação
71

main(){
FILE *p;
char c;
p = fopen(“arq”, “w”); //Abrir o arquivo arq
do {
printf("\nEntre com um caracter: ");
c= getche();
putc(c, p); // Armazena o caracter
} while (c != ‘\r’);
fclose(p); // Fecha o arquivo
} // término da função main()

12.1.6 Lendo Dados de um Arquivo


Para ler dados de um arquivo, deve-se abri-lo com o modo de operação “r”,
indicando leitura do arquivo. Para ler um único caracter, usa-se a função getc(). A
forma de uso desta função é:
getc( ponteiro_para_FILE );

O exemplo de programa a seguir lê um caracter por vez, em um arquivo.

#include<stdio.h>

main(){
FILE *p;
char ch;
p = fopen(“arq”, “r”); //Abrir o arquivo arq
while((ch=getc(p)) != EOF )
printf("Caracter: %c\n”, ch );
fclose(p); // Fecha o arquivo
} // término da função main()

Obs: O arquivo arq deve existir em disco, caso contrário, o programa dará erro
em tempo de execução. É importante verificar se a arquivo em disco pode ser
acessado antes de fazermos operações de leitura e escrita, para evitar erros. Se não
houver espaço em disco para armazenar valores em um arquivo, também ocorrerá
erros em tempo de execução.

Caso o arquivo não possa ser aberto ou criado, a função fopen() retorna um
valor nulo (NULL). O trecho a seguir ilustra a abertura de um arquivo testando antes
de acessá-lo.

if ((p = fopen(“arq”, “r”)) = = NULL){


printf(“Arquivo não pode ser aberto”);
exit();
else{
.
.
.
}
Algoritmos e Linguagem de Programação
72

12.1.7 Fim de Arquivo


Para indicar o fim de arquivo, usa-se um sinal de EOF, que é uma constante
inteira pré-definida denominada EOF. Está definida no header stdio.h e tem valor
igual a -1. A marca de fim de arquivo é enviada pelo sistema operacional e pode ser
diferente para cada sistema operacional.

12.1.8 Gravando uma cadeia de caracteres ( bytes )


Para gravar uma string por vez em um arquivo, usa-se a função fputs(). A
forma é
fputs( vetor_de_caracteres, ponteiro_para_FILE );

Exemplo:
#include <stdio.h>
#include <string.h>

main() {
FILE *fp;
char str[50];

fp = fopen(“arq”, “w”);
do {
printf(“\n Entre com o nome: “);
gets(str); // le uma string do teclado
fputs(str, fp); // grava a string lida
fputs(“\n”, fp); // grava o caracter para pula uma linha
} while (strlen(str) != 0 ); // fica lendo enquanto não digitar <ENTER>
fclose(fp);
} // end main()

A função fputs() não coloca o caracter de nova linha ( ‘\n’ ) ao final de cada
linha.

12.1.9 Lendo uma cadeia de caracteres ( bytes ) em um arquivo


Para ler uma cadeia de caracteres por vez de um arquivo, usa-se a função
fgets(). A forma geral desta função é:
fgets( vetor_de_caracteres, número_caracteres, ponteiro_para_FILE );

Esta função possui três parâmetros: onde será armazenado o conjunto de


caracteres lidos do vetor; um número que indica quantos caracteres, no máximo, serão
lidos e um ponteiro para o arquivo a cada vez. O tamanho do vetor deve ser no
mínimo um caracter a mais que o número de caracteres a serem lidos do arquivo por
vez
Exemplo: programa que le uma string e a imprime na tela.

#include <stdio.h>
#include <string.h>
Algoritmos e Linguagem de Programação
73

main() {
FILE *fp;
char str[50];

fp = fopen(“arq”, “r”);
while(fgets(str, 49, fp) != NULL )
printf(“str: %s\n” ,str);
fclose(fp);
} // end main()

A função fgets() termina a leitura após ler um caracter de nova linha (‘\n’) ou
um caracter de fim de arquivo.

12.1.9.1 Enviando uma string para a impressora


Para enviar uma cadeia de caracteres para a impressora, utilizamos a função
fputs. A forma geral é mostrada a seguir.
fputs(vetor_de_caracteres, strprn);
Onde strprn é o dispositivo padrão para a impressão (impressora paralela).

12.1.10 Gravando um arquivo de forma Formatada


Para gravar dados formatados em um arquivo em disco, usa-se a função
fprintf(). A forma geral desta função é dada por:
fprintf( ponteiro_para_FILE, string_de_formatação, lista_de_variáveis
);

Exemplo:

fprintf(p, “%s %d %f %c”, nome, depto, salario, carac);

Similar à função printf() onde, para cada valor a ser impresso, deve-se ter um
código de formatação correspondente ao tipo. Todos os formatos de printf() operam
com fprintf().

12.1.11 Lendo um arquivo Formatado


A função usada para ler dados formatados em um arquivo em disco é scanf(). É
similar à scanf() exceto que deve ser incluído um ponteiro para FILE. Forma geral:
fscanf(ponteiro_para_file, “string de formatação”, endereços de variáveis);

Exemplo:
#include <stdio.h>
main(){
FILE *fp;
char nome[31];
int depto;
float sal;
fp = fopen(“arq”, “r”)
while (fscanf(fp,”%s %d %f”, nome, &depto, &sal) != EOF)
printf(“%s %d %f\n”, nome, depto, sal);
Algoritmos e Linguagem de Programação
74

fclose(fp);
} // end main()

12.1.12 Lendo e Gravando Registros em um Arquivo


O modo registro, grava número em arquivos no formato binário; isto é, inteiro
são gravados em dois bytes, real em 4 ou 8 bytes, caracter em 1, etc.
Permite gravar qualquer quantidade de dados de uma única vez. Vetores,
matrizes, estruturas e matrizes de estruturas pode ser gravadas com uma única
instrução.

12.1.12.1 Gravando estruturas


Usa-se a função fwrite(). Esta função tem quatro parâmetros. O primeiro é um
ponteiro do tipo void que aponta para a localização de memória do dado a ser
armazenado. O segundo, é um número inteiro que indica o tamanho do tipo de dado a
ser armazenado. Pode-se usar o operador sizeof() que retorna o tamanho de uma
estrutura de dados. O terceiro é um número inteiro que informa quantos itens do
mesmo tipo serão gravados. O quarto é um ponteiro para FILE. Os dados são
gravados no modo binário.
O exemplo a seguir ilustra o uso da função fwrite para armazenar um registro.

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

void main(){

struct func{
char nome[40];
int depto;
float sal;
} f;
FILE *fp;
fp = fopen( “arq”, “wb”);
do {
printf(“entre com o nome: “);
gets(f.nome);
printf(“entre com o depto: “);
scanf(“%d”, &f.depto);
printf(“salario: “);
scanf(“%f”, &f.sal);
fwrite(&f,sizeof(f),1,fp);
printf(“Adiciona outro: (S/N)? “);
} while(getch() = = ‘s’);
fclose(fp);
} //end main()
Algoritmos e Linguagem de Programação
75

12.1.13 Gravando vetores


Pode-se gravar um vetor de números de uma só vez. Como exemplo:
float v[10];
fwrite(v, sizeof(v),1,fp);

12.1.14 Lendo estruturas de um arquivo


Para ler uma estrutura a partir de um arquivo, usa-se a função fread(). Como
fwrite(), possui quatro parâmetros. O primeiro é um ponteiro para void para a
localização de memória onde serão armazenados os dados lidos do arquivo. O
segundo indica quantos bytes serão lidos do arquivo. O terceiro, informa a quantidade
de elementos a serem lidos a cada vez e o quarto é um ponteiro FILE do arquivo de
onde os dados serão lidos. A função fread(), retorna o número de itens lidos. Este
número é igual ao terceiro argumento. Se for encontrado o fim de arquivo, a função
fread() retorna 0. O arquivo deve ser aberto no modo binário ( “rb”)
uma vez que os dados estão armazenados no modo binário.
Exemplo:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
void main(){
struct func{
char nome[40];
int depto;
float sal;
} f[50];
FILE *fp;
int i=0;
fp = fopen("arq","rb");
while(fread(&f[i], sizeof(f[i]),1,fp) == 1){
printf("%s %d %f\n", f[i].nome, f[i].depto,f[i].sal);
printf("alo\n");
i++;
} //end while()
fclose(fp);
} //end main()
Algoritmos e Linguagem de Programação
76

Referências Bibliográficas
Tremblay J.P.,Bunt R.B. Ciência dos Computadores: Uma Abordagem
Algorítmica. McGraw-Hill.
Forbellone, A.L.V & Eberspächer, H.F. Lógica de Programação - A
Construção de Algoritmos e Estrutura de Dados. Makron Books, 1993.
Mizrahi, Victorine Viviane. Treinamento em Linguagem C - Módulo 1. Editora
McGraw-Hill, 1990.
Mizrahi, Victorine Viviane. Treinamento em Linguagem C - Módulo 2.. Editora
McGraw-Hill, 1990
Schildt, Herbert. Turbo C - Guia do Usuário. McGraw-Hill.
Schildt, Herbert. Turbo C Avançado - Guia do Usuário. McGraw-Hill.

You might also like