68
ALGORITMOS COM PASCAL Prof. Miguel Jonathan – Dept. Ciência da Computação – IM/UFRJ - 2003 CAPíTULO 1 TIPOS E VALORES: A cada tipo básico da linguagem corresponde um conjunto de valores possíveis. Os tipos que usaremos e que existem na linguagem Pascal, são inteiro , real , lógico e caractere . Valores podem ser armazenados em variáveis na memória da máquina, e podem ser manipulados na unidade aritmética- lógica. Tipos de valores disponíveis: - números inteiros ex: 10 345 -27 - números reais ex: 2.45 2.450 2.4500 1267.54 (os 3 primeiros representam o mesmo valor) (e também em notação cientifica: 1.6754 x 10 3 ou 1.6754E+3 ou 1.6754e3 ou 0.126754E4 ) - valores lógicos (verdadeiro/sim e falso/não) - caracteres (símbolos) ex: ‘*’ ‘?’ ‘G’ ‘p’ ‘4’ OPERAÇÕES: Uma operação é realizada com valores, na Unidade Aritmética- Lógica da máquina, e produz como resultado outro valor, que fica armazenado temporariamente nos registros, podendo ser usado em operações subseqüentes. As operações podem ser unárias ou binárias , dependendo se operam sobre um ou dois valores. Uma operação é formada por um operador e um ou doisoperandos (operação unária ou binária ). Os operadores possíveis dependem do tipo dos operandos envolvidos.

Algoritmos Com Pascal

Embed Size (px)

Citation preview

Page 1: Algoritmos Com Pascal

ALGORITMOS COM PASCAL 

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

 CAPíTULO 1  TIPOS E VALORES: A cada tipo básico da linguagem corresponde um conjunto de valores  possíveis. Os tipos que usaremos e que existem na linguagem Pascal, são inteiro, real,  lógicoe caractere. Valores podem ser armazenados em variáveis na memória da máquina, e podem ser manipulados na unidade aritmética-lógica.Tipos de valores disponíveis:

-         números inteiros   ex:  10  345  -27-         números reais    ex:  2.45 2.450  2.4500  1267.54   (os 3 primeiros representam o

mesmo valor)     (e também  em notação cientifica:  1.6754 x 103  ou 1.6754E+3  ou 1.6754e3  ou 0.126754E4 )-         valores lógicos (verdadeiro/sim   e  falso/não)-         caracteres (símbolos)  ex:  ‘*’  ‘?’  ‘G’  ‘p’   ‘4’ 

  OPERAÇÕES:Uma operação    é realizada com valores, na Unidade Aritmética-Lógica da máquina, e produz como resultado outro valor, que fica armazenado temporariamente nos registros, podendo ser usado em operações subseqüentes.As operações podem ser unárias ou binárias , dependendo se operam sobre um ou dois valores. Uma operação é formada por um operador e um ou doisoperandos (operação unária  ou binária). Os operadores possíveis dependem do tipo dos operandos envolvidos. a) Operações sobre inteiros, com resultado inteiro:

operadores binários:   +  -  *   div e mod+  (soma)      ex:   10 + 30   resultado:  40- (subtração)    ex:   30 -  12    resultado:  18*    (multiplicação)    ex:   20 * 4   resultado:  80div (divisão inteira)    ex:  30 div 4   resultado: 7mod (módulo, ou resto da divisão inteira)  ex:  30 mod 7   resultado: 2

 operador unário:  -  (produz o negativo do seu operando)ex:  - 7      operador -  aplicado sobre o operando 7 produz o resultado –7       -(-7)  produz o resultado 7. 

b) Operações sobre reais com resultado real:

Page 2: Algoritmos Com Pascal

operadores binários:   +  -  *   / +  (soma)      ex:   10.5 + 30.27   resultado:  40.77-         (subtração)    ex:   30.2 -  12.8    resultado:  17.4*    (multiplicação)    ex:   20.0 * 4.2   resultado:  84.0/   (divisão real)  ex:  30.0 / 4.0    resultado:  7.5 Caso a operação envolva um operando real e um inteiro, o resultado será sempre real:30 – 2.5  resultado:  27.530 / 4.0   resultado: 7.5 O operador /  quando usado com 2 operandos inteiros, produz o resultado real:   30/4  resultado: 7.5 

c) Operadores relacionais binários, operando sobre inteiros e reais, com resultado lógico:>   <  >=    <=   <>   =>  (maior)   ex:   20  >  30     resultado:  falso  (não)< (menor)   ex:   20 <  30    resultado:  verdadeiro (sim)>=  (maior ou igual)     ex:  20 >= 30   resultado:  falso       20>=20    resultado:  verdadeiro<=  (menor ou igual)    ex:  20 <= 30   resultado: verdadeiro  <>  (diferente)     ex:  20 <> 30   resultado:  verdadeiro     30.6 <> 10.78   (verdadeiro)= (igual)   ex:   20 = 20  resultado: verdadeiro Comparação de caracteres:O operadores relacionais também podem ser usados para comparar dois valores do tipo caractere. Por exemplo, é correto escrever a operação:   ‘d’ > ’b’  Nas linguagens de programação em geral, e em Pascal em particular, essas comparações devem ser interpretadas de forma especial.A linguagem permite utilizar 256 caracteres diferentes. Os caracteres são colocados em ordem, em uma tabela que começa na posição 0 e vai até 255. Essa tabela é hoje em dia um padrão da indústria, e é conhecida como “tabela ASCII”. A cada posição da tabela corresponde um caractere. O “valor” de cada caractere é na realidade o numero inteiro que representa a posição desse caractere na tabela.  O caractere em si deve ser visto apenas como um símbolo, ou um desenho.A tabela é longa, mas é importante saber alguns detalhes úteis:-         os caracteres das letras maiúsculas estão na tabela em ordem alfabética-         os caracteres das letras minúsculas também.-         os caracteres dos algarismos (‘0’ a ‘9’) seguem a ordem crescente dos números-         as letras acentuadas estão em posições sempre acima de 128-         algumas teclas do teclado correspondem a 2 caracteres seguidos. A tecla ENTER

corresponde ao caractere CR (carriage return, ou retorno de carro), da posição 13, seguido do caractere LF (line feed, ou alimentação de linha), da posição 10.

O programador Pascal não precisa saber mais detalhes sobre as posições dos caracteres na tabela para poder programar sem problemas, mas por curiosidade a tabela é mostrada parcialmente abaixo: TABELA ASCII  (American Standard Code for Information Interchange)

Page 3: Algoritmos Com Pascal

0 .

Page 4: Algoritmos Com Pascal

1 .2 .. .10 LF . .13 CR. .48 ‘049 ‘1’50 ‘2’. .. .56 ‘8’57 ‘9’. .. .. .65 ‘A’66 ‘B’67 ‘C’. .. .89 ‘Y’90 ‘Z’. .. .97 ‘a’98 ‘b’. .. .121 ‘y’122 ‘z’. .. .133 ‘à’. .. .160 ‘á’   etc etc

 Então, quando fazemos a comparação de dois caracteres usando operadores relacionais, o que é comparado na realidade são as posições correspondentes na tabela.  Como as letras estão em ordem alfabética crescente na tabela, teremos que:   ‘D’ <  ‘F’   resulta em verdadeiro  (na realidade estará sendo feita a operação 68<  70)

Page 5: Algoritmos Com Pascal

Da mesma forma, ‘d’ < ‘f’ também resulta em verdadeiro  (será feito 100 < 102 ), ou seja, os operadores < , >, etc, podem ser interpretados como “antes” e “depois” na ordem alfabética. Mas isso só vale para comparação entre letras maiúsculas ou entre letras minúsculas. Se compararmos uma maiúscula com outra minúscula, essa interpretação pode falhar. Por exemplo,  ‘D’  <  ‘a’  dará verdadeiro  (pois 68 < 97), embora a letra ‘D’ esteja alfabeticamente “depois” da letra ‘a’.Para evitar isso é comum, em programas que comparam palavras alfabeticamente, primeiro converter todas as letras para maiúsculas ou para minúsculas, e só depois fazer as comparações. Mas isso será visto mais adiante. Outro ponto importante a ressaltar, é que fica difícil comparar letras acentuadas com as demais, para determinar a ordem alfabética relativa. Vemos acima o exemplo de ‘à’  e do ‘á’, em posições muito distantes das demais letras. Infelizmente o padrão da tabela ASCII vale apenas para os primeiros 128 caracteres, e as letra acentuadas estão em uma área da tabela que não é padronizada. Ainda existem em operação muitos ambientes de programação com valores diferentes entre si para as letras acentuadas. Por esse motivo, o uso de letras acentuadas em muitas aplicações é desencorajado. Neste curso evitaremos trabalhar com letras acentuadas. Também é importante observar que os caracteres que representam os algarismos estão também em posições contíguas na tabela, e seguem a ordem crescente dos números que representam. Assim vemos que, por exemplo, ‘7’ > ‘3’ dará verdadeiro   (porque  55 > 51).  d) Operadores lógicos  operando sobre valores lógicos, com resultado lógico: 

Operadores binários:     OU-INCLUSIVO (OU)    E     OU-EXCLUSIVO  (XOU)Operador unário:      NÃO

       Significados:     OU : para a OU b  ser Verdadeiro, basta um dos operandos, ou ambos, ter o valor Verdadeiro.       E:  para a E b  valer Verdadeiro, ambos os operandos devem valer Verdadeiro XOU:  para a XOU b valer Verdadeiro, apenas um dos operandos pode valer

Verdadeiro, o outro deve valer Falso. NÃO:  negação do operando.

 A tabela verdade abaixo resume essas operações:  (V – verdadeiro, F – falso) 

x y x ou y x E y x XOU y

não x

F F F F F VF V V F V V

Page 6: Algoritmos Com Pascal

V F V F V FV V V V F F

 Equivalente em inglês:  os operadores lógicos têm nomes consagrados na língua inglesa, que são usados na grande maioria das linguagens de programação. Usaremos também a notação em inglês, por ser universal.   OU-INCLUSIVO  (OU)   

