ALGORITMOS COM PASCAL

 

Prof. Miguel Jonathan – Dept. Ciência da Computação – IM/UFRJ – 2003 – versão 1.1

 

CAPíTULO 2

 

 

INSTRUÇÕES OU COMANDOS

 

As instruções  ou  comandos  são fórmulas que permitem realizar alterações na memória, agir sobre os dispositivos de entrada ou saída, ou controlar o fluxo do programa.

 

A seguir estão relacionados os comandos mais importantes que usaremos na construção de algoritmos de computador, e que são equivalentes aos comandos da Linguagem Pascal:

 

COMANDO DE ATRIBUIÇÃO:  :=

 

Definição:   < identificador de variavel > :=  <expressão>

Significado:  a expressão do lado direito do símbolo := é calculada e reduzida a um valor. Esse valor será, em seguida, transferido para a variável da memória designada pelo identificador do lado esquerdo.

 

Exemplo: supondo que x vale 3 no momento em que o comando abaixo for realizado, então:

     y := 2 * x + 10      

faz a expressão ser calculada e reduzida ao valor 16, e em seguida, esse valor é transferido para a variável y que passa então a ter também o valor 16. O valor anterior que y tinha é perdido.

 

Uma atribuição usa muitas vezes uma expressão trivial do lado direito, como em:

   y := 10   (a expressão da direita vale 10, e esse valor é transferido para a variável y)

 

OBS: jamais confunda o operador de atribuição :=  com  a idéia de igualdade.  O significado não  é que a variável da esquerda é igual ao valor da expressão da direita, mas que a variável da esquerda ficará igual ao valor calculado da expressão.

 

COMANDO DE LEITURA DE DADOS (ENTRADA)     ler (<variável>)

 

Esta é a outra forma pela qual se pode alterar o valor de uma variável na memória.

 

Significado:  um valor existente no dispositivo de entrada de dados (normalmente a memória do teclado da máquina) será lido pela máquina e armazenado na variável da memória cujo nome aparece no comando.

Por exemplo:

Seja uma variável x definida como do tipo real. Supondo que o comando:

   ler (x)  seja executado.

Então, se o usuário digitar  56.132 no teclado (terminando por teclar a tecla ENTER), o comando acima fará com que a variável x na memória receba o valor 56.132, sendo que o valor anterior dessa variável será perdido.

 

Como funciona o comando ler( ):

O entendimento correto de como funciona o comando de leitura de dados é essencial para que o programador iniciante não se depare com erros aparentemente inexplicáveis.

 

O comando mais usual é para ler dados que serão digitados no teclado da máquina. É possível também ler dados de outras mídias, como de um disco ou de uma fita magnética, mas esses casos serão vistos mais tarde.

 

Primeiramente é importante saber que os dados digitados pelo teclado são lidos pela máquina como uma linha de texto. Após digitar os dados, é necessário apertar a tecla ENTER para sinalizar que terminamos a linha. Nesse momento, os caracteres digitados serão colocados em uma memória intermediaria, conhecida popularmente como o buffer do teclado. O caractere correspondente à tecla ENTER também irá para o buffer.

 

Pelo fato de ser uma linha de texto, os dados digitados formam uma seqüência de valores de caracteres terminando com o valor do caractere ENTER. Se, por exemplo,  for digitado o número  –3.25 seguido de ENTER, então o buffer conterá os 5 caracteres do número (o caractere ‘-‘, seguido do caractere ‘3’, seguido do caractere ‘.’,  etc.), e após eles o caractere da tecla ENTER. É muito importante se ter essa noção de que o que digitamos não são “números”, mas sim uma seqüência de caracteres.

 

Números reais podem ser digitados em formato convencional (como 567.8), ou em notação cientifica (ex: 5.678E2 ou 0.567e+02 ou outra forma equivalente). Caracteres são digitados sem as aspas simples. (ex. A)

 

Quando o comando ler(<variável>) é executado, a máquina tenta construir um valor do tipo declarado da variável com os caracteres que já estão no buffer do teclado. Somente se não houver nada no buffer é que a máquina pára e aguarda que o buffer seja preenchido com uma nova linha de caracteres.  Se os caracteres que estiverem no buffer não formarem um valor do tipo esperado, haverá um erro de execução e o programa terminará imediatamente com uma mensagem de erro. Diz-se que o programa abortou a execução.

 

