Você está na página 1de 135

Algoritmo e Lógica de Programação

ALGORITMO E LÓGICA
DE PROGRAMAÇÃO

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 1
Algoritmo e Lógica de Programação

GRUPO A Faculdade Multivix está presente de norte a sul


do Estado do Espírito Santo, com unidades em
MULTIVIX Cachoeiro de Itapemirim, Cariacica, Castelo, Nova
Venécia, São Mateus, Serra, Vila Velha e Vitória.
Desde 1999 atua no mercado capixaba, des-
tacando-se pela oferta de cursos de gradua-
ção, técnico, pós-graduação e extensão, com
qualidade nas quatro áreas do conhecimen-
to: Agrárias, Exatas, Humanas e Saúde, sem-
pre primando pela qualidade de seu ensino
e pela formação de profissionais com cons-
ciência cidadã para o mercado de trabalho.

Atualmente, a Multivix está entre o seleto


grupo de Instituições de Ensino Superior que
possuem conceito de excelência junto ao
Ministério da Educação (MEC). Das 2109 institui-
ções avaliadas no Brasil, apenas 15% conquistaram
notas 4 e 5, que são consideradas conceitos
de excelência em ensino.

Estes resultados acadêmicos colocam


todas as unidades da Multivix entre as
melhores do Estado do Espírito Santo e
entre as 50 melhores do país.

MISSÃO

Formar profissionais com consciência cida-


dã para o mercado de trabalho, com ele-
vado padrão de qualidade, sempre mantendo a
credibilidade, segurança e modernidade, visando
à satisfação dos clientes e colaboradores.

VISÃO

Ser uma Instituição de Ensino Superior reconheci-


da nacionalmente como referência em qualidade
educacional.

FACULDADE CAPIXABA DA SERRA/EAD


2 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

EDITORIAL
FACULDADE CAPIXABA DA SERRA • MULTIVIX

Diretor Executivo Revisão de Língua Portuguesa


Tadeu Antônio de Oliveira Penina Leandro Siqueira Lima

Diretora Acadêmica Revisão Técnica


Eliene Maria Gava Ferrão Penina Alexandra Oliveira
Alessandro Ventorin
Diretor Administrativo Financeiro Graziela Vieira Carneiro
Fernando Bom Costalonga
Design Editorial e Controle de Produção de Conteúdo
Diretor Geral Carina Sabadim Veloso
Helber Barcellos da Costa Maico Pagani Roncatto
Ednilson José Roncatto
Diretor da Educação a Distância Aline Ximenes Fragoso
Pedro Cunha Genivaldo Félix Soares

Coordenadora Acadêmica da EaD Multivix Educação a Distância


Carina Sabadim Veloso Gestão Acadêmica - Coord. Didático Pedagógico
Gestão Acadêmica - Coord. Didático Semipresencial
Conselho Editorial Gestão de Materiais Pedagógicos e Metodologia
Eliene Maria Gava Ferrão Penina (presidente Direção EaD
do Conselho Editorial) Coordenação Acadêmica EaD
Kessya Penitente Fabiano Costalonga
Carina Sabadim Veloso
Patrícia de Oliveira Penina
Roberta Caldas Simões

BIBLIOTECA MULTIVIX (Dados de publicação na fonte)

Pinto, Bruno Perche.

Algoritimo e lógica da programação / Bruno Perche Pinto, Juliane Escola (revisora). – Serra : Multivix, 2017.

Catalogação: Biblioteca Central Anisio Teixeira – Multivix Serra


2017 • Proibida a reprodução total ou parcial. Os infratores serão processados na forma da lei.

As imagens e ilustrações utilizadas nesta apostila foram obtidas no site: http://br.freepik.com

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 3
Algoritmo e Lógica de Programação

APRESENTAÇÃO Aluno (a) Multivix,

DA DIREÇÃO Estamos muito felizes por você agora fazer parte


do maior grupo educacional de Ensino Superior do

EXECUTIVA Espírito Santo e principalmente por ter escolhido a


Multivix para fazer parte da sua trajetória profissional.

A Faculdade Multivix possui unidades em Cachoei-


ro de Itapemirim, Cariacica, Castelo, Nova Venécia,
São Mateus, Serra, Vila Velha e Vitória. Desde 1999,
no mercado capixaba, destaca-se pela oferta de
cursos de graduação, pós-graduação e extensão
de qualidade nas quatro áreas do conhecimento:
Agrárias, Exatas, Humanas e Saúde, tanto na mo-
dalidade presencial quanto a distância.

Além da qualidade de ensino já comprova-


da pelo MEC, que coloca todas as unidades do
Grupo Multivix como parte do seleto grupo das
Instituições de Ensino Superior de excelência no
Brasil, contando com sete unidades do Grupo en-
tre as 100 melhores do País, a Multivix preocupa-
-se bastante com o contexto da realidade local e
com o desenvolvimento do país. E para isso, pro-
cura fazer a sua parte, investindo em projetos so-
ciais, ambientais e na promoção de oportunida-
des para os que sonham em fazer uma faculdade
de qualidade mas que precisam superar alguns
obstáculos.
Prof. Tadeu Antônio de Oliveira Penina
Diretor Executivo do Grupo Multivix Buscamos a cada dia cumprir nossa missão que é:
“Formar profissionais com consciência cidadã para o
mercado de trabalho, com elevado padrão de quali-
dade, sempre mantendo a credibilidade, segurança
e modernidade, visando à satisfação dos clientes e
colaboradores.”

Entendemos que a educação de qualidade sempre


foi a melhor resposta para um país crescer. Para a
Multivix, educar é mais que ensinar. É transformar o
mundo à sua volta.

Seja bem-vindo!

FACULDADE CAPIXABA DA SERRA/EAD


4 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

SUMÁRIO

UNIDADE 1 1 NOÇÕES DE LÓGICA DE PROGRAMAÇÃO. 13


1.1 APRESENTAÇÃO DA UNIDADE 13
1.2 CONCEITOS BÁSICOS 13
1.3 ALGORITMO 14
1.3.1 MÉTODO PARA A CONSTRUÇÃO DE ALGORITMOS 17
1.3.2 REGRAS BÁSICAS PARA A CONSTRUÇÃO DE ALGORITMOS 18
1.3.3 CARACTERÍSTICA DE UM ALGORITMO 18
1.3.4 REPRESENTAÇÕES DE UM ALGORITMO 19
1.3.5 EXEMPLOS DE ALGORITMOS 23

2
2 CONCEITOS FUNDAMENTAIS PARA CONSTRUÇÃO
UNIDADE
DE ALGORITMOS ESTRUTURADOS 26
2.1 APRESENTAÇÃO DA UNIDADE 26
2.2 ALGORITMO COM ESTRUTURA SEQUENCIAL 26
2.3 ALGORITMO COM ESTRUTURA CONDICIONAL 28
2.3.1 ESTRUTURA DE CONDIÇÃO SIMPLES: SE - ENTÃO (IF - THEN) 28
2.3.2 ESTRUTURA DE CONDIÇÃO COMPOSTA:
SE - ENTÃO - SENÃO (IF - THEN - ELSE) 29
2.3.3 ESTRUTURA DE CONDIÇÃO CASO SEJA 31
2.4 ALGORITMO COM ESTRUTURA DE REPETIÇÃO 32
2.4.1 ENQUANTO-FAÇA 33
2.4.2 FAÇA-ENQUANTO 33
2.4.3 FAÇA-PARA 34

UNIDADE 3 3 ITENS FUNDAMENTAIS. 36


3.1 APRESENTAÇÃO DA UNIDADE 36
3.2 CONSTANTES 36
3.2.1 CONSTANTE NUMÉRICA 36
3.2.2 CONSTANTE LÓGICA 38
3.2.3 CONSTANTE LITERAL 38
3.3 VARIÁVEIS 39
3.3.1 FORMAÇÃO DE IDENTIFICADORES 40
3.3.2 DECLARAÇÃO DE VARIÁVEIS 41
3.4 COMENTÁRIOS 43

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 5
Algoritmo e Lógica de Programação

3.5 EXPRESSÕES ARITMÉTICAS 44


3.6 EXPRESSÕES LÓGICAS 45
3.6.1 OPERADORES LÓGICOS 46
3.6.2 PRIORIDADE 47
3.7 COMANDOS DE ATRIBUIÇÃO 47
3.8 COMANDOS DE ENTRADA E SAÍDA 48
3.8.1 ENTRADA DE DADOS 49
3.8.2 SAÍDA DE DADOS 50

UNIDADE 4 4 CONSTRUÇÃO DE ALGORITMOS POR REFINAMENTOS SUCESSIVOS. 52


4.1 APRESENTAÇÃO DA UNIDADE 52
4.2 SUB-ROTINAS 52
4.3 ESCOPO DE VARIÁVEIS 57
4.4 PROCEDIMENTOS 58
4.5 FUNÇÕES 60
4.6 PARÂMETROS FORMAIS 62
4.6.1 PASSAGEM DE PARÂMETROS POR VALOR 63
4.6.2 PASSAGEM DE PARÂMETROS POR REFERÊNCIA 64
4.7 FUNÇÕES RECURSIVAS 65

UNIDADE 5 5 CONSTRUÇÃO DE ALGORITMOS BÁSICOS: ORDENAÇÃO INTERNA. 68


5.1 APRESENTAÇÃO DA UNIDADE 68
5.2 ORDENAÇÃO 68
5.2.1 MEMÓRIA 69
5.2.2 ORDENAÇÃO INTERNA 71

UNIDADE 6 6 CONSTRUÇÃO DE ALGORITMOS BÁSICOS: INTERCALAÇÃO,


MANIPULAÇÃO DE CARACTERES E ARRAYS 89
6.1 APRESENTAÇÃO DA UNIDADE 89
6.2 INTERCALAÇÃO BALANCEADA DE VÁRIOS CAMINHOS 89
6.3 MANIPULAÇÃO DE CARACTERES 91
6.3.1 LENDO E IMPRIMINDO STRINGS 93
6.3.2 MANIPULANDO STRINGS 96
6.4 ARRAYS 98
6.4.1 DEFINIÇÃO DE ARRANJOS 99
6.4.2 DECLARAÇÃO DE VETORES 99
6.4.3 ACESSANDO OS ELEMENTOS DE UM VETOR 100
6.5 MATRIZES 103

FACULDADE CAPIXABA DA SERRA/EAD


6 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

UNIDADE 7 7 ARQUIVOS SEQUENCIAIS E DIRETOS 107


7.1 APRESENTAÇÃO DA UNIDADE 107
7.2 ARQUIVOS 107
7.3 ORGANIZAÇÃO DE ARQUIVOS 109
7.4 DECLARAÇÃO 109
7.5 ABERTURA DE ARQUIVO 110
7.6 FECHAMENTO DE ARQUIVO 111
7.7 COPIANDO UM REGISTRO 111
7.8 GUARDANDO UM REGISTRO 112
7.9 ELIMINANDO UM REGISTRO 113
7.10 ORGANIZAÇÃO SEQUENCIAL 113
7.11 ORGANIZAÇÃO DIRETA 117

UNIDADE 8 8 DEPURAÇÃO E TESTES DE ALGORITMOS. 122


8.1 APRESENTAÇÃO DA UNIDADE 122
8.2 TESTES 122
8.3 ESTRATÉGIA DE TESTES 124
8.3.1 TESTE DE UNIDADE 125
8.3.2 TESTE DE INTEGRAÇÃO 126
8.3.3 TESTE DE SISTEMA 127
8.3.4 TESTE DE VALIDAÇÃO 128
8.4 DEPURAÇÃO 130
8.4.1 ERRO DE SINTAXE 130
8.4.2 ERRO DE SEMÂNTICA 131
8.4.3 ERRO EM TEMPO DE EXECUÇÃO 132

REFERÊNCIAS 133

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 7
Algoritmo e Lógica de Programação

ICONOGRAFIA

ATENÇÃO ATIVIDADES DE
APRENDIZAGEM
PARA SABER

SAIBA MAIS
ONDE PESQUISAR CURIOSIDADES
LEITURA COMPLEMENTAR
DICAS

GLOSSÁRIO QUESTÕES

MÍDIAS
ÁUDIOS
INTEGRADAS

ANOTAÇÕES CITAÇÕES

EXEMPLOS DOWNLOADS

FACULDADE CAPIXABA DA SERRA/EAD


8 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

UNIDADE 1

OBJETIVO
Ao final desta
unidade,
esperamos
que possa:

> Compreender os
conceitos básicos
da Administração
de Pessoal.

> Familiarizar-se com


o tema e promover
melhor absorção do
conteúdo.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 9
Algoritmo e Lógica de Programação

APRESENTAÇÃO
Olá, acadêmico (a).

Bem-vindo (a) à disciplina de Algoritmo e Lógica de Programação, na qual estudare-


mos, para aprofundar seus conhecimentos sobre os principais conceitos da progra-
mação como variáveis, operadores lógicos e aritméticos, estruturas de laço e estru-
turas de decisão, algoritmos de ordenação e intercalação e terá a oportunidade de
aplicar esses conceitos na prática, criando alguns algoritmos.

Para que seu estudo se torne proveitoso e prazeroso, esta disciplina foi organizada
em 8 unidades, com temas e subtemas que, por sua vez, são subdivididos em seções
(tópicos), atendendo aos objetivos do processo de ensino-aprendizagem.

De forma geral na disciplina de Algoritmo e Lógica de Programação, será seu primei-


ro passo no aprendizado da programação de computadores. Pois é nela que você
aprenderá os fundamentos básicos que servirão de alicerce para todas as demais dis-
ciplinas da área de programação. Descreveremos as noções lógicas de programação.
Detalharemos os conceitos fundamentais para a construção de algoritmos estrutura-
dos. Abordaremos a construção de algoritmos por refinamentos sucessivos. Veremos
os algoritmos mais utilizados para ordenação e intercalação. Ao longo da disciplina
Algoritmo e Lógica de Programação promoveremos uma discussão partindo a con-
textualização sobre depuração e teste de algoritmos, destacando sua aplicabilidade
para assim realizar um bom curso.

Esperamos que, até o final da disciplina, você possa:

• ampliar o conhecimento sobre os princípios da programação;

• identificar os aspectos sobre refinamentos sucessivos;

• compreender sobre a sub-programação e sua importância;

• conhecer os diferentes algoritmos de ordenação;

• entender o funcionamento de testes e depuração de algoritmos.

Para tanto, fique atento (a) à leitura e acompanhamento das novas tecnologias que
vem surgindo.

FACULDADE CAPIXABA DA SERRA/EAD


10 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Antes de iniciar a leitura, gostaria que você parasse um instante para refletir sobre o
desenvolvimento de programas de computadores, parece ser complexo, não é? Não
se preocupe, até o final da disciplina, você terá respostas e, também, outras pergun-
tas formuladas.

Enfim, esperamos promover reflexões acerca do assunto e desejamos sucesso e bons


estudos!

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 11
Algoritmo e Lógica de Programação

UNIDADE 1

OBJETIVO
Ao final desta
unidade,
esperamos
que possa:

> Compreender os
conceitos da lógica
de programação e de
algoritmos;

> Por meio de


exemplos de
algoritmos aplicados
no nosso dia-a-dia
você desenvolverá
sua lógica de
programação;

> Entender as formas


mais comuns para
apresentações de
algoritmos;

FACULDADE CAPIXABA DA SERRA/EAD


12 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

1 NOÇÕES DE LÓGICA DE
PROGRAMAÇÃO.

1.1 APRESENTAÇÃO DA UNIDADE

Nesta unidade iremos conhecer o conceito de lógica de programação, essa será sua
primeira etapa no aprendizado da programação de computadores. Sendo assim, ela
é a base para o curso, pois é nela que você aprenderá os princípios básicos que lhe
darão suporte para todas as demais disciplinas desta área.

1.2 CONCEITOS BÁSICOS

Nesta disciplina, iniciaremos nossos estudos sobre Lógica de Programação. Mas, afi-
nal, qual o significado da palavra “Lógica”?

Segundo Farrer (1999), a lógica pode ser vista como a arte de pensar corretamente.
A lógica visa a colocar ordem no pensamento.

Aplicamos a lógica no dia-a-dia muitas vezes até mesmo sem percebermos. Por
exemplo:

a) Sei que água do mar está gelada

Estou querendo entrar no mar

Posso concluir então que para entrar no mar terei que suportar a água gelada.

b) Quero ganhar na Mega Sena

Tenho que fazer a aposta

Posso concluir então que para ganhar na Mega Sena, tenho que realizar a aposta.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 13
Algoritmo e Lógica de Programação

As instruções são um conjunto de regras ou normas definidas para a realização ou


emprego de algo. Em informática, é o que indica a um computador uma ação ele-
mentar a executar.

Agora que entendemos o conceito de lógica e instruções, podemos definir que a lógi-
ca de programação é a técnica de encadear pensamentos para atingir determinado
objetivo.

1.3 ALGORITMO

O principal objetivo do estudo da lógica de programação é a construção de algorit-


mos que serão transformados em programas de computadores, afinal, o que é um
algoritmo?

Podemos pensar no algoritmo como uma receita de um bolo, uma sequência de ins-
truções que com uma meta específica. Estas etapas devem ser claras e precisas, não
podem ser redundantes nem subjetivas na sua definição.

Segundo Forbellone (2005), o algoritmo trata-se de uma sequência de passos que de-
vem ser seguidos para atingir um determinado objetivo. O algoritmo não é a solução
do problema e sim o caminho para a solução do mesmo. O conceito de algoritmo
não se aplica apenas na área da computação, ele define os passos necessários para
realizar uma tarefa ou solucionar um problema, independente da área de atuação.

Analisando as definições anteriores, podemos observar que executamos no dia-a-dia


vários algoritmos como a leitura de um manual de aparelho eletrônico, uma receita
de bolo de laranja, veja um exemplo de algoritmo na sequência.

Problema: Sacar um dinheiro no caixa rápido.

Sequência de Passos para Solução:

Passo 1 – Ir até o banco 24 horas;

Passo 2 – Colocar o cartão;

Passo 3 – Digitar a senha;

FACULDADE CAPIXABA DA SERRA/EAD


14 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Passo 4 – Escolher a opção de saque;

Passo 5 – Solicitar a quantia desejada;

Passo 6 – Se o saldo for maior que a quantia desejada, sacar; caso contrário, mostrar
mensagem de impossibilidade do saque;

Passo 7 – Finalizar ação

Passo 8 – Retirar o cartão

Passo 9 – Sair do banco 24 horas;

Esta solução é apenas uma das muitas soluções possíveis para o problema apresenta-
do. Assim, ao criarmos um algoritmo, indicamos uma dentre várias possíveis sequên-
cias de passos para solucionar o problema.

Por exemplo, o problema acima poderia ser resolvido mesmo se alterássemos a se-
quência de passos para:

Passo 1 – Ir até o banco 24 horas;

Passo 2 – Verificar se não tem nenhum estranho lhe observando;

Passo 3 – Pegar a carteira;

Passo 4 – Escolher o cartão a ser utilizado;

Passo 5 – Colocar o cartão;

Passo 6 – Digitar a senha;

Passo 7 – Verificar o saldo;

Passo 8 – Escolher a opção de saque;

Passo 9 – Solicitar a quantia desejada;

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 15
Algoritmo e Lógica de Programação

Passo 10 – Se o saldo for maior que a quantia desejada, sacar; caso contrário, mostrar
mensagem de impossibilidade do saque;

Passo 11 – Finalizar ação

Passo 12 – Retirar o cartão

Passo 13 – Sair do banco 24 horas;

Agora considere o seguinte problema. Suponha que você dispõe de duas vasilhas de
nove e quatro litros respectivamente. Como elas não possuem marcação, não é possí-
vel ter medidas intermediárias sobre o volume ocupado. O problema consiste, então,
em elaborar uma sequência de passos, por meio da utilização das vasilhas de nove e
quatro litros, a fim de encher uma terceira vasilha com seis litros de água. A figura 1
abaixo, ilustra dois possíveis passos de um algoritmo para resolver o problema.

Figura 1. Ilustra dois passos possíveis envolvendo as operações de encher e esvaziar as vasilhas. Em (a) apenas a primeira vasilha está
cheia. Já em (b) os nove litros da primeira vasilha são colocados nas outras duas.

FACULDADE CAPIXABA DA SERRA/EAD


16 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Uma solução para o problema pode ser alcançada a partir do seguinte algoritmo:

ALGORITMO PARA ENCHER VASILHAS

1. Encha a vasilha de nove litros.

2. Usando a vasilha de nove litros, encha a de quatro.

3. Coloque a quantidade que sobrou (cinco litros) na terceira vasilha (v3 = 5).

4. Esvazie a vasilha de quatro litros.

5. Encha novamente a vasilha de nove litros.

6. Usando a vasilha de nove litros, encha a de quatro.

7. Esvazie a de quatro litros.

8. Usando a sobra da de nove litros (cinco litros), encha novamente a de quatro litros.

9. Coloque a sobra da de nove litros (agora um litro) na terceira vasilha (v3=5+1= 6).

1.3.1 MÉTODO PARA A CONSTRUÇÃO DE ALGORITMOS

Para a construção de qualquer tipo de algoritmo precisamos descrever a sequência


de instruções, de maneira simples e objetiva. Para isso utilizaremos algumas técnicas:

• Compreender o problema ser resolvido:

- Por exemplo, o nosso problema pode ser a multiplicação de dois números


inteiros;

• Identificarmos e definirmos os dados de entrada:

- Para multiplicação de dois números é necessário um primeiro número inteiro 1


(num1) e outro número inteiro 2 (num2);

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 17
Algoritmo e Lógica de Programação

• Descrever detalhadamente cada passo para processar ou transformar os da-


dos de entrada para chegar ao objetivo do problema;

- Depois da identificação dos dados de entrada, agora é definir como será o pro-
cessamento da multiplicação de num1 com num2;

• Identificarmos e definirmos os dados de saída (objetivo do problema):

