Métodos de Programação I
2. 20
Ana Maria de Almeida
2.2.8 ESTRUTURAS DE CONTROLO
Estruturas de controlo são instruções especiais em Pascal que permitem controlar o fluxo de sequência de
instruções, alterando a ordem sequencial explícita. Essas alterações podem ser devidas a escolhas de blocos
de instruções devido à ocorrência de determinadas condições, ou porque é necessário repetir instruções de
construção iterativa (construção passo a passo) de um determinado valor. Assim, podemos considerar as
esruturas de controlo agrupadas segundo o diagrama seguinte.
Sequência
Condicional
Selecção
Estruturas
de
Base
Alternativa
Repetição
Enquanto
Até que
Com contador
Procedimento
Subprograma
Função
•
SELECÇÃO
Selecção Condicional - a instrução if-then-else
if
expressão
lógica
then
instrução
else
instrução
Esta instrução permite fazer uma escolha de instruções a executar consoante o valor da expressão lógica é
verdadeiro ou falso. Assim, caso a avaliação da expressão a seguir ao if seja verdadeiro, executa-se a
instrução correspondente ao then. Caso contrário, executa-se a instrução presente no else.
De acordo com o diagrama de sintaxe, há ainda a hipótese de nem sequer se escrever o else e, neste caso, se
a expressão lógica fôr falsa, passa-se imediatamente à instrução seguinte. Por exemplo,
x := 5; y:= 8;
if x = y then write( x );
write(‘Eis!’);
EFEITO:
Eis!
ou ainda,
x := -81;
if x >= 0
then raiz := sqrt( x )
else raiz := sqrt( -x );
EFEITO:
raiz ←
9 (raiz toma o valor de raiz quadrada de -x)
Métodos de Programação I
2. 21
Ana Maria de Almeida
Vamos agora apresentar um exemplo típico do uso da alternativa num programa que lê 3 números inteiros
positivos, verifica se podem constituir lados de um triângulo e, em caso afirmativo, indica o tipo de
triângulo:
Especificações:
•
Dados: 3 valores inteiros positivos
•
Resultados: classificação de triângulo ou impossibilidade em formar um triângulo
Dados 3 valores naturais, para estes poderem constituir as medidas dos lados de um triângulo, cada lado
deve ser menor que a soma dos lados opostos. No caso de esta condição ser verdadeira, um triângulo diz-se:
“equilátero” se tiver os lados todos iguais; “isósceles”, caso tenha, apenas, dois lados iguais; “escaleno” se
os lados forem todos de medidas diferentes. Assim, um programa em Pascal para responder a esta questão
poderá ser o seguinte:
program triangulo (input, output);
var aa, bb, cc : 1 .. maxint;
begin
read( aa, bb, cc);
if ( aa < bb + cc ) and ( bb < aa + cc ) and ( cc < aa + bb )
then if ( aa = bb ) or ( aa = cc ) or ( bb = cc )
then if ( aa = bb ) and ( bb = cc )
then writeln(‘Equilatero‘)
else writeln(‘Isosceles‘)
else writeln(‘Escaleno‘)
else writeln(‘Nao pode ser triangulo‘);
writeln;
end.
Figura 2.5: programa para caracterizar um triângulo.
Repare como a identação é importante, permitindo-nos saber imediatamente, a que instrução if corresponde
cada then e cada else.
É também importante fazer notar que, entre os if, then e else não pode existir ; (ponto e vírgula). Caso seja
necessária mais do que uma instrução no then ou no else, e portanto o uso obrigatório de pontos e vírgulas,
deve-se usar o delimitador de blocos begin-end, obviamente, sem ponto e virgula a seguir ao end (a menos
de um else seguido de outra instrução qualquer3).
A Selecção Múltipla ou de Alternativa - instrução case
case
expressão
of
constante
,
:
instrução
end
;
;
não pode ser do tipo real
No caso de necessitarmos de escolha múltipla, ter uma instrução de escolha binária (if) torna-se demasiado
enfadonho de usar. Esta nova instrução dá-nos a possibilidade de apreciar vários casos e decidir para todos
eles ou para mais do que uma escolha.
3
Repare no último else do exemplo da figura 2.5
Métodos de Programação I
2. 22
Ana Maria de Almeida
Suponha-se, por exemplo, que, numa portagem de auto-estrada, existe o seguinte módulo num programa:
type tipoveiculo = (bicicleta, motociclo, motorizada, automovel,
autocomreb, camioneta, autocarro, camiao, reboque);
var veiculo : tipoveiculo;
Se chegar um veículo qualquer à portagem, o programa, dependendo de onde chega e em função do seu tipo,
tem de decidir qual a portagem que vai pagar:
case veiculo of
bicicleta, motociclo
autocomreb, camioneta
autocarro, camiao
reboque
end;
:
:
:
:
writeln(‘2,3 euros’ );
writeln(‘2,8 euros’ );
writeln(‘3 euros’ );
writeln(‘3,2 euros’ )
Um exemplo mais completo é o do programa abaixo que, dada uma data, calcula a data do dia seguinte:
Especificações:
• Dados: data no formato dia mês ano
• Resultados: data do dia seguinte ao dado.
È óbvio que a primeira coisa a fazer é delimitar um domínio para os séculos abrangidos pelo programa. Seja
ele,
Domínio =1900 .. 2100
Comecemos por descrever o algoritmo a implementar no programa:
o
o
o
ler dia , mês, ano ;
escrever “Dia seguinte a dia/mês/ano :” ;
determinar o número de dias desse mês:
caso mês?
mês =
1,3,5,7,8,10,12
mês =
4,6,9,11
ultimodia ← 31
mês =2
ultimo ← 30
(bissexto?)
ano mod 4 = 0 e ano ≠ 1900,2100
ultimo ← 28
o actualizar dia, mês, e ano para seguintes:
se dia = ultimo
senão
dia ← 1
se mes = 12
mes ← 1
ano ← ano + 1
o escrever dia/mês/ano.
senão
mes ← mes + 1
dia ← dia +1
senão
ultimo ← 29
Métodos de Programação I
2. 23
Ana Maria de Almeida
program dia_seguinte (input, output);
var dia : 1 .. 31 ;
mes : 1 .. 12 ;
ano : 1900 .. 2100 ;
ultimo : 28 .. 31 ;
begin
(* leitura e escrita da data dada *)
read( dia, mes, ano);
write(‘ Dia seguinte a ‘, dia :2, ‘/’, mes:2, ‘/’, ano:4, ‘:’:3);
(* determinação do numero de dias do mes *)
case mes of
1,3,5,7,8,10,12 : ultimo := 31;
4,6,9,11 : ultimo := 30;
2 : if (ano mod 4 = 0) and (ano <> 1900) and (ano <> 2100)
then ultimo := 29
else ultimo := 28
end;
if ( dia = ultimo )
then begin
necessitamos usar
dia := 1;
várias intruções
if ( mes = 12 )
then begin
dia := 1;
ano := ano + 1
end
else mes := mes + 1
end
else dia := dia + 1;
writeln(dia:2, ‘/’, mes:2, ‘/’, ano:4); writeln;
end.
Figura 2.6: programa para calcular data do dia deguinte
REPETIÇÃO - CICLOS
Ciclo “Enquanto” : instrução while - do
while
expressão
lógica
do
instrução
UMA INSTRUÇÃO (SIMPLES OU COMPOSTA)
Esta estrutura permite repetir uma instrução simples, ou um bloco de instruções delimitado por begin-end
(instrução composta). Essa repetição é efectuada enquanto a expressão lógica se mantiver verdadeira:
while TRUE do
INSTRUÇÂO;
Temos, portanto, duas partes principais nesta estrutura: o teste lógico, efectuado antes de qualquer outra
coisa - cabeça do ciclo - e a segunda parte que consiste na instrução (ou bloco de instruções) - corpo do
ciclo - que só é executada se o teste fôr verdadeiro. Isto significa que, se na primeira vez que a expressão fôr
testada, fôr avaliada para falso, o ciclo nunca é efectuado (há um salto sequencial directo para a primeira
instrução após o ciclo).
Métodos de Programação I
2. 24
Ana Maria de Almeida
Um ciclo é normalmente utilizado para calcular valores através de fórmulas iterativas - fórmulas que usam
valores anteriores para calcular novos valores. Um exemplo típico é o do cálculo de potências como, por
exemplo,
21 = 2, 22 = 21x2 = 4, 23 = 22x2 = 8, …, 2i = 2i-1x2, …,
onde cada novo valor é obtido multiplicando por 2 o valor anterior.
Vamos então construir um programa para imprimir uma tabela de potências sucessivas de 2, desde que
inferiores a 1000:
contador
i ←
1
potencia ←
inicializações
2
enquanto potencia < 1000
cabeça do ciclo
( teste lógico )
escrever i, potencia
i ← i+1
potencia ←
potencia * 2
fórmulas
iterativas
corpo do ciclo
Neste caso vamos usar duas fórmulas iterativas: uma para calcular a potência i em curso - que varia desde 1
até ao limite (2i < 1000) - e outra para o cálculo do valor concreto - multiplicação - da potência. Nestes
casos e em qualquer outro:
toda a fórmula iterativa tem de ser inicializada antes do ciclo.
A implementação deste algoritmo em Pascal é, portanto, a seguinte:
instrução
composta
program tabela (output);
var i, potencia : 0 .. 1000;
begin
i := 1;
potencia := 2;
while potencia < 1000 do
begin
writeln( i, potencia);
i := i +1;
potencia := potencia * 2
end
end.
Figura 2.7: programa para imprimir potências de 2 menores que 1000
Ciclo “Até que” : instrução repeat - until
repeat
instrução
until
expressão
lógica
;
UMA OU MAIS INSTRUÇÕES
Métodos de Programação I
2. 25
Ana Maria de Almeida
As principais diferenças entre esta estrutura e a anterior residem nos dois pontos seguintes:
●
Contrariamente ao que acontecia na repetição anterior, esta estrutura permite repetir, ou uma
instrução simples, ou uma série sequencial de instruções, e essa repetição é efectuada até que a
expressão lógica se torne verdadeira:
repeat
instruções;
until TRUE
●
O teste lógico do repeat (a cabeça deste ciclo) é no final do ciclo o que significa que o ciclo é
sempre executado pelo menos uma vez.
Passamos a apresentar alguns exemplos:
1. Calcular a soma de vários números inteiros, dados um em cada linha, sendo o final dado por uma
linha que só contém zero:
Descrição do algoritmo:
soma ← 0
fórmula
iterativa
ler numero, mudar de linha
soma ← soma + numero
até que numero = 0
inicialização
corpo do ciclo
teste do ciclo
escrever soma
Implementação:
program somar (input, output);
varnumero, soma : integer;
begin
soma := 0;
repeat readln( numero );
soma := soma + numero;
until numero = 0;
writeln( soma : 10 );
end.
Figura 2.8: programa para somar inteiros
2. Ler um número inteiro e verificar se é uma capicua:
2451542 é uma capicua (é igual ao seu “inverso”)
Métodos de Programação I
2. 26
Ana Maria de Almeida
Descrição do algoritmo:
ler número
n ← número
inverso ← 0
cópia para
“destruir”
digito ← n mod 10
inverso ← inverso*10 + digito
n ←
n div 10
até que numero = 0
número = inverso
é capicua
senão
não é
Implementação:
program capicua (input, output);
vardigito : 0 .. 9;
numero, n, inverso : 0 .. maxint;
begin
read( numero );
n := numero;
inverso := 0;
repeat
digito := n mod 10;
inverso := inverso * 10 + digito;
n := n div 10
until n = 0;
(* a cópia do número foi destruida *)
if numero = inverso
then writeln( numero, ‘ Capicua’ )
else writeln ( numero, ‘ Não e capicua ‘)
end.
Figura 2.9: programa para encontar capicuas
Exercícios:
1. Identifique a fórmula recursiva que está envolvida no algoritmo acima e qual é a sua inicialização.
2. Faça a simulação manual do programa para uma capicua e para outro número diferente do seu inverso.
3. Modifique o programa para usar um while-do em vez do repeat-until (Note que números de um só
algarismo também são capicuas).
Download

Capítulo 2 - páginas 20 a 26