• Nenhum resultado encontrado

Testar se um n´ umero lido ´ e positivo

No documento Algoritmos e Estruturas de Dados I (páginas 51-55)

Conceitos elementares

5.7 Testar se um n´ umero lido ´ e positivo

• ou o enunciado estabelece a quantidade exata de n´umeros a serem lidos;

• ou o enunciado estabelece uma condi¸c˜ao de parada alternativa.

No primeiro caso o enunciado deveria ser algo assim: “ler 30 pares de n´umeros do teclado e imprimir, para cada par, a soma deles”.

No segundo caso poderia ser algo mais ou menos assim: “ler pares de n´umeros do teclado e imprimir, para cada par, a soma deles. O algoritmo deve parar a execu¸c˜ao quando os dois n´umeros lidos forem iguais a zero”.

A figura 5.9 ilustra as duas formas. A esquerda apresenta a solu¸c˜ao usando-se um contador, a da direita apresenta a solu¸c˜ao com crit´erio de parada alternativo.

program soma2variasvezes v1 ; var a , b, cont : integer;

(∗ cont conta os numeros lidos ∗) begin

Figura 5.9: Duas formas para somar pares de n´umeros.

Este exemplo ´e extremamente interessante pois permite ver claramente que o c´odigo referente aos comandos de leitura e impress˜ao s˜ao os mesmos, apesar da ordem diferente no segundo exemplo. O que difere ´e a estrutura de controle do la¸co, isto

´

e, do bloco de comandos que se repete. No quadro da esquerda, o algoritmo precisa contar at´e 30, por isto existe uma vari´avel cont que faz esta conta. No quadro da direita, o la¸co ´e controlado por uma express˜ao booleana um pouco mais sofisticada que a do exemplo anterior, pois faz uso do operador or. A express˜ao em quest˜ao se torna falsa apenas quando ambos os n´umeros lidos forem nulos. Se um dois dois for n˜ao nulo, o la¸co ´e executado.

O comando de impress˜ao ficou aparentemente invertido pela simples raz˜ao de que o teste depende de uma primeira leitura das vari´aveis a e b antes do teste, sen˜ao o teste n˜ao pode ser feito. Mas, ressaltamos, o n´ucleo do programa ´e exatamente o mesmo, lˆe dois n´umeros e imprime a soma, o que muda ´e o controle do la¸co.

5.7 Testar se um n´ umero lido ´ e positivo

Problema: Ler um ´unico n´umero do teclado e imprim´ı-lo apenas se ele for positivo.

Parece simples para o ser humano saber se um n´umero ´e positivo ou n˜ao, mas

para o computador o que est´a em mem´oria ´e apenas uma sequˆencia de bits. Logo, para ele decidir se um n´umero ´e positivo deve usar uma express˜ao booleana. Mas, como executar o comando de impress˜ao apenas em um caso (do n´umero ser positivo) e ignorar a impress˜ao caso n˜ao seja? Este problema permitir´a introduzir a no¸c˜ao de desvio condicional.

Um desvio condicional produz exatamente o efeito desejado, faz um teste e depen-dendo do resultado executa ou n˜ao o comando subsequente. A figura 5.10 ilustra a solu¸c˜ao deste problema. No caso, o comando writeln s´o ´e executado se a express˜ao booleana for verdadeira. Caso o n´umero lido seja nulo ou negativo o fluxo de execu¸c˜ao 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 ´unico n´umero do teclado e imprim´ı-lo apenas se ele for positivo.

Se n˜ao for imprimir a mensagem “n´umero inv´alido”.

A solu¸c˜ao deste problema requer uma variante do comando if, conforme ilustrado na figura 5.11. Apenas um comando de impress˜ao ser´a executado.

program imprime se positivo v2 ; 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 vers˜ao.

5.8. RESUMO 53

5.8 Resumo

Neste cap´ıtulo vimos todas as estruturas elementares para qualquer algoritmo (ou programa) presentes em qualquer linguagem de programa¸c˜ao. S˜ao eles:

Comandos

• Entrada e sa´ıda (read e write, respectivamente);

• Atribui¸c˜ao (:=);

• Repeti¸c˜ao (while/do);

• Desvio condicional (if/then, ou if/then/else);

Express˜oes

• Aritm´eticas;

• Booleanas.

Qualquer algoritmo ´e escrito como uma combina¸c˜ao destes comandos manipu-lando dados em mem´oria (vari´aveis) da maneira como o algoritmo estabelece. Como sabemos, cada problema tem v´arias solu¸c˜oes poss´ıveis, mas uma vez fixado uma, pode-se escrever o programa na forma como o computador entenda, usando-pode-se apenas as no¸c˜oes apresentadas neste cap´ıtulo.

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

O que muda de uma linguagem de programa¸c˜ao para outra ´e basicamente a grafia dos comandos, as vezes com alguma ligeira modifica¸c˜ao na sintaxe e na semˆantica 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, n˜ao ´e apenas o nome que muda. Por exemplo, se imprime e muda de linha ou n˜ao, em qual formato escreve, etc.

Mas, estes s˜ao os elementos b´asicos para se programar. No pr´oximo cap´ıtulo veremos como usar estes comandos de maneira inteligente para resolver problemas mais complexos. O leitor pode pular o apˆendice da pr´oxima se¸c˜ao sem preju´ızo da compreens˜ao do restante do texto.

5.9 Apˆ endice

Existe mais um comando de controle de fluxo, presente em qualquer linguagem de programa¸c˜ao: ocomando de desvio incondicional. Segundo o modelo de Von Neumann estudado, isto nada mais ´e do que alterar o controlador de instru¸c˜oes para um endere¸co arbitr´ario (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 n´umeros de 1 a 30.

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 vari´avel i´e inicializada com o valor 1 e em seguida ´e executado o comando que imprime 1 na tela. Em seguida a vari´avel i ´e incrementada e, ap´os verificar que 1 ´e menor ou igual a 30, o fluxo do programa executa o comando de desvio incondicionalgoto, que faz com que o fluxo de execu¸c˜ao do programa v´a para a linha indicada pelo r´otulo 10, isto ´e, imprime o valor da vari´avel i, incrementa o ie assim por diante. Quandoi valer 31 ogoto n˜ao ´e executado, o que faz com que oend 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 observa¸c˜ao interessante ´e que, no n´ıvel de m´aquina, o que o compilador faz ´e gerar a partir do programa da figura 5.7, um c´odigo de m´aquina implementado usando-se uma no¸c˜ao de desvio incondicional, implementada no repert´orio reduzido de instru¸c˜oes, mas isto o programador n˜ao ´e obrigado a saber agora.

O que ele deve saber ´e que o uso de comandos de desvio incondicional n˜ao ´e recomendado pois na medida em que os programas v˜ao ficando com muitas linhas de c´odigo, 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 c´odigo ileg´ıvel e de dif´ıcil manuten¸c˜ao.

Como vimos, as linguagens de alto n´ıvel permitem mecanismos mais elegantes para repetir trechos de c´odigo sem necessidade do uso do goto, usando-se o while.

Isto ´e baseado no princ´ıpio da programa¸c˜ao estruturada, que nasceu com a linguagem ALGOL-60. Esta linguagem, apesar de n˜ao ser mais usada, deu origem `a maior parte das linguagens modernas, entre elas o pr´oprio Pascal.

Este comando est´a em um apˆendice pois n´os nunca mais o usaremos.

No documento Algoritmos e Estruturas de Dados I (páginas 51-55)