INCLUSIVE-OR   (OR)

E       ANDOU-EXCLUSIVO (XOU)

EXCLUSIVE-OR   (XOR)

NÃO NOT    VARIÁVEIS, CONSTANTES, MEMÓRIA  e IDENTIFICADORES Uma variável  consiste de um identificador ao qual é associada uma área de memória onde podem ser armazenados valores de um determinado tipo. Uma variávelsimples corresponde a apenas um valor. Uma variável composta representa um  agrupamento de valores na memória da máquina. Por exemplo, o identificador nota  pode representar uma área da memória onde é armazenado um valor real (a nota de um aluno). Então, se a nota do aluno for, digamos, 8.5, podemos associar o identificador nota com o valor 8.5.  Variáveis compostas serão vistas mais adiante. Uma constante é um identificador que corresponde a uma área da memória onde fica armazenado um valor que não deve ser alterado pelo algoritmo. Por exemplo, o identificador PI pode ser associado a uma área da memória onde será armazenado o valor 3.1416 no inicio de um algoritmo, mas que não deverá ser mais modificado. Um identificador pode ser formado por letras, algarismos e o caractere sublinhado (‘_’) em qualquer quantidade, desde que não iniciado por um algarismo. Em geral procura-se formar uma palavra que lembre mnemonicamente o significado do valor correspondente no problema que está sendo resolvido pelo algoritmo.Por exemplo, o identificador salário pode ser associado a um valor real que representa o salário de alguém, e o identificador achou  pode ser associado a um valor lógico que indica se a busca por um determinado valor numérico em uma lista foi bem sucedida ou não.  EXPRESSÕES:

Page 7: Algoritmos Com Pascal

Uma expressão   é uma fórmula contendo valores, operandos, identificadores de variáveis ou constantes, e outros símbolos permitidos, e que pode ser calculada de modo a ser reduzida a um valor final. No cálculo de uma expressão os identificadores são substituídos pelos valores correspondentes que estão na memória no momento em que a expressão é calculada.As operações que fazem parte de uma expressão são executadas da esquerda para a direita, respeitando as regras de precedência.Regras de Precedência: maior precedência:     -  unário,   NÃO

  *  /   div  mod  E  +   -  (binário)   OU  OU-EXCLUSIVO

menor precedência      >  <  >=   <=    <>  = Além disso, se houver parênteses na expressão, terão prioridade de execução as operações que estiverem nos níveis mais internos de parênteses. Exemplo de expressão:    PI + 3 * x – 2.5onde PI  tem o valor 3.1416  e x tem o valor 10, no momento em que a expressão será calculada na Unidade Aritmética Lógica da máquina.Para reduzir essa expressão a um valor, os identificadores são inicialmente substituídos pelos valores correspondentes na memória. A seguir, as operações são executadas da esquerda para a direita. Como o operador * tem precedência sobre o operador +, a operação  3 * x  será feita primeiro. Como + e – têm a mesma precedência, a operação de soma será feita a seguir, e finalmente a subtração. Os valores intermediários resultantes de cada operação são usados como operandos das operações seguintes.O gráfico abaixo indica os passos que levam à redução da expressão ao seu valor final:    PI + 3 * x – 3.13.1416 + 3 * 10 – 3.1    (subst. dos valores dos identificadores)  3.1416 + 30 – 3.1      (* tem precedência sobre +)    33.1416 – 3.1       ( + e – tem a mesma precedência, então a operação mais à esquerda é feita primeiro)      30.0416                (valor final da expressão) Uso de parênteses permite violar as regras de precedência:      PI + 3 *( x – 3.1)3.1416 + 3 * (10 – 3.1 )    3.1416 + 3 * 6.9    3.1416 + 20.70

23.8416  (valor final da expressão) OBS: usar parênteses em excesso não é erro:   (3+4)  ou ((3+4))  tem o mesmo valor que 3+4 Neste próximo exemplo, a expressão se reduz a um valor lógico. Note que não são necessários parênteses porque a precedência dos operadores relacionais é menor que a dos operadores aritméticos:

Page 8: Algoritmos Com Pascal

 PI + 3*x >  x – 23.1416 + 3 * 10 > 10 –23.1416 + 30 > 10-233.1416 > 10 – 2  33.1416 > 8         ( - tem precedência sobre >)    verdadeiro        (valor final da expressão)  Expressões bem e mal formadas:Uma expressão precisa estar bem formada sintaticamente para poder ser calculada. Por exemplo, a expressão abaixo não pode ser calculada, pois exige operações impossíveis: 10 > 20  OU  100 = 40     (expressão mal-formada ) Como o operador OU tem precedência sobre o operador >, a operação  20 OU 100 deveria ser feita primeiro. Mas não é possível fazer essa operação, porque o operador OU só se aplica a operandos lógicos. Existe nessa fórmula um erro de sintaxe (forma gramatical errada). Para corrigir o erro, introduzimos parênteses para forçar que a operação relacional seja feita antes: (10 > 20)  OU  (100 = 40)     falso  OU   falso            falso Nota: essa observação é válida para a linguagem Pascal. Na linguagem C, por exemplo, os operadores lógicos têm menor precedência que os operadores relacionais. Por isso, em C, a expressão acima sem parênteses estaria correta. Expressões Triviais:Uma única constante literal, ou um único identificador de variável, constitui uma expressão trivial, mas é uma expressão legitima:Por exemplo:      3   é uma expressão trivial, seu valor é 3.    Se x  tem o valor 3,  a expressão:   x   é trivial, com valor 3.   Expressões envolvendo funções:Assim como na Matemática, uma expressão pode conter também o uso de funções com argumentos que são também expressões. Funções serão vistas mais adiante, mas para ilustrar a expressão abaixo usa a função sqrt( )  (de square root – raiz quadrada):                                                                                             ____x + 3 * sqrt(y-2)     equivalente em Matemática a    x + 3  y-2 

CAPíTULO 2  

Page 9: Algoritmos Com Pascal

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. 

Page 10: Algoritmos Com Pascal

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 bufferdo 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>

Page 11: Algoritmos Com Pascal

(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

Page 12: Algoritmos Com Pascal

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: 25ABnã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 LINHAPara 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)novaLinhaler(letra1)ler(letra2)  e digitar:25<ENTER>AB<ENTER>

Page 13: Algoritmos Com Pascal

 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 comandoescrever() 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:

Page 14: Algoritmos Com 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>);      writelnNota: 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:

Page 15: Algoritmos Com Pascal

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 --- >  TRUEfalso --- >           FALSEO número de colunas usadas pode também ser controlado com o formato.

CAPíTULO 3 

Estrutura de um programa em Pascal 

Page 16: Algoritmos Com Pascal

Um texto contendo um programa na linguagem Pascal deve obedecer a regras de sintaxe (forma) bem específicas, para que o compilador possa reconhecer as suas diversas partes, e convertê-lo (traduzir) para uma seqüência equivalente de comandos em linguagem de máquina.

 

Nas definições abaixo, as palavras e símbolos que não estão entre os sinais de < e > são considerados como elementos da linguagem Pascal e devem ser escritos literalmente. As frases entre os sinais <  e  > são explicações em português do que deve entrar no lugar delas. Dizemos que essas frases estão escritas na meta-linguagem (a linguagem que usamos para definir uma outra linguagem).

 program <identificador>;

<declarações de constantes>

<declarações de variáveis>

<declarações de funções e procedimentos>

<bloco>

.

 

Funções e procedimentos serão vistos em um capitulo mais à frente.

Note a primeira palavra deve ser program e que o último caractere deve ser um ponto-final, após o <bloco>.

 

Na estrutura acima, definimos:

<declarações de constantes>  = const  <lista de definições de constantes>

 Exemplo:

const  pi=3.1415;  n = 30;Note que o sinal de igualdade é usado, e que tipos não são declarados. O compilador deduz os tipos pelo formato dos valores usados nas declarações. O ponto-e-vírgula deve terminar cada declaração de constante.

 

<declarações de variáveis> = var  <lista de definições de variáveis>

Exemplo:

Page 17: Algoritmos Com Pascal

var   x,y:integer;

  w,z:real; 

  letra1:char;

  terminou: boolean;

 

Observações:

Tanto faz escrever as declarações em uma ou em várias linhas.

O tipo de cada variável deve ser indicado após o sinal de dois-pontos.

Várias variáveis de um mesmo tipo podem ser declaradas juntas, separadas por virgulas.

O tipo boolean é o equivalente em Pascal a um valor lógico.

O tipo char indica que a variável contém o valor de um caractere.

 

O bloco de comandos:

O programa em si está contido no <bloco> que é definido como:

<bloco> =  begin <lista de comandos>  end

 <lista de comandos> = <comando-1>; <comando-2>; .....; <comando-n>   onde n>=0

 Note que, pela definição acima, um programa pode ter zero comandos, e ainda ser um programa “bem formado”, embora não sirva para nada.

 Exemplo de um programa:

program exemplo;

const

 n1= 5;

 n2= 3;

var

 x,y:integer;

Page 18: Algoritmos Com Pascal

 comp: boolean;

begin

 writeln('Digite um multiplo de ',n1, ' e outro multiplo de ', n2, ': ');

 read(x,y);

 comp:= x > y;

 writeln(x, ' > ', y, ' = ', comp);

 readln; readln;

end.

 No programa acima, o bloco de comandos que é executado começa logo após o begin.

O bloco contém 6 comandos. Os dois últimos estão escritos na mesma linha, mas apenas por conveniência. Cada comando deve ser separado do seguinte por um ponto-e-vírgula.

Após o ultimo comando de um bloco o ponto-e-vírgula é opcional.

No exemplo acima, n1 e n2 poderiam também ter sido declaradas como variáveis inteiras, em vez de constantes. Nesse caso, seus valores deveriam entrar como comandos de atribuição, dentro do bloco, como abaixo. O efeito seria exatamente o mesmo.