- Após o processamento, teremos que ter o resultado de saída que é a multipli-


cação de num1 com num2;

• Construirmos o algoritmo que representa a descrição dos passos;

- Transcrição do algoritmo para representar a solução do problema;

• Testarmos o algoritmo para possíveis correções que possam vir a ser necessá-
rias na lógica proposta;

- Finalmente, depois do algoritmo pronto, realizamos testes para ver se a lógica


atingiu o objetivo.

1.3.2 REGRAS BÁSICAS PARA A CONSTRUÇÃO DE


ALGORITMOS

• Usar somente um verbo na frase;

• Imaginar que você está desenvolvendo um algoritmo para pessoas que não
trabalham com informática;

• Usar frases curtas e simples;

• Ser objetivo;

1.3.3 CARACTERÍSTICA DE UM ALGORITMO

Todo algoritmo, seja ele computacional ou não, recebe uma entrada, processa-a e
gera uma saída segundo seu conjunto de passos. Todos eles possuem as seguintes
características:

FACULDADE CAPIXABA DA SERRA/EAD


18 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

1. Entrada: zero ou mais valores de entrada, estas são insumos ou quantidades


que são processadas pelos algoritmos durante a execução de seus passos;

2. Saída: pelo menos um valor é produzido, elas representam o resultado do traba-


lhado realizado pelos algoritmos;

3. Clareza ou Definição: cada passo, instrução ou etapa de um algoritmo deve ser


claro e não ambíguo;

4. Efetividade: cada passo, instrução ou etapa de um algoritmo deve ser executá-


vel de maneira exata e em um tempo finito;

5. Finitude: o algoritmo deve ter um conjunto finito de passos.

No caso do algoritmo para fazer o sanduíche, a entrada corresponde ao hambúrguer,


pão, faca, maionese, alface e o tomate. O processamento ocorre com a execução de
seus passos, gerando como saída o hambúrguer pronto. Os algoritmos computacio-
nais, especificamente, possuem as seguintes características:

1.3.4 REPRESENTAÇÕES DE UM ALGORITMO

Os três tipos mais utilizados para representar algoritmos são: descrição narrativa, flu-
xograma e pseudocódigo ou portugol, que descrevemos a seguir.

1.3.4.1 DESCRIÇÃO NARRATIVA

Consiste em analisar o enunciado do problema e escrever utilizando uma linguagem


natural (português, inglês, francês, espanhol, etc.). Sua principal desvantagem se en-
contra no fato da linguagem natural estar bem distante da linguagem utilizada pelos
computadores. Logo, a tradução de uma para a outra se torna uma atividade bastan-
te dispendiosa. Além disso, abre espaço para várias interpretações. Muitas vezes uma
palavra pode ter vários significados, dependendo do contexto no qual são utilizadas.
Em contrapartida, é bem mais fácil elaborar um algoritmo por meio de uma lingua-
gem com a qual já temos uma certa familiaridade, do que através de linguagens que
não são utilizadas com frequência no dia a dia. Não é necessário aprender nenhum

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 19
Algoritmo e Lógica de Programação

conceito novo, pois uma língua natural, neste ponto, já é bem conhecida. Os exem-
plos de algoritmos mostrados anteriormente refletem esta forma de representação.

1.3.4.2 1.4.4.2 FLUXOGRAMA

Os Fluxogramas ou Diagramas de Fluxo, são uma representação gráfica que utilizam


formas geométricas padronizadas ligadas por setas de fluxo, para indicar as diversas
ações (instruções) e decisões que devem ser seguidas para resolver o problema em
questão.

O fluxograma consiste em analisar o problema e escrever, utilizando símbolos gráficos


predefinidos (TABELA 1) os passos a serem seguidos para a resolução do problema.

Tabela 1- Símbolos utilizados em um fluxograma.

No exemplo da Figura 2, a primeira ação é executada (‘abrir forno’) e então a segunda


expressão é avaliada (‘fogo aceso?’) como verdadeira ou falsa; caso seja verdadeira, o
algoritmo prossegue para a ação à esquerda (‘botar lenha’); caso seja falsa, o algorit-
mo executa a ação à direita (‘acender fogo’). Em seguida, para qualquer um dos casos,
a próxima ação a ser executada é (‘assar pão’).

FACULDADE CAPIXABA DA SERRA/EAD


20 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Figura 2. Algoritmo representado em forma de um fluxograma.

A vantagem de se fazer uso dos fluxogramas está na facilidade de compreendê-los.


Descrições de algoritmos mediante formas gráficas são mais facilmente compreen-
didas do que descrições que envolvem apenas textos. Além do mais, os fluxogramas
possuem um padrão mundial no que se refere à sua simbologia, tornando sua utili-
zação independente das peculiaridades das linguagens naturais.

A desvantagem é que se faz necessário conhecer a simbologia do fluxograma bem


como é mais trabalhoso fazer um desenho do que escrever um texto. A problemática
é ainda maior quando é necessário fazer alguma alteração ou correção no desenho.
Além dessas desvantagens, há uma limitação no seu poder de expressão, se compa-
rado com a descrição narrativa.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 21
Algoritmo e Lógica de Programação

1.3.4.3 PSEUDOCÓDIGO OU PORTUGOL

O pseudocódigo é uma maneira intermediária entre a linguagem natural e uma lin-


guagem de programação de representar um algoritmo. Consiste em analisar o enun-
ciado do problema e escrever, por meio de regras definidas, os passos a serem segui-
dos para a resolução do problema. Ela utiliza um conjunto restrito de palavras-chave,
em geral na língua nativa do programador, que tem equivalentes nas linguagens de
programação.

A sintaxe do pseudocódigo não precisa ser seguida tão rigorosamente quanto a sin-
taxe de uma linguagem de programação, já que o algoritmo não será executado
como um programa.

Esta é a linguagem mais utilizada por ser mais formal do que a descrição narrativa
e mais fácil de manter do que um fluxograma. Além disso, essa linguagem é menos
rígida do que uma linguagem de programação, dando assim liberdade ao progra-
mador para “rascunhar” seus futuros programas sem ficar engessado na rigidez da
linguagem de programação escolhida por ele. Geralmente, essa forma de represen-
tação de algoritmos é uma versão reduzida de linguagens de alto nível como C e
Pascal. A Figura 3 apresenta um exemplo de algoritmo na forma de representação
de pseudocódigo.

Figura 3. Exemplo de Português Estruturado

A grande vantagem em se utilizar pseudocódigo está na facilidade da transcrição


do algoritmo para qualquer outra linguagem de programação é quase instantânea.
Assim como os fluxogramas, a desvantagem fica por conta da limitação do seu poder
de expressão, devido às regras impostas para a elaboração das instruções.

FACULDADE CAPIXABA DA SERRA/EAD


22 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

1.3.5 EXEMPLOS DE ALGORITMOS

Com base nos três tipos de algoritmos citados anteriormente, os exemplos a seguir mos-
tram os algoritmos para retornar o resultado da multiplicação de dois números inteiros.

Algoritmo em descrição narrativa:

• Passo 1 - Receber os dois números inteiros que serão multiplicados;

• Passo 2 - Multiplicar os dois números;

• Passo 3 - Mostrar o resultado da multiplicação;

Veja abaixo na Figura 4, o algoritmo em fluxograma:

Figura 4. Algoritmo em fluxograma

Algoritmo em pseudocódigo:

ALGORITMO

DECLARE N1, N2, M NUMÉRICO

ESCREVA “Digite dois números inteiros. ”

LEIA N1, N2

M ← N1 * N2

ESCREVA “Multiplicação = “, M

FIM ALGORITMO.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 23
Algoritmo e Lógica de Programação

Para aprofundar seus conhecimentos, recomendo a leitura do capítulo 1 do livro Tre-


inamento em Lógica de Programação, de Sandra Rita Pinto ou o capítulo 3 do livro
Técnicas de Programação - Uma Abordagem Moderna, do autor Mario Leite.

FACULDADE CAPIXABA DA SERRA/EAD


24 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

UNIDADE 2

OBJETIVO
Ao final desta
unidade,
esperamos
que possa:

> Compreender
a diferenciação
existente entre
as estruturas de
controle do fluxo de
execução;

> Estrutura sequencial;

> Estrutura de seleção;

> Estrutura de
repetição;

> Saber quando aplicar


uma determinada
estrutura de controle;

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 25
Algoritmo e Lógica de Programação

2 CONCEITOS
FUNDAMENTAIS
PARA CONSTRUÇÃO
DE ALGORITMOS
ESTRUTURADOS
2.1 APRESENTAÇÃO DA UNIDADE

Na unidade anterior aprendemos que os algoritmos são etapas a serem seguidas


para solucionar um problema. Vimos também que existem várias formas de repre-
sentação dos algoritmos. As etapas dos algoritmos são executadas na sequência em
que eles aparecem, porém, em várias situações é necessário alterar o fluxo de execu-
ção destas etapas. Pode existir a necessidade da execução de uma etapa somente
se uma determinada condição for verdadeira, ou talvez, pode ser necessário repetir
um conjunto de passos várias vezes até que uma condição seja aceita. Neste capítulo
vamos aprender sobre algumas estruturas de controles existentes de algoritmos.

2.2 ALGORITMO COM ESTRUTURA SEQUENCIAL

Os algoritmos dos exemplos que vimos até agora apresentam uma sequência de
passos que devem ser seguidos para atingir um objetivo final. Observe que, para o
atingimento do objetivo, todos os passos dos algoritmos devem ser executados sem
nenhuma alteração no seu fluxo, a não ser, claro, que exista alguma instrução explíci-
ta para a mudança do fluxo.

Trata-se de um conjunto de comandos que são executados numa sequência linear,


de cima para baixo, na mesma ordem que aparecem. A Figura 5 ilustra o modelo
básico para a escrita de algoritmos que será utilizado para escrever algoritmos. Como
boas práticas acadêmicas, todo algoritmo deverá ter a identificação do bloco, colo-
cando o início e o fim do trecho e dentro deles iniciamos com a declaração das variá-
veis e depois colocamos o corpo do algoritmo.

FACULDADE CAPIXABA DA SERRA/EAD


26 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Figura 5. Modelo básico de algoritmo.

A Figura 6 evidencia o algoritmo que recebe 4 notas de um aluno e calcula a média


aritmética e depois imprime a nota do mesmo.

Figura 6. Algoritmo de média aritmética

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 27
Algoritmo e Lógica de Programação

2.3 ALGORITMO COM ESTRUTURA CONDICIONAL

Também conhecido como algoritmo com estrutura de seleção ou de decisão. A exe-


cução de alguns passos neste tipo de algoritmo pode depender de decisões a serem
tomadas. Dessa forma, algum fato indicará se um ou mais passos do algoritmo serão
executados ou não.

Por exemplo, considere que precisamos escrever um algoritmo que calcule um au-
mento salarial de 10% para todos os funcionários que ganham até R$ 2.500,00 reais.
Para esse problema sabemos que precisamos avaliar o salário de cada funcionário.
Neste caso, para um intervalo de valores de até R$ 2.500,00 o algoritmo executa um
conjunto de ações e para outro intervalo executa um outro conjunto de ações. Para
este tipo de situação, em que um determinado valor é avaliado para executar alguma
determinada ação, utilizamos as estruturas de condição.

Podemos ter três tipos de estrutura de condição: condição simples, condição com-
posta e condição múltipla. Vamos ver adiante estes três tipos.

2.3.1 ESTRUTURA DE CONDIÇÃO SIMPLES: SE - ENTÃO


(IF - THEN)

A estrutura de condição mais simples é a se-então, utilizada da seguinte forma:

se <expressão-lógica> então:

<bloco de comandos>

fim-se

Uma expressão (<expressão-lógica>) deve ter como resultado apenas dois valores pos-
síveis: verdadeiro ou falso. A instrução (<bloco de comandos>) só será executada se a
condição tiver o valor verdadeiro. Caso seja falso, a execução do programa ignora o
bloco de comando e continua na linha seguinte à estrutura de condição.

Imagine um algoritmo que determine se o aluno estará aprovado se sua média for
maior ou igual a 5.0 pontos, veja no exemplo de algoritmo como ficaria.

FACULDADE CAPIXABA DA SERRA/EAD


28 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Se MÉDIA > 5.0 Então

Aluno Aprovado

A Figura 7, ilustra o diagrama do mesmo algoritmo que verifica se a média da nota


do aluno é maior que 5.0:

Figura 7. Diagrama do fluxo da média

Figura 8. Algoritmo da média da nota.

2.3.2 ESTRUTURA DE CONDIÇÃO COMPOSTA:


SE - ENTÃO - SENÃO (IF - THEN - ELSE)

A estrutura de condição se-então oferece a possibilidade de executarmos uma de-


terminada ação ou comando se o resultado da expressão lógica for verdadeiro e de
executarmos uma ação diferente se o resultado da expressão lógica for falso. Para
essas situações é utilizado o comando senão, como mostrado abaixo.

se <expressão-lógica> então:

<bloco de comandos verdade>

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 29
Algoritmo e Lógica de Programação

senão:

<bloco de comandos falsidade>

fim-se

A estrutura de decisão “SE/ENTÃO/SENÃO”, funciona exatamente como a estrutu-


ra “SE”, com apenas uma diferença, em “SE” somente podemos executar comandos
caso a condição seja verdadeira, diferente de “SE/SENÃO” pois sempre um comando
será executado independente da condição, ou seja, caso a condição seja “verdadeira”
o comando da condição será executado, chamado bloco-verdade, caso contrário o
comando da condição “falsa” será executado, chamado bloco-falso. Se a estrutura de
condição não possui uma cláusula “SENÃO”, então no caso da expressão lógica ser
falsa, a execução do algoritmo continua na linha subsequente ao bloco “SE/ENTÃO”.

Na Figura 9 podemos ver um exemplo de algoritmo que calcula o aumento salarial


de 2% quando o funcionário receber mais que R$ 2.500,00 reais. Quando essa condi-
ção não é atendida, o funcionário deverá receber 10% de aumento.

Figura 9. Algoritmo que calcula o aumento salarial.

Se MÉDIA >= 5.0 Então

Aluno Aprovado

Senão

Aluno Reprovado

FACULDADE CAPIXABA DA SERRA/EAD


30 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

No exemplo acima está sendo executada uma condição que, se for verdadeira, exe-
cuta o comando “APROVADO”, caso contrário executa o segundo comando “REPRO-
VADO”. Podemos também dentro de uma mesma condição testar outras condições.
Como no exemplo abaixo, na figura 10.

Figura 10. Diagrama com condições composta

2.3.3 ESTRUTURA DE CONDIÇÃO CASO SEJA

Uma outra forma de trabalhar com comandos condicionados a um determinado


valor é a estrutura caso seja. Nessa estrutura o valor de uma determinada variável é
testado e caso esse valor coincida com determinado valor pré-estabelecido um de-
terminado comando é executado. A vantagem de se utilizar este comando é a legi-
bilidade do código quando conhecemos os possíveis valores para uma determinada
variável. A estrutura de condição caso é utilizada da forma mostrada a seguir:

caso variável seja:

<bloco de comandos>

fim-se

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 31
Algoritmo e Lógica de Programação

Este tipo de estrutura condicional tem a mesma função do se-então, com a diferença
que a estrutura de condição caso oferece a opção chamada padrão. O bloco de co-
mandos dentro da opção padrão será executado caso nenhuma dos casos informados
sejam atendidos. A sua utilização é demonstrada na Figura 11, onde o algoritmo rece-
be o número inteiro correspondente ao dia da semana e mostre por extenso este dia.

Figura 11. Exemplo de algoritmo com estrutura de condição caso seja

2.4 ALGORITMO COM ESTRUTURA DE REPETIÇÃO

Utilizamos os comandos de repetição também conhecido como estruturas de intera-


ções ou estrutura de laços, quando desejamos repetir um conjunto de instruções ou
comandos até que determinado objetivo seja atingido. Todas as estruturas de repe-
tição têm em comum o fato de haver uma condição de controle, expressa através de
uma expressão lógica, que é testada em cada ciclo para determinar o momento em
que a repetição deva ser interrompida ou não.

FACULDADE CAPIXABA DA SERRA/EAD


32 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

As estruturas de repetição são basicamente três: enquanto-faça (while), faça-enquan-


to (do-while) e para-faça (for). A diferença básica entre as estruturas de repetição é
que enquanto-faça primeiro testa a condição para depois realizar o bloco de coman-
do, ao contrário de faça-enquanto que primeiro executa o bloco para depois realizar
o teste. Já na estrutura para-faça é necessário um controle para determinar quando
o laço deverá ser finalizado.

2.4.1 ENQUANTO-FAÇA

Neste caso, o bloco de operações será executado enquanto a expressão lógica (x)
for verdadeira, ou seja, antes de realizar a estrutura de repetição, uma condição x é
avaliada e caso o resultado da mesma for verdadeiro, os comandos que estão dentro
da estrutura serão executados. O teste da condição será sempre realizado antes de
qualquer operação e caso o resultado do teste de condição seja falso, o algoritmo sai
da estrutura de repetição e segue para a próxima linha.

A estrutura enquanto-faça é usada principalmente quando não se sabe com antecedên-


cia a quantidade de repetições que precisam ser realizadas. Por exemplo, suponha um
problema onde necessitamos fazer a leitura dos nomes dos funcionários de uma em-
presa. Esse processo deverá ser executado várias vezes até que a palavra “fim” seja digita-
da. Desta maneira não é possível saber quando o usuário digitará “fim” e não é possível
definir quantas vezes o algoritmo deverá repetir essa ação. Na figura 12 a seguir é apre-
sentado o formato básico da estrutura de repetição enquanto-faça de um algoritmo.

Figura 12. Algoritmo de estrutura de repetição enquanto faça

2.4.2 FAÇA-ENQUANTO

Muito conhecido também como repita-até, assim como o enquanto-faça, o coman-


do faça-enquanto também é uma estrutura de repetição. Assim como o enquanto-
-faça, o comando faça-enquanto também é uma estrutura de repetição. A principal
diferença entre eles é que, no caso do faça-enquanto, o bloco de instruções dentro do
laço é executado pelo menos uma vez, mesmo que a condição seja falsa. Isso acon-
tece porque o teste da condição é realizado apenas ao final da estrutura, ou seja, as
instruções já foram executadas. Seu formato é mostrado na Figura 13.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 33
Algoritmo e Lógica de Programação

Figura 13. Algoritmo de estrutura faça enquanto

Figura 14. Algoritmo de estrutura repita até

2.4.3 FAÇA-PARA

Esta estrutura também serve para criar um laço de repetição e geralmente é utilizado
quando conhecemos a quantidade de vezes que queremos que as instruções sejam
repetidas. Esta estrutura contém um controle para determinar quando o laço será
finalizado. A estrutura é mostrada na Figura 14 e para ser utilizada precisa das infor-
mações básicas: valores de início, fim e incremento.

Figura 15. Algoritmo de estrutura faça para

Em variável de início, geralmente um contador, recebe um valor inicial. Essa variável


será incrementada ou decrementada de acordo com a expressão definida em in-
cremento. O laço ficará executando as instruções (<bloco de comandos>) até que a
condição definida em fim seja falsa.

Para aprofundar seus conhecimentos, recomendo a leitura do capítulo 4 do livro Tre-


inamento em Linguagem C – Curso Completo – Módulo 1 de Victorine Mizrahi e do
capítulo 3 (da página 61 à 74) do livro C Completo e Total do autor Herbert Schildt.

FACULDADE CAPIXABA DA SERRA/EAD


34 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

UNIDADE 3

OBJETIVO
Ao final desta
unidade,
esperamos
que possa:

> Compreender os
conceitos de tipos
primitivos

> Entender Variáveis

> Entender como


funciona as
expressões
aritméticas, lógicas e
relacionais

> Expressões
Comandos de
entrada e saída

> Identificação dos


blocos

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 35
Algoritmo e Lógica de Programação

3 ITENS FUNDAMENTAIS.

3.1 APRESENTAÇÃO DA UNIDADE

Apresentar os tipos básicos de dados a serem adotados. Definir constantes, variáveis


e comentários explicando a sua utilização. Explicar as expressões aritméticas e lógi-
cas. Conceituar o processo de atribuição. Apresentar a importância e a aplicação dos
comandos de entrada e saída. Conceituar blocos lógicos.

3.2 CONSTANTES

Um dado é constante quando não sofre nenhuma variação no decorrer do tempo,


ou seja, seu valor é constante desde o início até o fim da execução do algoritmo.
Podemos associá-lo a uma posição de memória (endereço) que tem um conteúdo
fixo. Uma constante pode ser um número (real ou inteiro), um valor lógico ou uma se-
quência de caracteres quaisquer com algum significado para o problema em estudo.
As constantes podem ser classificadas em: numéricas, lógicas ou literais.

3.2.1 CONSTANTE NUMÉRICA

Uma constante numérica é formada por uma sequência de dígitos que:

a. pode estar ou não precedida de um sinal positivo (+) ou negativo (-);

Exemplo:

25; +3421; -315

b. pode estar ou não seguida de um ponto decimal (.) e outra sequência de dígitos;

Exemplo:

3.14; +3421; -0.53

FACULDADE CAPIXABA DA SERRA/EAD


36 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

c. pode terminar ou não pela letra E seguida de outra sequência de dígitos. Entre
a letra E e esta outra sequência de dígitos pode existir ou não sinal positivo (+)
ou negativo (-).

Exemplo:

7.8 E; -315.21E-3; 21E+3

1. Observe que:

2. não pode haver espaço em branco entre os caracteres usados para representar
uma constante numérica;

3. a separação entre a parte inteira e a parte decimal de um número é feita com o


ponto decimal (.) e não com a vírgula;

4. se existir ponto decimal numa constante numérica, pelo menos um dígito deve
preceder o ponto decimal e pelo menos outro dígito deve sucedê-lo, sendo in-
válido escrever constantes como no exemplo a seguir:

