apostila
259 pág.

apostila

Disciplina:Algoritmos e Estrutura de Dados I542 materiais7.968 seguidores
Pré-visualização50 páginas
v2 ;
var a,b: integer ;

begin
read (a) ;
read (b) ;
while (a <> 0) or (b <> 0) do
begin

writeln (a+b) ;
read (a) ;
read (b) ;

end;
end.

Figura 5.9: Duas formas para somar pares de nu´meros.

Este exemplo e´ extremamente interessante pois permite ver claramente que o
co´digo referente aos comandos de leitura e impressa˜o sa˜o os mesmos, apesar da ordem
diferente no segundo exemplo. O que difere e´ a estrutura de controle do lac¸o, isto
e´, do bloco de comandos que se repete. No quadro da esquerda, o algoritmo precisa
contar ate´ 30, por isto existe uma varia´vel cont que faz esta conta. No quadro da
direita, o lac¸o e´ controlado por uma expressa˜o booleana um pouco mais sofisticada
que a do exemplo anterior, pois faz uso do operador or. A expressa˜o em questa˜o se
torna falsa apenas quando ambos os nu´meros lidos forem nulos. Se um dois dois for
na˜o nulo, o lac¸o e´ executado.

O comando de impressa˜o ficou aparentemente invertido pela simples raza˜o de que
o teste depende de uma primeira leitura das varia´veis a e b antes do teste, sena˜o o
teste na˜o pode ser feito. Mas, ressaltamos, o nu´cleo do programa e´ exatamente o
mesmo, leˆ dois nu´meros e imprime a soma, o que muda e´ o controle do lac¸o.

5.7 Testar se um nu´mero lido e´ positivo

Problema: Ler um u´nico nu´mero do teclado e imprimı´-lo apenas se ele for positivo.

Parece simples para o ser humano saber se um nu´mero e´ positivo ou na˜o, mas

46 CAPI´TULO 5. CONCEITOS ELEMENTARES

para o computador o que esta´ em memo´ria e´ apenas uma sequeˆncia de bits. Logo,
para ele decidir se um nu´mero e´ positivo deve usar uma expressa˜o booleana. Mas,
como executar o comando de impressa˜o apenas em um caso (do nu´mero ser positivo)
e ignorar a impressa˜o caso na˜o seja? Este problema permitira´ introduzir a noc¸a˜o de
desvio condicional.

Um desvio condicional produz exatamente o efeito desejado, faz um teste e depen-
dendo do resultado executa ou na˜o o comando subsequente. A figura 5.10 ilustra a
soluc¸a˜o deste problema. No caso, o comando writeln so´ e´ executado se a expressa˜o
booleana for verdadeira. Caso o nu´mero lido seja nulo ou negativo o fluxo de execuc¸a˜o
do programa “pula” para o comando subsequente, que no caso e´ o fim do programa.

program imprime se positivo ;
var a,b: integer ;

begin
read (a) ;
i f a > 0 then

writeln (a) ; (∗ so executa se a for positivo ∗)
end.

Figura 5.10: Imprime se for positivo.

O comando de desvio condicional admite uma segunda forma, que estabelece um
fluxo alternativo ao programa dependendo do teste.

Considere o seguinte problema.

Problema: Ler um u´nico nu´mero do teclado e imprimı´-lo apenas se ele for positivo.
Se na˜o for imprimir a mensagem “nu´mero inva´lido”.

A soluc¸a˜o deste problema requer uma variante do comando if, conforme ilustrado
na figura 5.11. Apenas um comando de impressa˜o sera´ executado.

program imprime se positivo ;
var a,b: integer ;

begin
read (a) ;
i f a > 0 then

writeln (a) (∗ so executa se a for positivo ∗)
else

writeln (’numero invalido’) ; (∗ executa se a for nulo ou negativo ∗)
end.

Figura 5.11: Imprime se for positivo, segunda versa˜o.

5.8. RESUMO 47

5.8 Resumo

Neste cap´ıtulo vimos todas as estruturas elementares para qualquer algoritmo (ou
programa) presentes em qualquer linguagem de programac¸a˜o. Sa˜o eles:

Comandos

• Entrada e sa´ıda (read e write, respectivamente);
• Atribuic¸a˜o (:=);
• Repetic¸a˜o (while/do);
• Desvio condicional (if/then, ou if/then/else);

Expresso˜es

• Aritme´ticas;
• Booleanas.

Qualquer algoritmo e´ escrito como uma combinac¸a˜o destes comandos manipu-
lando dados em memo´ria (varia´veis) da maneira como o algoritmo estabelece. Como
sabemos, cada problema tem va´rias soluc¸o˜es poss´ıveis, mas uma vez fixado uma, pode-
se escrever o programa na forma como o computador entenda, usando-se apenas as
noc¸o˜es apresentadas neste cap´ıtulo.