Suponha que o comando ler(x) foi executado,  e x é do tipo inteiro. Se digitarmos mais de um número na mesma linha, então o primeiro número será copiado para o valor de x, e os demais caracteres permanecerão no buffer esperando serem lidos pelos próximos comandos de leitura.

 

Por exemplo, suponha a seqüência de comandos seguinte, onde x e z são variáveis inteiras, e y é uma variável real:

 

ler(x)

ler(y)

ler(z)

ler(x)

 

Inicialmente, como o buffer está vazio, a máquina pára e espera que uma linha de caracteres seja digitada, finalizando com ENTER. Suponha que o usuário digite:

 

34  -567.45   98 <ENTER>

(A quantidade de espaços entre os números é irrelevante, devendo ser pelo menos 1. Não é permitido separar os números por virgulas ou outros caracteres A notação <ENTER> acima significa pressionar a tecla ENTER.)

 

Essa linha de texto irá para o buffer do teclado.

A seguir, o primeiro comando ler(x) lerá os caracteres ‘3’ e ‘4’, parando ao encontrar o primeiro espaço em branco. A rotina construirá o número inteiro 34, e este número será armazenado em x.

 

Terminado o comando ler(x), o próximo comando será executado, que é ler(y).

A máquina verifica que ainda existem caracteres não lidos no buffer do teclado, e começa a ler após o último caractere lido (após o ‘4’). Os espaços adicionais são pulados, até encontrar o hífen    (‘-‘). Um hífen pode ser parte de um número nessa posição (sinal de menos), por isso é aceito, e a máquina vai lendo os caracteres ‘5’,’6’, ‘7’ e encontra o ponto. Como o tipo de y é real, é permitido haver um ponto decimal (mais de um ponto seria erro), e por isso a máquina continua lendo os caracteres ‘4’ e ‘5’ até encontrar um espaço. Nesse momento a máquina conclui que terminaram os caracteres de y, e inicia uma rotina que vai construir um número real com esses caracteres. O numero é então armazenado na variável y na forma de mantissa e expoente (equivalente a –5.6745 x 102. (Na realidade é um pouco diferente porque a máquina trabalha na base 2, e não na base 10, mas o principio é o mesmo).

 

Terminado o comando ler(y), o próximo comando é executado, que é ler(z).

A máquina verifica que ainda existem caracteres não lidos no buffer, pula os espaços não lidos, e encontra o caractere ‘9’. Como z é inteiro, ela aceita o caractere, lê o ‘8’, e encontra um espaço. Constrói então o número inteiro 98, que é armazenado na variável z da memória.

 

O próximo comando, ler(x), é executado. A máquina encontra alguns espaços seguidos do caractere ENTER no buffer, mas nenhum outro caractere. Conclui que o buffer está vazio, e nesse momento pára aguardando que o usuário digite outra linha.

(OBS: não é possível digitarmos varias linhas de uma vez. Ao final de cada linha, a máquina re-assume o controle e trabalha com os dados da linha digitada. Só depois que o buffer voltar a ficar vazio é que a máquina pára e aceita outra digitação de linha.)

 

O usuário então digita, digamos:

456.0   seguido de ENTER.

 

A máquina vai procurar construir um inteiro com esses caracteres. Vai lendo o ‘4’, depois o ‘5’ , depois o ‘6’, até deparar com o ponto. Nesse ponto o programa abortará a execução, pois um inteiro não pode conter ponto decimal.

 

 

Cuidados a tomar com a leitura de variáveis tipo caractere:

É preciso muito cuidado para se ler variáveis do tipo caractere. O motivo é que qualquer espaço em branco, ou o próprio caractere ENTER, que estiverem no buffer do teclado no momento da execução do comando ler( ), pode causar com que o caractere errado seja transferido para a variável.

 

Um erro clássico é tentar ler um número seguido de um caractere.

Suponha que queremos ler o valor de n (inteiro) e depois os valores de letra1 e letra2 (ambos caracteres) com os comandos:

ler(n)

ler (letra1)

ler (letra2)

 

Então digitamos a linha: 

25 A B<ENTER>

 

esperando que n receba o valor 25, letra1 receba o valor ‘A’, e letra2 receba o valor ‘B’. O resultado porém será inesperado. Na realidade, n receberá o valor 25, letra1 receberá o caractere que é o espaço que segue o ‘5’, e letra2 receberá o caractere ‘A’. Os demais caracteres depois do A permanecerão no buffer e poderão ser lidos por outros comandos de leitura que seguirem.

 

Como então é possível ler um caractere depois de um número? Já vimos que a forma:

 25AB

não é possível, porque deve sempre existir pelo menos um “valor branco”  (espaço, tabulação ou o caractere ENTER) após cada numero.

 

Mesmo que quiséssemos fazer a entrada em 2 linhas, como abaixo:

25<ENTER>

AB<ENTER>

isso não adiantaria, porque o ENTER final da primeira linha corresponde a 2 caracteres (CR seguido de LF), o que fará com que letra1 receba o caractere CR (valor 13) e letra2 receba o caractere LF (valor 10). Aliás a máquina por isso mesmo nem chegaria a pedir a segunda linha.

 

COMANDO PARA LER UMA NOVA LINHA

Para resolver esse problema, existe um comando que “esvazia o buffer do teclado”. Esse comando é novaLinha. O efeito desse comando é ignorar todos os caracteres não lidos que ainda existam no buffer do teclado, de modo a forçar que uma nova linha seja lida pela máquina.

 

Agora podemos fazer:

ler(n)

novaLinha

ler(letra1)

ler(letra2)

 

 e digitar:

25<ENTER>

AB<ENTER>

 

O comando ler(n) lerá o número 25 para a variável n, os 2 caracteres do <ENTER> serão ignorados por conta do comando novaLinha, e a máquina lerá os caracteres da segunda linha. Agora a letra A será associada à variável letra1, e a letra B (valor 66) será associada à variável letra2, corretamente. Observe que os caracteres A e B são digitados em seqüência, sem nenhum espaço entre eles. Caso existisse um espaço entre eles, a variável letra2 receberia o valor do espaço.

 

Na linguagem Pascal, os comandos correspondentes são:

ler(<variável>)    é   read (<variável>)

novaLinha       é   readln

 

COMANDO DE ESCREVER (SAÍDA)         escrever (<expressão>)

 

O comando escrever( )  recebe uma expressão como argumento. O efeito desse comando é normalmente de escrever o resultado da expressão no dispositivo padrão de saída, que em geral é o monitor de vídeo.

 

É importante notar que, ao contrário do comando de leitura, o argumento é uma expressão, e não uma variável.  

Mas, lembrando sempre que uma variável é também uma expressão trivial, esse comando também pode receber uma variável como argumento.

 

Por exemplo, supondo que no momento da sua execução, as variáveis x  e y valem, respectivamente,  10 e 20, então o comando:

  escrever (x*3 + x*y)

faz com que a expressão seja calculada na Unidade Aritmética Lógica, sendo reduzida ao valor 230, e a seguir esse numero será escrito no monitor de saída.

 

OBS: Os valores serão escritos na tela na posição onde estiver o cursor.  É preciso atenção para levar em conta onde o cursor estará quando o comando escrever() for realizado.

 

Expressões com uma seqüência de caracteres:

 

Uma seqüência de caracteres, delimitada por um par de aspas simples, é uma expressão válida em Pascal  e pode ser usada nos comandos de escrita. Elas serão escritas literalmente no campo correspondente.  Como as demais expressões, um formato pode ser adicionado para especificar o tamanho ocupado na linha de saída. Caso um formato não seja especificado, o tamanho usado será o menor possível.

 

Por exemplo, supondo que uma variável inteira n tenha o valor 30, o comando abaixo imprime duas expressões, a literal  'n+5 = '  seguida do valor calculado de n+5.

  escrever ('n+5 = ', n+5)

fará com que seja escrita na tela a frase:      n+5 = 35

 

Comandos de escrita na linguagem Pascal:

Os comandos abaixo escrevem na unidade padrão de saída, que é normalmente a tela do monitor de vídeo. Comandos semelhantes para escrever no disco serão vistos mais adiante.

 

write (<expressão>)  

     equivale ao que foi descrito acima para  escrever(<expressão>)

 

write (<expressão-1>, <expressão-2>,...., <expressão-n>)   onde n >= 1

     equivale à seqüência de n comandos:

     write (<expressão-1>);

     write (<expressão-2>); 

      ...... 

     write (<expressão-n>)

 

writeln

      O cursor avança para o inicio da próxima linha na tela de saída. Equivale a escrever o caractere <ENTER> ou novalinha.

 

writeln (<lista de expressões>)

      Equivale à seqüência de comandos:

      write(<lista de expressões>);

      writeln

Nota: o ponto-e-vírgula é necessário para separar 2 comandos na linguagem Pascal.

 

FORMATOS DE SAÍDA

 

O processo de escrita na saída é inverso ao processo de leitura. Os valores que estão na Unidade Aritmética Lógica estão em um formato interno da maquina, mas podem ser escritos de vários formatos diferentes. Por exemplo, o numero 2.567e2 pode ser impresso como 256.7, como 256.7000, etc. A linguagem permite escolher dois aspectos do formato de impressão:

a)      quantos caracteres no total terá o formato impresso do valor, incluindo o sinal (+ ou -) e o ponto decimal.