O exemplo mostra o uso de comentário delimitado por (*  e  *)  . Comentários podem também ser delimitados por {  e  } .

 

program exemplo2;

(******************************************************************

 Este exemplo evita usar constantes.

 Mas mostra o uso de comentários.

*******************************************************************)

var

 n1,n2,x,y:integer;

 comp: boolean;

begin

 n1:=5;

Page 19: Algoritmos Com Pascal

 n2:=3;

 writeln('Digite um multiplo de ',n1, ' e outro multiplo de ', n2, ': ');

 read(x,y);

 comp:= x > y;

 writeln(x, ' > ', y, ' = ', comp);

 readln; readln;

end.

 

Comandos de controle do fluxo de instruções:

 

COMANDOS DE DESVIO CONDICIONAL

 

a) se <expressão lógica>  então <comando-verdade>

b) se <expressão lógica>  então <comando-verdade>  senão <comando-falso>

 

No primeiro caso,  o valor da expressão lógica é calculado, e caso  seja Verdade (True) o <comando-verdade> é executado, caso seja Falso nada é feito.

 

No segundo caso, caso o valor da expressão lógica for Falso, o <comando-verdade> não é executado, mas o <comando-falso> é executado.

 

Exemplo:

 

Seja o comando:

 

se  (x mod 2 = 0) e (x < y) então escrever (x div 2) senão escrever (x+y)

 

Page 20: Algoritmos Com Pascal

Supondo que os valores de x e y sejam respectivamente 10 e 15 no momento da execução do comando acima, então teremos:

 Cálculo da expressão lógica:

(x mod 2= 0)  e (x <y)

(10 mod 2 = 0) e (10 < 15)

   (0 = 0) e  Verdade

  Verdade e Verdade

          Verdade

 

Como o valor calculado foi Verdade, o comando após a palavra-chave então será executado, e será impresso o valor de x div 2, ou seja, 10 div 2 que é 5.

 

Mas se os valores de x  e  y forem 11 e 15, o valor da expressão será outro:

(x mod 2= 0)  e (x <y)

(11 mod 2 = 0) e (11 < 15)

   (1 = 0) e  Verdade

  Falso e Verdade

          Falso

 

E nesse caso o comando após a palavra-chave senão será executado, sendo escrito na tela o valor de x+y, ou seja 11+15 que é 26.

 

 

Na linguagem Pascal, esses comandos são escritos assim:

 

a) if  <expressão lógica>  then <comando-verdade>

b) if  <expressão lógica>  then <comando-verdade>  else <comando-falso>

Page 21: Algoritmos Com Pascal

 

 

 

 

c) Comando case: 

O   comando case é   um   comando   que   permite   selecionar   um   ou  mais   comandos   para   serem executados conforme o valor de uma expressão escalar (ou seja, o valor deve ser simples, não pode   ser,   por   exemplo,   uma   string).   Somente   os   tipos inteiro, caractere, lógico,   e   tipos enumerados (não vistos ainda) podem ser usados.

 

Neste   comando   o   valor   da   expressão   é   comparado   com  os   valores   dos   casos   previstos   de execução. No máximo um caso pode ser verdadeiro.

 

Os valores dos casos podem ser:

-          um valor de uma constante escalar.

-          uma lista de valores escalares, separados por vírgulas.

-          uma   faixa   de   valores   da   forma   <valor-1> .. <valor-2>,   significando  o   conjunto   de   valores contidos no intervalo de <valor-1> a <valor-2>.

-          uma combinação de faixas de valores e listas de valores, separados por virgulas.

 

Alem disso os valores não podem ser repetidos, ou seja, um valor só pode aparecer em apenas um dos casos.

 

Sintaxe:

 

case  <expressão> of

Lista Constantes Escalares-1: Comando-1;

Lista Constantes Escalares-2: Comando -2;

Page 22: Algoritmos Com Pascal

. . .

Lista Constantes Escalares-k: Comando-k;

else

Comando;

. . .

Comando;

end

 

OBS: A parte do else pode não existir. Nesse caso, nada ocorrerá se nenhum dos casos for verificado. 

Exemplo:

No exemplo abaixo, a expressão é uma variável c , do tipo caractere. O primeiro caso é uma lista com duas faixas de valores,  e inclui todas as letras maiúsculas entre A e Z, e todas as letras minúsculas entre a e z.  O segundo caso inclui os dígitos de 0 a 9. O terceiro caso inclui uma lista com 4 valores , que são os caracteres usados para as operações aritméticas. Caso a expressão c não tenha nenhum desses valores, os dois comandos após o else serão executados. program exemplo; var c: char; begin write('Entre com um caractere: '); readln(c); case c of 'A'..'Z','a'..'z': writeln('Caractere lido e'' letra.'); '0'..'9': begin           writeln('Caractere lido e'' um digito ');           writeln('entre 0 e 9');           end; '+','-','*','/': writeln('Caractere lido e'' um operador matematico.'); else writeln('O caractere lido nao e'' letra, nem digito,');      writeln('nem operador matematico.'); end;end. 

Para melhor compreender o exemplo acima, segue abaixo o programa equivalente usando comandos if..then...else equivalentes:

 

program exemplo_if;

 var c: char;

Page 23: Algoritmos Com Pascal

 begin

 write('Entre com um caractere: ');

 readln(c);

 if (c>='A') and (c <= 'Z') or (c>= 'a') and (c <= 'z')

  then writeln('Caractere lido e'' letra.')

  else if (c>='0') and (c<= '9')

       then  begin

             writeln('Caractere lido e'' um digito ');

             writeln('entre 0 e 9');

             end

       else if (c='+') or (c='-') or (c='*') or (c= '/')

            then writeln('Caractere lido e'' um operador matematico.')

            else begin

                 writeln('O caractere lido nao e'' letra, nem digito,');

                 writeln('nem operador matematico.');

                 end;

 end.

 

 

Note bem que:

Todo comando case pode ser transformado em um comando if...then ...else equivalente, mas o reverso não é verdade.

O comando case deve ser usado onde um comando if equivalente só teria expressões lógicas do tipo:

     <expressão> = <constante-escalar>

e sempre usando a mesma expressão.

 

Caso a expressão não corresponda a nenhum dos casos, então o efeito do comando case é nulo.

Page 24: Algoritmos Com Pascal

 

 

EXERCÍCIOS DE FIXAÇÃO:

 1)      Escrever um programa em Pascal que solicita do usuário os coeficientes a, b e c da equação de 

segundo grau:  

           

ax2 + bx + c = 0

 

e imprime uma das seguintes respostas na tela:

a)      Existem duas raízes reais com valores <valor 1>  e  <valor 2>

b)      Existe apenas uma raiz real, com valor <valor único>

c)      Não existem valores reais.

 

O programa deve calcular inicialmente o determinante b2 – 4*a*c.  Caso seja positivo, calcula os valores (–b + sqrt(b*b-4*a*c))/(2*a)  e  (-b-sqrt(b*b-4*a*c))/(2*a)  e imprime a primeira resposta. Caso seja nulo, calcula o valor –b /(2*a)  e imprime a segunda resposta. E caso seja negativo, imprime a terceira resposta.

 

2)      Escrever um programa em Pascal que calcula o Imposto de Renda anual de um contribuinte pessoa física. O usuário deve digitar os seguintes valores reais:

a)      o rendimento bruto tributável recebido no ano;

b)      o total de deduções a que tem direito;

c)      o valor de Imposto de Renda na fonte, já pago durante o ano.

 

Como resposta, o programa deve escrever uma das frases abaixo:

a)      Imposto a pagar:  <valor em reais e centavos>

b)      Imposto a receber por devolução:  <valor em reais e centavos>

Page 25: Algoritmos Com Pascal

 

O valor do cálculo do Imposto usa  a tabela progressiva divulgada pelo Governo, que neste ano é a seguinte:

 

Base de cálculo anual em R$ Alíquota (%) Parcela a deduzir do imposto em R$

Até 12.696,00 - -

De 12.696,01 até 25.380,00 15,0 1.904,40

Acima de 25.380,00 27,5 5.076,90

 

A Base de cálculo acima é obtida subtraindo o total das deduções do rendimento bruto tributável recebido no ano. O imposto é calculado em partes, um valor para cada faixa de rendimentos. 

CAPíTULO 4 

Repetição em programas Pascal

 Desvio incondicional  -  o comando goto

A grande maioria dos programas de computador precisa repetir muitas vezes um mesmo comando, ou grupo de comandos, para realizar a sua tarefa.

Na fase inicial da programação, quando ainda não haviam programas muito grandes, as linguagens de programação dispunham apenas do comando goto(literalmente significando “vá para”) para forçar a repetição de comandos. A ele dá-se o nome de desvio incondicional.

Apesar do seu uso não ser mais recomendado hoje em dia, a compreensão do funcionamento do comando goto ajuda bastante a entender o funcionamento dos modernos comandos de repetição que serão vistos mais adiante.

O comando goto é usado junto com um ponto de retorno chamado de rótulo (label em inglês). Qualquer comando Pascal pode ser precedido por um rótulo seguido de : e o comando goto pode ser usado para forçar um retorno do programa para qualquer um dos rótulos definidos. Rótulos são declarados na seção de declarações do programa, precedidos da palavra-chave label.  Um rótulo pode ser qualquer identificador, ou um inteiro entre 0 e 9999. A sintaxe do comando é: goto <nome do rótulo>

Os exemplos abaixo ajudam a entender o mecanismo.

Seja obter a soma dos inteiros de 1 até um valor n qualquer maior que 1:

Exemplo 4.1 :

01:program testgoto;02:var x,soma,n:integer;03:label 1;04:begin05:soma:=0;06:x:=1;07:write('Ate'' que numero deseja somar os inteiros? ');08:readln(n);

Page 26: Algoritmos Com Pascal

