ALGORITMOS
COM PASCAL
Prof. Miguel Jonathan – Dept. Ciência da Computação – IM/UFRJ – 2003 –
versão 1.1
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.
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>)
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:
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):
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.