Exemplo:

6.; .13; 5.E-10

5. os dígitos que seguem a letra E indicam a potência de 10 que deve multiplicar


o número que a precede.

Exemplo:

-315.21E-3 significa -315,2110= -0,31521

Os dados numéricos podem ser de dois tipos: inteiras ou reais.

Constantes inteiras são os números positivos ou negativos e que não possuem par-
te decimal compreendidos num intervalo. Esse tipo de dado, quando armazenado
na memória do computador, ocupa 2 bytes, por isso temos 28 x 28 = 2 * 16 = 65 536
possibilidades de representação dos números inteiros. O intervalo de valores inteiros
possíveis é de -32768 até + 32767.

Constantes reais podem ser positivos ou negativos e possuem parte decimal. Esse
tipo de dados, quando armazenado na memória do computador, ocupa 4 bytes, por
isso temos, 28 x 28 x 28 x 28 = 232 possibilidades de representação dos números reais. A
faixa de valores reais possíveis é muito maior de 6 a 11 dígitos significativos com sinal.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 37
Algoritmo e Lógica de Programação

Nos números reais a parte decimal é separada da parte inteira por um .(ponto) e não
por uma , (vírgula).

Exemplos:

3; -521; 0; 30000 - constantes inteiras

3.146; -8.21; 6E24; 0.0 - constantes reais.

3.2.2 CONSTANTE LÓGICA

As duas constantes lógicas são representadas pelas palavras true (verdadeiro) e false
(falso) e são denominadas constantes booleanas. Esse tipo de dado, quando armaze-
nado na memória do computador, ocupa 1 byte, pois possui apenas duas possibili-
dades de representação.

3.2.3 CONSTANTE LITERAL

São dados formados por uma cadeia de caracteres ou por apenas um único carac-
tere. Esses caracteres podem ser os números, os caracteres especiais (&, #, @, ?, +), as
letras maiúsculas e as letras minúsculas. Esses tipos de dado, ocupa um byte para
cada caractere quando armazenado na memória do computador.

As constantes literais predefinidas na linguagem PASCAL são formadas por uma se-
quência de caracteres aceitos pela implementação da linguagem, incluindo as 26
letras latinas

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z,

os dígitos

0 1 2 3 4 5 6 7 8 9,

o espaço em branco e outros caracteres disponíveis no computador.

Num programa em PASCAL, as constantes literais são representadas pelos caracteres


correspondentes colocados entre apóstrofos simples (‘).

FACULDADE CAPIXABA DA SERRA/EAD


38 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Exemplo:

‘José da Silva’, ‘X1Y2W3, ‘Mensagem’, ‘*A!B?-’, ‘12345’, ’23/09/55’

A representação de um apóstrofo se faz com dois apóstrofos entre apóstrofos, portan-


to, com quatro apóstrofos (‘’’’).

3.3 VARIÁVEIS

Uma variável é um identificador que, como sugere o nome, tem a possibilidade de


alterar o conteúdo da variável durante a execução de um algoritmo ou programa.
Podemos associar uma variável a uma posição da memória (endereço) e poderemos
armazenar (guardar) neste endereço qualquer valor do conjunto de valores de um
tipo básico associado a ela.

Segundo Farrer (1999), a memória é utilizada para armazenar tanto as instruções dos
programas quando os dados utilizados pelos mesmos. Qualquer programa, para ser
executado, tem de estar na memória.

Uma variável pode assumir vários valores diferentes ao longo da execução do progra-
ma, mas, em um determinado momento, possui apenas um valor.

Ao escrevermos os algoritmos, necessitamos armazenar dados referentes ao proble-


ma, como o resultado de uma operação, um número ou até mesmo um nome. Para
armazenar esses dados, precisamos reservar uma área da memória do computador
para esta utilização. A forma de solicitar ao computador a reserva dessa memória é
chamada de declaração de variáveis. Veja a sintaxe da declaração:

var nome_da_variavel: tipo_da_variavel

onde:

var: Indica o início do bloco de declaração de variáveis de um algoritmo. Indepen-


dente da quantidade de variáveis a serem declaradas, a palavra var é escrita apenas
uma vez.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 39
Algoritmo e Lógica de Programação

nome_da_variavel: Para que o computador reserve o espaço de memória, temos


que informar como será referenciado essa área de memória, ou seja, qual nome será
dado a esse espaço de memória. As regras para nomear às variáveis serão abordadas
ainda nesta unidade.

tipo_da_variavel: É necessário informar o tipo de dados que será armazenado na


variável para que o computador saiba o tamanho do espaço de memória necessário
a ser reservado. Apresentado na sequência.

As variáveis e outras entidades são representadas por identificadores.

3.3.1 FORMAÇÃO DE IDENTIFICADORES

Suponhamos que, estamos desenvolvendo um algoritmo que calcule o aumento do


dissídio dos colaboradores da empresa, precisamos de variáveis para armazenar o va-
lor do salário e para os resultados dos cálculos. Assim, o nome dado à variável deve ser
intuitivo evidenciando o objetivo da mesma, as seguintes regras de formação tam-
bém devem ser seguidas:

1. Um identificador deve começar com um caractere alfabético;

2. Podem ser seguidos por mais caracteres alfabéticos ou numéricos;

3. Não é permitido o uso de espaço em branco ou de qualquer outro caractere,


que não seja letra, dígito ou underline na formação de um identificador;

4. Utilize nomes sugestivos.

A linguagem PASCAL considera as letras maiúsculas de um identificador como equi-


valente às minúsculas correspondentes.

Exemplo:

a) Identificador permitidos:

A X5

Nota A32B

Matrícula F1G3H5

Nota final LucroTotal

FACULDADE CAPIXABA DA SERRA/EAD


40 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

b) Identificadores não permitidos

5B X-Y

E(13) Nota[1]

A:B B*D

Km/H Terca-feira

Alguns identificadores possuem seu sentido prefixado na linguagem e não podem


ser utilizadas como variáveis comuns, são as denominadas palavras reservadas ou
palavras-chaves. As mais comuns são:

and end nil set

array file not then

begin for of to

case function or type

const goTo packed until

div if procedure var

do in program while

downTo label record with

else mod repeat

3.3.2 DECLARAÇÃO DE VARIÁVEIS

No ambiente computacional, os dados das variáveis são armazenados em memória.


Podemos imaginar essa memória como sendo um armário repleto de gavetas, no
qual as gavetas seriam os locais físicos responsáveis por armazenar objetos; os objetos
(que podem ser substituídos) seriam os dados e as gavetas, as variáveis.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 41
Algoritmo e Lógica de Programação

Vimos que a forma de identificar e diferenciar as variáveis (gavetas) na memória (ar-


mário) se faz por meio de identificadores (etiquetas). Cada variável (gaveta), pode
guardar apenas um dado (objeto) de cada vez, sendo sempre do mesmo tipo primi-
tivo (material).

Portanto, quando declaramos uma variável, devemos ter em mente quais valores se-
rão armazenados naquele espaço de memória. Uma variável pode ser de um dos
seguintes tipos:

• Tipo inteiro: Qualquer número inteiro, negativo, nulo ou positivo. Por exemplo,
se precisarmos de uma variável para armazenar a idade dos funcionários, o
tipo ideal para essa variável seria inteiro.

• Tipo real: Qualquer número real, ou seja, valores com ponto decimal. Esse seria
o tipo ideal para armazenar o salário dos funcionários.

• Tipo caractere: Variável do tipo literal caractere para armazenar um único ca-
ractere, que pode ser uma letra ou um símbolo. Por exemplo, para identificar
o sexo do funcionário.

• Tipo cadeia: Variável do tipo literal cadeia para armazenar uma sequencia de
caracteres, ou seja, uma palavra. Por exemplo, para armazenar o nome do fun-
cionário.

• Tipo Lógico: Variável para armazenar valores lógicos. Será sempre verdadeiro
ou falso.

Sua sintaxe é:

var

nome_variavel1, nome_variavel2 : tipo_variavel1e2

nome_variavel2 : tipo_variavel3

FACULDADE CAPIXABA DA SERRA/EAD


42 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

3.4 COMENTÁRIOS

À medida que um programa cresce, ele vai ficando cada vez mais difícil de ser lido
e consequentemente de ser entendido. Para tornar o algoritmo legível e claro, deve-
mos colocar textos que expliquem o raciocínio adotado durante seu desenvolvimen-
to para que outras pessoas, ou o próprio desenvolvedor, ao ler o programa mais tarde,
não tenhamos dificuldades em entender sua lógica. Esses textos são chamados de
comentários.

O comentário é um texto ou simplesmente uma frase, que aparece sempre delimi-


tado por chaves, podendo ser colocado em qualquer ponto do algoritmo onde se
façam necessários.

No exemplo a seguir é mostrado um conjunto de declarações onde foram introduzi-


dos comentários como o intuito de explicar o significado de cada uma das variáveis.

var mat, {número de matrícula do aluno}

nota {total de pontos obtidos no semestre letivo}

cod: {código do curso}

integer;

var nome, {nome completo do aluno}

end, {endereço do aluno}

c: {conceito final}

string;

Na linguagem de programação C, há dois tipos de comentários: os comentários de