09:1: soma:=soma+x;10:x:= x+1;11:if x <= n  then goto 1;12:writeln('A soma de 1 a ', n, ' e'' igual a ', soma);13:end.

 

No programa acima, as linhas estão numeradas para melhor compreensão das explicações. A seqüência de comandos acima fará com que o programa fique repetindo os comandos das linhas 9, 10 e 11 enquanto o valor de x não ultrapassar o valor de n. Outra maneira de dizer a mesma coisa, é dizer que essas linhas serão repetidas até que o valor de x ultrapasse o valor de n.  Os comandos entre um rótulo e o comando goto para esse rótulo recebem o nome de laço de repetição.

 

O programa seguinte mostra um exemplo mais complexo. Desejamos imprimir a seqüência de inteiros da forma:

122333444455555 etc.

para inteiros variando de 1 até um valor máximo n.

Note que a seqüência tem um laço dentro de outro laço. O laço mais “externo” faz com que os números da seqüência variem de 1 até n, e o laço mais “interno” faz com que, para cada numero k, entre 1 e n, este seja repetido k vezes.

Exemplo 4.2 :

01:program tesgoto2;02:var x,k,n:integer;03:label 1,2;04:begin05:write('Valor maximo da sequencia(< 20): ');06:readln(n);07:k:=0;08:1: k:= k+1;09:   x:=1; {x conta quantas vezes k sera' escrito}10:   2: write(k);11:   if x<k then12:    begin13:    x:= x+1;14:    goto 2;15:    end;16:if k<n then goto 1;17:end. 

No programa acima, os comandos das linhas 08 a 16 formam o laço mais externo, e os comandos das linhas 10 a 15 formam o laço mais interno.

 O comando while

 

O comando while permite eliminar completamente a necessidade de comandos goto explícitos, sem impedir que se possa construir laços de repetição em programas. Com isso, evita-se o uso indiscriminado do comando goto , e ao mesmo tempo o programa ganha mais estrutura. A técnica que   evita   o   comando   goto,   e   utiliza   apenas   o   comando while e   equivalentes   para   laços   de repetição, é  chamada de programação estruturad

Page 27: Algoritmos Com Pascal

 

Forma sintática:  while <expressão lógica>  do <comando-a-repetir>

Tradução literal: enquanto <expressão lógica>  faça <comando>

Significado:

“A expressão lógica é calculada. Se o seu valor for True, o comando é executado, e em seguida a expressão volta a ser calculada. Enquanto o valor da expressão for True, o processo se repete: o comando é executado, e a expressão volta a ser calculada. Caso o valor da expressão seja False, o comando não é executado, e o controle passa para a próxima instrução após o while”. O comando:  while <expressão lógica>  do <comando-a-repetir>é equivalente ao trecho seguinte:1: if  <expressão lógica> then begin <comando-a-repetir>; goto 1 end; Note que, se a expressao lógica for falsa logo na primeira vez que for calculada, o <comando-a-repetir> não será executado nem uma vez. Obviamente, o <comando-a-repetir> deve conter elementos que façam com que a expressão lógica se torne falsa após um número finito de voltas, caso contrário o laço de repetição nunca terminará. Esse tipo de erro chama-se de laço infinito, e quando ocorre diz-se, no jargão popular de computação, que o programa entrou em “loop”. (“Loop” é a palavra inglesa para laço, e pronuncia-se lup). A única forma de sair desse erro é forçar o fim do programa. No ambiente Turbo Pascal isso é feito pressionando a tecla Control (CTRL), e BREAK, simultaneamente. Exemplo super simples:  O programa abaixo imprime:  12345 Exemplo 4.3: program ex4_3;var i: integer;begin i:=0; while i < 5 do   begin     i:= i+1;    write(i)   end;end.

 Esse programa equivale ao programa abaixo, que usa goto: 

Exemplo 4.4: program ex4_4;var i: integer;label 1;begin i:=0; 1: if i < 5 then

Page 28: Algoritmos Com Pascal

   begin     i:= i+1;    write(i);    goto 1;   end;end.

 A seguir mostramos como ficam os exemplos 4.1 e 4.2 acima, quando o comando goto é substituído pelo comando while: 

Exemplo 4.5: 

program ex4_5;var x,soma,n:integer;beginsoma:=0;x:=1;write('Ate'' que numero deseja somar os inteiros? ');readln(n);while x <= n do begin soma:=soma+x; x:= x+1; end;writeln('A soma de 1 a ', n, ' e'' igual a ', soma);end.

 Exemplo 4.6: 

program ex4_6;(****************************************** Este programa imprime a seqüência 122333444455555... nnnn,  de 1 a n. Utiliza dois laços de repetição while, um dentro do outro.******************************************)var x,k,n:integer;beginwrite('Valor maximo da sequencia(< 20): ');readln(n);k:=0;while k<n do begin k:= k+1; write(k); x:=1; {x conta quantas vezes k sera' escrito} while x<k do  begin   write(k);   x:= x+1;  end; {fim do while interno} end;  {fim do while externo}end. 

 A linguagem Pascal ainda dispõe de dois outros comandos para construir laços de repetição: 

Page 29: Algoritmos Com Pascal

O comando repeat 

Forma sintática: repeat <seqüência de comandos a repetir> until  <expressão lógica>Tradução literal:  repita <seqüência de comandos a repetir> até  <expressão lógica>Significado:

“A seqüência de comandos é executada. A seguir, a expressão lógica é calculada. Se o seu valor for False, a seqüência de comandos volta a ser executada e, em seguida, a expressão é novamente calculada. O processo se repete até que valor da expressão se torne True. Nesse momento, o comando repeat termina, e o controle passa para o próximo comando do programa.” A  diferença  principal  de   significado  entre  o  comando while e  o   comando repeat é  que,  no  comando   repeat,  a   seqüência  de comandos a repetir é executada sempre pelo menos uma vez, enquanto que no comando while o comando a repetir pode não ser  nunca executado. Há outras diferenças mais sutis, somente na forma:a)      No comando while o que é repetido é “um comando”, enquanto que no comando repeat o que é repetido é  “uma seqüência 

de comandos”.A diferença é apenas na forma de escrever (sintática): se você quiser repetir uma seqüência de comandos com while, basta colocá-las dentro de um blocobegin ....end, e com o comando repeat, não é necessário envolver a seqüência em um bloco. O motivo é que as palavras repeat e until já são suficientes para indicar ao compilador o inicio e o fim dos comandos a repetir.

b)      No   comando while,   o   teste   para   saber   se   o   comando   terminou   é   verificar   se   a   expressão   lógica   se   torna false.   No comando repeat, o teste para saber se o comando terminou é quando a expressão se torna true (verdadeira). O motivo é que o significado do comando while é : enquanto a expressão for verdadeira, faça algo, e o do comando repeat é faça algo até que a expressão se torne verdadeira.

 O exemplo abaixo mostra como fica o programa do exemplo 4.3 quando o while é substituído por um repeat: 

Exemplo 4.7: 

program ex4_7;(************************ uso de repeat..until************************)var i: integer;begin i:=0; repeat  i:= i+1;  write(i) until i>=5end.

 Note as diferenças em relação ao Exemplo 4.3:-         a expressão lógica i>=5 é o oposto da expressão anteior i<5-         não foi necessário envolver os comandos a repetir em um bloco begin-end.

  O comando for O comado for é uma forma abreviada de se escrever o comando while, para alguns casos particulares mais freqüentes. A descrição abaixo se refere ao caso em que a variável de controle é inteira, mas esse comando pode ser usado com qualquer variável de controle que seja ordinal, ou seja, cujos elementos possuam umaordem determinada, como é o caso dos caracteres e outros tipos enumerados ainda não vistos.

Page 30: Algoritmos Com Pascal

 Formas sintáticas:

    for <variável de controle> :=  <expressão inicial inteira> to  <expressão final inteira> do <comando a repetir>Significado:

    “a expressão inicial é calculada e a expressão final é calculada (ambas inteiras) com os valores na memória no momento em que o comando for inicia. A variável de controle recebe o valor inicial. Se esse valor for menor ou igual que o valor final, então o comando a repetir é executado, a variável de controle é incrementada de 1 unidade, e o novo valor da variável é comparado com o valor final. Enquanto o valor da variável de controle for menor ou igual ao valor final, o comando a repetir será novamente executado, e a variável novamente incrementada. O comando termina quando o valor da variável de controle ficar maior que o valor final.” IMPORTANTE: a expressão inicial e final são calculadas apenas uma vez, no inicio da execução do comando for. Mesmo que valores de variáveis que façam parte da expressão final forem alterados pelo comando a repetir, isso não altera o valor final que será usado nos testes de comparação. A segunda forma sintática, ligeiramente diferente, é a seguinte:

    for <variável de controle>  :=  <expressão inicial inteira> downto  <expressão final inteira> do <comando a repetir> Significado:

    “a expressão inicial é calculada e a expressão final é calculada (ambas inteiras) com os valores na memória no momento em que o comando for inicia. A variável de controle recebe o valor inicial. Se esse valor for maior ou igual que o valor final, então o comando a repetir é executado, a variável de controle é decrementada de 1 unidade, e o novo valor da variável é comparado com o valor final. Enquanto o valor da variável de controle for maior ou igual ao valor final, o comando a repetir será novamente executado, e a variável novamente decrementada. O comando termina quando o valor da variável de controle ficar menor que o valor final.” A diferença é que a variável de controle é incrementada no primeiro caso, e decrementada no segundo caso. 

Exemplo 4.8: Programa para escrever a seqüência:  123....n  para um n inteiro qualquer. 

program ex4_8;(************************** uso de for incrementando a variável de controle**************************)var i,n: integer;begin write ('Digite um valor de n inteiro: '); readln(n); for i:= 1 to n do write(i);end.

 Compare com o programa 4.3 ou 4.7. Não é necessário incrementar a variavel i explicitamente, pois isso é feito automaticamente pelo comando for. E também não é preciso fazer o teste se i  ainda é menor que n, pois isso também é feito automaticamente. Com isso o programa fica simplificado. A forma ideal de “ler” o programa acima é: “para i variando de 1até 5, imprima o valor de i”.