b)      qual a precisão (numero de casa decimais) com que o valor será impresso (só para valores reais).

 

Os números reais serão impressos na notação cientifica se o formato não indicar o número de casas decimais.

 

Para indicar o formato de impressão, a expressão deve ser seguida do tamanho em caracteres com que o seu valor será escrito, seguido (no caso de reais) do número de casas decimais, ambos precedidos por um dois-pontos (: ) , como em escrever(x+y:10:3)

 

Note que o comando escrever( ) não acrescenta nenhum espaço após escrever cada valor de expressão. Isso deve ser providenciado pelo programador.  Por exemplo, se imprimir os valores de x e y (inteiros) e z (real), valendo  153, 10245  e -32.767, respectivamente, o comando:

  escrever (x,y,z)   escreverá na tela algo como:

15310245-3.27670000000000000E+001    o que pode ser muito desagradável.

 

Para ter uma saída mais legível, devemos levar em conta a necessidade dos espaços entre os valores, e colocar um formato adequado para cada valor, com casas decimais para os números reais. O comando:

  escrever(x:5, y:6, z:9:2)  escreverá na tela o seguinte (note o arredondamento de z):

  153 10245   -32.77

 

Os exemplos abaixo ilustram os vários casos,  onde as variáveis x (inteiro), y (real) , e  letra (caractere) são respectivamente a -10,  25.68  e  A. Note que os números serão arredondados automaticamente para se ajustarem ao número de casas decimais definido no formato. Em particular, um real com zero casas decimais será impresso como o inteiro mais próximo. Números reais serão impressos sempre em notação cientifica caso não seja especificado no formato a quantidade de casas decimais desejada. Números reais sem tamanho definido, serão impressos em um tamanho padrão definido pelo compilador usado. Números inteiros sem tamanho definido ocupam o menor tamanho necessário para escrevê-los.

 

Nos exemplos abaixo, as colunas de texto foram numeradas para melhor visualização:

 

colunas da tela--->    

1

2

3

4

5

6

7

8

9

10

11

12

13

escrever(x:4)

 

-

1

0

 

 

 

 

 

 

 

 

 

escrever(y:9:1)

 

 

 

 

 

2

5

.

7

 

 

 

 

escrever(y/2:12)

 

1

.

2

8

4

0

0

E

+

0

1

 

escrever(y/2:8:3)

 

 

1

2

.

8

4

0

 

 

 

 

 

escrever(y/2+1:10:0)

 

 

 

 

 

 

 

 

1

4

 

 

 

escrever(letra)

A

 

 

 

 

 

 

 

 

 

 

 

 

escrever(letra:5)

 

 

 

 

A

 

 

 

 

 

 

 

 

 Nota: O formato de impressão em notação cientifica pode variar ligeiramente entre várias implementações.

 

OBSERVAÇÕES ADICIONAIS:

Valores lógicos são impressos da seguinte forma (em Pascal):

verdadeiro --- >  TRUE

falso --- >           FALSE

O número de colunas usadas pode também ser controlado com o formato.

 

Capítulo 1                Capítulo 3