Escolar Documentos
Profissional Documentos
Cultura Documentos
CURSO DE LÓGICA DE
PROGRAMAÇÃO
© 2007 by Digerati Books
Todos os direitos reservados e protegidos pela Lei 9.610 de
19/02/1998.
Nenhuma parte deste livro, sem autorização prévia por escrito da
editora, poderá ser reproduzida ou transmitida sejam quais forem os
meios empregados: eletrônicos, mecânicos, fotográficos, gravação
ou quaisquer outros.
Diretor Editorial
Luis Matos
Assistência Editorial
Monalisa Neves
Erika Sá
Edição de Arte e
Projeto Gráfico
Daniele Fátima
Revisão
Cárita Ferrari Negromonte
Diagramação
Rogério Chagas
Capa
Daniel Brito
ISBN 978-85-60480-24-1
1. Programação (Computadores).
2. Algoritmos. I. Título.
CDD 005.1
Lógica e algoritmos
7. Retire o dinheiro.
Figura 1.1.
Análise preliminar
Entenda o problema com a maior precisão possível, identifique os
dados e os resultados desejados. Este é o estágio do processo no
qual o programador obtém entendimento total do problema antes de
pensar numa solução.
Alteração
Fluxograma tradicional
Figura 1.6.
Figura 1.7.
Diagrama de Chapin
Figura 1.8.
Pseudocódigo, ou Portugol
3. O casal Silva tem vários filhos. Cada filha tem o mesmo número
de irmãos e irmãs, e cada filho tem duas vezes mais irmãs que
irmãos. Quantos filhos e filhas o casal tem?
Oscar Wilde
Inteiro
Real
Lógico
Data
Exercícios de fixação
Indique para cada dado citado se ele é do tipo Inteiro(I), Real (R),
Lógico (L), Moeda (M) ou Texto (T).
Figura 2.1.
Profissao Profissão
Bim1 1bim
Depto _ XY Depto(xy)
Tabela 2.1.
Tendo como objetivo facilitar a compreensão do algoritmo, os
identificadores são escritos, sempre, com letras minúsculas,
enquanto as palavras-chave são escritas com maiúsculas e grifadas
(regra de legibilidade).
Denomina-se palavra-chave aquela que tem um significado
próprio, independente do algoritmo em que esteja inserida. Em vista
disso, as palavras-chave não podem ser usadas como
identificadores.
Prefixos Exemplos
Tabela 2.2.
Declaração de variáveis em um
pseudocódigo
Para declarar uma variável ou uma constante em um
pseudocódigo, unimos dois conceitos já vistos: o identificador e o
tipo de dado primitivo com a seguinte regra de sintaxe:
VAR
Identificador1, Identificador2, IdentificadorN : Tipo de dado
CONST
Identificador1, Identificador2, IdentificadorN : Tipo de dado
Vejamos um exemplo:
VAR
Nome : TEXTO
Salario _ familia : REAL
Codigo, quantidade, matricula : INTEIRO
CONST
Pi : REAL
Atribuição de um dado a uma
variável
Antes de explicar o que vem a ser um comando de atribuição,
devemos definir o conceito de comando como a descrição de uma
ação a ser executada em dado momento.
O comando de atribuição permite que se forneça um valor a uma
variável, sendo que a natureza deste valor tem de ser compatível
com o tipo da variável na qual está sendo armazenado o comando.
Qualquer tentativa de atribuição de valores de outro tipo é
considerada um erro:
Identificador Expressão
em que:
Tabela 2.3.
Exemplos:
• nu _ chamada 1;
• cor “VERDE”;
• existe Falso;
• A B;
• media soma / n.
Desafio
Operador Significado
+ Adição
- Subtração
* Multiplicação
/ Divisão
** ou ^ MENOS O OU Potenciação
Operadores relacionais
operador significado
= Igual
<> Diferente
Veja um exemplo:
Nota 6,5
Média 7,0
Expressão Resultado
Operadores lógicos
V1 E V2
V V V
V F F
F F V
F F F
V1 OU V2
V V V
V V F
F V V
F F F
V1 NÃO V1
V F
F V
Função Descrição
Retorna a quantidade de
Tamanho(exp)
caracteres de uma expressão texto.
Função Descrição
Veja a sintaxe:
VarRetorno FUNÇÃO(P1,P2,Pn)
Em que:
VarRetorno é uma variável de memória que receberá o valor de
retorno ao processamento da função, seu tipo de dado tem de
ser compatível com o tipo de dado de retorno da função;
P1, P2, Pn são parâmetros que serão fornecidos à função,
necessários à sua finalidade e funcionamento, sempre
separados por vírgula.
Prioridade dos operadores
Pode-se ter mais de um operador na mesma expressão. Em
alguns casos, conforme os valores envolvidos, a ordem em que são
efetuadas as operações afeta o resultado final.
Assim como acontece entre as operações aritméticas, também
existe uma relação de prioridade entre todos os operadores. Na
tabela seguinte, são apresentadas as prioridades entre todos os
operadores conhecidos, visto que podem estar presentes em uma
mesma expressão lógica:
Prioridades Operadores
Quinto lugar E
Sexto lugar OU
2)
J ”INFO/2006-ATUAL”
W 6
A ESQUERDA (J , W) = “INFO/2”
B QUOCIENTE (TAMANHO( J ) ,2)
C DIREITA (SUBCADEIA(J , 5 , 6) , 2)
D RESTO (QUOCIENTE (TAMANHO(J)*2,3),TAMANHO(ESQUERDA(J,2))
D TAMANHO( J ) > RAIZ (TAMANHO (J+10) ) e W / 2 <>TAMANHO(J)
^ 2
3)
A RAIZ (121)
B A ^ 0
C B > A e A > B ou A <> B e B <> A ou A = B
C NÃO C
C NÃO (NÃO C)
A 10 ^ 2 + (( A / B * 2) -20 / 2 / 2 / 2)
4)
D 1
E “MIRIAN”
G “SALA DE AULA”
F SUBCADEIA (G, 3, 5) + DIREITA (E, 3)
H (TAMANHO (F) ** D) * 2 < QUOCIENTE (36, TAMANHO (E))
5)
A 3
B 6
C B < A E (TAMANHO (B) * 2 / 4 < 10
D RAIZ (TAMANHO (B) ^ 2) = B E A ^ 3 <> RESTO (8 * 2, 4) OU
C
6)
A RAIZ (36)
B 2
C A ^ B >= B / 2 E A > B OU B <> A
G C= A OU B < A E (A ^ B / 2) < B
7)
A RAIZ (144) + 6
B ((A ^ 2) – 24)) / 3
C B * 2 / 4 > A OU QUOCIENTE (18, 6) <> A E NÃO V
8)
A “COMPUTADOR 10”
B RESTO (TAMANHO(A) – 1, 2) > 10 E SUBCADEIA (A, 2, 2) =
DIREITA (A, 6)
9)
A “BRASIL”
B “SUDESTE”
C “PRAIA”
D SUBCADEIA (B, 3, 2) + DIREITA (A, 3) + ESQUERDA (C, 2) =
ESQUERDA (A, 4)
E NÃO D
10)
A RAIZ(144)
B 3
C B ^ 2 + ((A + B) / 3) > (A - B)/3
C NÃO C
C NÃO ( NÃO C)
11)
A 10
B “PROGRESSO”
C (TAMANHO (B) / 2 ^ 5 > 100 OU ( RAIZ (49)) < > A > OU
QUOCIENTE ( 20, A) > TAMANHO (B)
E NÃO (D) E NÃO ( NÃO (C)) OU (TAMANHO (SUBCADEIA (B,5,2)))
> ( TAMANHO (CADEIA (B,2,2)))
12)
A 2
B 3
C B ^ A / 3 + B * 2 ^ 2
D V
E F
H A < 10 + A * C E D OU C > B ^ 3
13)
A 2
B 4
C B ^ 2 / A * 4 + B
D F
E V
H A > 10 E D OU B ** 2 < = 6 E C < > 4
14)
K “LAGOA”
L “PATO”
M DIREITA (K,2) + ESQUERDA (L,3) = “LAGO”
N M OU NÃO M E (TAMANHO (K) > TAMANHO (L))
15)
B 4
C “INFORMÁTICA”
D (TAMANHO (C) 12 / 11 < QUOCIENTE ( 10,B)
E DIREITA (C,4) + ESQUERDA (C,2) = “FOR”
16)
J “MURILO – OE”
K “MARQUES – EST”
Y “2”
A (TAMANHO (K) ^ 2) < > 3 E SUBCADEIA (J, 1,2) = “MU”
B RESTO (TAMANHO (J) / 3,2) > QUOCIENTE (8,Y)
17)
A RAIZ (36)
B “EDGAR”
S “CASSIANA”
18)
X 4
Y 6
A ”CELESTE”
B “TEDIEL”
C (TAMANHO (A + B) + X * Y – QUOCIENTE (12,X) ^ RESTO (Y,2))
D CADEIA (A,2,3) = ESQUERDA (CADEIA (B,4,2),1) E TAMANHO (A
- B) = QUOCIENTE (C + B,4) – RESTO (X,3)
19)
A 10
B QUOCIENTE (A,2)
C RESTO (B,2)
D B > A OU (A – C * B) > C
20)
A RAIZ (25)
B A ^ 2
C “RAFAEL”
D CADEIA (C,3,4) < > B E ESQUERDA (C,2,5) = A
21)
A RAIZ (36)
B 5 + A ^ 0
C A > = B OU B = < A E B < > A E A > B
C NÃO C
C NÃO (NÃO C)
22)
A “CURSO TÉCNICO INFORMÁTICA”
B 8
C ESQUERDA (A,B)
D CADEIA (A,8,8)
E TAMANHO (A ^ 2) / 5 = A E QUOCIENTE (C * D ^ 2) / 2 = D
23)
A 25
B 8
C “TÉCNICO ADMINISTRAÇÃO”
D “TÉCNICO ENFERMAGEM”
E TAMANHO (A ^ 2) / 5 = TAMANHO A E QUOCIENTE (TAMANHO (C +
D ^ 2) / 2 = TAMANHO D)
F B > A E A > B OU A < > B E B <A
24)
A 20
B 12
C “LIVIA”
D RESTO (20,3) < > B E QUOCIENTE (TAMANHO (C) ^ 2 , 4) =
TAMANHO (DIREITA (C,2))
25)
C TAMANHO (CADEIA (C,1,2) + DIREITA (C,3) < 6 OU RAIZ (100)
+ QUOCIENTE (TAMANHO (C) / 2) – RESTO (13,3)) = 10
26)
H 5
M 2
A “LUCIO”
B “PRISCILA”
H QUOCIENTE (TAMANHO (A + B), 13)
B TAMANHO (A) ^ 2 / 5 > QUOCIENTE (10,M)
M ESQUERDA (B + A,3) + DIREITA (A + B,5)
27)
A 2
B A ^ 2
C 10
D RESTO ((C + B + A),2) + QUOCIENTE (( C + B+ A),2) > (A +
B) * 10 ** 0
28)
A1 “GRUPO SEIS”
B1 ESQUERDA (A1,5) < > DIREITA (A1,4) E SUBCADEIA (A1, 4,4)
< > “POSE”
A ESQUERDA (A1,5) = DIREITA (A1,4) OU SUBCADEIA (A1,4,4 ) =
“POSE”
C NÃO (NÃO A = NÃO B1) E A = B1 OU B1 = A
a. Não D
b. D e E
c. (D e E) ou (A = B)
d. (D ou E) e (A < B)
e. (A > B) ou (B < C)
f. Não (A < B)
g. A + B < C e D ou E e Não D
h. A + B * C / B = 3 e Não (A ou B)
Como representar um algoritmo
em pseudocódigo?
Para representar um algoritmo em pseudocódigo, utilizaremos um
formato padrão que facilita muito a passagem, posteriormente, da
solução desenvolvida, para uma linguagem de programação
estruturada.
Vale ressaltar que abordaremos, nos próximos capítulos, uma
outra metodologia, que será aplicada para as implementações dos
pseudocódigos em linguagem de programação visual.
O formato-padrão pode ser visto a seguir:
ALGORITMO nomedoAlgoritmo
VAR
NomeVar : TIPODEDADO
CONST
NomeConst : TIPODEDADO
INICIO
BLOCO DE COMANDOS
FIM
FIM ALGORITMO
em que:
ALGORITMO: é uma palavra reservada que indica o início da
definição de um algoritmo em forma de pseudocódigo;
nomedoAlgoritmo: é um nome simbólico dado ao pseudocódigo
com a finalidade de distingui-lo dos demais;
VAR e CONST: consiste em uma área reservada para declarar
as variáveis “globais” e constantes usadas no pseudocódigo
principal;
INICIO e FIM: são as palavras que delimitam o corpo do
pseudocódigo.
VAR
horas _ trab: INTEIRO
sal _ hora, sal _ receber : REAL
INICIO
LEIA horas _ trab
LEIA sal _ hora
sal _ receber horas _ trab * sal _ hora
FIM
FIM ALGORITMO
VAR
horas _ trab: INTEIRO
sal _ hora, sal _ receber : REAL
INICIO
LEIA horas _ trab
LEIA sal _ hora
sal _ receber horas _ trab * sal _ hora
MOSTRE “O funcionário vai receber”, sal _ receber
FIM
FIM ALGORITMO
Para treinar
1. Dois homens vão fazer uma viagem de 18.000 km, de
automóvel. Entretanto, os pneus só agüentam 12.000 km.
Quantos pneus, no mínimo, precisam levar de reserva?
Estruturas de controle de um
algoritmo
Peter Drucker
Estruturas de controle de um
algoritmo
A utilização de estruturas de controle sobre um algoritmo permite
a execução automática de seus passos (comandos) predefinidos, e
permite, ainda, que o algoritmo possa “decidir” entre dois ou mais
valores em uma condição, ou testar várias condições paralelas para
o conteúdo de uma variável lida.
O estudo dessas estruturas permite ao programador resolver
qualquer problema em pseudocódigo aplicado à computação.
Essas estruturas serão apresentadas simultaneamente em
pseudocódigo, NS e no fluxograma tradicional, para que o leitor
tenha uma visão global da aplicação de cada estrutura existente nos
três tipos de representação de algoritmos.
Estrutura seqüencial
Exercício resolvido
Estrutura condicional
Condicional simples
Este tipo de estrutura permite executar uma seqüência de
comandos de acordo com o resultado de uma comparação
(condição) ou de uma decisão.
Após a avaliação da condição, uma das alternativas é executada.
Sendo executada a alternativa ENTÃO, quando a condição for
satisfeita (verdadeira), ou a alternativa SENÃO, quando a condição
não for satisfeita (falso):
SE condição ENTÃO
Comando1
Comando2
.
.
.
ComandoN
SENÃO
Comando1’
Comando2’
.
.
.
ComandoN
FIM SE
Figura 3.3.
Condicional composta
Certas aplicações envolvem um grande número de testes
condicionais simples e, para tratá-los, é preciso aninhamento de
partículas SE. Existe uma estrutura que, aplicada a certos casos de
aninhamento, produz o mesmo resultado e torna o algoritmo mais
inteligível e menos vulnerável a ambigüidades. Esta estrutura é
chamada estrutura condicional composta. Observe:
Figura 3.4.
Exercício resolvido
Exercício resolvido
Menos de R$ 500,00 5%
De R$ 501,00 a R$ 1.200,00 7%
De R$ 1.201,00 a R$ 1.800,00 9%
Tabela 3.1.
Algoritmo calc _ desc _ inss
Var
Salar _ liq : moeda
início
Leia salar _ liq
Selecione Caso
Caso salar _ liq <= 500,00
Salar _ liq salar _ liq * 0,95
Caso salar _ liq > 500,00 E salar _ liq <= 1200,00
Salar _ liq salar _ liq * 0,93
Caso salar _ liq > 1200,00 E salar _ liq <= 1800,00
Salar _ liq salar _ liq * 0,91
Do contrário
Salar _ liq salar _ liq * 0,90
Fim-selecione
Mostre “O Salário líquido do funcionário será “, salar _
liq
Fim
Estruturas de repetição
Figura 3.5.
Figura 3.6.
Figura 3.7.
Enfim:
LEIA P1, P2, P3
PARA J = 1 ATÉ 50 FAÇA
LEIA NT1,NT2, NT3
MED (NT1*P1 + NT2*P2 + NT3*P3) / 10
MOSTRE MED
FIMPARA
Figura 3.8.
Exercício resolvido
Exercício resolvido
Tabela 3.2.
ALGORITMO faz _ sequencia
VAR
I, j : inteiro
INÍCIO
PARA i = 1 ATÉ 4 FAÇA
PARA j = 1 ATÉ 8 FAÇA
MOSTRE i + “.” + j
FIM-PARA
FIM-PARA
FIM
Condições compostas a partir de
operadores lógicos
Para alguns problemas, as relações simples são inadequadas
para descrever as condições requeridas. O resultado poderia
usualmente ser obtido com inclusão, entretanto, isso pode tornar os
algoritmos desnecessariamente complicados e difíceis de entender.
Um método alternativo é utilizar condições compostas. Estas
condições são obtidas das relações simples, utilizando os
operadores lógicos E, OU e NÃO.
Veja os exemplos seguintes. Primeiro, sem uso de condição
composta:
.
.
.
SE salario < 400 ENTÃO
SE num _ faltas = 0 ENTÃO
salario salario + gratificacao
FIM-SE
FIM-SE
Máximas de programação e
programação estruturada
A qualidade do programa
O programa funciona
Nunca devemos nos esquecer de que a característica mais
importante de um programa é sua funcionalidade. Isso parece óbvio,
mas é difícil averiguar esse quesito em programas de tamanho
significativo ou de grande complexidade.
Os programadores devem tomar muito cuidado para que o
programa eventualmente implementado seja realmente o requerido.
A solução parcial de um problema leva a insatisfação do usuário. É
importante que as especificações (que podem mudar) sejam
revistas continuamente, desde o projeto até a implementação.
O programa é eficiente
Esta característica está relacionada com o desempenho do
programa. Programas mais rápidos e que consomem menos espaço
de memória são considerados mais eficientes.
Outro fator importante para avaliarmos a eficiência de um
programa é o funcionamento correto e confiável, isto é, a garantia
de que todas as suas especificações tenham sido obtidas e de que
erros não previstos sejam improváveis de ocorrer. Para que um
programa tenha tais características, é necessário que ele passe por
um processo contínuo de manutenção e modificação para
acompanhar as mudanças de especificações e tecnologia.
A programação como atividade
humana
Um programador de sucesso deve aprender a dominar uma
grande variedade de habilidades, desde aquelas de natureza
criativa, tais como análise e projeto da solução de problemas, até as
tarefas puramente mecânicas, como codificação. Essas tarefas
requerem diferentes habilidades e todas devem ser executadas
corretamente, caso um programa de boa qualidade esteja para ser
produzido.
Programadores não são máquinas: são seres humanos
executando tarefas complexas e, por esta razão, pode-se esperar
que cometam erros, como resultado de sua condição humana.
Seres humanos têm limitações reais quanto à capacidade de
percepção e desempenho, que varia de indivíduo para indivíduo. É
importante que cada programador reconheça e aprenda a viver
dentro de suas limitações.
A seguir, vou retratar os efeitos de vários fatores que afetam o
trabalho de um programador.
Veja um exemplo:
A 14, 2 ;I 1; ENQUANTO I<10 FAÇA X X + 1 ; K I*K;I I+1
FIM-ENQUANTO;
Primeiro exemplo
ALGORITMO SOMA _ 5 _ NUMEROS
VAR
soma, num1, num2, num3, num4, num5 : REAL
INICIO
LEIA num1, num2, num3, num4, num5
SOMA num1+num2+num3+num4+num5
MOSTRE soma
MOSTRE num5, num4, num3, num2, num1 FIM
FIM ALGORITMO
Figura 5.1.
MOSTRE soma
Segundo exemplo
Qual será o valor da variável RESULT impressa pelo algoritmo
seguinte?
ALGORITMO EXEMPLO2
VAR
RESULT : REAL
vetexemplo : VETOR[1 : 5] DE REAL
I : INTEIRO
INÍCIO
vetexemplo[1] 2
vetexemplo[2] 4
vetexemplo[3] 1
vetexemplo[4] 3
vetexemplo[5] 5
RESULT vetexemplo[1] + vetexemplo[5]
MOSTRE RESULT
RESULT vetexemplo[2] - vetexemplo[5]
MOSTRE RESULT
RESULT vetexemplo[4] * vetexemplo[1] - result
MOSTRE RESULT
I 3
RESULT vetexemplo[i]
MOSTRE RESULT
RESULT vetexemplo[i] / vetexemplo[vetexemplo[1]]
MOSTRE RESULT
FIM
FIM ALGORITMO
Figura 5.2.
Depois, 7:
RESULT VETEXEMPLO[4] * VETEXEMPLO[1] - result
RESULT 3 * 2 - (-1)
Agora, 1:
I 3
RESULT VETEXEMPLO[I]
RESULT VETEXEMPLO[3]
E, enfim, 0,25:
RESULT VETEXEMPLO[I] / VETEXEMPLO[VETEXEMPLO[1]]
RESULT VETEXEMPLO[3] / VETEXEMPLO[2]
RESULT 1 / 4
Terceiro exemplo
Figura 5.3.
Observe a solução:
Figura 5.4.
Exercício resolvido
Em que:
Li é o limite inferior;
Ls é o limite superior;
Li e Ls só podem ser valores inteiros;
1, 2 e n são os índices da matriz.
Primeiro exemplo
Veja a solução:
Mat1 tem duas dimensões e 15 elementos: (2 - 0 + 1) * (5 - 1 +
1);
Mat2 tem três dimensões e 18 elementos: (3 - 1 + 1) * (4 - 2 +
1) * (4 - 3 + 1).
Segundo exemplo
Observe a matriz:
cartao _ loteria : MATRIZ[ 1..13, 1..3] DE TEXTO
Tabela 5.1.
Tabela 5.2.
Tabela 5.3.
Tabela 5.4.
Veja um exemplo:
TIPO r = REGISTRO
Nome,Sexo : TEXTO
Salario : REAL
Idade : INTEIRO
FIM-REGISTRO
r : REG
Classificação e pesquisa de
elementos de um vetor
W. Martins
{ordenação do vetor}
J 20
AUX VETCODIGO[I]
VETCODIGO[I] VETCODIGO[I + 1]
VETCODIGO[I + 1] AUX
FIM SE
FIM-PARA
J J - 1
FIM-ENQUANTO
{impressão dos elementos ordenados}
MOSTRE VETCODIGO[I]
FIM-PARA
FIM
FIM ALGORITMO
Pesquisa seqüencial de um
elemento em um vetor
A pesquisa seqüencial, ou linear, é o método mais direto de
encontrar um elemento particular em um vetor não classificado. Esta
técnica envolve a verificação seqüencial de cada elemento do vetor
até que o elemento desejado seja encontrado (neste caso, diz-se
que a pesquisa foi bem sucedida) ou até que todos os elementos do
vetor tenham sido verificados, mas o elemento desejado não seja
encontrado (pesquisa malsucedida).
Como exemplo, suponha uma situação em que seja preciso
construir um algoritmo que leia um nome e verifique se este nome
encontra-se em um vetor com outros 50 nomes. O algoritmo deve
usar a pesquisa seqüencial. Veja:
ALGORITMO Pesquisa _ nome
VAR
CHAVE: TEXTO
VETNOMES : VETOR[1 : 50] DE TEXTO
I: INTEIRO
ACHOU: LÓGICO
INÍCIO
{carregamento dedados no vetor}
LEIA CHAVE
I 1
ACHOU FALSO
ENQUANTO I <= 50 E NÃO ACHOU FAÇA
SE VETNOMES[I] = VALOR ENTÃO
ACHOU VERDADEIRO
SENÃO
I I + 1
FIM-SE
FIM-ENQUANTO
{resultado da pesquisa}
SE ACHOU ENTÃO
MOSTRE CHAVE, “ FOI ENCONTRADO ! ”
SENÃO
MOSTRE CHAVE, “ NÃO FOI ENCONTRADO ! ”
FIM-SE
FIM
FIM ALGORITMO
Pesquisa binária de um elemento
em um vetor
Se os elementos de um vetor forem previamente classificados,
pesquisas muito mais eficientes poderão ser conduzidas. Uma
técnica simples de pesquisa em um vetor carregado (seus
elementos têm valores) e classificado (estejam em ordem
ascendente ou decrescente) é conhecida como método de pesquisa
binária.
A pesquisa binária pode ser feita sobre o vetor classificado a fim
de verificar se determinado valor externo existe ou não no vetor. O
meio aproximado do vetor é localizado e seu valor examinado. Se
este valor é mais alto que o valor procurado, outro elemento do meio
da primeira metade é examinado e o procedimento é repetido na
primeira metade, até que o valor requerido seja ou não encontrado.
Se o valor for mais baixo que o procurado, um elemento médio da
segunda metade é tentado e o procedimento se repete. Este
procedimento continua até que o elemento desejado seja
encontrado ou o intervalo de pesquisa se torne vazio.
Este algoritmo serve-se de um conceito análogo ao conceito de
“tamanho lógico”, usado em alguns algoritmos de ordenação. O
“tamanho lógico” indica o número de elementos de um vetor, ou
seja, o vetor logicamente existe desde o elemento um até o
elemento N, sendo que N é o “tamanho lógico”. Na pesquisa binária,
são utilizados o “início lógico” e o “final lógico” do vetor, ou seja,
posições do vetor em que começam e terminam os dados
considerados (vetor lógico). O meio do vetor lógico, no qual está o
elemento a ser comparado, em geral é calculado pela adição do
“início lógico” e do “final lógico”, dividido por dois, desconsiderando
as casas decimais.
Vejamos um exemplo. Nele, vamos assumir que o vetor já foi lido
e está ordenado:
ALGORITMO Pesquisa _ binaria
VAR
VETMATRIC : VETOR[1 : 50] DE INTEIRO
valor, baixo, alto, medio : INTEIRO
achou: LÓGICO
INÍCIO
MOSTRE “Entre com o valor desejado para pesquisa”
LEIA valor
achou FALSO
baixo 1
alto 50
ENQUANTO BAIXO <= ALTO E NÃO achou FAÇA
medio TRUNCA(BAIXO+ALTO) / 2
SE VALOR < VETMATRIC[medio] ENTÃO
alto medio - 1
SENÃO SE valor > VETMATRIC[medio] ENTÃO
baixo medio + 1
SENÃO
achou VERDADEIRO
FIM-SE
FIM-ENQUANTO
SE achou ENTÃO
MOSTRE “pesquisa bem-sucedida !”
SENÃO
MOSTRE “pesquisa malsucedida !”
FIM-SE
FIM
FIM ALGORITMO
Para treinar
1. Se de um número de três algarismos subtrairmos sete, ele se
tornará divisível por 7. Se subtrairmos oito, ele se tornará
divisível por oito, e se subtrairmos nove, ele se tornará divisível
por nove. Qual é esse número?
Modularização e
recursividade
Uma visão sem ação é somente um sonho. Uma ação sem visão
é apenas um passatempo. Uma visão com ação pode transformar o
mundo.
Joel Barker
Modularização
No fim da década de 1960, um conjunto de problemas no
desenvolvimento de sistemas de programação levou os países
desenvolvidos à chamada “crise do software”.
Os custos das atividades de programação mostravam, a cada
ano, uma clara tendência a se elevarem em relação aos custos dos
equipamentos. Essa tendência se devia, em grande parte, ao rápido
avanço tecnológico na fabricação dos equipamentos de
computação, em contrapartida à lenta evolução das técnicas
aplicadas ao desenvolvimento de software.
A ausência de uma metodologia para a construção de programas
conduz a um software geralmente cheio de erros e com alto custo
de desenvolvimento que, conseqüentemente, exige um custo
elevado para sua correção e manutenção futuras.
A programação estruturada foi o resultado de uma série de
estudos e propostas de disciplinas e metodologias para o
desenvolvimento de softwares. Conceitos associados, como técnica
de refinamentos sucessivos e modularização de programas,
integram o conjunto de ferramentas para a elaboração de
programas visando, principalmente, aos aspectos de confiabilidade,
legibilidade, manutenção e flexibilidade.
Pode-se reunir as idéias da programação estruturada em três
grupos:
Desenvolvimento de algoritmos por fases ou refinamentos
sucessivos;
Uso de um número muito limitado de estruturas de controle;
Transformação de certos refinamentos sucessivos em módulos.
Figura 7.1.
A maneira mais intuitiva de proceder à modularização de
problemas é definindo-se um módulo principal de controle e
módulos específicos para as funções do algoritmo. No diagrama
anterior, o módulo principal tem a função de receber os dados,
escrever os resultados e exercer o controle na execução das
funções do algoritmo. A determinação das vantagens e deduções é
delegada a módulos específicos.
As linguagens de programação hoje existentes dispõem de
recursos que facilitam a construção e manipulação de módulos.
Estes recursos permitem não só a modularização dos comandos do
programa, mas também a modularização dos dados utilizados.
A experiência recomenda que os módulos de um programa
devem ter um tamanho limitado. Módulos muito grandes são de
difícil compreensão e, em geral, multifuncionais.
Um outro aspecto importante é a possibilidade de cada módulo
poder definir as próprias estruturas de dados, suficientes e
necessárias apenas para atingir o objetivo final do módulo.
Todo módulo é constituído por uma seqüência de comandos que
operam sobre um conjunto de objetos, que podem ser globais ou
locais:
Objetos globais são entidades que podem ser usadas em
módulos internos a outro módulo do algoritmo em que foram
declaradas;
Objetos locais são entidades que só podem ser usadas em
módulos do algoritmo no qual foram declaradas. Estes objetos
não possuem qualquer significado fora deste módulo.
Sub-rotina (procedimentos)
bloco de instruções
FIM SUBROTINA
Função
bloco de instruções
FIMFUNÇÃO
em que:
VAR: é o nome da variável que receberá o retorno da função;
NomeFunção: é o nome dado à função;
Lista _ de _ Parâmetros _ Atuais: é a lista de variáveis que
substituirão os parâmetros formais durante a execução da
função. Os parâmetros atuais devem concordar em número,
ordem e tipo de dados com os parâmetros formais.
O fluxo de controle é desviado para a função no momento em que
ela é ativada. Ao terminar a execução dos comandos da função, o
fluxo de controle retorna ao comando seguinte aquele no qual ela foi
ativada:
ALGORITMO verifica _ numeros
VAR
Valor,CONT : inteiro
soma : inteiro
INÍCIO
CONT 1
ENQUANTO CONT <= 50 FAÇA
LEIA valor
TipoValor Verifica _ numero(valor)
{chama a função verifica _ numero a qual retornara se o valor
lido é par ou ímpar}
MOSTRE TipoValor
Soma soma + valor
CONT cont + 1
FIM-ENQUANTO
FIM
Função Verifica _ numero (val : inteiro) : texto
INÍCIO
SE RESTO(val,2) = 0 ENTÃO
verifica _ numero “O número lido é Par”
SENÃO
verifica _ numero “O número lido é Ímpar”
FIM-SE
FIM
Parâmetros
Parâmetros são como variáveis de memória usadas para manter
uma comunicação entre o módulo principal e os módulos
secundários, enviando valores para serem transformados, ou
ajudando a definir as ações que o módulo secundário deve executar
mediante o teste de seus valores.
Os parâmetros podem ser passados a uma função ou a uma
subrotina de dois modos: por valor ou por referência.
A vinculação entre módulos pode ser feita mediante a
transferência, ou passagem, de parâmetros, que associam
parâmetros atuais com os parâmetros formais.
Vejamos os modos de transferência de parâmetros.
N! = N*(N-1)!
Retorno : INTEIRO
Retorno 0
SE numero > = 0 ENTÃO
SE numero = 1 OU numero = 0 ENTÃO
Retorno 1 {o fatorial de 1 e 0 é igual a 1}
SENÃO
Numero numero * Fatorial(numero - 1)
Retorno numero
FIM-SE
FIM-SE
Fatorial Retorno {Retorno da função}
FIM-FUNÇÃO
Para treinar
1. Se a média aritmética de cinco números inteiros consecutivos é
17, o menor dos cinco números é:
11;
12;
13;
14;
15.
Organização x acesso
Organização seqüencial
Nesta forma, os registros estão fisicamente arrumados, um após o
outro. É a forma mais simples de organização.
Para trabalhar com arquivos seqüenciais, devemos, sempre,
acessar cada registro em sua ordem física, ou seja, caso
precisemos das informações do décimo registro, devemos ler os
registros anteriores (do primeiro ao nono) até encontrar o registro
desejado.
Para gravar um novo registro, isso deve ser feito após o último
registro anteriormente existente.
Pelo que foi dito, é fácil compreender que a organização
seqüencial é recomendável quando se deseja processar uma
grande parte dos registros na ordem como estão gravados. Esse
tipo de organização, na maioria das vezes, é utilizado em
processamentos do tipo batch.
Organização relativa
A organização relativa difere da seqüencial na forma de acesso
aos registros. Nesse modo de organização, o programa pode
acessar um registro pela sua posição física no arquivo, isto é, se
precisarmos ler o décimo registro do arquivo de dados, o programa
pode acessálo diretamente, sem ter de acessar antes nenhum outro
registro.
Organização indexada
Nesta forma de organização, os registros são gravados em forma
aleatória. Para acessar um registro do arquivo de dados, isso deve
ser feito por um dos campos do registro, denominado de campo
chave ou índice.
Essa organização cria dois arquivos separados, relacionados
(interligados) pela chave primária. O primeiro arquivo, o arquivo de
índices, contém os valores do campo chave primária do arquivo de
dados e o endereço físico correspondente àquela chave primária no
arquivo de dados original. O outro arquivo denominado arquivo de
dados contém os dados em registros propriamente ditos.
As operações (consulta, inclusão, alteração e exclusão) sobre os
registros são feitas mediante o arquivo de índices, menor e mais
fácil de manipular.
Esse tipo de acesso difere do seqüencial, pois não precisamos ler
os registros anteriores, e do relativo, porque o registro é identificado
por uma chave lógica, e não por sua posição física no arquivo de
dados.
Noções de organização de dados
na memória principal
Os elementos necessários ao processamento estão
sistematicamente organizados na memória. Dessa forma, é
importante que esses elementos (dados) estejam convenientemente
organizados, de forma a permitir um acesso rápido e menor perda
possível de espaço de memória.
Principais estruturas de dados
Entre as formas de organizar os dados, destacam-se três, que
veremos adiante. Vale ressaltar que a escolha de uma ou de outra
estrutura deve ser feita com base nas necessidades de velocidade
de acesso e no espaço de memória disponível. Algumas dessas
estruturas não são usadas diretamente, na maioria dos casos,
porém, elas servem de suporte a outras estruturas usadas
corriqueiramente.
Tabela 8.1.
Operações realizadas sobre as pilhas
Empilhamento (push)
Realiza a inserção de um item I na pilha P. O topo é incrementado
e o novo elemento é colocado na posição indicada pelo novo valor
do topo:
SUBROTINA Push (P, I, N)
SE P.Topo = N ENTÃO
MOSTRE “Pilha P Cheia !!”
SENÃO
P.Topo P.Topo + 1
P.Elementos[P.Topo] I
FIM-SE
FIM SUBROTINA
Desempilhamento (pop)
Realiza a retirada de um elemento da pilha para obedecer à
restrição imposta a esta estrutura, do tipo LIFO. O elemento a ser
excluído é sempre o do topo:
SUBROTINA Pop (P, J)
SE P.Topo = 0 ENTÃO
MOSTRE “Pilha P Vazia !!”
SENÃO
J P.Elementos[P.Topo]
P.Topo P.Topo - 1
FIM-SE
FIM SUBROTINA
Visita à pilha
Consiste em obter o valor do elemento que está no topo da pilha
no momento da visita:
SUBROTINA Visita (P, J)
SE P.Topo = 0 ENTÃO
MOSTRE “Pilha P Vazia !!”
SENÃO
J P.Elementos[P.Topo]
FIM-SE
FIM SUBROTINA
Underflow
É a condição contrária à do overflow: é a tentativa de realizar uma
operação pop quando P.Topo = 0.
Inicialização
Acontece quando uma pilha representada por vetor é inicializada
com P.Topo = 0.
Esta estrutura é bastante usada nas linguagens de programação
para implementar o uso de subprogramas.
Quando um subprograma “chama” o outro, é guardada a posição
de retorno e, quando ocorre um retorno, o fluxo de execução é
passado para esta posição:
Figura 8.2.
Estrutura de dados: fila (queue)
Figura 8.3.
Entrar
Entrar com um elemento na fila significa colocá-
lo no fim da fila.
Sair
Sair da fila significa retirar um elemento do início
da fila.
Tabela 8.2.
Inicialização da fila
F.Comeco 1
F.Termino 0
Esta inicialização garante a condição necessária para tornar
verdadeiro o teste de fila vazia.
Visita à fila
Consulta a obtenção do valor do elemento do começo da fila sem
removê-lo:
SE F.Termino < F.Comeco ENTÃO
MOSTRE “Fila F Vazia !!”
SENÃO
J F.Elementos[F.Comeco]
FIM-SE
Overflow
Ocorre quando se deseja inserir um elemento na fila e não é mais
possível fazê-lo, pois F.Termino = N.
Underflow
É a condição contrária à do overflow, isto é, deseja-se remover
um elemento de uma fila vazia (F.Termino < F.Comeco).
Observação: a igualdade de valores entre F.Comeco
e F.Termino indica que na fila só existe um elemento.
Figura 8.4.
Figura 8.5.
Para treinar
1. Considerando verdadeiras as seguintes proposições:
Se João cometeu um grave delito, ele sonegou impostos;
João não sonegou impostos.
Mapeamento de
pseudocódigo e comandos da
linguagem Turbo Pascal
Charles Chaplin
Mapeamento de pseudocódigo com
algumas linguagens de
programação
Será exibido adiante um simples exemplo de pseudocódigo que
trabalha com três variáveis, com as quais é calculada a média
aritmética de duas notas, para, depois, emitir seu resultado. O
referido pseudocódigo será codificado em cinco diferentes
linguagens de programação estruturadas, para que o leitor tenha
uma idéia de implementação de algoritmos computacionais:
ALGORITMO calcmedia
VAR
Nt1,nt2,media : inteiro
INÍCIO
Nt1 10
Nt2 2
Media (nt1 + nt2)/ 2
MOSTRE media
FIM
FIM ALGORITMO
Agora, em C:
MAIN( )
{
FLOAT nt1,nt2, media;
Nt1 = 10;
Nt2 = 2;
Media := (nt1 + nt2) / 2;
PRINTF(%D, media);
Em Cobol, temos:
IDENTIFICATION DIVISION.
PROGRAM-ID. calcmedia.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 nt1 PIC 99 VALUE 10.
77 nt2 PIC 99 VALUE 2.
77 media PIC 99 VALUE ZEROS.
PROCEDURE DIVISION.
ROT01.
COMPUTE media = (nt1 + nt2) / 2
DISPLAY media
STOP RUN.
Em Clipper:
PROCEDURE MAIN( )
Nt1 = 10
Nt2 = 2
media = (nt1 + nt2) / 2
@ 10, 5 SAY “A média foi “
@ 10, 16 SAY media PIC “999”
INKEY(5)
RETURN
PROGRAM NomeProg ;
VAR
Nomevar : TIPO ;
BEGIN
END.
Declaração de variáveis
VAR
Var1 : TIPO;
Atribuição
Entrada de dados
READLN(‘Texto Descritivo’ , Var1);
Muda de linha para a nova entrada de dados.
READ(‘Texto Descritivo’ , Var1);
Saída de dados
WRITELN(‘Texto Descritivo’, Var1);
WRITELN(‘Texto Descritivo’);
Estrutura condicional
IF Condição THEN
BEGIN
C1;
C2;
C3;
END
ELSE
C4;
Condicional composta
CASE expressão OF
VALOR1 : C1;
VALOR2 : C2;
VALOR3 : C3;
ELSE
C4;
END;
Vetores
Veja um exemplo:
VAR
VetCodigo : ARRAY[1..40] OF INTEGER;
Matriz
Veja um exemplo:
VAR
MatCurso : ARRAY[1..4 , 1..3] OF STRING;
Registros
Veja um exemplo:
TYPE
Alunos : RECORD
Notas : ARRAY[1..4] OF REAL;
Media : REAL;
Conceito : STRING[10];
Nome : STRING[30];
END;
VAR
Estudante : ALUNOS;
Comparação de algoritmos
Algoritmos estruturados x
orientação a eventos (uma nova
abordagem)
Características principais das linguagens
estruturadas
Já para um formulário:
Ser carregado, ao fechar, ao ativar, ao mover o mouse sobre
ele etc.
ALGORITMO nomedoalgoritmo
PÚBLICAS
VAR
Nomevar1,Nomevar2 : tipodedado
CONST
Nomeconst : tipodedado
EVENTOS
COMPONENTE : nomecomponente
TIPO COMPONENTE : tipocomponente
FIM ALGORITMO
em que:
PROJETO nomedoprojeto: por trabalhar com o conceito de
projeto, as linguagens OE/OO requerem essa linha, na qual
cada programa de um sistema faz parte de um mesmo projeto.
Essa linha exibe, para facilitar uma futura manutenção ou
documentação, o nome do projeto que está sendo
desenvolvido;
ALGORITMO nomedoalgoritmo: corresponde ao nome do
programa propriamente dito, com o mesmo objetivo do
comando anteriormente utilizado nos algoritmos estruturados;
{ DECLARAÇÕES }
PÚBLICAS
VAR
Nomevar1,Nomevar2 : tipodedado
CONST
Nomeconst : tipodedado
BLOCO DE INSTRUÇÕES
FIM
Figura 10.1.
Agora, o código:
PROJETO Locadora
ALGORITMO frmCadSenhas
PÚBLICAS
VAR
ContsenhaInvalida : INTEIRO
EVENTOS
COMPONENTE : CmdVerificaSenha
TIPO COMPONENTE : Botão de Comando
TIPO EVENTO : ao Clicar
VAR
LOCAL
Erros : INTEIRO
INÍCIO
SENÃO
ATIVAR menuPrinc
FIM-SE
FIM
COMPONENTE : FrmCadsenhas
TIPO COMPONENTE : formulário
INÍCIO
ContsenhaInvalida 0
Txtsenha = “”
CboUsuario FOCO
FIM
COMPONENTE : CmdCancelar
TIPO COMPONENTE : formulário
INÍCIO
CANCELAR
FIM
FIM ALGORITMO
1 X
2 X
3 X
4 X
5 X
6 X
7 X
8 X
9 X
10 X
11 X
12 X
13 X
Tabela 5.1.
x x x x
Tabela 5.2.
x x x x x
Tabela 5.3.
x x x x
Tabela 5.4.