linha e os comentários de bloco. Os comentários de linha são identificados pelo uso
de duas barras seguidas (//). Assim, quando usamos // em uma linha, tudo o que esti-
ver nessa linha depois do // são considerados comentários.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 43
Algoritmo e Lógica de Programação

Os comentários de bloco são iniciados por /* e finalizados por */. Tudo o que estiver
entre esses dois símbolos são considerados comentários. Os comentários de bloco
podem ocupar várias linhas.

Figura 16. Exemplo de algoritmo com comentários

A Figura 15 mostra a execução do programa acima. Note que o comentário só apare-


ce no código fonte, não influenciando na execução do programa.

3.5 EXPRESSÕES ARITMÉTICAS

As expressões aritméticas são escritas linearmente, usando-se a notação matemática,


com as seguintes restrições:

• O sinal de multiplicação é indicado com asterisco (*) e nunca deve ser suben-
tendido;

• A divisão é indicada com a barra (/);

• Não existe sinal para a potenciação e radiciação, devendo-se indicá-las com


combinações de produtos ou funções predefinidas;

• A prioridade entre as operações:

1ª -> * / div mod

2ª -> +-

FACULDADE CAPIXABA DA SERRA/EAD


44 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

• Div e mod são operadores que só podem ser aplicados com operandos intei-
ros dando, respectivamente, o quociente inteiro (obtido por divisão e trunca-
mento, sem arredondamento) e o resto inteiro da divisão entre operandos.

11 div 4 dá resultado 2

11 mod 4 da resultado 3

• Uma expressão que só tenha operandos inteiros e operadores *, mod, div, + e –


terá com resultado um valor inteiro. Se, pelo menos, um dos operandos for real
(o outro podendo ser inteiro) e se os operadores forem *, /, + ou -, o resultado
da expressão será real.

• O operador / sempre conduz a um resultado do tipo real, mesmo que os dois


operandos sejam inteiros.

Os parênteses servem para indicar uma sequência de cálculo da expressão aritmética


diferente da que seria indicada exclusivamente com o uso das prioridades preesta-
belecidas.

3.6 EXPRESSÕES LÓGICAS

São expressões formadas a partir do uso de variáveis e constantes, operadores relacio-


nais e operadores lógicos. As expressões lógicas são avaliadas e retornam sempre um
valor lógico: verdadeiro ou falso.

Os operadores são comuns para construirmos equações. Adotaremos por convenção


para esses operadores os seguintes símbolos apresentados na tabela 2.

Tabela 2 – Operadores e funções

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 45
Algoritmo e Lógica de Programação

O resultado obtido de uma relação é sempre um valor lógico. Por exemplo, analisan-
do a relação numérica A + B = C, o resultado será verdade ou falsidade à medida que
o valor da expressão aritmética A + B seja igual ou diferente do conteúdo da variável
C, respectivamente.

Eis algumas relações:

A <> B

Nome == “Bruno”

X=1

Com as declarações:

var x, y, z: integer;

Nome, Cor: string;

Têm-se as seguintes relações, a partir dos valores atribuídos às variáveis:

VARIÁVEIS RELAÇÕES
x y z Cor Nome X*X+Y>Z Cor = 'Azul' Nome <> 'Jose'
1 2 5 'azul' 'Paulo' false true true
4 3 1 'verde' 'Jose' true false false
1 1 2 'branco' 'Pedro' false false true
1 2 1 'azul' 'Jose' true true false

3.6.1 OPERADORES LÓGICOS

A álgebra das preposições define três conectivos usados na formação de novas pre-
posições a partir de outras já conhecidas. Esses conectivos são os operadores nas
expressões lógicas:

and para a conjunção

or para a disjunção

not para a negação

FACULDADE CAPIXABA DA SERRA/EAD


46 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Sejam as variáveis lógicas P, Q, R, S contendo, respectivamente, os valores true, false,


false, true.

O valor lógico das conjunções:

a. P and S -> true c. Q and S -> false

b. P or R -> true d. Q or R -> false

3.6.2 PRIORIDADE

Como foi mostrado anteriormente, pode-se ter mais de um operado lógico na mes-
ma expressão, além dos operadores de relação e dos operadores aritméticos. Em
PASCAL, a prioridade das operações está dada na tabela 3.

Tabela 3 – Prioridade das operações aritméticas

PRIORIDADE OPERADORES
1ª not
2ª *, /, div, mod, and
3ª +, - , or
4ª =, <>, <, <=, >=, >, in

3.7 COMANDOS DE ATRIBUIÇÃO

Um comando de atribuição permite-nos fornecer um valor a uma variável (guardar


um valor na memória), em que o tipo de dado deve ser compatível com o tipo da
variável, isto é, somente podemos atribuir um valor lógico a uma variável capaz de
comportá-lo, ou seja, uma variável declarada como sendo do tipo lógico.

O comando de atribuição possui a seguinte sintaxe:

identificador <- expressão

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 47
Algoritmo e Lógica de Programação

Onde:

identificador: é o nome da variável à qual será atribuído o valor da expressão;

<- : é denominado operador de atribuição;

expressão: é uma expressão dos tipos já estudados.

No exemplo a seguir:

lógico: A, B

inteiro: X;

A <- B;

X <- 4 + 6 div 2;

B <- 5 = 3;

X <- 2;

Nos comandos em que o valor a ser atribuído à variável é representado por uma ex-
pressão aritmética ou lógica, estas devem ser resolvidas em primeiro lugar, para que
depois o resultado possa ser armazenado na variável.

Notemos também que uma variável pode ser utilizada diversas vezes. Ao atribuirmos
um segundo valor, o primeiro valor armazenado será descartado, sendo substituído
pelo segundo.

3.8 COMANDOS DE ENTRADA E SAÍDA

Um programa de computador se torna praticamente inútil se não apresentar algum


tipo de interação com o usuário. Os algoritmos precisam de interações de dados pro-
venientes do meio externo para efetuarem operações e cálculos que são necessários
para alcançar o resultado desejado. Com essa finalidade, utilizamos os comandos de
entrada e saída.

FACULDADE CAPIXABA DA SERRA/EAD


48 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

3.8.1 ENTRADA DE DADOS

Para que o algoritmo possa receber os dados de que necessita, adotaremos o coman-
do entrada de dados denominado leia, em PASCAL read e readln, cuja finalidade é
atribuir o dado a ser referenciado à variável identificada.

No PASCAL, a diferença entre read e readln é que neste último, após a leitura dos va-
lores correspondentes à lista-de-identificadores, provoca uma mudança de linha na
unidade de entrada utilizada.

Se for feita a declaração:

var num: integer;

nota: real;

e se forem fornecidas, na unidade de entrada, diversos valores como:

01 60.05 02 88.6

03 84.04 04 54.00

cada linha dispondo de quatro valores, então quatro execuções repetidas do coman-
do readln (num, nota);

atribuirão à variável num, sucessivamente, os valores:

01 03

e a variável nota, respectivamente, os valores:

60.05 84.04

Em cada linha, os valores, além do segundo, serão ignorados.

Por outro lado, em quatro execuções repetidas do comando ao serem read(num,


nota) fornecidas as mesmas linhas, serão atribuídos à variável num, sucessivamente,
os valores:

01 02 03 04

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 49
Algoritmo e Lógica de Programação

e a variável nota, os respectivos valores:

60.05 88.6 84.04 54.00

3.8.2 SAÍDA DE DADOS

Para que o algoritmo possa mostrar os dados que calculou, como resposta ao proble-
ma que resolveu, adotaremos um comando de saída de dados denominado escreva,
cuja finalidade será apresentar o valor da variável identificada. No PACAL, os coman-
dos de saída possuem a forma write e writeln a diferença básica entre os comandos
é que no writeln após a leitura dos valores correspondentes à lista-de-identificadores,
provoca uma mudança de linha na unidade de saída utilizada.

Exemplos:

read(X); readLn (nome, n, y) write(k, soma)

Para aprofundar seus conhecimentos, recomendo a leitura do capítulo 4 (da página


33 à 44) do livro Treinamento em Lógica de Programação, de Sandra Rita Pinto ou o
capítulo 2 (da página 34 à 44) do livro Técnicas de Programação - Uma Abordagem
Moderna, do autor Mario Leite.

FACULDADE CAPIXABA DA SERRA/EAD


50 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

UNIDADE 4

OBJETIVO
Ao final desta
unidade,
esperamos
que possa:

> Identificar o problema e


pensar na solução bem
geral ou abstrata;

> Refinar até obter um


nível apropriado de
detalhamento, ou
seja, a cada passo de
refinamento a solução se
torna menos abstrata;

> Construção de sub-


rotinas ou sub-algoritmos;

> Identificação dos


contextos das sub-rotinas;

> Criação de subprogramas

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 51
Algoritmo e Lógica de Programação

4 CONSTRUÇÃO DE
ALGORITMOS POR
REFINAMENTOS
SUCESSIVOS.

4.1 APRESENTAÇÃO DA UNIDADE

Nesta unidade vamos conhecer as técnicas de refinamento sucessivos. Vamos abor-


dar os conceitos de sub-rotinas e sua aplicabilidade reduzindo a complexidade do al-
goritmo. Vamos aprender também o significado de escopo e a utilização de variáveis
bem como a comparação dos diferentes contextos de sub-rotinas e suas aplicações.

4.2 SUB-ROTINAS

A divisão de um problema em fragmentos menores é um fator determinante para a


redução da complexidade. Um dos grandes pontos positivos quanto a esta decom-
posição, está na possibilidade de concentrar as atenções em um conjunto pequeno
de cada vez, possibilitando assim uma melhor compreensão do todo.

Nos algoritmos, uma sub-rotina é um conjunto de algoritmo completo de instru-


ções, com uma função bem definida no contexto do algoritmo. O algoritmo principal,
quando necessário, realiza o desvio na execução indicando que aquele conjunto de
instruções devem ser executadas. Após a execução desta sub-rotina, o fluxo dos co-
mandos é retomado para o fluxo principal.

Em geral, não existem regras específicas para a criação das sub-rotinas, porém, al-
guns critérios devem ser analisados:

• Divisão do problema de acordo com as principais partes;

• Garantir que existem coerências nas divisões realizadas;

FACULDADE CAPIXABA DA SERRA/EAD


52 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

• Se mesmo após a divisão, o trecho ainda continuar complexo, divide-o


novamente;

• Analisar a divisão final para garantir a legibilidade e a coerência.

A técnica de refinamentos sucessivos também conhecido como Top-Down (de cima


para baixo), onde parte dos conceitos macros, ou seja, mais abstratos, até atingir o
nível de detalhamento ideal para o entendimento do problema.

Em geral, as sub-rotinas possuem os seguintes propósitos:

• organizar conjuntos de instruções que se repetem em várias partes do algo-


ritmo, possibilitando a escrita da solução uma única vez e indicar os pontos
diferentes em que ela deva ser aplicada;

• separar as instruções de forma a obter uma melhor organização do algoritmo,


possibilitando maior clareza e entendimento do algoritmo;

• testes e correções das sub-rotinas podem ser feitos em separado;

• separar as instruções que realizam tarefa simples ou complexa, de forma que


uma solução feita para um problema possa ser reaproveitado em outro, mini-
mizando esforços;

• uma sub-rotina independente pode ser utilizada em outros algoritmos que


requeiram o mesmo processamento por ele executado.

Uma sub-rotina não pode ser executado diretamente como um programa. Ele pre-
cisa ser “invocado” ou “chamado” de algum ponto do código do programa como um
todo do qual faz parte. Se durante a execução do fluxo de instruções atingir um pon-
to de invocação, ou seja, quando em um determinado ponto do algoritmo contém
o mesmo identificador utilizado na definição da sub-rotina, o fluxo de controle da
execução passa para a sub-rotina, e, ao ser concluída a execução deste subprograma,
o fluxo de controle é retomado imediatamente após o ponto de invocação do algo-
ritmo de origem.

Uma sub-rotina pode eventualmente invocar outras sub-rotina e assim sucessiva-


mente. Muitas linguagens de programação permitem também que um sub-rotina
invoque a si próprio. Nestes casos dizemos que ocorreu uma chamada recursiva.
Este assunto ainda será explanado nesta unidade.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 53
Algoritmo e Lógica de Programação

Como pode ser observado no fluxo de execução do algoritmo na Figura 16, assim
que for encontrado um identificador contendo o mesmo nome da sub-rotina, neste
exemplo, Primeiro e Segundo, o fluxo é direcionado para as respectivas sub-rotinas e
no final de cada trecho, retorna-se para o algoritmo principal.

Figura 17. Figura 16. Fluxo de execução do algoritmo

No exemplo seguinte observe as etapas do algoritmo para calcular o salário líquido


de um empregado (FIG. 17).

Figura 18. Etapas de algoritmo

O comando “determine o salário” pode ser refinado como a seguir (FIG. 18):

Figura 19. Refinamento das etapas de algoritmo

FACULDADE CAPIXABA DA SERRA/EAD


54 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Observe que no refinamento realizado acima, não foi detalhado como seria a lógica
dos cálculos de vantagens e das deduções. Estas ações serão definidas adiante em
sub-rotinas específicas, conforme a Figura 19.

Figura 20. Refinamento mais aprofundado das etapas de algoritmo

As sub-rotinas seriam (FIG. 20 e 21):

Figura 21. Sub-rotina para cálculos das vantagens

Figura 22. Sub-rotina para cálculo das deduções

A versão final do refinamento sucessivo do algoritmo ficaria da seguinte forma (FIG.


22, 23 e 24):

Figura 23. Algoritmo refinado.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 55
Algoritmo e Lógica de Programação

Figura 24. Algoritmo refinado do cálculo das vantagens.

Figura 25. Algoritmo refinado do cálculo das deduções.

Já no exemplo a seguir, o objetivo é receber o salário de um funcionário e conceder


um aumento salário de acordo com o % informado. Para solução deste problema,
uma sub-rotina foi utilizada (FIG. 25)

Figura 26. Algoritmo para cálculo salarial.

O programa principal é executado linearmente até a linha 4. Nesse ponto é chama-


do a sub-rotina cálculo, o programa principal fica aguardando o retorno da sub-roti-
na. As instruções a serem executadas neste momento é direcionada para a linha 9.
O controle retorna sua execução novamente ao programa principal apenas quando
a linha 13 é executada.

FACULDADE CAPIXABA DA SERRA/EAD


56 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

4.3 ESCOPO DE VARIÁVEIS

Quando trabalhamos com várias sub-rotinas, nos deparamos com questões relativas
à visibilidade das variáveis em diferentes partes do programa. Ou seja, se uma variável
é visível ou acessível em certas partes de um programa.

Todas as variáveis declaradas no início do algoritmo os tornam visíveis e utilizáveis em


qualquer sub-rotina integrante. Essas variáveis são denominadas globais.

Em algumas situações, as variáveis são utilizadas apenas em uma sub-rotina especí-


fica. Neste caso, não justifica uma definição global, pois a mesma deverá ser visível e
utilizada apenas dentro daquele limite de instruções lógicas. Nesta situação, a variá-
vel é declarada internamente na sub-rotina, denominada, variável local.

Para entendermos como funciona a visibilidade das variáveis, precisamos falar sobre
o escopo. O escopo ou abrangência de uma variável é a parte do programa na qual
ela é visível e pode ser acessada. A visibilidade refere-se a hierarquia, ou seja, uma va-
riável é global quando e visível e acessada por todas as sub-rotinas inferiores, e local,
quando é visível apenas em seu contexto e não nas sub-rotinas superiores.

Observe na Figura 26 as variáveis K e J definidos no início do algoritmo são visíveis, a


princípio, a todo e qualquer módulo, ou seja, são globais a todos. A variável M é local
ao módulo 3 e visível a apenas estes, assim como a variável Y é local do módulo 2.

Figura 27. Escopo de variáveis.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 57
Algoritmo e Lógica de Programação

Em outra situação temos a variável X, que é local ao módulo 1, sendo visível também
no módulo 2, podendo ser definida relativamente como global ao módulo 2.

Em uma situação bastante particular, na qual ocorre um conflito de declaração da


variável K (início do algoritmo e interior do módulo 1), assumiremos que sempre que
a variável a ser utilizada no interior do módulo será a que foi definida neste, ignoran-
do a existência de outra variável de mesmo nome no âmbito global. Temos, então,
que os módulos 1 e 2 não enxergam a mesma variável global K vista pelo módulo 3,
e sim a variável K definida localmente a 1 e globalmente a 2.

4.4 PROCEDIMENTOS

No processo de escrita de algoritmo frequentemente escrevemos instruções que


pode se repetir várias vezes ao longo da lógica. Por exemplo, se quisermos calcular a
média salarial do Centro de Tecnologia da empresa composta por dois analistas de
sistemas da equipe, temos que somar o salário do analista 1 com o salário do analista
2 e dividir por 2. Se tivermos que calcular a média salarial de outra equipe da empre-
sa, temos que repetir esse mesmo cálculo: somar os salários e dividir pela quantidade
de analistas. Inicialmente, a forma mais simples de resolver esse problema é replican-
do esse algoritmo para cada equipe.

Imagine se essa empresa possuir mais de 30 setores e decida realizar esse cálculo?
A repetição de trechos de código em um programa é considerada uma péssima prá-
tica. Imagine que após a replicação deste mesmo trecho de código para os 30 se-
tores, é identificado um erro no cálculo. A resposta para a eliminar a repetição de
código chama-se: procedimentos e funções.

É muito comum o isolamento dos códigos em procedimentos ou funções de acordo


com as instruções que se repetem em vários trechos do código. Quando precisarmos
executar estas instruções repetidas vezes, basta invocar o nome do bloco de código que
as contém. A esse bloco de código é que chamamos de procedimentos ou funções.

Depois de decompor um problema complexo em subproblemas, podemos criar um


procedimento para cada um destes problemas menores. Para delimitar um procedi-
mento, utilizaremos os delimitadores procedimento e fim_procedimento. A forma
genérica do procedimento é apresentada abaixo (FIG.27).

FACULDADE CAPIXABA DA SERRA/EAD


58 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Figura 28. Algoritmo contendo a declaração do procedimento.

O identificador é o nome dado ao procedimento, este deverá ser único e não confli-
tante com as demais declarações (como variáveis e tipos). A lista de parâmetros, que
pode ser nula ou até mesmo vazia, lista os parâmetros formais do procedimento (de-
talhados nas próximas seções). As declarações de variáveis internas correspondem a
quaisquer declarações, seja de tipos, variáveis, sub-rotinas e etc.

A sequência de ações corresponde às instruções que devem ser executadas para


completar o propósito do procedimento. Estes comandos manipulam os parâmetros
e as declarações internas para obter-se o resultado desejado. As variáveis, os tipos e
as constantes declaradas dentro de um procedimento só são acessíveis dentro dos
comandos do procedimento. São chamadas variáveis locais.

Dentro do procedimento podem ser utilizadas tanto variáveis locais quanto variáveis
globais. Todas as variáveis locais aos procedimentos são alocadas somente quando
o procedimento entra em execução, mas são liberadas quando o procedimento ter-
mina, perdendo assim, seus conteúdos. Caso seja necessário o aproveitamento dos
dados manipulados, o procedimento deverá utilizar as variáveis globais (FIG.28)

Figura 29. Algoritmo utilizando chamada de procedimentos.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 59
Algoritmo e Lógica de Programação

4.5 FUNÇÕES

Outro tipo de sub-rotina são as funções. Uma função possui o mesmo objetivo de
um procedimento, ou seja, desviar a execução do algoritmo principal para realizar
uma tarefa específica, com uma única diferença, uma function sempre retorna um
valor.

Diferente dos procedimentos, uma função não deverá simplesmente ser chamada,
mas deverá ser atribuída à alguma variável. Uma função deve ter um nome e um tipo,
e sua sintaxe é mostrada abaixo (FIG. 29)

Figura 30. Algoritmo de declaração de função.

O nome da função é quem deve assumir o valor da função, como se fosse uma variá-
vel. O tipo corresponde ao tipo do valor que será retornado. NOME é o próprio nome
dado à função. Já a lista-de-parâmetros-formais, corresponde à lista dos objetos que
serão substituídos por outros objetos, fornecidos quando da chamada da função.

Assim como nos procedimentos, uma função deve ser definida dentro do espaço
de declaração de variáveis do programa. Para que a função possa retornar um valor,
este deverá ser explicitamente atribuído ao nome da função, dentro da rotina da fun-
ção.

A diferença entre procedimentos e funções é unicamente no retorno do bloco de


código: funções retornam valores após a execução da sua lista de instruções, procedi-
mentos não. Os algoritmos a seguir resolvem o mesmo problema, com uma simples
diferença, no algoritmo da Figura 30 é utilizado procedimento, enquanto que na Fi-
gura 31 é utilizado função. O resultado dos algoritmos neste caso, é o mesmo.

FACULDADE CAPIXABA DA SERRA/EAD


60 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Figura 31. Algoritmo com procedimento somar.

Figura 32. Algoritmo com função somar.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 61
Algoritmo e Lógica de Programação

Para facilitar o entendimento, vamos ver o exemplo a seguir na Figura 32.

Figura 33. Algoritmo para calcular a média utilizando função.

Agora criamos uma função que calcula a média das notas com base nos parâmetros
recebidos, e devolve o valor da média ao invés de fazer a impressão. A função deve
ser definida usando o tipo de retorno que ela irá fornecer (no caso do exemplo, valor
de tipo real) além dos parâmetros que são opcionais. Dentro do bloco da função,
devemos usar uma instrução que indique o valor que será retornado (nas linguagens
geralmente a palavra é return para retornar um valor). Em pseudocódigo, a represen-
tação usada é de que o nome da função recebe o valor, isso quer dizer que quando
chamarmos essa função podemos atribuí-la a uma variável de tipo real, pois ela irá
conter um valor de resposta.

4.6 PARÂMETROS FORMAIS

Os parâmetros possuem a capacidade de permitir uma solução genérica para o có-


digo da sub-rotina e, no momento da chamada, é indicado o (s) argumento (s) sobre
o qual as ações serão realizadas. Estes argumentos podem ser tantos constantes ou

FACULDADE CAPIXABA DA SERRA/EAD


62 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

variáveis que serão correspondidos na sub-rotina na mesma ordem em que estão


definidos no algoritmo chamador, ou seja, o primeiro argumento corresponde ao pri-
meiro parâmetro, o segundo argumento ao segundo parâmetro e assim por diante.

Como exemplo do uso de parâmetros em um procedimento, observe a Figura 33,


que realiza a troca do valor inteiro de duas variáveis.

Figura 34. Algoritmo para troca de valores em duas variáveis.

Ao invocar a sub-rotina Troca, supondo valores 15 e 7 para os respectivos parâmetros


A e B. Após executar todas as instruções, A valerá 7 e B valerá 15, realizando assim a
troca de valores.

Uma sub-rotina comunica-se com o algoritmo chamador de duas maneiras: através


de passagem e retorno de valores ou modificando os valores que são globais à fun-
ção. Estes dois comportamentos distintos para os parâmetros refere-se a passagem
por valor ou passagem por referência.

4.6.1 PASSAGEM DE PARÂMETROS POR VALOR

Na passagem de parâmetros por valor não existe ligação entre o parâmetro e a variá-
vel usada na chamada. Esta variável poderá ser utilizada e alterada dentro da função
sem afetar a variável da qual ela foi gerada, pois esta possui sua própria área de me-
mória para armazenamento.

Ao finalizar a função chamada, todas as variáveis criadas para os parâmetros locais


deixam de existir. A passagem de parâmetro por valor é simples e geralmente é a
melhor que se encaixa nos casos. Mas em algumas situações pode ser desejável ter
uma forma de modificar variáveis externas à uma determinada sub-rotina e, para isso,
usa-se a passagem de parâmetros por referência.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 63
Algoritmo e Lógica de Programação

Como exemplo do uso da passagem de parâmetro por valor, observe o comporta-


mento do procedimento na Figura 34.

Figura 35. Algoritmo exemplificando a passagem de parâmetro por valor.

O resultado impresso será: “O valor da variável A é”: 3. Observe que na passagem de


parâmetro por valor, o valor da variável é copiado para o procedimento, garantindo
assim que o seu valor original não sofra modificações caso seja alterado dentro do
procedimento.

4.6.2 PASSAGEM DE PARÂMETROS POR REFERÊNCIA

Passagem de parâmetros por referência indica que, na sub-rotina, o parâmetro formal


é uma referência à variável utilizada no momento da chamada. O termo referência
quer dizer que o endereço de memória do parâmetro e da variável é o mesmo. A con-
sequência disso é que qualquer modificação realizada no parâmetro formal é refletida
também, na variável externa. A principal utilização de passagem por referência é ter
a possibilidade de modificar o valor das variáveis dentro de uma sub-rotina, de modo
que as alterações feitas internamente reflitam também externamente à sub-rotina.

Para diferenciar as duas formas de passagem de parâmetros, a palavra reservada VAR


é usada para indicar, para cada parâmetro individualmente, que se trata de uma
passagem por referência. Caso não exista esta indicação, então a passagem do parâ-
metro será por valor.

FACULDADE CAPIXABA DA SERRA/EAD


64 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Observe na Figura 35 o exemplo de utilização de passagem de parâmetro por refe-


rência.

Figura 36. Algoritmo exemplificando a passagem de parâmetro por referência.

O resultado impresso será: “O valor da variável A é”: 2. Observe que na passagem de


parâmetro por referência a variável não é copiada como na passagem de parâmetro
por valor e sim referenciada através de um endereço de memória, caso esta sofra
alterações dentro da função, seu valor original também será alterado.

4.7 FUNÇÕES RECURSIVAS


Uma função pode ser chamada a partir de qualquer outro ponto do algoritmo prin-
cipal como também por uma função no mesmo programa. Dessa forma, podemos
pensar em uma função chamando a si mesma. Isso é possível e útil em muitos casos.
Quando uma função f chama a si mesma em algum ponto, dizemos que f é uma fun-
ção recursiva. Recursividade se refere a um objeto auto-referente, ou seja, que referen-
cia a si próprio; isso inclui as funções recursivas, mas também outros tipos de objetos.
Um exemplo é o cálculo do fatorial de um número. O fatorial de um número inteiro po-
sitivo N (cuja notação é N!) é definido como o produto de todos os números de 1 até N:

N! = N x (N -1) x … x 2 x 1

Por exemplo, o fatorial de 3 é 3! = 3 x 2 x 1 = 6, e o fatorial de 4 é 4! = 4 x 3 x 2 x 1 = 24,


e assim por diante. Para números N maiores que 1, sempre podemos fazer a seguinte
relação:

N! = N x (N -1)!

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 65
Algoritmo e Lógica de Programação

ou seja, 4! = 4 x 3! = 4 x 6 = 24. Isso indica a estrutura recursiva do cálculo do fatorial:


o fatorial de um número N é igual a N vezes o fatorial do número anterior a N, N-1.

Seguindo essa ideia, podemos escrever uma função recursiva que calcula o valor do
fatorial de um número. Como a função chama a si mesma, é muito importante saber
quando a cadeia de chamadas da função a ela mesma termina. No caso do fatorial,
quando queremos calcular o fatorial do número 1 ou do número 0, podemos respon-
der diretamente: 1! = 0! = 1, sem usar a recursividade. Esse é o chamado caso-base
da recursão. Sem isso, a função nunca pararia de chamar a si mesmo, e o programa
seria finalizado com algum erro dependente do sistema operacional e do compilador
utilizados (FIG.36).

Figura 37. Algoritmo de cálculo fatorial recursivo.

O código calcula o fatorial de um número inteiro recursivamente. Se o número for 0


a resposta é direta: 1. Se o número for maior do que 0, a resposta é obtida pela mul-
tiplicação do número pelo fatorial do número anterior a ele. Note que esse processo
sempre termina se o parâmetro n da função fatorial for um inteiro positivo, pois em
cada chamada recursiva o argumento da função fatorial será um número menor que
o anterior, até eventualmente chegar a 1, cuja resposta é direta

O conceito de programação recursiva é considerado avançado, bastante utilizado em


programas mais complexos. Alguns paradigmas de programação como a programa-
ção funcional e a programação lógica são bastante baseadas no uso de funções re-
cursivas, e muitos processos se tornam muito mais fáceis de implementar usando
funções recursivas.

Para aprofundar seus conhecimentos, recomendo a leitura do capítulo 8 (da página


103 à 117) do livro Treinamento em Lógica de Programação, de Sandra Rita Pinto.

FACULDADE CAPIXABA DA SERRA/EAD


66 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

UNIDADE 5

OBJETIVO
Ao final desta
unidade,
esperamos
que possa:

> Entender os métodos


de ordenação interna
mais importantes sob o
ponto de vista prático;

> Compreender um
conjunto amplo
de algoritmos para
realizar a mesma
tarefa, cada um deles
com uma vantagem
particular sobre os
outros, dependendo da
aplicação.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 67
Algoritmo e Lógica de Programação

5 CONSTRUÇÃO DE
ALGORITMOS BÁSICOS:
ORDENAÇÃO INTERNA.

5.1 APRESENTAÇÃO DA UNIDADE

Nesta unidade vamos conhecer alguns algoritmos de ordenação interna. Vamos


aprender sobre quando escolher um determinado algoritmo para realizar a ordena-
ção em que será avaliado sua eficiência e desempenho.

5.2 ORDENAÇÃO

As várias técnicas de ordenação existentes permitem uma coleção de algoritmos dis-


tintos para resolver uma mesma atividade. Dependendo da sua aplicação, cada um
deste algoritmo possui uma vantagem específica sobre os demais algoritmos.

Segundo Ziviani (2005), ordenar corresponde aos processos de rearranjar um conjun-


to de objetos em uma ordem ascendente ou descendente. O objetivo principal da
ordenação é facilitar a recuperação posterior de itens do conjunto ordenado. Imagine
a dificuldade que seria recuperar os contatos do telefone se a agenda não estivesse
em ordem alfabética.

Os algoritmos trabalham sobre os registros de um arquivo. Apenas uma parte do re-


gistro, chamada chave, é utilizada para controlar a ordenação. Além da chave, podem
existir outros componentes em um registro, os quais não tem influência no processo
de ordenar, a não ser pelo fato de que permanecem com a mesma chave.

Quando no processo de ordenação a ordem relativa dos itens com chaves iguais
mantém-se inalterada pelo processo de ordenação, é dito um método de ordenação
estável. Por exemplo, se uma lista alfabética de nomes de alunos de turma é ordena-
da pelo campo nota, então um método estável produz uma lista em que os alunos

FACULDADE CAPIXABA DA SERRA/EAD


68 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

com a mesma nota aparecem em ordem alfabética. Alguns dos métodos de ordena-
ção mais eficientes não são estáveis.

Os métodos de ordenação são classificados em dois grandes grupos: a ordenação


internar e a externa. Se o arquivo a ser ordenado cabe na sua totalidade na memória
interna (principal) do computador, então o método de ordenação é chamado de
ordenação interna. Sendo assim, o número de registros a ser ordenado é pequeno o
bastante para caber em um array do pascal, por exemplo. Se o arquivo a ser ordenado
não cabe na memória principal e, por isso, tem que ser armazenado em fita ou disco,
então o método de ordenação é chamado de ordenação externa. A principal dife-
rença entre os dois métodos é que, em um método de ordenação interna, qualquer
registro pode ser imediatamente acessado, enquanto em um método de ordenação

externa, os registros são acessados sequencialmente ou em grandes blocos.

5.2.1 MEMÓRIA

A memória é um dispositivo que permite ao computador armazenar dados de forma


temporária ou permanente. Segundo Tanenbaum (2007), a memória é a parte do
computador onde os programas e os dados são armazenados. Todo computador é
composto por uma quantidade de memória (que pode variar de máquina para má-
quina).

Existem vários tipos de memórias para que o computador tenha o seu funcionamen-
to adequado onde estas apresentam diferentes características devido às diferentes
tecnologias utilizadas em suas fabricações. Nos próximos tópicos são apresentados os
dois tipos mais comuns de memórias: a principal e a secundária.

5.2.1.1 MEMÓRIA PRINCIPAL

A memória principal, ou memória de trabalho, é onde normalmente devem estar ar-


mazenados os programas e dados a serem manipulados pelo processador. É um tipo
de memória indispensável para o funcionamento do computador, à qual o proces-
sador pode fazer acesso direto. Além de alocar os dados e instruções de programas a
serem manipulados pelo processador, esse tipo de memória dá acesso às memórias

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 69
Algoritmo e Lógica de Programação

secundárias, de forma a disponibilizar dados ao processador. Geralmente é esta me-


mória que se referenciada na especificação de um microcomputador.

Fávero (2011), afirma que a memória principal é denominada memória RAM (Ran-
dom Access Memory), corresponde a um tipo de memória volátil, ou seja, seu conteú-
do fica armazenado enquanto o computador estiver ligado (energizado); ao desligar
a corrente elétrica, o conteúdo da memória RAM é apagado. Esse é o motivo pelo
qual muitas pessoas perdem arquivos que estão utilizando quando ocorrem fatos
como, por exemplo, alguém esbarrar no cabo ligado à tomada de energia elétrica ou
mesmo cessar o fornecimento de energia.

5.2.1.2 MEMÓRIA SECUNDÁRIA

A memória secundária também é conhecida como memória auxiliar ou de massa,


por possuir uma capacidade de armazenamento muito superior à da memória prin-
cipal já discutida no tópico anterior. Outra característica que difere a memória secun-
dária das outras memórias é o fato de ser permanente (não volátil), ou seja, não perde
o conteúdo armazenado caso o computador seja desligado. A memória secundária
geralmente possui alta capacidade de armazenamento, e um custo muito mais bai-
xo do que o da memória principal.

Como exemplos de memórias secundárias, Damasceno (2016) cita os discos mag-


néticos e as fitas magnéticas, muito utilizados nas técnicas de backups de grandes
quantidades de dados. Além desses existem os HDs, SSD que apresentam memórias
flash RAM para armazenamento não-volátil de dados com acesso de alta velocidade.

De acordo com Monteiro (2007), a memória secundária pode ser constituída por di-
ferentes tipos dispositivos, alguns diretamente ligados ao sistema para acesso ime-
diato (ex.: discos rígidos) e outros que podem ser conectados quando desejado (ex.:
pen-drive, CD/DVD).

Willrich et al. (2010) afirmam que muitas vezes os programas precisam manipular
uma quantidade de dados tão grande que não cabem na memória principal. Nesse
caso, esses dados são armazenados em arquivos que são lidos da memória secundá-
ria e processados por partes. Muitas vezes esses dados podem até caber na memória
principal, mas por uma questão de organização ficam armazenados em arquivos.

FACULDADE CAPIXABA DA SERRA/EAD


70 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

5.2.2 ORDENAÇÃO INTERNA

Segundo Ziviani (2005), o aspecto predominante na escolha de um algoritmo de


ordenação é o tempo gasto para ordenar um arquivo. Para algoritmos de ordenação
interna as medidas de complexidade relevantes contam o número de comparações
entre chaves e o número de movimentações (ou trocas) de itens do arquivo. Seja C
uma função de complexidade tal que C(n) é o número de comparações entre chaves,
e seja M uma função de complexidade tal que M(n) é o número de movimentações
de itens no arquivo, onde n é o número de itens do arquivo.

A quantidade extra de memória auxiliar utilizada pelo algoritmo é também um as-


pecto importante, o uso econômico da memória disponível é um requisito primor-
dial na ordenação interna. Os métodos que utilizam a estrutura vetor e que executam
permutação dos itens no próprio vetor, exceto para a utilização de uma pequena
tabela ou pilha são os preferidos.

Existem duas classificações para os métodos de ordenação interna: métodos simples


e métodos eficientes. Os métodos simples são propícios para pequenos arquivos e
requerem O(n2) comparações, enquanto os métodos eficientes são adequados para
arquivos maiores e requerem O(n log n) comparações. Os métodos simples possuem
poucas linhas de instruções, são fáceis de serem entendidos, em que ilustra com sim-
plicidade os princípios de ordenação por comparação.

Os métodos simples são mais eficientes para pequenos arquivos, uma vez que, ape-
sar de os métodos mais sofisticados usarem menos comparações, estas comparações
são mais complexas nos detalhes.

5.2.2.1 ORDENAÇÃO POR SELEÇÃO

Um dos algoritmos mais simples de ordenação. A lógica deste algoritmo é em cada


etapa, selecionar o menor item do vetor e a seguir troque-o com o item que está na

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 71
Algoritmo e Lógica de Programação

primeira posição do vetor. Repita essas duas operações com os n-1 itens restantes,
depois com os n-2 itens, até que reste apenas um elemento. O método é ilustrado
abaixo na Figura 37 e o algoritmo na Figura 38, os números sublinhados representam
a sequência destino:

Figura 38. Exemplo de ordenação por seleção.

Figura 39. Ordenação por seleção.

O algoritmo de ordenação por seleção é um dos métodos de ordenação mais sim-


ples que existem. Além disso, o método possui um comportamento espetacular
quanto ao número de movimentos de registros, cujo tempo de execução é linear no
tamanho da entrada, o que é muito difícil de ser batido por qualquer outro método.
Consequentemente, este é o algoritmo a ser utilizado para arquivos com registros
muito grandes. Em condições normais, com chaves do tamanho de uma palavra, este
método é bastante interessante para arquivos com até 1000 registros.

FACULDADE CAPIXABA DA SERRA/EAD


72 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Como aspectos negativos cabe registrar que:

a. O custo continua quadrático, ou seja, não adianta se o mesmo já estiver orde-


nado.
b. Nem sempre este algoritmo deixa os registros com chaves iguais na mesma
posição relativa, ou seja, o algoritmo não é estável.

5.2.2.2 ORDENAÇÃO POR INSERÇÃO

A ordenação por Inserção é quase tão simples quanto o algoritmo de ordenação por

Seleção, e além disso é um método estável, pois deixa os registros com chaves iguais
na mesma posição relativa.

O método consiste em cada passo, a partir de i=2, o i-ésimo item da sequência origi-
nal é selecionado e transferido para a sequência destino, sendo colocado na posição
correta. O método é ilustrado utilizando a mesma sequência utilizada anteriormente,
os números sublinhados representam a sequência de destino (FIG.39)

Figura 40. Exemplo de ordenação por inserção.

A inserção do elemento no lugar de destino é efetuada movendo-se os itens com


chave maiores para a direita e então inserindo-o na posição que ficou vazia, conforme
pode ser visto na Figura 40. Neste processo de alternar comparações e movimentação
de registros existem duas condições distintas que podem causar o término do pro-
cesso, a primeira é quando um item com chave menor que o item em consideração
é encontrado e a segunda situação é quando o final da sequência destino é atingido
(à esquerda). A melhor solução para a situação de um anel com duas condições de
terminação é a utilização de uma sentinela, para isto, na posição zero do vetor colo-
camos o próprio registro analisado.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 73
Algoritmo e Lógica de Programação

Figura 41. Ordenação por inserção.

O número mínimo de comparações e movimentos ocorre quando os elementos es-


tão originalmente em ordem, e o número máximo ocorre quando os itens estão ori-
ginalmente na ordem reversa, o que indica um comportamento natural para o algo-
ritmo. Para arquivos já ordenados o algoritmo descobre a um custo O(n) que cada
item já está em seu lugar. Logo, este é o método a ser utilizado quando o arquivo está
“quase” ordenado. É também um método bom para adicionar um pequeno conjunto
de dados a um arquivo já ordenado, originado um outro arquivo ordenado, pois neste
caso o custo pode ser considerado linear.

5.2.2.3 ORDENAÇÃO POR SHELLSORT

Shell (1959), propôs uma adaptação do algoritmo de ordenação por inserção, em


que o princípio de ordenação é o mesmo utilizado para a ordenação por inserção.
Relembrando, no método de inserção é realizado a troca dos itens adjacentes quan-
do está procurando o ponto de inserção na sequência destino. Se o menor item esti-
ver na posição mais à direita no vetor então o número de comparações e movimen-
tações é igual a (n - 1) para encontrar o seu ponto de inserção.

FACULDADE CAPIXABA DA SERRA/EAD


74 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

O método shellsort realiza trocas de registros que estão distantes um do outro.


Os itens que estão separados h posições são rearranjados de tal forma que todo h-é-
simo item leva a uma sequência ordenada. Tal sequência é dita estar h-ordenada.
A Figura 41, abaixo mostra a sequência de ordenação usando os incrementos: 4, 2 e
1 como valores de h.

Figura 42. Exemplo de ordenação por shellsort.

Na primeira passada (h = 4), o número 44 e o 12 (posição 1 e 5) são comparados e


trocados; a seguir o 94 e o 18 (posições 2 e 6) são comparados e trocados. Na segunda
passada, (h = 2) , 12, 55, 44 , nas posições (1, 3, 5) são rearranjados para resultar em 12,
44, 55. A última passada, h = 1, corresponde ao algoritmo de inserção, mas nenhum
item tem de se mover para as posições muito distantes. O algoritmo do shellsort
pode ser observado da Figura 42.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 75
Algoritmo e Lógica de Programação

Figura 43. Ordenação por shellsort

A razão pela qual este método é eficiente ainda não foi determinada, porque é difícil
analisar o algoritmo. A sua análise contém alguns problemas matemáticos muito di-
fíceis, a começar pela própria sequência de incrementos, mas cada incremento não
deve ser múltiplo do incremento anterior.

Shellsort é uma ótima opção para arquivos de tamanho moderado (da ordem de
5000 registros), mesmo porque sua implementação é simples e requer um conjunto
de códigos pequeno. O tempo de execução do algoritmo é sensível à ordem inicial
do arquivo, além do que o método não é estável, pois ele nem sempre deixa os regis-
tros com chaves iguais na mesma posição relativa.

FACULDADE CAPIXABA DA SERRA/EAD


76 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

5.2.2.4 ORDENAÇÃO POR QUICKSORT

Segundo Ziviani (2005), este é o método de ordenação interna mais rápido que se co-
nhece para uma ampla variedade de situações, sendo provavelmente mais utilizado
do que qualquer outro algoritmo. É um método de ordenação por troca, onde a ideia
básica é dividir o problema de ordenar um conjunto com n itens em dois problemas
menores. Na sequência, os problemas menores são ordenados independentemente
e depois os resultados são combinados para produzir a solução do problema maior.

A parte mais delicada deste método é relativa ao procedimento Partição, o qual tem
que rearranjar o vetor A através da escolha arbitrária de um item x do vetor denomi-
nado pivô, de tal forma que ao final o vetor A está particionada em uma parte es-
querda com os elementos menores ou iguais a x e uma parte direita com elementos
maiores ou iguais a x.

Este comportamento pode ser descrito pelo algoritmo:

1. escolha arbitrariamente um elemento do vetor e coloque-o em x;

2. percorra o vetor a partir da esquerda até que um elemento A[i] >= x é encontra-
do; da mesma forma percorra o vetor a partir da direita até que um elemento
A[j] <= x é encontrado;

3. como os dois elementos A[i] e A[j] estão fora do lugar no vetor final, então
troque-os de lugar;

4. continue este processo até que os apontadores i e j se cruzem em algum ponto


do vetor

Ao final o vetor A[esq .. dir] está particionada de tal forma que:

Os elementos em A[esq], A[esq + 1], ..., A[j] são menores ou iguais a x;

Os elementos em A[i], A[i + 1], ..., A[dir] são maiores ou iguais a x.

O método é ilustrado para o conjunto de seis chaves apresentado na Figura X. O item


x é escolhido sendo A[(i + j) div 2]. Como inicialmente i = 1 e j = 6, então x = A[3] = D, o
qual aparece em negrito na segunda linha da mesma figura. A varredura a partir da

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 77
Algoritmo e Lógica de Programação

posição 1 pára no item O e a varredura a partir da posição 6 pára no item A, sendo s


dois itens trocados, como mostrado na terceira linha da Figura 43. A seguir, a varre-
dura a partida da posição 2 pára no item R e a varredura a partir da posição 5 pára
no item D, e então os dois itens são trocados, como mostrado na quarta linha. este
momento, i e j se cruzam (i = 3 e j = 2), o que encerra o processo de partição. Na Figura
44 poder ser visto o algoritmo de partição.

Figura 44. Exemplo de ordenação por Quicksort.

Figura 45. Algoritmo de partição.

FACULDADE CAPIXABA DA SERRA/EAD


78 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Observe que o anel interno do procedimento Partição consiste apenas em incremen-


tar um apontador e comparar um item do vetor contra um valor fixo em x. Este anel
é extremamente simples, razão pela qual o algoritmo Quicksort é tão rápido.

Após obter os dois pedaços do vetor por meio do procedimento Partição, cada pe-
daço é ordenado recursivamente. O refinamento final do procedimento Quicksort é
mostrado no algoritmo da Figura 45. O procedimento Ordena é recursivo, e o vetor A
é global aos procedimentos Partição e Ordena.

Figura 46. Ordenação por Quicksort.

A Figura 46, ilustra o que acontece com o vetor exemplo em cada chamada recursiva
do procedimento Ordena. Cada linha mostra o resultado do procedimento Partição,
em que o pivô é mostrado em negrito.

Figura 47. Exemplo de ordenação por Quicksort.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 79
Algoritmo e Lógica de Programação

Uma característica interessante do Quicksort é a sua ineficiência para arquivos já or-


denados quando a escolha do pivô é inadequada. Por exemplo, a escolha sistemá-
tica dos extremos de um arquivo já ordenado leva ao seu pior caso. Neste caso, as
partições serão extremamente desiguais, e o procedimento Ordena será chamado
recursivamente n vezes, eliminando apenas um item em cada chamada. Essa situa-
ção é desastrosa, pois o número de comparações passa a cerca de n2/2 e o tamanho
da pilha necessário para as chamadas recursivas é cerca de n. Entretanto, o pior caso
pode ser evitado empregando pequenas modificações no programa, conforme vere-
mos mais adiante.

O quicksort é extremamente eficiente para ordenar arquivos de dados. O método


necessita de apenas uma pequena pilha como memória auxiliar, e requer cerca de
(n log n) operações em média para ordenar n itens. Como aspectos negativos tem-se:

• A versão recursiva do algoritmo tem um pior caso que é O(n2);

• A implementação do algoritmo é muito delicada e difícil;

• O método não é estável.

5.2.2.5 ORDENAÇÃO POR HEAPSORT

O método de ordenação por heapsort refere-se a um método de ordenação imple-


mentado para melhorar o desempenho do método de ordenação por seleção, que
é ineficiente em se tratando de comparações, mas que tem como vantagem fazer
poucas movimentações. O princípio de funcionamento é o mesmo utilizado para a
ordenação por seleção:

• Selecione o menor item do vetor;

• Troque-o com o item que está na primeira posição do vetor;

• Repita estas duas operações com os (n-1) itens restantes, depois com os (n-2)
itens e assim sucessivamente.

O custo para encontrar o menor (ou o maior) item entre os n itens custa (n-1) compa-
rações. Este custo pode ser reduzido através da utilização de uma estrutura de dados
denominada fila de prioridades, esse assunto será tratado em outra unidade.

FACULDADE CAPIXABA DA SERRA/EAD


80 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

5.2.2.6 FILAS DE PRIORIDADES

A fila de propriedade trata-se de uma estrutura de dados composta de chaves, que


suporta as operações de inserir um novo item e retirar o item com a maior chave,
onde a chave de cada item reflete sua habilidade relativa de abandonar o conjunto
de itens rapidamente.

Filas com prioridades são utilizadas em um grande número de aplicações. Sistemas


operacionais usam filas de prioridades, nas quais as chaves representam o tempo em
que os eventos devem ocorrer. Alguns métodos numéricos iterativos são baseados na
seleção repetida de um item com maior (ou menor) valor.

As operações mais comuns são: Adicionar um novo item ao conjunto e extrair o item
do conjunto que contenha o maior (ou o menor) valor.

Um tipo abstrato de dados fila de prioridades, contendo registros com chaves numé-
ricas (prioridades), deve suportar as operações:

1. Constrói uma fila de prioridades a partir de um conjunto com n itens;

2. Insere um novo item;

3. Retira o item com maior chave;

4. Substitui o maior item por um novo item, a não ser que o novo item seja maior;

5. Altera a prioridade de um item;

6. Remove um item qualquer;

7. Ajunta duas filas de prioridades em uma única fila.

A operação constrói é equivalente ao uso repetido da operação Insere, e a operação


Altera é equivalente à operação Remove seguida da operação Insere.

Uma representação para a fila de prioridades é uma lista linear ordenada. Neste caso,
a operação Constrói leva o tempo O(n log n), Insere é O(n) e Retira é O(1). Outra repre-
sentação é através de uma lista linear não ordenada, na qual a operação Constrói tem
custo linear e é de O(1), Retira é O(n) e Ajunta é O(1) para implementações através
de apontadores e O(n) para implementações através de arranjos, onde n representa
o tamanho da menor fila de prioridades.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 81
Algoritmo e Lógica de Programação

Filas de prioridades podem ser representadas por estruturas de dados chamadas de


heaps. A operação Constrói tem custo linear, e Insere, Retira, Substitui e Altera tem
custo logarítmico. Para implementar a operação Ajunta de forma eficiente e ainda
preservar um custo logarítmico para as operações Insere, Retira, Substitui e Altera é
necessário utilizar estruturas de dados mais sofisticadas, tais como árvores binomiais.

Qualquer algoritmo para filas de prioridades pode ser transformado em um algorit-


mo de ordenação, através do uso repetido da operação insere para construir a fila,
seguido do uso repetido da operação retira para receber os itens na ordem inversa.
Deste modo, o uso de listas lineares não ordenadas corresponde ao método da sele-
ção, o uso de listas lineares ordenadas corresponde ao método da inserção e o uso de
heaps corresponde ao método heapsort (ZIVIANI, 2005).

5.2.2.7 HEAPS

Uma estrutura de dados eficiente para suportar as operações Constrói, Insere, Retira,
Substitui e Altera um heap. É definido como uma sequência de itens com chaves:

c[1], c[2], …, c[n],

tal que

c[i] >= c[2i],

c[i] >= c[2i + 1], para todo i = 1, 2, …, n/2

Esta ordem é visualizada se a sequência de chaves for desenhada em uma árvore bi-
nária, onde as linhas que saem de uma chave levam a duas chaves menores no nível
inferior conforme ilustra a Figura 47.

Figura 48. Árvore binária

FACULDADE CAPIXABA DA SERRA/EAD


82 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Esta estrutura é conhecida como uma árvore binária completa: o primeiro nodo é
chamado raiz, os nodos abaixo de cada nodo são chamados nodos filhos e o nodo
acima é chamado de nodo pai. Uma árvore binária completa pode ser representada
por um vetor.

Esta representação é extremamente compacta e, permite caminhar pelos nodos da


árvore facilmente, onde os filhos de um nodo i estão na posição 2i e 2i+1, caso exis-
tam, e o pai de um nodo i está na posição (i div 2).

5.2.2.8 HEAPSORT

Um método elegante e que não necessita de memória auxiliar foi apresentado por
Floyd (1964) dado um vetor A[1], A[2], ..., A[n], os itens A[n/2+1], A[n/2+2], ..., A[n] for-
mam um heap, porque neste intervalo do vetor não existem dois índices i e j tais que
j=2i ou j=(2i+1). A construção do heap:

a) dada as chaves iniciais:

1 2 3 4 5 6 7
O R D E N A S

b) estendendo o heap para a esquerda (Esq=3), englobando o item A[3], pai dos itens
A[6] e A[7], aqui a condição do heap é violada e os itens A[3] e A[7] são trocados;

Esq = 3

1 2 3 4 5 6 7
O R S E N A D

c) a seguir o heap é estendido novamente a esquerda (Esq=2) incluindo o item A[2],


pai dos itens A[4] e A[5], que atendem a condição do heap.

Esq = 2

1 2 3 4 5 6 7
O R S E N A D

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 83
Algoritmo e Lógica de Programação

d) finalmente, estendendo o heap a esquerda (Esq= 1), englobando o item A[1], pai
dos itens A[2] e A[3], a condição é violada e os itens A[1] e A[3] são trocados, encer-
rando o processo.

Esq = 1

1 2 3 4 5 6 7

S R O E N A D

Inicialmente, o algoritmo não parece eficiente, pois as chaves são movimentadas vá-
rias vezes. Entretanto, o procedimento Refaz gasta cerca de (log n) operações no pior
caso. Portanto, Heapsort gasta um tempo de execução proporcional a (n log n) no
pior caso.

Heapsort não é recomendado para arquivos com poucos registros, por causa do tem-
po necessário para construir o heap, bem como porque o anel interno do algoritmo
é bastante complexo, se comparado com o anel interno do Quicksort. O quicksort é,
em média, duas vezes mais rápido que o Heapsort. Entretanto, o Heapsort é melhor
que o Shellsort para grandes arquivos. Deve-se observar que o comportamento do
Heapsort é O(n log n) qualquer que seja a entrada. Aplicações que não podem tolerar
um caso desfavorável devem usar o Heapsort. Um aspecto negativo é que o método
não é estável.

5.2.2.9 COMPARAÇÃO ENTRE OS MÉTODOS DE


ORDENAÇÃO

A ordenação interna é usada quando todos os registros do arquivo (ou lista ou vetor)
cabem na memória principal. Usando dois métodos simples (seleção e inserção) que
requerem O(n2) comparações e três métodos eficientes (shellsort, quicksort e heap-
sort) que requerem O(n log n) comparações em seus casos médios para uma lista
com n elementos.

ZIVIANI (2005) criou as tabelas 4, 5 e 6 abaixo para apresentar os quadros compa-


rativos do tempo para ordenar arranjos com 500, 5000, 10000 e 30000 registros na
ordem aleatória (4, 2, 9, 1, ..., n), na ordem ascendente (1, 2, 3, ..., n), e na ordem des-
cendente (n, n-1,..., 3, 2, 1). Em cada tabela, o método que gastou o menor tempo para

FACULDADE CAPIXABA DA SERRA/EAD


84 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

executar o procedimento recebeu o valor 1 e os outros valores são relativos a este.


Assim, na Tabela 4, o Shellsort levou o dobro do tempo do Quicksort para ordenar
30.000 registros.

Tabela 4- Ordem aleatória dos registros

Fonte: ZIVIANI, 2005, p. 88.

Tabela 5- Ordem ascendente dos registros

Fonte: ZIVIANI, 2005, p. 88.

Tabela 6- Ordem descendente dos registros

Fonte: ZIVIANI, 2005, p. 88.

Analisando os quadros acima, pode-se apresentar os seguintes comentários:

1. Shellsort, Quicksort e o Heapsort possuem a mesma ordem de grandeza;

2. O Quicksort é o mais rápido para todos os tamanhos na situação de ordem ale-


atória experimentados;

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 85
Algoritmo e Lógica de Programação

3. A relação Heapsort/Quicksort se mantém constante para todos os tamanhos,


sendo o Heapsort mais lento;

4. A relação Shellsort/Quicksort aumenta à medida que o número de elementos


aumenta, para arquivos pequenos (próximos de 500 elementos) o Shellsort é
mais rápido que o Heapsort, porém quando o tamanho da entrada cresce, a
relação inverte;

5. A Inserção é o método mais rápido para qualquer tamanho se os elementos já


estão ordenados, este é o seu melhor caso O(n). Pode também ser utilizado nos
casos em que os elementos já estão quase ordenados. Mas é o mais lento para
qualquer tamanho se os elementos estão em ordem decrescente, este é o seu
pior caso O(n2);

6. Entre os métodos de custo O(n2), a Inserção é melhor para todos os tamanhos


de ordenação aleatória experimentados;

7. A Inserção é o mais interessante para arquivos pequenos com até 20 elementos;

8. O método de seleção somente é vantajoso quanto ao número de movimentos


de registros, que é O(n). Logo, ele deverá ser utilizado para arquivos com registros
muito grandes, desde que o tamanho do arquivo não exceda 1.000 elementos;

9. O Shellsort é o método escolhido para a maioria das aplicações por ser muito
eficiente para um conjunto de elementos de até 10000 elementos. Sua imple-
mentação é simples e fácil de colocar funcionando corretamente e geralmente
resulta em um programa pequeno;

10. O Quicksort é o algoritmo mais eficiente que existe para uma grande variedade
de situações. Entretanto, deve-se procurar uma implementação estável. O algorit-
mo é recursivo, o que demanda uma pequena quantidade de memória adicional;