Page 31: Algoritmos Com Pascal

 O exemplo seguinte escreve a seqüência invertida, na forma:  n n-1 .... 4321, para um n inteiro qualquer: 

Exemplo 4.9: 

program ex4_9;(************************** uso de for decrementando a variável de controle**************************)var i,n: integer;begin write ('Digite um valor de n inteiro: '); readln(n); for i:= n downto 1 do write(i);end.

   O próximo exemplo imprime em uma única tela todos os caracteres da tabela. Nota: em Pascal existem duas funções especiais pré-definidas, que servem para fazer a associação entre os caracteres e suas posições na tabela de caracteres. São elas:ord (c)   onde c é uma expressão que representa um caractere. A função retorna um inteiro entre 0 e 255, que é a posição (ou número de ordem) do caractere na tabela. Ex: ord (‘A’) é 65. chr(n)  onde n é uma expressão inteira com valor entre 0 e 255. A função retorna o caractere que fica na posição n da tabela. Por ex:  chr(65)  é ‘A’. Seja agora escrever um programa para listar todos os 256 elementos da tabela em uma única tela de saída. A tela tem 24 linhas, com 80 caracteres em cada linha. Podemos ver toda a tabela em uma única tela se tivermos 11 colunas, com 24 caracteres em cada uma (11 x 24 = 264). Para as 11  colunas caberem em uma linha, cada coluna deve ter 7 caracteres. A saída terá a aparência seguinte (apenas alguns caracteres são mostrados aqui, os demais estão representados por um -):

coluna  j  0     1      2      3      4      5      6      7     8      9      10 linha i  0 -   24 -   48 0   72 H   96 -  120 x  144 -  168 -  192 -  216 -  240 -  1 -   25 -   49 1   73 I   97 a  121 y  145 -  169 -  193 -  217 -  241 -  2 -   26 -   50 2   74 J   98 b  122 z  146 -  170 -  194 -  218 -  242 -.................................................................................................................................................... 23 -   47 -   71 G   95 -  119 w  143 -  167 -  191 -  215 -  239 -        

 O programa deve ter um laço de repetição para escrever as 24 linhas e, para cada linha, outro laço para escrever as 11 colunas. Vamos usar a variável i para numerar as linhas de 0 a 23, e a variável j para numerar as colunas, de 0 a 10. Uma análise do quadro acima mostra que a posição do caractere k está na linha i e coluna j que satisfazem a relação:   k = j* 24 + i . O programa deve levar ainda em consideração que alguns caracteres não representam símbolos a serem escritos. Eles são usados como sinais de controle para o dispositivo de saída (monitor de vídeo ou impressora) e portanto não convém que se tente imprimi-los. No lugar deles, colocamos duas letras que indicam a sua função. São eles: 

Page 32: Algoritmos Com Pascal

 8  backspace, faz o cursor voltar uma posição para a esquerda (BS)10  line feed, faz o cursor descer para a linha seguinte. É representado por LF13  carriage return, ou retorno do carro, faz o cursor voltar para a posição inicial da linha (CR) O caractere da posição 0 também não tem representação impressa, ele é o caractere nulo, na tabela representado por NUL. O caractere 7 também não tem representação impressa, e tem o nome de BEL.O programa abaixo cria então a tabela desejada. Note que em cada coluna, o valor de k é escrito com 3 posições,   seguido do caractere chr(k), ocupando 2 posições, e seguido de mais 2 espaços para completar as 7 posições da coluna. Para os caracteres especiais que não tem representação impressa, a expressão chr(k) é substituída por uma palavra adequada, ou por espaços: 

program tabela;uses crt;var i,j,k: integer;beginclrscr; for i:= 0 to 23 do begin  for j:= 0 to 10 do begin    k:= j* 24 + i;    if k<=255 then begin     write(k:3);     case k of     0: write(' NUL');     7: write(' BEL');     8: write(' BS ');     10: write(' LF ');     13: write (' CR ');     else write(chr(k):2, '  ');     end; {case}    end; {if}  end; {for interno}  writeln; end; {for externo}end.

  

CAPíTULO 5 

Variáveis Compostas Homogêneas - Vetores e Matrizes 

Um vetor (array em inglês) é um agregado de variáveis do mesmo tipo (homogêneas). O exemplo abaixo mostra a representação gráfica de um vetor de 6 inteiros chamado v:

           

               1        2         3        4       5        6

 

Page 33: Algoritmos Com Pascal

 

           Cada “casa” , ou “elemento”, do vetor é uma variável independente. No exemplo acima, cada elemento pode conter um valor inteiro, e as posições foram ordenadas de 1 até 6.  Os elementos de um vetor são identificados pelo nome do vetor associado ao número de ordem da sua posição relativa no vetor:  v[1], v[2], v[3], v[4], v[5] e v[6]. Assim, no caso acima, a variável v[2] tem o valor 67.Podemos alterar esse valor exatamente como fazemos com qualquer variável:v[2] := 100;  readln(v[2]); etc. Para declarar esse vetor em um programa Pascal, é usada a forma abaixo:var   v: array[1..6] of integer; A forma geral é:  var <identificador do vetor>: array [<intervalo das posições>] of  <tipo dos valores do vetor> Cada variável do conjunto é representada por:    <identificador do vetor>[<expressão cujo valor é a posição da variável> ]onde a expressão deve ser do tipo declarado. Por exemplo, a variável na posição 3 do vetor pode ser representada por:  v[3]      v[10-7]      v[5*5-2*11]    v[x-4],  supondo que x tenha o valor 7,  etc.  Uso do comando for com vetores

 A manipulação de vetores é grandemente facilitada pelo uso dos comandos de repetição, especialmente o for.  Por exemplo, para zerar (colocar o valor 0) todas as posições do vetor v definido acima, seria necessário escrever 6 comandos:v[1]:= 0;v[2]:= 0;v[3]:= 0;v[4]:= 0;v[5]:= 0;v[6]:= 0;

 A mesma operação pode ser feita com apenas um comando de repetição for, usando uma variável de controle para representar as posições do vetor:   for i:= 1 to 6 do v[i]:=0;É fácil imaginar o que isso representa de simplificação para a manipulação de vetores grandes.

Page 34: Algoritmos Com Pascal

 Da mesma forma, para ler do teclado todos os valores do vetor v, seriam também necessários 6 comandos:read (v[1]);read (v[2]);read (v[3]);read (v[4]);read (v[5]);read (v[6]);

 Todos esses comandos podem ser substituídos por um único comando for:   for i:= 1 to 6 do read(v[i]); O que se pode e o que não se pode fazer com vetores, na linguagem Pascal:Nota: essas regras não se aplicam ao tipo string que é um caso especial de vetor de caracteres com regras própria, e que será visto mais adiante. Não é possível:a) Não se pode ler todo um vetor diretamente com um comando read. Não se pode

escrever:  read(v);É necessário ler casa a casa, diretamente, ou com um laço de repetição como for no exemplo acima.

b) Não se pode escrever todos os elementos de um vetor com um único comando write. Não é permitido escrever: write(v).  Também nesse caso cada elemento deve ser tratado como uma variável independente, por exemplo: 

        for i:= 1 to 6 do write(v[i]:3);c) Não é possível copiar os valores dos elementos de um vetor para outro com um único

comando de atribuição. Ou seja, dados dois vetores v  e w, ambos do mesmo tamanho e do mesmo tipo, não é permitido fazer:  w:= v; . Também aqui é necessário trabalhar elemento a elemento, e o comando for mais uma vez é indicado:

      for i:= 1 to 6 do w[i]:= v[i];c) Não existe comandos ou funções que dão o tamanho (número de elementos) de um vetor.d) Não é permitido tentar acessar uma posição fora do intervalo de posições definido para o

vetor. A tentativa causará um erro em tempo de execução e o programa abortará. No caso do vetor v acima, por exemplo, não é permitido escrever:    v[8]:= 20,    read(v[8])    ou write (v[8])  porque a faixa de valores das posições vai de 1 a 6 apenas.

 O que é permitido:a) A faixa de valores das posições não precisa começar em 1. Qualquer intervalo de valores

pode ser usado na definição de um vetor. Por exemplo, podemos definir um vetor assim:var v:array[15..20] of real;

Nesse caso o vetor v terá apenas os elementos:  v[15], v[16], v[17], v[18], v[19] e v[20]b) As posições não precisam ser necessariamente números inteiros. Podem ser qualquer

tipo ordinal, ou seja, que possa ser definido por uma seqüência ordenadade valores. Por exemplo, os caracteres em Pascal formam uma seqüência ordenada na tabela de caracteres, e podem portanto serem marcadores de posição em um vetor.Podemos definir um vetor assim:

Page 35: Algoritmos Com Pascal

   var letras: array['a'..'z'] of integer;

Nesse caso os elementos do vetor são: letras['a'], letras['b'], ….., letras['z']Um uso possível para esse vetor poderia ser que cada posição poderia guardar a quantidade de vezes que a letra dessa posição aparece em uma determinada frase.  