A menos do uso de estruturas de dados sofisticadas, as quais veremos a partir
do cap´ıtulo 10, agora ja´ e´ poss´ıvel escrever qualquer algoritmo, e consequentemente,
qualquer programa!

O que muda de uma linguagem de programac¸a˜o para outra e´ basicamente a grafia
dos comandos, as vezes com alguma ligeira modificac¸a˜o na sintaxe e na semaˆntica do
comando.

Por exemplo, na linguagem C, o comando write e´ grafado printf, na linguagem
BASIC e´ grafado print. Cada linguagem tem um comportamento diferente, na˜o e´
apenas o nome que muda. Por exemplo, se imprime e muda de linha ou na˜o, em qual
formato escreve, etc.

Mas, estes sa˜o os elementos ba´sicos para se programar. No pro´ximo cap´ıtulo
veremos como usar estes comandos de maneira inteligente para resolver problemas
mais complexos. O leitor pode pular o apeˆndice da pro´xima sec¸a˜o sem preju´ızo da
compreensa˜o do restante do texto.

5.9 Apeˆndice

Existe mais um comando de controle de fluxo, presente em qualquer linguagem de
programac¸a˜o: o comando de desvio incondicional. Segundo o modelo de Von Neumann
estudado, isto nada mais e´ do que alterar o controlador de instruc¸o˜es para um enderec¸o
arbitra´rio (na verdade controlado) quando pensamos no modelo de baixo n´ıvel.

A figura 5.12 ilustra o uso do desvio incondicional para resolver o problema de se
imprimir todos os nu´meros de 1 a 30.

48 CAPI´TULO 5. CONCEITOS ELEMENTARES

program contar ;
label : 10;
var i : integer ;

begin
i := 1;

10:write ( i ) ;
i := i + 1;

i f i <= 30 then
goto 10;

end.

Figura 5.12: Exemplo do uso do desvio incondicional.

Neste exemplo, a varia´vel i e´ inicializada com o valor 1 e em seguida e´ executado
o comando que imprime 1 na tela. Em seguida a varia´vel i e´ incrementada e, apo´s
verificar que 1 e´ menor ou igual a 30, o fluxo do programa executa o comando de
desvio incondicional goto, que faz com que o fluxo de execuc¸a˜o do programa va´ para
a linha indicada pelo ro´tulo 10, isto e´, imprime o valor da varia´vel i, incrementa o i e
assim por diante. Quando i valer 31 o goto na˜o e´ executado, o que faz com que o end
final seja atingido e o programa termina.

Em outras palavras, e´ uma outra maneira (mais estranha) de se implementar o
mesmo programa da figura 5.7. A observac¸a˜o interessante e´ que, no n´ıvel de ma´quina,
o que o compilador faz e´ gerar a partir do programa da figura 5.7, um co´digo de
ma´quina implementado usando-se uma noc¸a˜o de desvio incondicional, implementada
no reperto´rio reduzido de instruc¸o˜es, mas isto o programador na˜o e´ obrigado a saber
agora.

O que ele deve saber e´ que o uso de comandos de desvio incondicional na˜o e´
recomendado pois na medida em que os programas va˜o ficando com muitas linhas de
co´digo, digamos algumas centenas de linhas ou mais, o que ocorre e´ que o programador
tende a se perder e passa a ter muita dificuldade em continuar o desenvolvimento do
programa quando o uso do goto e´ feito de qualquer maneira e, em especial, de forma
exagerada. Isto tende a tornar o co´digo ileg´ıvel e de dif´ıcil manutenc¸a˜o.

Como vimos, as linguagens de alto n´ıvel permitem mecanismos mais elegantes
para repetir trechos de co´digo sem necessidade do uso do goto, usando-se o while.
Isto e´ baseado no princ´ıpio da programac¸a˜o estruturada, que nasceu com a linguagem
ALGOL-60. Esta linguagem, apesar de na˜o ser mais usada, deu origem a` maior parte
das linguagens modernas, entre elas o pro´prio Pascal.

Este comando esta´ em um apeˆndice pois no´s nunca mais o usaremos.

5.10. EXERCI´CIOS 49

5.10 Exerc´ıcios

1. Leia o mini guia da linguagem Pascal, dispon´ıvel em http://www.inf.ufpr.
br/cursos/ci055/pascal.pdf, em especial os cap´ıtulos de 1 a 3, a sec¸a˜o 4.2 e
o cap´ıtulo 7.

2. Tente compilar e executar com va´rias entradas os programas Pascal vistos neste
cap´ıtulo.

3. Modifique o programa Soma2 para que ele receba um nu´mero inteiro N de en-
trada e imprima a seguinte sequeˆncia