11. O Heapsort é um método de ordenação elegante e eficiente. Por causa do


anel interno complexo (que o torna duas vezes mais lento que o Quicksort) ele
não necessita de memória adicional, e é sempre O(n log n) qualquer que seja
a ordem inicial dos elementos. Este é o método a ser usado por aplicações que
não podem tolerar variações no tempo esperado de ordenação.

Quando os registros do arquivo são muito grandes é desejável que o método de or-
denação realize o menor número de movimentação com os registros, podendo ser
usada uma ordenação indireta.

FACULDADE CAPIXABA DA SERRA/EAD


86 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Para aprofundar seus conhecimentos, recomendo a leitura do capítulo 8 (da página


337 à 374) do livro Estruturas de Dados & Algoritmos em Java - 5ed, de Michael T.
Goodrich,Roberto Tamassia ou o capítulo 19 (da página 501 à 515) do livro C Com-
pleto e Total do autor Herbert Schildt.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 87
Algoritmo e Lógica de Programação

UNIDADE 6

OBJETIVO
Ao final desta
unidade,
esperamos
que possa:

> Entender o funcionamento


do método de ordenação
externa: intercalação
balanceada de vários
caminhos.

> Compreender um conjunto


amplo de operações e
manipulações de caracteres
como: gets e puts de strings,
função para recuperar o
tamanho da string, função
para comparar duas strings,
dentre outras funções que
lidam com string.

> Conhecer sobre as variáveis


compostas homogêneas: o
array e matrizes.

FACULDADE CAPIXABA DA SERRA/EAD


88 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

6 CONSTRUÇÃO DE
ALGORITMOS BÁSICOS:
INTERCALAÇÃO,
MANIPULAÇÃO DE
CARACTERES E ARRAYS
6.1 APRESENTAÇÃO DA UNIDADE

Nesta unidade vamos conhecer o algoritmo de intercalação balanceada de vários ca-


minhos que se trata de um método de ordenação externa. Vamos aprender sobre as
principais operações em cadeias de caracteres e as funções mais interessantes para
manipulação de strings.

6.2 INTERCALAÇÃO BALANCEADA DE VÁRIOS


CAMINHOS

Vamos considerar o processo de ordenação externa quando o arquivo está armaze-


nado em alguma mídia de armazenamento qualquer, como uma fita magnética por
exemplo. Para apresentar os vários passos envolvidos em um algoritmo de ordenação
por intercalação balanceada vamos utilizar um arquivo exemplo. Considere um ar-
quivo armazenado em uma fita de entrada, composto pelos registros com as chaves
mostradas na Figura 48.

Os 22 registros devem ser ordenados de acordo com as chaves e colocados em uma


fita de saída. Neste caso os registros são lidos um após o outro.

Figura 49. Formação dos blocos ordenados iniciais

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 89
Algoritmo e Lógica de Programação

Na segunda etapa os blocos ordenados devem ser intercalados. O primeiro registro


de cada uma das três fitas é lido para a memória interna, ocupando toda a memória
interna. A seguir o registro contendo a menor chave dentre as três é retirado e o pró-
ximo registro da mesma fita é lido para a memória interna, repetindo-se o processo.
Quando o terceiro registro de um dos blocos é lido aquela fita fica inativa até que o
terceiro registro das outras fitas também sejam lidos e escritos na fita de saída, for-
mando um bloco de 9 registros ordenados. A seguir o segundo bloco de 3 registros
de cada fita é lido para formar outro bloco ordenado de nove registros, o qual é es-
crito em uma outra fita. Ao final três novos blocos ordenados são obtidos, conforme
mostra a Figura 49.

Figura 50. Intercalação de 3 caminhos

A seguir mais uma intercalação de 3 caminhos das fitas 4, 5 e 6 para as fitas 1, 2 e 3


completa a ordenação. Se o arquivo exemplo tivesse um número maior de registros,
então vários blocos ordenados de 9 registros seriam formados nas fitas 4, 5 e 6. Neste
caso, a segunda passada produziria blocos ordenados de 27 registros nas fitas 1, 2 e
3; a terceira passada produziria blocos ordenados de 81 registros nas fitas 4, 5 e 6, e
assim sucessivamente, até obter-se um único bloco ordenado. Neste ponto cabe a
seguinte pergunta:

quantas passadas são necessárias para ordenar um arquivo de tamanho arbitrário?

Considere um arquivo contendo n registros (neste caso cada registro contém apenas
uma palavra) e uma memória interna de m palavras. A passada inicial sobre o arqui-
vo produz n/m blocos ordenados (se cada registro contiver k palavras, k > 1, então
teríamos n/m/k blocos ordenados.) Seja P uma função de complexidade tal que P(n)
é o número de passadas para a fase de intercalação dos blocos ordenados, e seja f o
número de fitas utilizadas em cada passada. Para uma intercalação-de- f -caminhos
o número de passadas é

P(n)= logf n
m

FACULDADE CAPIXABA DA SERRA/EAD


90 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

No exemplo anterior, n=22, m= 3 e f=3. Logo

P(n)= log3 22 = 2
3

Considere um exemplo de um arquivo de tamanho muito grande, tal como 1 bilhão


de palavras. Considere uma memória interna disponível de 2 milhões de palavras e 4
unidades de fitas magnéticas. Neste caso P(n) = 5, e o número total de passadas, in-
cluindo a primeira passada para obter os n/m blocos ordenados, é 6. Uma estimativa
do tempo total gasto para ordenar este arquivo pode ser obtido multiplicando-se por
6 o tempo gasto para transferir o arquivo de uma fita para outra.

Para uma intercalação-de- f -caminhos foram utilizadas 2f fitas nos exemplos acima.
Para usar apenas f + 1 fitas basta encaminhar todos os blocos para uma única fita e,
com mais uma passada, redistribuir estes blocos entre as fitas de onde eles foram lidos.
No caso do exemplo de 22 registros apenas 4 fitas seriam suficientes: a intercalação
dos blocos a partir das fitas 1, 2 e 3 seria toda dirigida para a fita 4; ao final, o segundo
e o terceiro blocos ordenados de 9 registros seriam transferidos, de volta para as fitas 1
e 2, e assim por diante. O custo envolvido é uma passada a mais em cada intercalação.

6.3 MANIPULAÇÃO DE CARACTERES

Na maioria dos algoritmos implementamos, se faz necessário lidar com cadeias de


caracteres no processamento e armazenamento das informações que nos são forne-
cidas. Nas linguagens de programação, essas cadeias de caracteres são conhecidas
como strings. Esse tipo de variável é utilizado para armazenar textos com palavras e
nomes. Na linguagem C, por exemplo, não há um tipo de dados primitivo que seja
equivalente as strings, utilizamos vetores de elementos do tipo char para a manipu-
lação de cadeias de caracteres. Em outras palavras, para armazenar uma cadeia de
caracteres utilize vetores (matrizes unidimensionais) do tipo char, onde cada posição
representa um caractere.

No exemplo a seguir, temos a declaração de três strings: cidade, empresa e nome.


Observe que cada string é um array de char. Significa dizer que a string cidade tem
a capacidade de armazenar 30 caracteres, a string empresa 20 caracteres e a string
nome 100 caracteres.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 91
Algoritmo e Lógica de Programação

char cidade[30];

char empresa[20];

char nome[100];

Uma string em C tem um caractere especial que determina o seu fim. Esse caracte-
re nulo (\0), e ele é inserido automaticamente pelo compilador no último elemento
do vetor de elementos do tipo char. Com isso, deve-se levar isso em consideração na
hora de declarar suas strings. Assim sendo, se você deseja que uma string armazene
N caracteres, você deve declará-la com um tamanho N+1, pois a última posição con-
terá caractere nulo. Esse caractere não precisa ser declarado manualmente, isso feito
de forma automática pelo compilador.

No exemplo a seguir podemos observar a utilização de um vetor de 8 posições, para


armazenar a palavra “Futebol”.

F U T E B O L \0

0 1 2 3 4 5 6 7

A declaração deste vetor será: char Palavra[8]. Observe que na última posição do ve-
tor é inserido o caractere nulo. A variável Palavra, quando é declarada, pode ocu-
par qualquer espaço livre na memória, entretanto, todas as posições deste vetor ocu-
pam posições de memória adjacentes, onde, cada caractere ocupa 1 byte.

Assim como as variáveis e vetores, uma string pode ser inicializada no momento da
sua criação ou após a sua criação, veja os exemplos a seguir.

char str1[11] = “Algoritmo”;

char str2[ ] = “Karina”;

char str3[4] = “Contagem”;

FACULDADE CAPIXABA DA SERRA/EAD


92 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

No exemplo char str1[11] = “Algoritmo”, o compilador reserva 11 posições na memória.


Como a cadeia “Algoritmo” possui 9 caracteres, estes caracteres são armazenados nas 9
posições, e as restantes posições serão inicializadas automaticamente pelo carácter ‘\0’

str1=

'A' 'L' 'G' 'O' 'R' 'I' 'T' 'M' 'O' '\0' '\0'
0 1 2 3 4 5 6 7 8 9 10

No exemplo char str2[ ] = “Karina”, o compilador reserva 6 + 1 posição de memória,


onde as 6 posições para guardar os caracteres “Karina” e 1 posição para guardar o
caractere ‘\0’.

Já no exemplo char str3[4] = “Contagem”, o compilador acusará erro ao compilar,


pois, o tamanho da cadeia de vetores é maior que o número de posições de memória
reservadas. Foi reservado apenas 4 posições de memória, mas a cadeia “Contagem”
contém 8 caracteres.

6.3.1 LENDO E IMPRIMINDO STRINGS

A maioria das linguagens de programação possuem funções pré-definidas para faci-


litar a manipulação das cadeias de caracteres. Assim como no pseudocódigo utiliza-
mos a instrução leia e escreva para ler e imprimir as strings, a linguagem C, por exem-
plo, possui as funções gets() e puts(), elaboradas especialmente para este mesmo
objetivo, ler e imprimir strings, respectivamente. Vejamos um exemplo da utilização
destas instruções na Figura 50.

Figura 51. Algoritmo utilizando as funções gets e sets.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 93
Algoritmo e Lógica de Programação

Na linha 3, declaramos uma string palavra que armazena 7 caracteres (considerando


o caractere NULO). Em seguida, utilizamos a função gets(), que tem como função
realizar a leitura de uma string, onde após o término da entrada de dados por par-
te do usuário, se faz necessário teclar ENTER. Na linha 6, utilizamos a função puts(),
para imprimir na saída padrão a string da palavra lida. Digamos que o usuário digite
a string ‘ONIBUS’. Dessa forma, a cadeia de caracteres será armazenada na memória
da seguinte forma:

'O' 'N' 'I' 'B' 'U' 'S' '\0


0 1 2 3 4 5 6

Como uma string em C trata-se na verdade de um vetor de caracteres, podemos


acessá-los individualmente do mesmo modo que acessamos os elementos de um
vetor qualquer. Ao serem executadas as linhas 8 e 9 do código anterior, por exemplo,
serão exibidos na saída padrão os caracteres “U” e “I”, respectivamente.

Em C, para capturar o valor de um caractere fornecido pelo usuário via teclado, usa-
mos a função scanf, com o especificador de formato %c.

char nome;
...
scanf(“%c”, &nome);
...

Diante disso, se o usuário digitar a letra b, por exemplo, o código associado à letra b
será armazenado na variável nome. Vale ressaltar que, diferente dos especificadores
%f e %d, o especificador %c não pula os caracteres brancos, um caractere branco
pode ser: um espaço (‘ ‘), um caractere de tabulação (‘\t’) ou um caractere de nova
linha (‘\n’). Portanto, se o usuário digitar um espaço antes da letra b, o código do es-
paço será capturado e a letra b será capturada apenas numa próxima chamada da
função scanf. Se desejarmos pular todas as ocorrências de caracteres brancos que
porventura antecedem o caractere que queremos capturar, basta incluir um espaço
em branco no formato, antes do especificador.

FACULDADE CAPIXABA DA SERRA/EAD


94 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

char nome;
...
scanf(“ %c”, %nome); /* o branco no formato pula brancos da entrada */
...

Para que nomes compostos possam ser lidos (nome de cidades, pessoas, endereços
para correspondência, etc.), o especificador no formato %[...] poderá ser utilizado, no
qual todos os caracteres aceitos na leitura deverão estar listados entre colchetes. As-
sim, o formato “%[aeiou]” lê sequências de vogais, isto é, a leitura prossegue até que
se encontre um caractere que não seja uma vogal. Se o primeiro caractere entre col-
chetes for o acento circunflexo (^), teremos o efeito inverso (negação). Assim, com o
formato “%[^aeiou]” a leitura prossegue enquanto uma vogal não for encontrada. Esta
construção permite a captura de nomes compostos. Consideremos o código abaixo:

char nome[51];
...
scanf(“ %[^\n]”, nome);
...

No exemplo acima, a função scanf lê uma sequência de caracteres até que seja encon-
trado o caractere de mudança de linha (‘\n’), ou seja, até que o usuário tecle “Enter”.
A inclusão do espaço no formato (antes do sinal %) garante que eventuais caracteres
brancos que precedam o nome serão ignorados. Como o vetor foi dimensionado com
51 elementos, o trecho de código acima produzirá um erro se o usuário fornecer uma
linha que tenha mais de 50 caracteres, pois utilizará um espaço de memória que não
foi reservado.

Para eliminar esta possível invasão, podemos limitar o número máximo de caracteres
que serão capturados.

char nome[51];
...
scanf(“ %50[^\n]”, nome); /* lê no máximo 50 caracteres */

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 95
Algoritmo e Lógica de Programação

6.3.2 MANIPULANDO STRINGS

Existem várias funções interessantes para manipulação de strings predefinidas em


linguagem C. A manipulação de strings envolve o seguinte:

• Determinar o comprimento da string;

• Copiar uma string para uma outra posição de memória;

• Concatenar ou juntar strings;

• Comparação de duas strings;

• Procurar um caracter dentro de uma string;

• Procurar uma substring dentro de uma string;

• E etc.

Todas estas funções estão presentes na biblioteca string.h

6.3.2.1 FUNÇÃO STRLEN

Esta função tem como objetivo receber uma string via parâmetro e retornar a quan-
tidade de caracteres da string ou seja o tamanho da string excluindo o caracter ‘\0’.

Exemplo:

strlen(“Bruno”); retorna o inteiro 5.

6.3.2.2 FUNÇÃO STRCPY

Essa função permite realizar a cópia do conteúdo da string s2 para a string s1.

Exemplo:

char nome[12]; /*declaração da string*/

strcpy(nome, “Bruno”); /* Onde a cadeia de caracteres “Bruno” é copiada para


string nome*/

FACULDADE CAPIXABA DA SERRA/EAD


96 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

6.3.2.3 FUNÇÃO STRCAT

Essa função permite concatenar (unir) a string s2 com a string s1 e o resultado da


concatenação é guardado na string s1.

Exemplo:

char nome[12] = “Pedro”; /*declaração da string*/

strcat(nome, “Augusto”); /*a cadeia de caracteres resultante será “PedroAugusto”


e será guardada na variável nome*/

6.3.2.4 FUNÇÃO STRCMP

Essa função permite comparar duas strings. A função devolve um inteiro negativo se
str1 for menor alfabeticamente em relação a str2. A função devolve 0 (zero) se str1
for igual a str2. A função devolve um inteiro positivo se str1 for maior alfabeticamente
em relação a str2.

Exemplo:

char nome1[12]=“Bruno”; /*declaração da string*/

char nome2[12]=“Lu”; /*declaração da string*/

int numero;

strcmp(nome1, nome2); /*devolve um número positivo*/

strcmp(nome1, nome1); /*devolve 0*/

strcmp(nome2, nome1); /*devolve um número negativo*/

Na Figura 51, é possível observar a utilização de alguma destas funções implementa-


das na linguagem C.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 97
Algoritmo e Lógica de Programação

Figura 52. Funções básicas em C.

Este trecho de algoritmo acima apresenta um exemplo de uma função básica na