Exemplos de uso: Ordenação de números:Fazer um programa para ler n valores inteiros quaisquer, n <50, onde o valor de n deve ser previamente fornecido pelo usuário.Em seguida, o programa deve escrever na tela os valores em ordem numérica crescente.A solução utiliza um algoritmo de ordenação .O algoritmo abaixo é conhecido como ordenação por seleção. Os números são colocados em um vetor definido com 50 posições. Inicialmente, procura-se a posição no vetor (posMenor) onde está o menor número. Se essa posição for diferente da posição 1, então troca-se os valores das casas 1 e posMenor. Isso garante que o menor elemento agora está na posição 1. A seguir, repete-se o processo a partir da posição 2. Ou seja, procura-se a posição do menor elemento da posição 2 em diante, que será posMenor. Se o valor de posMenor for diferente de 2, troca-se os valores das casas 2 e posMenor. O processo é repetido a partir da posição 3, depois 4, etc, até n-1. Nesse ponto o vetor estará com os valores ordenados. Basta então escrever na tela os valores das posições 1 a n e teremos os números em ordem crescente. program ordenasel;const nmax=50;var  v: array[1..nmax] of integer;  i,j,n,posMenor,temp: integer;begin  writeln('Digite um inteiro menor ou igual a ' ,nmax, ' :  '); readln(n);  writeln('Digite ',n,' inteiros separados por espacos');  for i:=1 to n do read(v[i]);  for i:=1 to n-1 do begin   posMenor:=i;   for j:=i+1 to n do     if v[j] < v[posMenor] then posMenor := j;     if i <> posMenor then begin     temp := v[i];     v[i] := v[posMenor];     v[posMenor] := temp;    end;  end;  writeln;  for i:=1 to n do  write(v[i]:4);end.

  O tipo STRING

Page 36: Algoritmos Com Pascal

 A linguagem Pascal original não possuía o tipo string. Hoje em dia, todas as versões modernas de Pascal estendido possuem esse tipo (Turbo Pascal, Free Pascal, etc). O tipo string é um caso especial de vetor de caracteres criado especialmente para tratar com texto: palavras, frases, etc, onde a seqüência de caracteres deve ser tratada como uma única entidade. A palavra string significa uma cadeia de caracteres. Cada posição de uma string contém apenas um caractere. A definição de uma variável é:  var  frase: string; Não há necessidade de se definir um tamanho máximo, embora seja possível:    var nome: string[15]; Se não for definido um tamanho máximo, a string poderá expandir-se ou encolher-se automaticamente para acomodar a quantidade de caracteres necessária. As regras para vetores em geral não se aplicam às strings. Em particular, é permitido paara strings:a)      ler uma string inteira com um único comando read ou readln:  readln(frase);b)      escrever uma string inteira com um único comando write ou writeln:  writeln(frase);c)      atribuir uma string diretamente:   frase2:= frase;d)      escrever o valor literal de uma string entre aspas simples e usar em comandos de

atribuição ou de escrita:  frase:= ‘rio de janeiro’;   write(‘rio de janeiro’);e)      Caracteres individuais e strings podem ser usados de forma idêntica:            frase:= ‘a’;    faz a string frase ser uma string com apenas o caractere ‘a’.f)        O uso da função length() que dá o tamanho (número de caracteres) de uma string.g)      O uso do operador de concatenação +, que permite unir duas strings produzindo uma

string que é a concatenação das duas:  ‘ab’ +  ‘cd’ produz a string ‘abcd’. O mesmo pode ser obtido com a função concat(). Também aqui pode-se misturar strings com caracteres de qualquer maneira:   ‘a’ + ‘b’ dá  a string ‘ab’,  etc. O operador e a função podem ser usados para concatenar varias strings e/ou caracteres:Ex:   frase := frase1 + frase2 + ‘!’;         frase := concat(frase1, frase2, ‘!’);

h)  É possível comparar duas strings diretamente, usando os operadores relacionais =,  <>,   >, <,   >=, e   <=,  onde a comparação é feita pela ordem dos elementos na tabela de caracteres, o que garante a ordem alfabética para strings contendo apenas letras maiúsculas ou apenas minúsculas:

           ‘cde’ < ‘fgh’   dará true   e    ‘AB’ = ‘CD’  dará falsei)  A posição zero de uma string contém sempre um número inteiro que é o tamanho da

string. Esse valor pode ser obtido usando a função ord(). Por exemplo, para imprimir o tamanho da string frase, pode-se escrever:   write ( ord(frase[0]);  Na realidade a função length() obtém o seu valor consultando a posição 0 da string.

 Com esses conhecimentos, podemos adaptar muito facilmente o algoritmo de ordenação por seleção, descrito acima para vetores de números, para ordenar um vetor de nomes em ordem alfabética, assumindo que estão todos escritos em letras da mesma caixa (maiúsculas

Page 37: Algoritmos Com Pascal

ou minúsculas). Note que isso só foi possível por causa das regras especiais para strings, e que é possível também se criar um vetor de strings:  program ordenanomes;(********************************************************************** algoritmo de selacao para ordenar nomes em ordem alfabética.**********************************************************************)const nmax=50;var  v: array[1..nmax] of string;  i,j,n,posMenor: integer;  temp:string;begin  writeln('Digite um inteiro menor ou igual a ' ,nmax, ' :  '); readln(n);  writeln('Digite ',n,' strings, uma em cada linha);  for i:=1 to n do readln(v[i]);  for i:=1 to n-1 do begin   posMenor:=i;   for j:=i+1 to n do     if v[j] < v[posMenor] then posMenor := j;     if i <> posMenor then begin     temp := v[i];     v[i] := v[posMenor];     v[posMenor] := temp;    end;  end;  writeln;  for i:=1 to n do  writeln(v[i]);end.   

MATRIZES – vetores com mais de 1 dimensão: 

Os elementos de um vetor guardam uma relação de posicionamento entre si apenas em uma dimensão. Essas variáveis estão dispostas como que em uma linha, e cada elemento é identificado pela sua posição relativa na linha:

 

20 30 17 35 7               1        2      3       4      5   (posições na linha)

 

Quando há mais de uma dimensão, damos o nome de matriz a esse arranjo de variáveis. O caso mais comum é a matriz de 2 dimensões. Os elementos ficam dispostos em um plano, composto por várias linhas do mesmo tamanho, como abaixo:

 colunas 

linhas

1 40 34 50 27

2 25 4 18 80

3 0 3 65 11

  1 2 3 4

Page 38: Algoritmos Com Pascal

 

 

 

 

Na matriz de inteiros acima, existem 3 linhas, cada linha com 4 colunas, ou 3x4 (três por quatro). Essa matriz pode ser declarada assim:var mat: array[1..3, 1..4] of integer;

Após o nome da matriz, são colocados entre colchetes os intervalos em que ficam os números das linhas, e os números das colunas, nessa ordem. Note que também aqui os elementos da matriz devem ser todos do mesmo tipo.

Cada elemento da matriz é identificado pela notação:  mat[i,j], onde i é o número da linha, e j o número da coluna, onde se encontra o elemento. Na figura acima, temos então que mat[1,1] tem o valor 40.

O comando for... do é muito usado para processar os valores de matrizes.

Exemplos:

 

a) Para zerar todos os elementos de uma matriz m, com 3 linhas e 4 colunas, declarada como:var

  m: array[1..3, 1..4] of integer;

 

basta fazer:for i:= 1 to 3 do

  for j:= 1 to 4 do  m[i,j] := 0;

 

Nota: é usual usar-se a variável i para representar as linhas de uma matriz, a variável j para representar as colunas.

 

b) Para ler do teclado valores para preencher a matriz acima (12 valores):for i:= 1 to 3 do

  for j:= 1 to 4 do read(m[i,j] );

 

Nota: O usuário poderá digitar todos os 12 números em uma só linha (separados por espaços), ou um número por linha, ou, melhor, 4 números por linha, de forma a visualizar melhor a matriz.

 

 

CAPíTULO 6 

Page 39: Algoritmos Com Pascal

Sub-programas em Pascal: Funções e Procedimentos

 

 

Conceituação:

Sub-programas são partes de um programa que podem ser consideradas como tarefas relativamente independentes das demais. Por isso, podem ser programadas de forma separada, recebem um nome, e depois podem usadas várias vezes dentro do programa bastando serem “chamadas” pelo nome.

Há duas categorias clássicas de sub-programas: funções e procedimentos.

 

Funções:

Uma função é um sub-programa que realiza uma tarefa de calcular e produzir como resultado um valor, o qual será usado por outras partes do programa:

Ex: o programa abaixo usa a função pré-definida sqrt(n), que calcula a raiz quadrada de um real n, e dá como resultado um valor real:

Exemplo 6-1:

 program ex6_1;

var L1,L2,H: real;

begin

 L1:= 3.0;

 L2:= 4.0;

 H:= sqrt(L1*L1+L2*L2);

 writeln('A hipotenusa do triangulo retangulo de lados ', L1:3:1, ' e ',

   L2:3:1, ' e'' ' ,H:3:1);

end.

 

No exemplo acima, a função sqrt já vem pré-definida na linguagem Pascal, e pode ser utilizada diretamente. Note o seguinte:

a)      a função tem um argumento real n, ou seja, para usá-la é preciso fornecer um valor real entre parênteses. A definição de uso é sqrt(n) onde n deve ser um valor real.

b)      esse argumento pode ser qualquer expressão real, no exemplo foi L1*L1+L2*L2.

c)      a função realiza uma tarefa, através de um algoritmo próprio, para calcular a raiz quadrada. Essa tarefa constitui o sub-programa, que nesse caso já está armazenado no computador em forma compilada.

d)      quando o programa for executar o comando:    H:= sqrt(L1*L1+L2*L2);

vai ocorrer o seguinte:

-         primeiro,  a expressão do argumento será calculada, para obter o seu valor. No caso, será calculado o valor 3.0*3.0 + 4.0*4.0  que dá 25.0.

Page 40: Algoritmos Com Pascal

-         em seguida o programa entrará em um estado de suspensão da sua execução, e o controle da execução passará para o primeiro comando do sub-programa sqrt.

-         antes de iniciar o sub-programa, o valor calculado do argumento, no caso 25.0, será passado como valor inicial de uma variável especial do sub-programa que representa o argumento da função. Essa variável é chamada de parâmetro de valor e a operação é chamada de passagem de parâmetro.

-         o sub-programa executará seus comandos, e a raiz quadrada do argumento será calculada, obtendo o valo 5.0, nesse caso.

-         ao terminar, o sub-programa repassará o valor obtido de volta para o programa. Isso é feito substituindo a aplicação da função, sqrt(L1*L1+L2*L2),pelo resultado obtido.