linguagem C. A instrução apresentada na linha 1 (#include <stdio.h>) é a sintaxe para
inclusão da biblioteca stdio.h. O intuito desta biblioteca é facilitar a vida do progra-
mador, agrupando um conjunto de funções relacionadas a entrada e saída de dados
do programa, por exemplo: printf e scanf.

Na linha 4, declaramos duas strings: var1 e var2. Nas linhas 6 e 7, utilizamos o coman-
do gets() para que o usuário informe as duas strings que serão armazenadas nas va-
riáveis mencionadas. As linhas 9 e 10 imprimem os tamanhos das strings var1 e var2,
enquanto que a linha 12 é responsável por concatenar as strings var2 e var1, ou seja,
var1 passa a ter o conteúdo anterior com a adição do conteúdo de var2. Por fim, a
linha 13 exibe o tamanho de var1 após a sua concatenação com var2.

6.4 ARRAYS
Até agora vimos que uma variável armazena apenas um único valor por vez.
Por exemplo, em um programa para ler o salário de vários colaboradores de uma
empresa, cada salário é armazenado em uma variável, e assim que os salários de
um novo colaborador são lidos, os salários do colaborador anterior são perdidos. Em
algumas situações, é bem comum a necessidade de armazenar um conjunto de da-
dos onde os valores lidos não podem ser esquecidos ou perdidos à medida que o
processamento for ocorrendo. Diante desta situação, seria inviável declarar uma va-
riável distinta para armazenar cada valor, quando a quantidade de valores a serem

FACULDADE CAPIXABA DA SERRA/EAD


98 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

manipulados for relativamente grande. Para situações como essas utilizamos arranjos
(arrays), que consistem em estruturas de dados (ou variáveis compostas homogêneas)
capazes de agrupar em uma única variável vários elementos de um mesmo tipo e
permitir facilmente o acesso a cada item em particular.

6.4.1 DEFINIÇÃO DE ARRANJOS

Os arranjos podem ter diferente dimensões, onde um tipo especial de arranjo com
apenas uma dimensão é chamado de vetor. Um arranjo é uma única variável, a qual é
formada por um conjunto homogêneo (isto é, do mesmo tipo) de valores. Para iden-
tificar cada valor é usado um número inteiro, que corresponde à posição do valor em
relação aos demais. Este número, apropriadamente, é chamado de índice.

A Figura 52 ilustra o conceito de vetor, apresentando um vetor de inteiros com cinco


elementos individuais, cada um com seu índice correspondente. O índice do primei-
ro elemento é sempre zero, outro na posição um, seguindo assim até a última posi-
ção, que neste caso, possui o índice 4.

Figura 53. Vetor de inteiros.

As linguagens de programação apresentam variações no modo como os índices são


numerados. Algumas marcariam índices de 1 a 5, para o exemplo acima, outras permi-
tiriam marcações menos intuitivas, como de -3 a 1. O ponto em comum na maioria das
linguagens é que o índice é um valor inteiro e que os valores são sempre consecutivos.

6.4.2 DECLARAÇÃO DE VETORES

Na linguagem C, devemos declarar um vetor da seguinte forma:

tipo_vetor nome_vetor[quantidade_elementos];

onde:

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 99
Algoritmo e Lógica de Programação

o tipo_vetor é o tipo de cada elemento do vetor. O nome_vetor é o nome da variável


que irá identificar o vetor. A quantidade_elementos representa a quantidade máxi-
ma de elementos que o vetor poderá armazenar. Observe que essa quantidade deve
ficar entre colchetes. A única diferença entre a declaração de vetores e a declaração
de variáveis simples é que, ao declarar vetores, especificamos ao fim da declaração
e entre colchetes [ ] o tamanho do vetor, ou seja, sua capacidade de armazenamen-
to. Os índices do vetor irão de zero até quantidade_elementos - 1. O compilador irá
reservar o espaço de memória correspondente ao que o programador definiu em
quantidade_elementos.

Na sequência, alguns exemplos de declarações de vetores:

int cpf[11];

char placa[8];

float valor[30];

Uma declaração de um vetor é feita para um tamanho fixo de elementos. Em outras


palavras, já na declaração do vetor a quantidade de posições que existirá deverá ser
informada e este tamanho não poderá ser modificado. Embora muitas vezes desejá-
vel, não se podem usar variáveis para especificar o número de posições que um vetor
terá. No exemplo acima temos três declarações de vetores diferentes. Na primeira li-
nha temos a declaração de um vetor chamado cpf que terá no máximo 11 elementos
do tipo int, com índices de 0 a 10. Na segunda linha temos um vetor chamado placa
com 8 elementos do tipo char, com índices de 0 a 7. Por fim, temos na última linha
um vetor com identificador valor, com espaço para armazenar 30 elementos do tipo
float, cujos índices variam de 0 a 29.

6.4.3 ACESSANDO OS ELEMENTOS DE UM VETOR

Um vetor ao ser criado, como qualquer outra variável, contém em suas várias posições
valores indefinidos (“lixo”). Semelhante a outras variáveis, a utilização do seu conteúdo
faz sentido apenas se já houver sido feita uma leitura ou uma atribuição àquela posição.

Para exemplificar, considere-se uma declaração de dados como a abaixo.

int lista[5]

FACULDADE CAPIXABA DA SERRA/EAD


100 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

O trecho de código seguinte ilustra o preenchimento do vetor com valores, obede-


cendo uma regra, que é a de que cada posição contenha o triplo do valor da posição
imediatamente anterior, acrescido de 5 unidade.

lista[0] ← 1 { primeiro da lista }

para [i] 1 até 4 { demais posições }

lista[i] ← lista[i – 1] * 3 + 5

fim-para

A Tabela 6 apresenta a situação do vetor lista nos vários momentos em que um de


seus valores é modificado.

Tabela 6. Ilustração passo a passo dos valores de um arranjo para atribuições sucessivas.

Um vetor é como uma coleção de caixas numeradas. Cada caixa é capaz de armaze-
nar um valor e tem o seu “endereço”. O “endereço” de cada caixa é conhecido como
índice e serve para identificar qual posição do vetor queremos acessar. Por exemplo:
se precisarmos armazenar a idade de 10 crianças podemos declarar um vetor de 10
posições do tipo int. A declaração do nosso vetor ficaria assim: int idade[10]. Na se-
quência, a Figura 53 representa esse vetor de idade:

Figura 54. Vetor contendo as idades.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 101
Algoritmo e Lógica de Programação

No vetor acima temos, por exemplo, armazenado do índice “4” o valor “24”. Observe,
que declaramos um vetor de 10 posições, os índices variam de 0 a 9.

Para referenciar as posições do vetor e armazenar dados na mesma é utilizado a se-


guinte sintaxe:

nome_do_vetor[índice]

Desta forma, para armazenar o valor 34 na segunda posição do vetor, seria utilizado
o comando: idade[1] = 34.

A Figura 54 exibe um trecho de algoritmo na linguagem C que recebe N elementos


digitados pelo usuário e imprime o maior e o menor elemento do array.

Figura 55. Algoritmo para identificar o menor e o maior número dos informados.

Suponhamos que os seguintes valores sejam digitados, nas respectivas ordens:

A=

20 100 0 30 -60 10 0 0
0 1 2 3 4 5 6 7

FACULDADE CAPIXABA DA SERRA/EAD


102 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

onde, A.length = 8. Na tabela abaixo é possível acompanhar o passo a passo da exe-


cução do algoritmo a cada interação.

i Menor Maior
20 20
7 0 20
6 0 20
5 0 20
4 -60 20
3 -60 30
2 -60 30
1 -60 100
0 -60 100
-1

E o resultado final do algoritmo é:

Menor = -60

Maior = 100

6.5 MATRIZES

Como já foi dito anteriormente, os arranjos podem ter várias dimensões. Quando pos-
suem mais de uma dimensão, eles são chamados de matrizes, também conhecido
como conjuntos bidimensionais. O conceito de matrizes em programação é bem se-
melhante ao da matemática. A Figura 55 a seguir apresenta o formato de uma matriz
m x n, onde m é representa o número de linhas e n o número de colunas.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 103
Algoritmo e Lógica de Programação

Figura 56. Matriz de m x n.

Na Figura 56 abaixo, a primeira matriz é 3 x 3, pois possui 3 linhas e 3 colunas. A se-


gunda matriz é 2 x 3, pois possui 2 linhas e 3 colunas. Se quisermos saber o elemento
da primeira matriz que possui índice A2,3, basta seguirmos em direção à 2a linha e
depois em direção à 3a coluna. Logo o valor de A2,3 é 1.

Figura 57. Exemplo de uma matriz 3x2 e outra 2x3.

As matrizes possuem:

• um número fixo de elementos;

• todos elementos são do mesmo tipo;

• arranjadas na forma de tabela de 2 dimensões.

FACULDADE CAPIXABA DA SERRA/EAD


104 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Podemos representar essas matrizes na linguagem C acrescentando mais um índice


entre colchetes no identificador do arranjo. Abaixo temos alguns exemplos de como
declaramos matrizes:

int matriz[4][3];

char nomes[4][5];

Para aprofundar seus conhecimentos, recomendo a leitura do capítulo 7 (da página


185 à 196) do livro Treinamento em Linguagem C – Curso Completo – Módulo 1, de
Victorine Mizrahi e do capítulo 4 (da página 92 à 98) do livro C Completo e Total do
autor Herbert Schildt

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 105
Algoritmo e Lógica de Programação

UNIDADE 7

OBJETIVO
Ao final desta
unidade,
esperamos
que possa:

> Aplicações dos arquivos

> Como declarar um


arquivo

> Como manipular um


arquivo: consultas,
inclusão, alteração e
exclusão

> Arquivos sequencial e


direto

FACULDADE CAPIXABA DA SERRA/EAD


106 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

7 ARQUIVOS SEQUENCIAIS E
DIRETOS
7.1 APRESENTAÇÃO DA UNIDADE

Será apresentado os principais conceitos e terminologias utilizados na organização


de um arquivo. Explicar a forma básica de manipulação. Diferenciar os tipos de ar-
quivos, adaptando a manipulação prática associada a cada concepção: sequencial,
direto ou indexado.

7.2 ARQUIVOS

De acordo com as unidades anteriores já estudadas, utilizamos variáveis simples ou


compostas para armazenar as informações necessárias à resolução de determinado
problema, ou seja, os dados ficavam armazenados em memória. Considerando a me-
mória do computador como ambiente comum ao algoritmo e a estrutura de dados,
em um determinado momento ou situação, pode acontecer de não existir espaço
para armazenar um volume de dados muito grande. Em outra situação poderá haver
necessidade realizar o armazenamento de um determinado conjunto de informa-
ções por um longo período, tornando assim inviável de mantê-lo na memória princi-
pal por se tratar de um recurso caro e limitado.

Uma forma de contorno este tipo de problema é trabalhar com uma nova estrutura:
os arquivos, que tem como objetivo principal realizar o armazenamento de grandes
quantidades de informação por um grande período de tempo. Este, é também uma
alternativa para estruturas de dados que não podem ou não necessitam estar aloca-
das no ambiente do algoritmo. Esta estrutura de dados geralmente fica alocada fisi-
camente em um meio secundário, sendo mais comum o uso de meios magnéticos
como fitas, discos ou disquetes.

Um arquivo é um conjunto de registros (ou seja, uma estrutura de dados) armazena-


dos em um dispositivo de memória secundária. Os registros são formados por unida-
des de informação denominadas campos.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 107
Algoritmo e Lógica de Programação

Utilizaremos como exemplo a carteira de identidade de uma pessoa. Como pode ser
visto na Figura 57. Nela encontram-se alguns dados básicos do cidadão: nome, filia-
ção, naturalidade, data de nascimento e etc. O conjunto de informações apresentado
por estes dados formam um registro:

Figura 58. Carteira de identidade do cidadão.

R.G Nome Pai Mãe Naturalidade Nascimento

MG - 548 Fulano Sicrano Beltrana Sabará 29/02/2018

A relação lógica entre estas informações é a sua associação a uma pessoa. Quando
reunimos várias destas carteiras de identidades dos membros de uma família, poderá
formar por exemplo, um arquivo.

R.G Nome Pai Mãe Naturalidade Nascimento

MG - 548 Fulano Sicrano Beltrana Sabará 29/02/2018


B - 5845 Joana Silva João Silva Maria Silva Belém 25/22/1980
C -45455 Henrique T Afonso B Ana Maria Brasília 22/10/1890

Como o arquivo pode ser armazenado em uma memória secundária o torna inde-
pendente de qualquer algoritmo. Isto é, um arquivo pode ser criado, consultado, pro-
cessado e eventualmente removido por algoritmos distintos.

FACULDADE CAPIXABA DA SERRA/EAD


108 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

7.3 ORGANIZAÇÃO DE ARQUIVOS

As operações mais comuns que podem ser feitas em um arquivo através de algorit-
mo são: obtenção de um registro do arquivo, inserção de um novo registro, modifica-
ção do registro ou exclusão de um registro.

A localização dos registros no arquivo pode favorecer determinadas operações em


detrimento a outras. Basicamente, existem dois tipos de organização de arquivos: a
organização sequencial, onde os registros são obtidos ou inseridos no arquivo em
ordem sequencial, e a organização direta, onde os acessos dos registros são feitos em
ordem aleatória.

7.4 DECLARAÇÃO
Como o arquivo é um conjunto de registros, é necessário definir o registro que com-
põe o arquivo primeiro, para somente então definir o arquivo. De acordo com o exem-
plo da identidade citado anteriormente, cada identidade é formada por um registro:

tipo identidade = registro


caracter: nome, filiação, naturalidade
data: data de nascimento, data de expedição
fim registro;
tipo arqIdent = arquivo composto de identidade;
ident: identidade;
fami: arqIdent;

A declaração de um arquivo é feita através da seguinte especificação:

tipo Identificador = arquivo composto de Registro ;

onde:

• tipo: é uma palavra-chave;

• Identificador: representa o nome do tipo arquivo;

• Registro: identificador de um registro previamente definido;

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 109
Algoritmo e Lógica de Programação

Complementando toda a declaração necessária para utilizamos um arquivo de nosso


exemplo, teríamos:

tipo identidade = registro

caracter: nome, filiação, naturalidade

data: data de nascimento, data de expedição

fim registro;

tipo arqIdent = arquivo composto de identidade;

identidade: ident;

arqIdent: fami;

em que:

• identidade: é o identificador da estrutura do tipo registro que formará o ar-


quivo;

• arqIdent: é o identificador do tipo associado ao arquivo, formado pelos tipos


de registro identidade;

• ident: é a variável de registro;

• fami: é a variável de arquivo.

As variáveis ident e fami são utilizados no algoritmo para a manipulação do arquivo;


trata-se de variáveis que armazenarão as informações.

7.5 ABERTURA DE ARQUIVO

Na vida real, não se pode obter alguma informação contida em uma gaveta sem an-
tes abri-la, isso é feita através do seguinte comando:

abra ( IdArquivo ) ;

FACULDADE CAPIXABA DA SERRA/EAD


110 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

em que:

IdArquivo: representa o identificador da variável do arquivo previamente definida.

Exemplo:

abra (FAMI)

abra (AGENDA)

7.6 FECHAMENTO DE ARQUIVO

Não devemos manter uma gaveta aberta depois de usá-la, isso deixaria o seu con-
teúdo exposto em que podem danificá-lo. Por isso, convém sempre fechar o arquivo
após sua utilização com o comando:

fecha ( IdArquivo ) ;

em que:

IdArquivo: representa o identificador da variável do arquivo previamente definida.

Exemplo:

feche (FAMI)

feche (AGENDA)

Utiliza-se este comando, geralmente, no fim do algoritmo ou quando se deseja alte-


rar o tipo de utilização do arquivo.

7.7 COPIANDO UM REGISTRO

Um arquivo geralmente não deve ser consumido, e sim consultado. Para tal, precisa-
mos copiar o conteúdo que nos interessa em algum lugar. Utilizamos então:

copie ( IdArquivo, IdRegistro ) ;

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 111
Algoritmo e Lógica de Programação

em que:

IdArquivo: representa o identificador da variável do arquivo previamente definida.

IdRegistro: representa o identificador da variável do registro de formato igual àquele


que compõe o arquivo.

Exemplo:

copie (FAMI, AUX);

A cópia é realizada de algum lugar para outro. Neste comando, copiam-se as infor-
mações da posição do arquivo para o registro especificado no comando, o qual pos-
sui um formato idêntico ao do registro que compõe o arquivo.

Podemos observar neste fluxo que sempre parte da variável de arquivo para a variável
de registro, ou seja, é a variável de registro que recebe o resultado da operação.

7.8 GUARDANDO UM REGISTRO

Da mesma maneira que os registros são lidos de um arquivo, também devemos gra-
var registros em um arquivo. Para armazenar um registro no arquivo, faz-se necessário
que ele possua estruturação de campos idênticos à dos registros já armazenados.
Para tal, temos:

guarde( IdArquivo, IdRegistro ) ;

em que:

IdArquivo: representa o identificador da variável do arquivo previamente definida.

IdRegistro: representa o identificador da variável do registro de formato igual àquele


que compõe o arquivo.

Exemplo:

guarde(FAMI, AUX);

FACULDADE CAPIXABA DA SERRA/EAD


112 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

A gravação consiste na transferência de um registro da memória, para um periférico


(disco, disquete).

7.9 ELIMINANDO UM REGISTRO

Para podermos eliminar as informações indesejadas, utilizamos:

elimine( IdArquivo ) ;

em que:

IdArquivo: representa o identificador da variável do arquivo previamente


definida.

IdRegistro: representa o identificador da variável do registro de formato igual


àquele que compõe o arquivo.

Exemplo:

elimine(FAMI);

Este comando, elimina sempre o registro da posição corrente do arquivo especificado.

7.10 ORGANIZAÇÃO SEQUENCIAL

A principal característica da organização sequencial é a de que os registros são arma-


zenados um após o outro. Como consequência, os acessos aos registros do arquivo,
tanto na leitura quanto na escrita, são feitos sequencialmente, ou seja, a leitura de um
registro só é possível após a leitura de todos os registros anteriores e a escrita de um
registro só é feita após o último registro.

Na organização sequencial, a localização de qualquer um registro que foi armaze-


nado é indeterminada, ou seja, para acessar um registro específico, precisamos obe-
decer a sua ordem de gravação, sendo necessário percorrer todos os registros que o
antecedem.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 113
Algoritmo e Lógica de Programação

Como exemplo de organização sequencial, podemos citar a lista telefônica, no qual


os dados (nome e número) foram armazenados pelo usuário à medida que conhecia
as demais pessoas.

Considerando que a agenda do usuário já possui vários contatos já cadastrados, e


que uma nova pessoa tenha sido conhecida, só é possível armazenar os dados desta
pessoa após o último registro (nome e telefone) armazenados, o que nos leva a ter
que percorrer todos os registros do arquivo, a partir do primeiro, até encontrar o fim
do arquivo, o que pode ser feito com o comando:

avance ( IdArquivo ) ;

em que:

IdArquivo: representa o identificador da variável do arquivo previamente definida.

Esse comando coloca o arquivo na próxima posição, ou seja, no próximo registro.


Utilizando de forma consecutiva, permite percorrer o arquivo passando por uma se-
quência de registros.

fda( IdArquivo ) ;

em que:

IdArquivo: representa o identificador da variável do arquivo previamente definida.

Esse comando retorna verdadeiro quando a posição corrente é o fda (Fim do Arqui-
vo), caso contrário, retorna falso. O algoritmo para armazenar um novo telefone na
agenda do usuário utilizando esses comandos pode ser observado na Figura 58:

FACULDADE CAPIXABA DA SERRA/EAD


114 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Figura 59. Algoritmo para armazenar o telefone do usuário na agenda.

Quando o comando abra (linha 10) é executado, a posição corrente do arquivo é o


primeiro registro;

O comando guarde (linha 15) arma-


zena todas as informações contidas
no registro na posição corrente do
arquivo, neste algoritmo, foi selecio-
nado a última posição do mesmo;

No exemplo do algoritmo da Figura


59, o objetivo é localizar o telefone
de algum usuário já salvo na agenda.
Por não saber a posição do contato
no arquivo, se faz necessário percor-
rer todos os registros do início ao fim
em busca do nome da pessoa pro-
curada. No final, se todos os registros Figura 60. Algoritmo para localizar o telefone do usuário.
forem verificados e caso o não tenha
sido localizado, concluímos que ele
não existe.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 115
Algoritmo e Lógica de Programação

No algoritmo da Figura 60, exibe trecho de código onde se faz necessário atualizar o
telefone de um contato já salvo na agenda. Neste caso, o registro do usuário tem que
ser localizado no arquivo, o seu conteúdo tem que ser copiado para um registro auxi-
liar, e em seguida, o campo fone deverá ser atualizado para o novo número. Com este
registro auxiliar atualizado, basta gravá-lo na mesma posição em que se encontrava
antes, substituir o registro antigo do arquivo pelo registro atualizado (auxiliar).

Figura 61. Atualização do telefone do usuário.

A ação apresentada no algoritmo da Figura 61 é a exclusão de um registro. Supondo


que um determinado telefone não seja mais desejado, ele deverá ser excluído, para
isso, primeiramente o registro deverá ser localizado, para na sequência, ser eliminado.

FACULDADE CAPIXABA DA SERRA/EAD


116 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Figura 62. Exclusão do telefone do usuário.

Como pode ser visto na linha 22 do algoritmo acima, ao realizar a exclusão de registro
de arquivo, é recomendável solicitar ao usuário uma confirmação para a operação de
exclusão, pois após excluído não haverá mais volta.

7.11 ORGANIZAÇÃO DIRETA

A principal característica da organização direta é a facilidade de acesso a um registro


desejado. Ao contrário da organização sequencial, podemos acessar um registro es-
pecífico diretamente, sem nos preocuparmos com seus antecessores. Isto é possível
porque a posição do registro no arquivo é determinada a partir de um dos campos do
registro, escolhido no momento da criação do arquivo, este campo será denominado
“chave”. A chave deverá ser única, pois nunca podemos armazenar dois registros dife-
rentes com a mesma localização.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 117
Algoritmo e Lógica de Programação

Se a organização for direta, as disponibilidades dos registros no arquivo não são ne-
cessariamente apresentadas pelo arquivo sequencial. Ou seja, os registros não ficam
armazenados na ordem em que são gravados, por meio da chave, cada registro será
locado em uma posição reservada.

Para exemplificar uma organização direta, suponha que o gestor do RH da sua em-
presa deseja armazenar informações dos colaboradores, como o nome do colabora-
dor e salário. Para tal, ele utiliza como chave a matrícula do colaborador, esta matri-
cula também faz parte do registro e é única, ou seja, cada colaborador possui apenas
uma matrícula, não havendo chances de existirem mais de um colaborador com a
mesma matrícula.

Na medida que novos colaboradores são admitidos pela empresa, o gestor precisa
cadastrá-los no arquivo. A posição é determinada pela chave de acesso (matrícula do
colaborador) e para utilizar a chave para localizar e mover para a posição no arquivo,
utilizamos o código:

posicione( IdArquivo, CHAVE) ;

em que:

IdArquivo: representa o identificador da variável do arquivo previamente definida.

CHAVE: é um inteiro (constante ou variável) que indica a posição corrente desejada.

Na Figura 62, construímos o algoritmo para fazer o cadastramento dos colaboradores,


temos:

FACULDADE CAPIXABA DA SERRA/EAD


118 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Figura 63. Algoritmo para realizar o cadastramento do usuário.

Para que o gestor possa consultar o salário de um determinado colaborador, o mes-


mo poderá consultar diretamente o conjunto de informações deste colaborador no
arquivo, ou seja, acessar o registro diretamente por meio da chave.

Figura 64. Busca pelo salário do colaborador.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 119
Algoritmo e Lógica de Programação

Observando a Figura 66, logo após o registro ser recuperado pela chave (linha 13)
utilizando-se o comando posicione, o registro está apto a ser manipulado. Observe
que não foi necessário percorrer todos os registros do arquivo na busca da matrícula
informada, como na busca sequencial.

Para aprofundar seus conhecimentos, recomendo a leitura do capítulo 5 (da página


98 à 126) do livro Lógica de Programação, de FORBELLONE, André Luiz Villar, EBERS-
PACHER, Henri Frederico.

FACULDADE CAPIXABA DA SERRA/EAD


120 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

UNIDADE 8

OBJETIVO
Ao final desta
unidade,
esperamos
que possa:

> Entender a importância


dos testes, bem como
suas principais técnicas:
teste de unidade, teste
de integração, teste
de sistema e teste de
validação;

> Mostrar as etapas da


depuração, e o principais
tipos de erro no sistema:
erro de sintaxe, erro de
semântica e erro em
tempo de execução.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 121
Algoritmo e Lógica de Programação

8 DEPURAÇÃO E TESTES DE
ALGORITMOS.

8.1 APRESENTAÇÃO DA UNIDADE

Será apresentado os principais conceitos sobre os testes e a depuração de algoritmos.


O teste é a ação da validação de um determinado programa. Já a depuração, é o pro-
cesso de executar o passo a passo de um programa a fim apurar seus erros. Os testes
e a depuração são duas atividades difíceis e custosas que consomem elevado tempo
no processo de desenvolvimento de códigos.

8.2 TESTES

A fase de testes, é uma das principais etapas no desenvolvimento de um software.


Geralmente ela corresponde a última etapa. Através da fase de testes que é possível
detectar e solucionar a maioria dos erros no software. No decorrer de todo o desen-
volvimento, atividades e ações para garantir a qualidade do software são executadas,
porém, mesmo após a conclusão do desenvolvimento do software a possibilidade de
continuar encontrando erros é enorme.

Dijkstra (1976), afirma que, enquanto os testes mostram efetivamente a presença de


erros, nunca podem mostrar sua ausência. Um teste com sucesso, significa que ne-
nhum erro foi descoberto nas circunstâncias particulares testados, mas não diz nada
sobre outras circunstâncias. A única forma de assegurar que um programa não possui
defeitos é testar todas as possibilidades de entrada, ou seja, realizar uma bateria de
testes exaustiva. Esta situação até mesmo para os programas mais simples tende a
ser quase se não impossível de se fazer. Considere um caso simples, onde o programa
deve informar se um número é par ou ímpar, para garantir seu funcionamento sem
erros, é necessário testar todos os conjuntos de números possíveis, desconsiderando
a limitação numérica dos computadores, esse conjunto de entrada é infinito. Ou seja,
não é possível garantir que esse programa está correto por meio de testes exaustivos.

FACULDADE CAPIXABA DA SERRA/EAD


122 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Ou mesmo considerando a limitação numérica dos computadores esse resultado po-


deria levar anos, décadas ou séculos para assegurar a correção do programa. Mesmo
com limitações a atividade de teste continua sendo muitíssimo importante para a
relação de satisfação do cliente com o software.

Segundo Pressman (1995), na fase de testes, os engenheiros executam uma série de


atividades que consistem em varrer o software criado a procura de qualquer tipo de
erro ou falha na codificação, que possam vir a interferir no correto funcionamento do
aplicativo. O teste é responsável por detectar o maior número possível de erros, pois
encontrar todos é praticamente impossível. Os testes de software são responsáveis
por executar o software utilizando valores reais, com a finalidade de encontrar erros.
Caso os testes sejam realizados e nenhuma falha seja descoberta, provavelmente,
os casos de testes não foram bem elaborados. Seguindo o raciocínio de Pressman
(1995), os casos de testes devem elevar a probabilidade de detecção de erros, caso
contrário, os testes não serão bem-sucedidos. Pressman (1995), defende ainda que o
teste bem-sucedido, além de apontar falhas ainda não constatadas, deve fazer isso
com o mínimo tempo e esforço.

Inthurn (2001), afirma que há um gasto frequente muito grande de tempo e dinheiro
em correções de software, em que o desenvolvimento não foi adequado e a fase de
testes não foi satisfatória. Assim, entende-se que os testes são importantes, também,
para evitar surpresas desagradáveis no futuro. Além disso, os testes são responsáveis
por mostrar que o software possui erros e que os mesmos devem ser corrigidos, mas
isso não significa que a partir das correções, o software estará imune a possíveis falhas
posteriores. Novos erros podem ser inseridos ao software no momento em que outros
erros são corrigidos, através de alterações realizadas no código a fim de corrigir os er-
ros descobertos até o momento.

Os defeitos nos softwares ocorrem porque que os escrevem são pessoas humanas, e
por sua vez sabemos que as pessoas não são perfeitas e estão sujeitas a falhas. Entre-
tanto, elas têm habilidades para tal responsabilidade, mas também não são perfeitas,
o que nos leva a admitir que são suscetíveis de cometer erros. E muitas vezes, quem
demanda o software não tem total clareza da sua real necessidade, fazendo com que
os softwares sejam desenvolvidos sobre crescente pressão para entregá-los em pra-
zos rigorosos, sem tempo para checar as atividades realizadas.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 123
Algoritmo e Lógica de Programação

O custo de realizar os testes no decorrer do desenvolvimento do software é relativa-


mente pequeno se comparado ao gasto com manutenção corretiva após a finaliza-
ção do software, sem mencionar que para, um software ter qualidade, é necessário
que haja uma rotina exaustiva de testes, que se estende por todo o desenvolvimento
do projeto.

O teste de software sempre foi uma tarefa crítica no processo de desenvolvimento de


software, todos entendem a sua importância, mas na prática dificilmente investem o
suficiente nessa atividade. Diversos são os fatores que corroboram com este cenário,
como:

1. Testar software geralmente não é uma tarefa trivial;

2. Mercado desprovido de profissionais qualificados;

3. Falta de conhecimento em técnicas e critérios de testes;

4. Não há informações quantitativas suficientes sobre o custo/benefício do teste


de software;

5. O software normalmente só é testado depois do produto pronto;

6. A área de teste de software é muito pouco explorado nas universidades;

7. Há um preconceito sobre a produtividade do teste relacionado ao projeto


como um todo;

8.3 ESTRATÉGIA DE TESTES

Existem diversas maneiras de se testar um software, uma delas é aguardar que o


software seja totalmente construído para aí sim iniciar os testes. Esta prática já se de-
monstrou não ser muito eficiente. Uma estratégia muito comum na literatura é a di-
visão das atividades de teste em fases assim como acontece no desenvolvimento de
software. Utiliza-se a estratégia de “dividir para conquistar” e em cada etapa é reali-
zado um tipo de teste focando em determinada característica do software, iniciando
nas unidades menores, depois nas integrações dessas unidades e incrementalmente
até alcançar o todo do sistema. O objetivo principal das técnicas são os mesmos,
encontrar as falhas no software. Abaixo estão descritas algumas das técnicas mais
conhecidas.

FACULDADE CAPIXABA DA SERRA/EAD


124 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

8.3.1 TESTE DE UNIDADE

Também conhecida como teste unitário ou teste de módulo, é a fase em que se va-
lida as menores unidades de software desenvolvidas (pequenas partes ou unidades
do sistema) como: uma classe de métodos, funções isoladas e unidades lógicas. O
objetivo é o de encontrar falhas de funcionamento dentro de uma pequena parte do
sistema funcionando independentemente do todo. Medeiros (2005), afirma que este
tipo de teste deve ser realizado várias vezes, dia a dia, pois é muito mais fácil corrigir
pequenas falhas do que o sistema inteiro após construído.

Como o software no todo é composto por várias unidades e estas unidades apresen-
tando erros fazendo com que o software não funcione, fato que credencia o teste de
unidade a um dos primeiros testes a serem realizados no software. Diante disso, o
esforço é concentrado nessas unidades menores e só após o teste de unidade segue
avançando para as próximas fases. Alguns dos defeitos mais comuns encontrados nos
testes de unidade são:

1. inicialização incorreta de variáveis;

2. precedência aritmética incorreta;

3. operações mescladas;

4. imprecisão numérica;

5. comparação de tipos de dados diferentes ou variáveis diferentes;

6. operadores e precedência lógica incorreta;

7. final de ciclo inadequada ou inexistente;

8. variáveis de laço inadequadamente alteradas.

As boas práticas defendem que o teste unitário deve ser independente de outros
testes, validando assim cada parte ou funcionalidade individualmente. Quando uma
unidade que está sendo testada necessita realizar chamadas a outros métodos ou
classes que não estão sob teste, são utilizados os mocks, que são objetos criados para
simular o comportamento de objetos reais nos testes, simulando assim seu funciona-
mento na unidade. O teste unitário também é caracterizado pelo uso de controlado-
res (drivers) e simuladores (stubs), este último tem como objetivo, simular o compo-
nente invocado a fim de focar o teste na unidade previamente selecionada.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 125
Algoritmo e Lógica de Programação

Um ponto importante, que diz respeito também aos testes unitários, é com relação à
futura manutenção do código. Não é necessário se preocupar com o fato de que pos-
síveis refatorações ou alterações no código façam com que novos erros inesperados
ocorram, já que todas as funcionalidades do sistema estão sendo testadas novamente.

Outro ponto positivo que destaca a fundamental importância em se realizar o teste


unitário, está no fato da antecipação de um erro crítico, imagine se os testes a serem
realizados em um carro zero, seja feito somente após a conclusão do mesmo. Se algo
sair errado, os danos podem ser irreparáveis, ou seja, o erro quanto mais cedo ser
diagnosticado, mas barato será sua correção.

8.3.2 TESTE DE INTEGRAÇÃO

Em softwares complexos as unidades sozinhas não fazem sentido. Quando se utiliza


a ideia de “dividir para conquistar” é necessário ligar as unidades após o seu desenvol-
vimento. Sendo que a união de todas as unidades forma o sistema completo. Como
recomendado por Pressman (1995), não precisa esperar todo o sistema ficar pronto
para iniciar os testes, encontrar e corrigir defeitos.

Durante o desenvolvimento do sistema os gerentes decidem quem ficará responsável


por cada fase de teste, normalmente cada programador se encarrega de testar seu
próprio código, ao final, as partes desenvolvidas por cada programador são passadas
a outra equipe que irá unificar os códigos. Essa equipe realiza a integração do softwa-
re e mais testes são feitos. Os testes são realizados em partes separadas ou subsiste-
mas e no sistema como um todo, por fim o teste é detalhadamente documentado e
arquivado (SOMMERVILLE, 2011).

Os tipos de erros mais comuns nos testes de integração são:

1. Dados inválidos nas chamadas às interfaces do componente;

2. Modificações em variáveis globais utilizadas por várias unidades;

3. Incompatibilidade ou perda de precisão nas passagens de valores; e outros.


Por exemplo, quando um módulo A chama outro módulo B e passa uma in-
formação de A para B incorreta, há uma enorme chance do módulo B produzir
uma saída incorreta ou não esperada.

FACULDADE CAPIXABA DA SERRA/EAD


126 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Na fase de teste de integração, o objetivo é encontrar falhas provenientes da inte-


gração interna dos componentes de um sistema. Geralmente os tipos de falhas en-
contradas são de transmissão de dados. Por exemplo, um componente A pode estar
aguardando o retorno de um valor X ao executar um método do componente B; po-
rém, B pode retornar um valor Y, gerando uma falha. Não faz parte do escopo dessa
fase de teste o tratamento de interfaces com outros sistemas (integração entre siste-
mas). Essas interfaces são testadas na fase de teste de sistema, apesar de, a critério do
gerente de projeto, estas interfaces podem ser testadas mesmo antes de o sistema
estar plenamente construído.

As formas mais comuns de se conduzirem os testes de integração é de forma descen-


dente ou top-down e ascendente ou button-up.

8.3.2.1 INTEGRAÇÃO TOP-DOWN

É um tipo de abordagem da integração incremental. Segue uma ordem hierárquica,


de cima para baixo. Os módulos mais importantes do sistema são desenvolvidos pri-
meiro, depois os menos importantes. Após desenvolvido, cada módulo é testado in-
dividualmente, integrado aos outros módulos e testado novamente, assim, é possível
conferir se a interface com os demais módulos continua compatível.

8.3.2.2 INTEGRAÇÃO BOTTOM-UP

Nesta abordagem a ordem dos testes dos módulos são inversos da top-down, onde
os módulos menos importantes, ou de níveis mais baixos da hierarquia são desen-
volvidos e testados primeiro, depois os próximos níveis acima na hierarquia até que o
último módulo seja testado.

8.3.3 TESTE DE SISTEMA

Após a execução e a eliminação das falhas aplicando os testes preliminares: teste de


unidade e o teste de integrações entre as unidades e o software, já é o momento de
preparar um pacote completo com todas as unidades do programa e iniciar o teste
de sistema.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 127
Algoritmo e Lógica de Programação

O objetivo deste teste é executar o sistema sob ponto de vista de seu usuário final,
varrendo todas as funcionalidades em busca de falhas em relação aos objetivos ori-
ginais do produto. Os testes devem ser executados em condições similares ao de um
ambiente de produção, ou seja, um ambiente próximo ao utilizado pelo usuário final
no seu dia-a-dia. Contemplando interfaces sistêmicas, massas de dados e configura-
ções de hardwares.

O produto final consiste na união de vários sistemas e subsistemas. O teste de sistema,


por sua vez, consiste em descobrir supostas falhas nas interações desses módulos e,
ainda, em verificar que todos os requisitos funcionais ou não, estão sendo atendidos.

Nesse teste as expectativas definidas nas especificações de requisitos do software de-


verão ser utilizadas como insumo para a criação do projeto dos casos de teste. Nesse
caso, o testador tem um trabalho de investigação com o desafio de tentar burlar o
sistema, tentar passar pelos pontos inseguros e vulneráveis do software. Buscar simu-
lar o comportamento dos seus usuários, de simples operadores à usuários avançados
e experientes, com a visão de usuário tentar descobrir as falhas produzidas durante a
fase de montagem do sistema.

Dentre os tipos de testes realizados nessa etapa pode-se citar:

1. teste de recuperação;

2. teste de segurança;

3. teste de estresse;

4. teste de desempenho;

5. teste de usabilidade, dentre outros.

8.3.4 TESTE DE VALIDAÇÃO

O teste de validação ou verificação pode ser considerado bem-sucedido quando o


software funciona da maneira que o cliente o idealizou. Ou seja, seguindo as especi-
ficações e os documentos de requisitos do software, verifica-se se o produto certo foi
construído. A validação do software, na fase de testes, é realizada por meio de uma
série de testes que demonstram a conformidade com os requisitos.

FACULDADE CAPIXABA DA SERRA/EAD


128 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Segundo Sommerville (2011), os testes de validação ou verificação são responsáveis


por constatar se o sistema desenvolvido está realmente de acordo com as especifica-
ções fornecidas pelo cliente e se satisfaz as suas necessidades. Os testes de validação
devem evoluir de acordo com o desenvolvimento do software, não sendo executados
de maneira isolada, ou seja, sempre que um módulo ou uma classe é desenvolvido,
testes são realizados. Os testes são incrementados a cada etapa de desenvolvimento,
mais classes e funções implementadas, são testados.

Geralmente, os testes de aceitação são realizados por um grupo de usuários finais do


sistema, que possuem um conhecimento do resultado esperado do programa, que
simulam operações de rotina do sistema de modo a verificar se seu comportamento
está de acordo com o solicitado. Este teste possui uma enorme importância, visto
que é este que determinará se o sistema satisfaz ou não seus critérios de aceitação e
para permitir ao cliente determinar se aceita ou não o sistema. Nesta etapa de testes,
pode incluir testes funcionais, de configuração, de recuperação de falhas, de seguran-
ça e o de desempenho.

Neste tipo de teste, a procura por defeitos já não faz parte do objetivo maior, e sim,
a tentativa de estabelecer a confiança entre as partes, de um lado o sistema ou uma
característica específica do sistema e do outro quem demandou o sistema.

O teste de aceitação é composto pelas seguintes formas de testes:

Teste de aceite do usuário: tem como objetivo verificar se o sistema está apropriado
para o uso por um determinado perfil de usuário;

Teste operacional de aceite: verifica a realização de atividades de operação pelo usuá-


rio administrador;

Teste de aceite de contrato e regulamento: verifica se algum critério de aceite incluso


em contrato na produção de software sob encomenda.  O critério de aceite deve ser
definido quando o contrato é assinado. Teste de aceite de regulamento é quando se
verifica a necessidade de adesão a algum regulamento de acordo com outras normas
(ex: segurança, governamental, legislação).

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 129
Algoritmo e Lógica de Programação

8.4 DEPURAÇÃO

A principal função da atividade de teste é demonstrar que um produto de software


contém defeitos. Com isso, sendo a atividade de teste bem-sucedida é necessário
identificar o que levou o produto de software a falhar. Nesse ponto, entra em ação ou-
tra atividade denominada depuração. O objetivo da atividade de depuração é apurar
o produto em teste e localizar, precisamente, qual defeito resultou na falha apontado
pelos testes. Assim sendo, as atividades de teste e depuração são consideradas com-
plementares.

Deus (2009), afirma que, assim como os testes, depuração é uma área de pesquisa que
está recebendo muita atenção da sociedade acadêmica, vários experimentos, mo-
delos e ferramentas já foram desenvolvidos buscando aperfeiçoar essa atividade na
construção de software. Pode-se citar um modelo de depuração chamado Hipótese-
Validação, técnica de fatiamento de programas e outras. As informações oriundas
do teste podem ter um papel importante durante a fase de depuração, fornecendo
informações para acelerar o processo de busca e correção dos defeitos.

A depuração ou debugging ocorre quando um caso de teste encontra e mostra erros


do sistema, ou seja, para que se faça a depuração é necessário que os testes realizados
tenham obtido êxito. A depuração consiste em analisar os resultados obtidos com os
esperados, e, no caso de diferença entre eles, encontrar a causa, ou seja, encontrar o
motivo da não correspondência entre os dados reais e os esperados, e, por fim, cor-
rigir o problema (PRESSMAN, 1995). Em resumo, a depuração objetiva encontrar e
corrigir a causa, ou as causas, dos erros no sistema.

8.4.1 ERRO DE SINTAXE

Assim como no português, nas linguagens de programação espera-se que os diversos


símbolos sejam dispostos de uma forma lógica uns em relação aos outros, seguin-
do as regras da gramática da linguagem de programação. Um erro sintático ocorre
quando as “frases” do programa (instruções, expressões, declarações de variáveis) es-
tão mal formuladas, também chamado de “erro gramatical”. Dentro os outros tipos
de erro, este geralmente é o mais fácil de ser identificado, uma vez que o próprio
compilador/interpretador da linguagem consegue detectá-los. Diante disso, o pro-
grama não é executado enquanto existir alguma instrução sintaticamente incorreta.

FACULDADE CAPIXABA DA SERRA/EAD


130 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

Segundo Stroustrup (2009), apesar do compilador rejeitar a execução do programa


acusando um erro, nem sempre é fácil para o compilador relatar ao desenvolvedor
este erro. Isso porque o compilador necessita apurar melhor sobre o erro, até mesmo
para saber se realmente trata-se de um erro. O efeito disso é que, mesmo que os erros
de sintaxe tendem a ser completamente triviais, as mensagens de erros muitas vezes
são enigmáticas e, ocasionalmente, se refere a uma linha mais adiante do programa.
Portanto, para erros de sintaxe, se você nada vê de errado na linha que o compilador
indicou, examine também as linhas anteriores do programa. Observe alguns erros
típicos de sintaxe:

Figura 65. Erros de sintáxe

Em todas as linhas do algorimo da Figura 64 existe um erro sintático, ou seja, elas


não estão bem formatadas de acordo com a gramática da linguagem C, portando, o
compilador vai rejeitá-las.

8.4.2 ERRO DE SEMÂNTICA

O segundo tipo de erro é o erro de semântica, também conhecido como erro de


lógica do programa. Geralmente são difíceis de serem encontrados uma vez que o
compilador não gera nenhuma mensagem de erro, ou seja, mesmo existindo o erro
semântico, o programa será executado com sucesso sem gerar nenhuma mensagem
de erro ao usuário. Porém, o programa não executará as instruções como realmente
deveria ser executada obedecendo as regras do documento de requisitos.

Identificar os erros semânticos não é uma tarefa trivial, requer uma análise investiga-
tiva validando e checando as saídas do programa avaliando o resultado do algoritmo.
O compilador não fornece informações sobre o que está errado. Somente o usuário
consegue identificar o que o programa realmente deveria fazer, porém, não o está.
A origem deste tipo de erro se dá de o fato do programador não ter expressado corre-
tamente, através da linguagem de programação, a sequência de instruções a serem.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 131
Algoritmo e Lógica de Programação

O processo de identificação e correção de erros, tanto os erros sintáticos quando os


semânticos, dá-se o nome de depuração ou debugging, e os erros no programa são de-
nominados bugs. Observe no algoritmo da Figura 65 um exemplo de erro semântico:

Figura 66. Erro no cálculo da média.

Como pode ser observado no algoritmo acima, o cálculo da média está sendo feito de
forma errada já que existem 11 números (de 0 até 10) e não apenas 10 como escrito.

8.4.3 ERRO EM TEMPO DE EXECUÇÃO

O terceiro tipo de erro é o runtime error, ou erro em tempo de execução, assim cha-
mado porque só aparece quando você executa o programa. Também são conheci-
dos como exceções, porque normalmente indicam que alguma coisa excepcional
aconteceu.

Os erros de execução ocorrem quando o programa tenta fazer algo impossível. Estes
tipos de erros são detectados somente na execução do algoritmo. Erros típicos:

• Divisão por zero;

• Tentar utilizar um subíndice fora dos limites definidos em um array;

• Recurso externo inacessível como uma tabela inexistente em um banco de


dados;

• Acessar um objeto em uma lista nula.

Para aprofundar seus conhecimentos, recomendo a leitura do capítulo 5 (da página


53 à 60) do livro Estruturas de Dados & Algoritmos em Java - 5ed, de Michael T. Goo-
drich,Roberto Tamassia

FACULDADE CAPIXABA DA SERRA/EAD


132 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

REFERÊNCIAS
AGUILAR, Luis Joyanes. Fundamentos de Programação: Algoritmos, estruturas
de dados e objetos. Porto Alegre: AMGH, 2008.

ASCENCIO, Ana Fernanda Gomes. Fundamentos da programação de


computadores: algoritmos, pascal e C/C++ e Java. 2.ed.São Paulo: Pearson
Prentice Hall, 2007.

DAMASCENO, Alexandro Lima. O Impacto da Hierarquia de Memória sobre


a Arquitetura IPNOSYS. 2016. Dissertação (Mestrado em Computação) –
UNIVERSIDADE DO ESTADO DO RIO GRANDE DO NORTE

DEUS, Gilcimar Divino de. Avaliação de Técnicas de Teste para Dispositivos


Móveis por Meio de Experimentação. 2009. Dissertação (Mestrado em
Computação) – Instituto de Informática da Universidade Federal de Goiás

DIJKSTRA, E. A Discipline of Programming. Prentice Hall, Englewood Cliffs,


NJ, 1976.

FARRER, Harry. et al. Algoritmos Estruturados. Rio de Janeiro: LTC, 3º ed,1999.

FARRER, Harry. et al. Pascal Estruturado. Rio de Janeiro: LTC, 3º ed, 1999.

FÁVERO, Eliane Maria de Bortoli. Organização e arquitetura de computadores


/ Eliane de Bortoli Fávero. – Pato Branco : Universidade Tecnológica Federal do
Paraná, 2011.

FORBELLONE, André Luiz Villar, EBERSPACHER, Henri Frederico. Lógica de


Programação: A construção de algoritmos e estruturas de Dados. São paulo:
Prentice Hall, 3º ed, 2005.

INTHURN, Cândida. Qualidade & Teste de Software. Florianópolis: Visual


Books, 2001.

PRESSMAN, Roger S. Engenharia de Software. São Paulo: Makron Books, 1995.

FACULDADE CAPIXABA DA SERRA/EAD


Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 133
Algoritmo e Lógica de Programação

SHELL, D.L. “A Highspeed Sorting Procedure”. Communications of the ACM.2


(7), 30-32, 1959.

SOMMERRVILLE, Ian. Engenharia de Software, 9ª Edição. Pearson Education,


2011

TANENBAUM, Andrew S. Organização estruturada de computadores. São


Paulo: Pearson Prentice Hall, 2007.

WILLRICH, R.; CARMO, Luiz Fernando Rust da Costa; FARINES, Jean Marie;
GAUTHIER, F.A.O.. Uma abordagem Semântica para a especificação de
Qualidade de Serviço em Redes de Computadores. 2010. Dissertação (Mestrado
em Ciências da Computação) - Universidade Federal de Santa Catarina.

ZIVIANI, Nivio. Projeto de Algoritmos com implementação em Pascal e C.


São Paulo: 2ºed. Revista e Ampliada, 2005.

FACULDADE CAPIXABA DA SERRA/EAD


134 SUMÁRIO
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
Algoritmo e Lógica de Programação

CONHEÇA TAMBÉM NOSSOS CURSOS DE PÓS-GRADUAÇÃO A DISTÂNCIA NAS ÁREAS DE:

SAÚDE • EDUCAÇÃO • DIREITO • GESTÃO E NEGÓCIOS

EAD.MU LTIVIX.EDU.BR
FACULDADE CAPIXABA DA SERRA/EAD
Credenciada pela portaria MEC nº 767, de 22/06/2017, Publicada no D.O.U em 23/06/2017
SUMÁRIO 135

Você também pode gostar