-         nesse ponto o controle da execução voltará para o programa no ponto em que havia interrompido, e o programa executará o comando:  H:= 5.0;continuando a execução normalmente a partir desse ponto.

 

Funções definidas no próprio programa:

No exemplo acima, foi usada uma função pré-definida na linguagem Pascal. Mas a linguagem permite que qualquer função possa ser definida no próprio programa.

O programador deve escrever a definição da função na área de declarações do programa.  Essa é a área antes do trecho  begin ....end. do programa.

No exemplo abaixo, o programa declara, e depois usa, uma função para calcular o fatorial de um inteiro. A função está destacada em azul. Note que a variável x faz parte das declarações do programa, e não da função. A função tem sua própria área de declarações de variáveis.

 

Exemplo 6-2:

 program ex6_2;var  x:integer;function fat(n:integer): longint; var   i: integer;   f: longint; begin   f:=1;   for i:= 2 to n do f:= f*i;   fat:= f; end; {fim da declaracao da funcao} begin {inicio do programa} writeln('Digite varios numeros para saber o fatorial'); writeln('Termine com -1'); read(x); while x > 0 do begin  writeln ('fatorial de ', x, ' = ', fat(x) );  read(x); end;

Page 41: Algoritmos Com Pascal

end. 

 

 

Ao executar o programa, o seguinte diálogo poderá ocorrer: (dados do usuário em itálico):Digite varios numeros para saber o fatorial.

Termine com –1:

4

Fatorial de 4 = 24

5

Fatorial de 5 = 120

6

Fatorial de 6 = 720

-1    (aqui o programa termina)

 

As seguintes observações são importantes para um bom entendimento de funções e do programa acima:

 

a)      A declaração da função fica na área de declarações, junto com as declarações de variáveis e constantes:function fat(n:integer): longint;

 var

   i: integer;

   f: longint;

 begin

   f:=1;

   for i:= 2 to n do f:= f*i;

   fat:= f;

 end; {fim da declaracao da funcao}

b)      O formato da declaração da função é bastante parecido com o de um programa, apenas no cabeçalho a palavra program é substituída pela palavrafunction. A declaração da função tem sua própria área de declarações e sua área de comandos. Mas termina com end;  e não com end.

c)      Além disso, no cabeçalho da função são declarados os seus argumentos, agrupados por tipo, seguidos do tipo do resultado que produz. A forma sintática do cabeçalho é:

function <nome da função> (<lista de argumentos>:<tipo>; <lista de argumentos>: tipo; etc):<tipo do resultado>

No caso do fatorial, há apenas um parâmetro inteiro (chamado n) e o resultado será do tipo longint, porque os fatoriais crescem muito rapidamente:function fat(n:integer): longint;

d)      No corpo da função (parte executável, começando após o primeiro begin) o nome da função deve receber por atribuição pelo menos uma vez o valor do resultado:

Page 42: Algoritmos Com Pascal

fat:= f;

É dessa forma que o resultado calculado será repassado de volta ao programa, onde irá substituir a aplicação da função. Note que, apesar de receber um valor por atribuição, o nome da função não é  uma variável. Caso o nome da função receba mais de um valor durante a execução da função, o valor que finalmente será repassado para o programa será o último valor atribuído ao nome da função antes dela terminar sua execução.

e)      Outro ponto importante a registrar é que os identificadores definidos na função só têm significado dentro da função, e não para fora dela. Chama-se a isso o escopo dos identificadores. No exemplo acima, as variáveis n, i e f não são “vistas” pelo programa que usa a função, e são chamadas variáveis locais da função. A variável n é especial, chamada de parâmetro formal de valor. É ela que receberá o valor do argumento a ser usado no inicio da execução da função. A partir daí, os parâmetros de valor se comportam como qualquer outra variável local.

 

Voltando então para a execução do Exemplo 6-2, vemos que o laço de repetição fará com que a função fat seja chamada várias vezes, cada vez com um argumento diferente. A cada vez, o programa será interrompido, o controle será passado para a função, um resultado será obtido e repassado de volta ao programa, substituindo a aplicação da função.

 

Tipos dos argumentos e do resultado de funções:

Em uma linguagem de programação como Pascal, as funções podem ter argumentos de tipos diferentes. Argumentos podem ser de tipos escalares simples, como integer, longint, real, char e boolean, e podem ser também de tipos estruturados, como vetores, strings, matrizes e registros (records), esse último tipo ainda por ser estudado.

Por outro lado, o resultado da função tem maiores limitações: o tipo do resultado de uma função só pode ser um tipo escalar simples, com a exceção do tipo string, que também pode ser um resultado. Portanto, vetores comuns não podem ser resultado de funções, Veremos mais adiante que, para contornar essa limitação, podemos usar procedimentos para obter resultados de sub-programas que sejam tipos estruturados. Mas, para isso, teremos que usar parâmetros de referência, outro assunto que será visto mais adiante.

Os exemplos a seguir mostram várias funções com tipos diferentes de argumentos e de resultados.

Exemplo 6-3:

Neste exemplo,  a função maiuscula(c) é usada para obter a letra maiúscula correspondente ao caractere c, se este for uma letra minúscula, caso contrário o valor retornado é o próprio caractere original:

 program ex6_3;var frase:string; i: integer;function maiuscula(c:char):char;{essa funcao converte letras minusculas em maiusculas} begin case c of

Page 43: Algoritmos Com Pascal

 'a'..'z': maiuscula:= chr(ord('A') + ord(c)-ord('a')); else maiuscula:= c; end;end;begin writeln('Digite uma frase. Ela sera'' re-escrita em letras maiusculas: '); readln (frase); for i:=1 to length(frase) do frase[i] := maiuscula(frase[i]); writeln(frase);end.

 

Note que a função foi aplicada a um argumento do tipo char, e que o valor resultante também é do tipo char. Para alterar as letras da string frase, foi necessário usar um laço de repetição para aplicar a função sucessivamente a cada caractere da frase.

No próximo exemplo, a função será aplicada a toda a frase de uma vez (o argumento é do tipo string) e o resultado também será do tipo string, isto é, a função retorna a frase inteira alterada:

 program ex6_4;var frase:string; i: integer;function maiusc_str(s:string):string;{essa funcao retorna uma string com todas as letras maiusculas} var i: integer; begin for i:= 1 to length(s) do case s[i] of   'a'..'z': s[i]:= chr(ord('A') + ord(s[i])-ord('a')); end; maiusc_str:= s;end;begin writeln('Digite uma frase. Ela sera'' re-escrita em letras maiusculas: '); readln (frase); writeln(maiusc_str(frase));end.

 

 

Uma observação importante: a função não altera a string frase. Ela retorna outra string, com as letras alteradas, que substituirá a expressão maiusc_str(frase).É essa string retornada que será impressa. O valor original da string frase não foi alterado.

 

 

No exemplo seguinte, a função cripto(c,n) onde c é um caractere, e n é um inteiro, positivo, tem o seguinte valor:

Page 44: Algoritmos Com Pascal

-         se c for uma letra (maiúscula ou minúscula), cripto(c,n) retorna a letra n posições adiante no alfabeto, considerado circular (depois do ‘z’ vem o ‘a’, depois do ‘Z’ vem o ‘A’).    Ex: cripto(‘Z’, 3)  retorna  ‘C’ 

-         se c for um dígito, cripto(c,n) retorna o dígito n posições adiante, também circular (depois do ‘9’ vem o ‘0’)

Ex: cripto(‘3’, 11)  retorna ‘4’.

-         para qualquer outro caractere, a função retorna o próprio caractere sem alteração.  

Esse exemplo é mais complexo, e é interessante para ressaltar a importância de se separar as tarefas em sub-programas separados. Dessa forma, o programa que usa a função fica muito mais compreensível,  e   também a   função pode ser   testada  e  aperfeiçoada   independentemente  dos programas que a usarão. O programa que usa a função é bem simples, e toda a complexidade da criptografia fica encapsulada na definição da função.

 

 

 

 

 

 

Exemplo 6-5:

 

program ex6_5;var frase: string; i,n: integer; function cripto(c: char; n: integer): char; var pos,d:integer; begin n:= n mod 26;  {reduz logo o n } pos:= ord(c) + n; {posicao na tabela de caracteres n casas adiante de c} case c of 'a'..'z': begin           d:= pos -ord('z');  {d e' quanto pos passou de z}           if d<=0 then cripto:= chr(pos)            else cripto:= chr(ord('a') + d-1 )           end; 'A'..'Z': begin           d:= pos -ord('Z');  {d e' quanto pos passou de Z}           if d<=0 then cripto:= chr(pos)

Page 45: Algoritmos Com Pascal

            else cripto:= chr(ord('A') + d-1 )           end; '0'..'9': begin           d:= pos -ord('9');  {d e' quanto pos passou de 9}           if d<=0 then cripto:= chr(pos)            else cripto:= chr(ord('0') + d-1 )           end;  else cripto:= c; {se for outro caractere, nao altera} end;end;begin writeln('Digite uma frase: '); readln(frase); writeln('Escolha o valor de n para a criptografia: '); readln(n); for i:=1 to length(frase) do write(cripto(frase[i], n)); readln;end.

 

Procedimentos

 

Procedimentos representam outra categoria de sub-programas em Pascal. As diferenças entre procedimentos e funções são:

a)      um procedimento é um sub-programa que realiza uma tarefa, mas não retorna um valor de resultado, como as funções.

b)      o uso do procedimento é semelhante a um comando, e tem o mesmo valor sintático, isto é, onde na linguagem se espera um comando, pode ser colocada uma chamada de procedimento.

 

O exemplo abaixo ilustra a declaração e o uso de um procedimento de nome msg, que faz a tarefa de escrever uma mensagem (uma string) em um ponto determinado da tela:

Ele utiliza um procedimento pré-definido em Pascal, gotoxy(x,y), que posiciona o cursor no ponto correspondente à interseção da linha y com a coluna x: Exemplo 6-6: program ex6_6;uses crt;  {necessario para usar gotoxy e clrscr} var linhamedia,colunamedia: integer;    m:string; procedure msg(frase:string; x,y: integer);  begin  gotoxy(x,y);  write(frase); end;begin clrscr; msg('esta frase na linha 1 coluna 1', 1, 1); msg('esta frase na linha 3 coluna 2', 2, 3); msg('esta frase na linha 5 coluna 3', 3, 5);

Page 46: Algoritmos Com Pascal

 m:= 'meio da tela'; linhamedia:=12; colunamedia:=40; msg(m,colunamedia-length(m) div 2,linhamedia);end.

 

O procedimento msg tem 3 parâmetros formais de valor: frase, x e y. Ele é chamado 4 vezes pelo programa. Note que cada chamada tem a forma de um comando. A cada chamada, o valor de cada parâmetro é inicializado com o valor correspondente do argumento usado. Da mesma forma que para as funções, cada argumento usado na chamada de um procedimento pode ser qualquer expressão que tenha valor do tipo esperado.

Existem vários comandos que usamos normalmente na linguagem Pascal que são na realidade procedimentos pré-definidos. Os casos mais comuns são os procedimentos de leitura e escrita: read, readln, write, e writeln, são procedimentos bastante complexos, que têm a faculdade adicional de aceitar um numero variável de argumentos. Outros comandos, como clrscr, gotoxy, etc também são procedimentos.

 

 Parâmetros de Referência

Até agora todos os parâmetros usados nos exemplos de funções e procedimentos foram parâmetros de valor. Um parâmetro de valor é uma variável local do sub-programa, que tem a propriedade de receber um valor inicial passado durante a chamada. Fora disso, comporta-se como uma variável local normal,  como as demais definidas na seção var.

As variáveis locais de um sub-programa existem em um espaço de memória próprio, que só é acessível ao sub-programa. Por esse motivo, os parâmetros de valor não podem ser ”vistos” pelo programa externo ao sub-programa. Apenas o resultado do cálculo da função pode retornar ao programa.

Os parâmetros de referência, ou parâmetros variáveis, permitem que valores calculados no sub-programa possam ser repassados ao programa, de forma diferente do mecanismo de retorno de função.

O mecanismo usado no parâmetro de referência é o seguinte:

a)      na definição do procedimento, os parâmetros de referência devem ser precedidos do prefixo var.

b)      Na chamada do procedimento, os argumentos usados no lugar de parâmetros de referência devem ser obrigatoriamente nomes de variáveis do programa, e não expressões.

c)      Quando o procedimento é chamado, o parâmetro de referencia recebe, não mais um valor, mas uma referência para a variável correspondente do programa. Na prática, isso significa que o parâmetro do sub-programa, e a variável correspondente do programa, passam a ser a mesma variável, como se fossem sinônimos. O efeito é que tudo que acontece com um parâmetro de referência do sub-programa vai se refletir imediatamente na variável correspondente do programa. Ou seja, quando o sub-programa termina, e devolve o controle de execução ao programa, as variáveis passadas por referência para o sub-programa podem ter sido alteradas.

 

Page 47: Algoritmos Com Pascal

O exemplo a seguir define dois procedimentos, que são usados no programa.

O primeiro procedimento chama-se altera_variavel, e tem dois parâmetros: o parâmetro de referência  x e o parâmetro de valor n. O efeito desse procedimento é fazer com que uma variável do programa tenha o valor somado a n pelo procedimento. A variável que deverá ser alterada será passada por referência. Já a quantidade a ser somada, será passada por valor.

O segundo procedimento elimina os n primeiros caracteres de uma string do programa. A string a ser alterada é passada por referência. A quantidade de caracteres a serem eliminados é passada por valor:

Exemplo 6-7:program ex6_7;uses crt;var a,b,c: integer;    nome: string;procedure altera_variavel(var x:integer; n:integer); {a e' parametro de referencia, n e' parametro de valor} begin  x:= x+n; end;procedure reduz_string (var frase:string; n:integer); {esse procedimento elimina os n primeiros caracteres da frase} var i:integer;     s:string; begin  s:=''; {s e'  inicializada com uma string vazia, ou nula}  for i:= n+1 to length(frase) do s:=s+frase[i]; {operador + de concatenacao}  frase:=s; {o conteudo de frase no programa sera’ alterado} end; begin  {aqui inicia a execucao do programa}clrscr; a:=10; b:=20; c:=30; writeln(a:4,b:4,c:4); altera_variavel(a, 5); {a variavel a tera' seu valor alterado para a+5} altera_variavel(b, 7); {a variavel b tera' seu valor alterado para b+7} altera_variavel(c, 15); {a variavel c tera' seu valor alterado para c+15} writeln(a:4,b:4,c:4); nome:= 'Antonio Claudio da Sliva'; writeln('nome antes : ', nome); reduz_string(nome,8); {deve eliminar os 8 caracteres antes de Claudio} writeln('nome depois: ', nome); readln;end.   

O próximo exemplo mostra um programa que usa vários procedimentos e funções.Um processo de criptografia de frases de até 100 caracteres, com código (chave) igual a k<=10, consiste em colocar os caracteres da frase em uma matriz, usando apenas as primeiras k colunas. 

Page 48: Algoritmos Com Pascal

No exemplo abaixo,  com k=8, são usadas as 8 primeiras colunas de uma matriz 10x10 para criptografar a frase:

   UNIVERSIDADE FEDERAL DO RIO DE JANEIRO

O número de linhas necessárias para conter todos os caracteres da frase é dado pela expressão:

  no. de linhas = menor inteiro maior ou igual a tamanho da frase/k

Para k=8, e como a frase acima tem 37 caracteres, o número necessário de linhas é: 37/8= 4,6 => 5.

 

Inicialmente, os caracteres da string são colocados na matriz linha a linha, ocupando as k primeiras colunas apenas:

                                                      1     2    3     4      5     6    7    8    9  10

                                           1

                                           2                                           3                                           4                                           5                                           6                                           7                                           8                                           9                                         10

 A codificação é completada reescrevendo a matriz em forma de string, desta vez escrevendo os caracteres segundo as colunas, a partir da coluna 1, apenas para as linhas usadas.Completando o exemplo acima, a frase codificada fica da forma seguinte:

 

UDERANARINIDAOEVEL IE  DRRFDEOSEO  ID J 

O interessante é que o mesmo processo pode ser usado tanto para codificar como para decodificar. Para decodificar, toma-se a frase codificada, desta vez com chave (no. de colunas) igual ao número de linhas usado na codificação original, obtendo a matriz transversa abaixo:

                                                          1     2    3     4     5   6   7  8  9  10

U N I V E R S I    

D A D E   F E D    

E R A L   D O      

R I O   D E   J    

A N E I R O        

                   

                   

                   

                   

                   

Page 49: Algoritmos Com Pascal

                                            1

                                            2                                            3                                            4                                            5                                            6                                            7                                            8                                            9                                          10 

Basta usar o processo de codificação para obter a frase original, lendo coluna a coluna.

O número mínimo de linhas necessárias para codificar uma frase com ncar caracteres, e chave k, é dada pela expressão:   round(ncar/k + 0.4)

A solução abaixo usa 2 procedimentos e 2 funções.

Os procedimentos le_frase e le_chave são usados para solicitar do usuário a frase a ser codificada, e a chave a ser usada. Ambos usam parâmetros de referência varpara passar os valores lidos para o programa.

A função linhas_necessarias(f, k) calcula e retorna o menor número de linhas necessárias para codificar a frase f com a chave k.

A função codifica(frase,k) é que faz o trabalho de codificar a string frase com a chave k, e retorna a string codificada. A função utiliza o procedimento limpa_matriz, para inicializar os elementos da matriz com espaços em branco. Note que o  procedimento é interno à função, e que a matriz é acessada como variável global ao procedimento, não sendo necessário passar parâmetro.

A função usa uma matriz 10x10, podendo acomodar frases de até 100 caracteres.

O programa propriamente dito consiste apenas de chamadas dos procedimentos. Todo o trabalho real é feito nos sub-programas, o programa apenas coordena a chamada dos mesmos para realizar uma tarefa completa.

 

program codifica_matr;{Este programa codifica textos usando o metodo da matriz transposta}var    frase: string;    chave:integer; procedure le_frase (var frase:string);

U D E R A          

N A R I N          

I D A O E          

V E L   I          

E     D R          

R F D E O          

S E O              

I D   J            

                   

                   

Page 50: Algoritmos Com Pascal

begin writeln('Digite a frase a ser codificada ate'' 100 caracteres:' ); readln(frase);end; procedure le_chave(var chave:integer); var i: integer;begin writeln('Digite a chave de codificacao < 10: '); readln(chave);end; function linhas_necessarias(f:string; k: integer):integer;{retorna o menor numero de linhas necessarias para codificar a string f com a chave k} begin linhas_necessarias:= round(length(f)/k +0.4); end; function codifica (frase:string; k: integer):string; var    m: array[1..10,1..10] of char;    i,j,n,lin,col,linhas, colunas:integer;    s: string; procedure limpa_matriz;  var i,j:integer;  begin  for i:= 1 to 10 do   for j:= 1 to 10 do m[i,j]:= ' '; end; {limpa_matriz} begin  limpa_matriz;  colunas:= k;  linhas:= linhas_necessarias(frase,k);  for i:= 1 to length(frase) do begin   lin:= (i- 1) div colunas+1;   col:= i mod colunas;  if col=0 then col:=colunas;   m[lin,col]:= frase[i];  end;  s:='';  for j:=1 to colunas do   for i:= 1 to linhas do s:=s+m[i,j];  codifica:=s;end; {codifica}begin le_frase(frase); le_chave(chave); frase:=codifica(frase,chave); writeln('Frase codificada com a chave ', chave,': ', frase); chave := linhas_necessarias(frase, chave); frase:= codifica(frase,chave); writeln('Decodificando com a chave ', chave, ': ', frase); readln;end.