Grupo

  • J. Cláudio Souza Jr.
  • Gustavo Wrege
  • Ruhan Conceição

Pascal

Introdução

Pascal é uma linguagem de programação estruturada, que recebeu este nome em homenagem ao matemático Blaise Pascal. Foi criada em 1970 pelo suíço Niklaus Wirth, tendo em mente encorajar o uso de código estruturado. Programação estruturada é uma forma de programação de computadores que preconiza que todos os programas possíveis podem ser reduzidos a apenas três estruturas: sequência, decisão e repetição. Blaise Pascal

Pascal é normalmente uma das linguagens de escolha para ensinar programação, junto com Scheme, C e Fortran. Comercialmente, a linguagem foi sucedida pela criação da linguagem Object Pascal, atualmente utilizada nos IDEs Embarcadero Delphi (Object Pascal), Kylix e Lazarus. Academicamente, seus sucessores são as linguagens subsequentes de Niklaus Wirth: Modula-2 e Oberon. A partir da versão 2005, o Delphi passou a se referir a sua linguagem de programação como Delphi Language.

Assim como a linguagem C, que foi padronizado pela ANSI (ANSI C), o Pascal possui padrões pela ISO, como o Pascal Standard e o Advanced Pascal.

Implementações

O primeiro compilador Pascal foi desenvolvido em Zurique para a família de computadores CDC 6000 em 1970. Também neste ano foi desenvolvido o primeiro compilador Pascal norte americano, que gerava o código de máquina nativo para o micro-computador PDP-11.

Nos anos 80, a Borland reescreveu o compilador transformando em Turbo Pascal para a plataforma IBM, uma linguagem compilada, que gerava o código de máquina real para a arquitetura Intel 8088 o tornando mais rápido que as linguagens interpretadas e ainda o mais barato do mercado.

Nos anos 90, Pascal e outros compiladores que podiam ser modificados para trabalhar em diferentes arquiteturas tiveram um grande destaque.

O próximo grande passo para a linguagem, foi a implementação da orientação a objeto (OO ou OOP em inglês) na sua estrutura, começando com a versão 5.5 do Turbo Pascal. Mais tarde, ao projetar o Delphi, querendo funcionalidades mais elaboradas da orientação a objeto, a Borland utilizou o conceito Object Pascal criado pela Apple, utilizando-o como base para uma nova linguagem, que nas versões iniciais era chamado de Object Pascal foi rebatizado como Delphi Programming Language nas versões posteriores. As maiores diferenças em relação às implementações OO das versões mais antigas foram a adição do conceito de objetos por referência, construtores, destrutores e propriedades, entre outros.

Sintaxe

1 Introdução a Sintaxe

A linguagem Pascal foi criada para incentivar a programação modular e estruturada, facilitando a criação de procedimentos com baixo acoplamento e alta coesão. Um programa em Pascal é composto de constantes e variáveis globais, procedimentos e funções re-entrantes e um programa principal.

Procedimentos não retornam valores, funções sim. Tanto em procedimentos quanto em funções os parâmetros podem ser passados por referência ou por valor. É possível passar vetores e matrizes com o tamanho, mas não a quantidade de dimensões, especificado no tempo de execução.

Procedimentos e funções podem conter, dentro de seu escopo, novos procedimentos e funções. Dentro de qualquer parte do programa também podem ser criados blocos com os comandos BEGIN eEND, que também possuem seu próprio escopo. Nas versões originais, as variáveis só podiam ser declaradas em posições específicas e não ao decorrer do programa, o que limitava a regra de escopo.

O conjunto de procedimentos e funções pré-definidos é fixo e inclui as funções read, readln, write e writeln, para realizar E/S.

2 ESTRUTURA DO PROGRAMA

Qualquer programa escrito em Pascal e dividido em três partes: cabeçalho, área de declarações e o corpo do programa.

2.1 Cabecalho do programa

Esta área e dedicada a identificação do programa, através da palavra “program + nome_do_programa;”. O nome dado ao programa não pode ser definido a nenhuma variável do programa.

Exemplo:

program OLA_MUNDO; 

2.2 Area de declarações

Esta área e reservada para a validação de qualquer identificador que não seja predefinido. Esta área e dividida em: uses, label, const, type, var, procedure e function.

2.2.1 Subárea Var

Esta área e dedicada a declaração das variáveis, e seus tipos, que serão utilizadas no corpo do programa. A declaração das variáveis é atribuída pela instrução var seguida das variáveis. Após o nome de cada variável é seguida de (:) e o tipo da variável.

Exemplo:

var
   nome: string;
   cor: integer;
   marca: string;
   área: real;

No caso de variáveis do mesmo tipo, podem ser definidas na mesma linha, separadas por virgula.

Exemplo:

var
   dia, mês, ano: integer;

2.3 Corpo do programa

Nesta área é escrito o programa, propriamente dito. Esta área é identificada pelo uso da instrução begin, no inicio, e end seguida de um (.), no final.

Exemplo:

begin
   instruções;
   (...)
end.

2.4 Entrada e Saída de dados

Read e write são os comandos utilizados para leitura do teclado e saída para o monitor, ainda temos o comando readln e writeln, a diferença esta na posição que sera posicionado o cursor após a leitura ou escrita. Ln significa new line, desta forma, readln e writeln posicionam o cursor na linha seguinte, o que não ocorre com read e write.

Exemplo:

program soma_numeros;
   var
      a, b, x: integer;
   begin
      readln(a);
      readln(b);
      x:=a+b;
      writeln(‘resposta:’, x);
   end.

3 VARIÁVEIS E CONSTANTES

3.1 Identificadores

São os nomes dados as variáveis, tipos definidos, procedimentos, funções e constantes nomeadas.

Devem seguir as seguintes regras de construção:

  • Iniciar sempre por uma letra ou um underscore;
  • Os outros dos caracteres devem conter apenas dígitos, letras ou underscore.

Não existe diferença entre caracteres maiúsculo e minúsculo.

Exemplos de identificadores não validos:

  • %quantidade – o símbolo % não é valido
  • 4carro – não pode começar com um número
  • nome sobrenome – não pode conter espaço entre os caracteres

3.2 Palavras Reservadas

Existe um conjunto de palavras utilizadas para funções especiais, desta forma não podem ser utilizadas como identificadores no programa. A seguir é apresentado a lista de palavras reservadas no Pascal padrão:

and downto in packed
array else inline procedure
asm end interface program
begin file label record
case for mod repeat
const forward nil set
constructor function not shl
destructor goto object shr
div if of string
do implementation or

Tabela 1: palavras reservadas no Pascal

3.3 Comentários

São textos escritos dentro do programa afim de explicar ou descrever funcionamentos ou características do programa, facilitando o entendimento. Podem ser colocados em qualquer lugar do programa, mas utilizando a seguinte estrutura:

{<comentario>}

ou

(*<comentario>*)

ou

{(*<comentario>*)<comentario>}

O compilador ao encontrar um “{” ou “(*” pula todos os caracteres até encontrar “}” ou “*)”.

3.4 Tipos de dados

Todo o dado possui um tipo associado, para identificar como ele deve ser interpretado e representado pela máquina. O Pascal fornece alguns tipos predefinidos.

3.4.1 Inteiro

São tipos que podem representar positivos e negativos, excluindo-se qualquer número fracionário. Em Pascal utilizam-se os seguintes identificadores:

Tipo de dado inteiro Faixa de abrangência Tamanho (bytes)
shortint -128 até 127 1
integer -32768 até 32767 2
longint –2.147.483.648 até 2.147.483.647 4
byte 0 até 255 1
word 0 até 65535 2

3.4.2 Reais

Pode ser atribuído qualquer valor positivo ou negativo, fracionários ou não. Vejamos os tipos:

Tipo de dado real Faixa de abrangência Tamanho (bytes)
real 2.9 e-39 até 1.7 e38 6
single 1.5 e-45 até 3.4 e38 4
double 5.0 e-324 até 1.7e308 8
extended 3.4 e-4.932 até 1.1 e4.932 10
comp –9.2 e18 até 9.2 e18 8

3.4.3 Caracteres

São considerados tipos caracteres, as sequências contendo letras, números e símbolos especiais. Uma sequência de caracteres, em Pascal, deve ser representada entre apóstrofos (‘’). Este tipo de dado é referenciado pelo identificador string, podendo armazenar de 1 até 255 caracteres. Podemos ainda especificar um tamanho menor do que os 255 caracteres permitidos. Vejamos a sintaxe para criarmos uma variável do tipo string com tamanho limitado.

Sintaxe:

variável: string[tamanho];

Exemplo:

var
   frase: string;
   nome: string[45];

Existe também o tipo char, porém armazena apenas um caractere.

Exemplo:

var
   sexo: char;

3.4.4 Lógicos

Apresentado também como tipo booleano, pode representar apenas true ou false.

Exemplo:

verdadeiro: boolean;

3.5 Constantes

Valor que não pode ser alterado durante a execução do programa. Tipicamente utilizado por parâmetros que são bastante utilizados no programa.

Sintaxe:

const 
   identificador = expressão;
   identificador = expressão;

Exemplo:

program Area_Circulo;
{ Programa para calcular a área de um círculo. }
const
   PI = 3.141519265;
var
   Area, Comprimento, Raio : real;
begin
   writeln( ´Digite o Raio : ´ );
   readln( Raio );
   Area := PI * Raio * Raio;
   Comprimento := 2 * PI * Raio;
   writeln( ´Área = ´, Area );
   writeln( ´Comprimento da Circunferencia = ´, Comprimento );
end.

4 OPERADORES E EXPRESSÕES

4.1 Ordem de precedência dos operadores

Se existe uma expressão com vários operadores, os operadores são processados a partir das seguintes regras:

  • Emprego de parênteses
  • Pela ordem de precedência dos operadores
  • Em caso de operadores de mesma ordem, a leitura será feita da esquerda para a direita.
Ordem de precedência (maior para menor)
Operador Categoria
( ) Parêntese
not Operador Lógico Unário
* / div mod Operador Multiplicativo
and or Operador Lógico
= <> < > ⇐ >= Operador Relacional

4.3 Tipos de operadores

4.3.1 Operador de atribuição

Utilizado para atribuir um valor a uma variável

Sintaxe:

identificador_variavel := expressão;

Exemplo:

A:= 10;
Nome:= ‘Josias’;

4.3.2 Operadores Aritméticos

Utilizados para efetuar operações aritméticos entre números reais e inteiros. A tabela a seguir apresenta os operadores aritméticos disponíveis em Pascal.

Operador Simbolo
Subtração -
Adição +
Multiplicação *
Divisão Real /
Divisão inteira (truncar) Div
Resto da divisão inteira Mod
Inverter sinal -
Mantem sinal +

4.3.3 Operador Concatenação

Faz a junção de duas variáveis ou constantes do tipo string ou char.

Sintaxe:

Identificador_variavel_string := variável_string_ou_char1 + variável_string_ou_char2;

Exemplo:

nomeCompleto := nome + sobrenome;

4.3.4 Operadores relacionais

São utilizados para efetuar comparação entre dados do mesmo tipo. Os operadores estão descritos na tabela a seguir:

Operador Simbolo
Maior que >
Menor que <
Maior ou igual >=
Menor ou igual
Igual =
Diferente <>

4.3.5 Operadores lógicos

São utilizados para analisar duas ou mais expressões booleanas. A seguir os operadores lógicos:

Operador Simbolo
E and
OU or
NÃO not

4.4 Funções predefinidas

O Pascal oferece um conjunto de funções predefinidas:

  • Funções Matemáticas
Nome da função Objetivo Tipo parâmetro Tipo do retorno
Abs(x) Calcula o valor absoluto de x. inteiro ou real o mesmo que x
Cos(x) Calcula o coseno de x em radianos inteiro ou real real
Exp(x) Calcula ex, em que e=2.7182818 inteiro ou real real
Ln(x) Calcula o logaritmo natural de x (x>0)inteiro ou real real
Exp(ln(x)*y) Retorna x elevado a y {utilizando regras de logaritmos}. inteiro ou realreal
Sin(x) Calcula o seno de x em radianos inteiro ou real real
Sqr(x) Calcula o quadrado de x inteiro ou real o mesmo que x
Sqrt(x) Calcula a raiz quadrada de x (x>=0) inteiro ou real real
Odd(x) Determina se x é par ou impar. TRUE, X é par. FALSE, X é imparinteiroboolean
Random(x) Ver OBS inteiro real
pi Retorna o valor de PI (3.1415…) nenhum real

OBS: Retorna um número pseudo-aleatório entre 0 e x. Se x não for especificado retorna um valor entre 0.0 e 1.0

  • Funções Literais
Nome da função Objetivo Tipo parâmetro Tipo do retorno
Length(x) Determina o número de caracteres de xstring inteiro
concat(x1,x2,x3,…)Concatena duas ou mais strings (máx 255 caracteres)stringstring
copy(x,y,z) ver OBS string,inteiro,inteirostring
UpCase(x) Retorna x convertido para maiúscula char char

OBS: Retorna uma subcadeia da cadeia x, com z caracteres, começando no caracter y.

  • Funções para Conversão
Nome da função Objetivo Tipo parâmetro Tipo do retorno
trunc(x) Trunca x para um número inteiro real inteiro
int(x) Retorna a parte inteira de x real real
frac(x) Retorna a parte fracionária de x real real
round(x) Arredonda x para um inteiro real inteiro
chr(x) Determina o caracter ASCII representado por x inteiro real
  • Funções e Procedimentos de Uso Geral:
Nome da função Objetivo Tipo parâmetro Tipo do retorno
sizeof(x) Retorna o número de byte de x qualquer tipo inteiro
gotoxy(x,y) Move o curso para a coluna x e linha y inteiro -

5 ESTRUTURAS DE DECISÃO

5.1 A instrução if…then

Instrução if…then tem por finalidade tomar uma decisão e efetuar um desvio no processamento, dependendo, é claro, da condição atribuída ser verdadeira ou falsa. Sendo a condição verdadeira, será executada a instrução que estiver escrita após a instrução if..then. Se a instrução for falsa, serão executadas as instruções que estejam após as instruções consideradas verdadeiras.

Sintaxe:

if <condição> then
   <instrução para condição verdadeira>;
   <instrução para condição falsa ou após condição ser verdadeira>;

Exemplo:

if (x > 10) then
   writeln(“O valor da variavel X e 10”);

Caso venha a existir mais de uma instrução verdadeira para uma determinada condição, estas deverão estar inseridas em um bloco. Um bloco é o conjunto de instruções estar entre begin e end.

Sintaxe:

if <condição> then
begin
   <instrução para condição verdadeira>;
   <instrução para condição verdadeira>;
   <instrução para condição verdadeira>;
   <instrução para condição verdadeira>;
end;
<instrução para condição falsa ou após condição ser verdadeira>;

Exemplo:

if (x > 10) then
begin
   writeln(“O valor da variavel X e 10”);
   x : = x + 1;
   writeln(“O valor da variavel X agora e11”);
end;

5.2 A instrução in…then…else

Assim como a instrução if…then, a instrução if…then…else tem por finalidade tomar uma decisão e efetuar um desvio no processamento. Se a condição for verdadeira será executada a instrução logo abaixo do if. Sendo a condição falsa, será executada a instrução que estiver posicionada logo após a instrução else. O conceito de blocos de instruções vale também para esta instrução.

Sintaxe:

if <condição> then
   <instruções para condição verdadeira>;
else
   <instruções para condição falsa>;

Caso venha a existir mais de uma instrução verdadeira ou falsa para uma condição, estas deverão estar inseridas em um bloco.

Sintaxe:

if <condição> then
begin
   <instruções para condição verdadeira>;
   <instruções para condição verdadeira>;
end
else
begin
   <instruções para condição falsa>;
   <instruções para condição falsa>;
end;

Observe que nos dois casos abordados acima, qualquer instrução que antecede a instrução else está escrita sem o ponto-e-vírgula (;). Isto ocorre pelo fato de a instrução else ser uma extensão da instrução if…then, e sendo assim, o final da condição somente ocorre após o processamento da instrução else.

Exemplo:

program ADICIONA_NUMEROS;
var 
   X, A, B : integer;
begin
   write(‘Informe um valor para a variavel A: ‘);
   readln(A);
   write(‘Informe um valor para a variavel B: ‘);
   readln(B);
   writeln;
   X := A + B;
   write (‘O resultado equivale a: ‘);
   if (X>=10) then
      writeln(X+5);
   else
      writeln(X-5);
   end.
   

5.2 A instrução case…of

Estrutura semelhante ao if…then.

Sintaxe:

case <variavel> of
   <opcao1> : <instrucao1>;
   <opcao2> : <instrucao2>;
   <opcao3> : <instrucao3>;
else
   <instrução4>;
end;    

onde: variavel é o nome da variável a ser controlada na decisão, opção é o conteúdo da variável a ser verificado e instrucao é a execução de um comando ou bloco de comandos.

Lembre-se que você pode inserir um bloco de instruções após uma instrução condicional. Para isto basta colocar as instruções entre begin e end.

6 ESTRUTURAS DE REPETIÇÃO (LOOPS)

Existem situações em que é necessário repetir um determinado trecho de programa, as vezes é possível fazer manualmente, mas você terá muito trabalho. Para isso existem os laços de repetição que facilitarão o trabalho. Existem dois tipos de laços:

  • Finitos: neste tipo de laço se conhece previamente o número de repetições que serão executadas;
  • Infinitos: neste tipo não se conhece previamente o número de repetições que serão executadas. São também chamados de condicionais, pelo fato de encerrarem sua execução mediante uma determinada condição.

6.1 Intrução For

O comando FOR executa repetitivamente um comando enquanto é atribuído uma série de valores a uma variável de controle (contador do FOR).

Sintaxe :

for variavel := <início> to/downto <fim> do
   instrução;

ou

for variavel := <início> to/downto <fim> do
begin
   <...>;
end;

Exemplo:

program EXEMPLO_FOR;
var A, B, R, I : integer;
begin
   for I := 1 to 5 do
   begin
      write(‘Entre um valor para A: ’);
      readln(A);
      write(‘Entre um valor para B: ’);
      readln(B);
      writeln;
      R := A + B;
      writeln(‘O resultado corresponde a: ’,R);
      writeln;
   end;
end.  

6.2 Instrução While…do

Esta estrutura de repetição se caracteriza por efetuar um teste lógico no início de um loop, verificando se é permitido executar o trecho de instruções abaixo dela. A estrutura while…do tem o seu funcionamento controlado por condição. Desta forma, poderá executar um determinado conjunto de instruções enquanto a condição verificada permanecer verdadeira. No momento em que a condição se torna falsa, o processamento da rotina é desviado para fora do loop. Sendo a condição falsa logo no início do loop, as instruções contidas nele são ignoradas.

Sintaxe:

while <condição> do
   <instrução para condição verdadeira>;

ou

while <condição> do
begin
   <instruções para condição verdadeira>;
end;  

Exemplo:

program EXEMPLO_WHILE_DO1;
var 
   A, B, R, I : integer;
begin
   while (I <= 5) do
   begin
      write(‘Entre um valor para A: ’);
      readln(A);
      write(‘Entre um valor para B: ’);
      readln(B);
      writeln;
      R := A + B;
      writeln(‘O resultado corresponde a: ’,R);
      writeln;
      I := I + 1;
   end;
end.  

6.3 Instrução repeat…until

Esta estrutura caracteriza-se por efetuar um teste lógico no final de um looping, sendo parecida com a estrutura while…do. Seu funcionamento é controlado também por decisão. Esta instrução irá efetuar a execução de um conjunto de instruções pelo menos uma vez antes de verificar a validade da condição estabelecida. Desta forma, repeat irá processar um conjunto de instruções, no mínimo uma vez, até que a condição se torne verdadeira. Para a estrutura repeat um conjunto de instruções é executado enquanto a condição se mantém falsa e até que se torne verdadeira.

Sintaxe:

repeat
   <instrução1 até que a condição seja verdadeira> ;
   <instrução2 até que a condição seja verdadeira> ;
   <instrução3 até que a condição seja verdadeira> ;
until <condição>;

Exemplo:

program EXEMPLO_REPEAT1;
var 
   A, B, R, I : integer;
begin
   I := 1;
   repeat
      write(‘Entre um valor para A: ’);
      readln(A);
      write(‘Entre um valor para B: ’);
      readln(B);
      writeln;
      R := A + B;
      writeln(‘O resultado corresponde a: ’,R);
      writeln;
      I := I + 1;
   until (I > 5);
end.  

7 VETORES, MATRIZES E REGISTROS

Ao utilizamos variáveis, podemos armazenar apenas um valor por vez. Agora, imagine um programa onde precisa-se armazenar as notas de 5 provas realizadas por um aluno. Com os conhecimentos que você possui até agora, seria necessário criar cinco variáveis para armazenar as notas.

Desta forma:

NOTA1, NOTA2, NOTA3, NOTA4, NOTA5 : integer;

Em Pascal existem estruturas que nos permitem agrupar várias informações dentro de uma mesma variável. Estas estruturas são chamadas de vetores e matrizes.

7.1 Vetores

Este tipo de estrutura é também chamado de matriz unidimensional. Um vetor é representado por seu nome, tamanho e seu tipo.

Sintaxe:

<vetor> : array[tamanho] of <tipo_de_dado>;

onde: vetor é o nome atribuído ao vetor, tamanho é o tamanho atribuído ao vetor, em número de elementos e tipo_de_dado é o tipo de elemento armazenado.

A leitura e gravação de vetores é feita utilizando índices, entre colchetes, para acessar uma determinada posição.

Sintaxe:

array[posicao] := valor_desejado_ou_variavel;

Exemplo:

program EXEMPLO_VETOR;
var
   A, B : array[1..10] of integer;
   I : integer;
begin
{ *** Entrada dos Dados ***}
   for I := 1 to 10 do
   begin
      write(‘Informe o valor’, I);
      readln(A[I]);
   end;
{ *** Teste Par ou Ímpar ***}
   for I := 1 to 10 do
      if (I mod 2 = 0) then
         B[I] := A[I] * 5
      else
         B[I] := A[I] + 5;
      writeln;
{ *** Apresentação das matrizes ***}
      for I := 1 to 10 do
         writeln(‘A[‘, I:2,’] = ’, A[I]:2, ‘ ’, ‘B[’, I:2, ‘] = ’, B[I]:2 );
      writeln;
      writeln(‘Tecle <ENTER> para encerrar: ’);
      readln;
end.

7.2 Matrizes Como existem matrizes unidimensionais é de se esperar que teríamos as multidimensionais. O que vamos apresentar a seguir.

Sintaxe:

<matriz> : array[dimensão_linha,dimensão_coluna] of <tipo_de_dado>;

onde: matriz é o nome atribuído à matriz, dimensão_linha é o tamanho da matriz em número de linhas, dimensão_coluna é o tamanho da matriz em número de colunas e tipo_de_dado é o tipo do elemento armazenado.

A leitura e gravação de matrizes é semelhante ao dos vetores, a indexação também é feita entre colchetes, para acessar uma determinada linha e coluna.

Sintaxe:

matriz[linha, coluna] := valor_desejado_ou_variavel;

Exemplo:

program NOTA_ALUNO;
var 
   NOTAS : array[1..5,1..4] of real;
   I, J : integer;
begin
   writeln(‘Leitura e Apresentacao da Notas’);
   writeln;
   for I := 1 to 5 do
   begin
      writeln;
      writeln(‘Informe as notas do ’, I:2, ‘o. aluno: ’);
      for J:= 1 to 4 do
      begin
         write(‘Nota’, J:2, ‘:’);
         readln(NOTAS[I, J]);
      end;
   end;
   writeln;
   for I:= 1 to 5 do
   begin
      write(‘As notas do aluno ’, I:2, ‘ são: ’);
      for J := 1 to 4 do
         write(NOTAS[I, J] :2 :2, ‘ ’);
      writeln;
   end;
   writeln;
   writeln(‘Tecle <ENTER> para encerrar: ’);
   readln;
end.

7.3 Registros

Em um registro poderemos utilizar uma estrutura que agrupe várias informações, que podem ser de tipos de dados diferentes. Por esta razão, este tipo de dado é considerado heterogêneo. Em Pascal, os tipos registro devem ser declarados ou atribuídos antes das definições das variáveis, pois é muito comum ocorrer a necessidade de se declarar uma variável com o tipo de registro atribuído. Um tipo registro é declarado em Pascal com a instrução type em conjunto com a instrução record.

Sintaxe:

type
   <identificador> = record
      <lista de campos e seus tipos>
   end;
var
   <variavel> : <identificador_registro>
   

onde: identificador é o nome do tipo registro e lista de campos e seus tipos é a relação de variáveis que serão usadas como campos, bem como seu tipo(real, integer…). Após a instrução var, deverá ser indicada uma variável tipo registro e a declaração do seu tipo de acordo com um identificador definido anteriormente. Perceba que a instrução type deverá ser utilizada antes da instrução var, pois, ao definir um tipo de variável, pode-se fazer uso deste tipo definido.

Vamos analisar o exemplo do aluno e suas 4 notas, considerando, que devemos armazenar o nome deste aluno e suas 4 notas em uma mesma estrutura.

Exemplo:

program EX_REGISTRO1;
type
   CAD_ALUNO = record
      NOME : string;
      NOTA1 : real;
      NOTA2 : real;
      NOTA3 : real;
      NOTA4 : real;
   end;
var
   ALUNO : cad_aluno;
begin
   writeln(‘Cadastro de Aluno’);
   writeln;
   write(‘Informe o nome..............: ’); readln(ALUNO.NOME);
   write(‘Informe a primeira nota..: ’); readln(ALUNO.NOTA1);
   write(‘Informe a segunda nota...: ’); readln(ALUNO.NOTA2);
   write(‘Informe a terceira nota....: ’); readln(ALUNO.NOTA3);
   write(‘Informe a quarta nota......: ’); readln(ALUNO.NOTA4);
   writeln;
   writeln(‘Nome..: ’ , ALUNO.NOME);
   writeln(‘Nota 1.: ’ , ALUNO.NOTA1 :2:2);
   writeln(‘Nota 2.: ’ , ALUNO.NOTA2 :2:2);
   writeln(‘Nota 3.: ’ , ALUNO.NOTA3 :2:2);
   writeln(‘Nota 4.: ’ , ALUNO.NOTA4 :2:2); writeln;
   writeln(‘Tecle <ENTER> para encerrar: ’); readln;
end.

8 PROCEDURES E FUNCTION

É comum, em programação, decompor a lógica de programas complexos em programas menores e, depois, juntá-los para compor o programa final. Essa técnica de programação é denominada programação modular. A programação modular consiste num método para facilitar a construção de grandes programas, através de sua divisão em pequenas etapas, que são os módulos ou rotinas e para possibilitar o reaproveitamento de código, já que podemos utilizar um módulo quantas vezes for necessário, eliminando assim a necessidade de escrever o mesmo código do programa em situações repetitivas. Outra importância da modularização é que ela permite que diferentes programadores trabalhem simultaneamente na solução de um mesmo problema, através da codificação separada dos diferentes módulos. A modularização, em Pascal, pode ser feita através de procedimentos (procedures) e funções (functions). Isso é feito associando-se um nome a uma seqüência de comandos através do que chamamos Declaração do Procedimento ou da Função. Pode-se, então, usar o nome do procedimento ou da função dentro do corpo do programa, sempre que desejarmos que o seu bloco de comandos seja executado, isso é o que chamamos de Chamada do Procedimento ou da Função. Além das rotinas desenvolvidas pelo usuário, existe na linguagem Pascal, um conjunto de rotinas embutidas. Este tipo de rotina embutida é conhecido pelo nome de unidade (do inglês, unit).

8.1 Utilização de Units

Vejamos de forma básica as units embutidas no Turbo Pascal. As units são conjuntos de rotinas prontas para serem usadas pelo programador. Uma unit é, na verdade, uma biblioteca de funções e procedimentos. Vejamos a lista das unidades do Pascal:

  • CRT: esta unidade é a mais utilizada na programação Pascal. Ela possui a maior parte das rotinas e variáveis de geração de som, controle de vídeo e teclado;
  • DOS: esta unidade possui as rotinas que envolvem a utilização do sistema operacional, na maior parte das vezes permitindo controles de baixo nível;
  • GRAPH: esta unidade possui rotinas destinadas à manipulações gráficas;
  • OVERLAY: esta unidade possibilita gerenciar as atividades de um programa, desta forma, é possível aproveitar uma mesma área de memória para rodar várias rotinas diferentes, economizando memória;
  • PRINTER: esta unidade permite declarar um arquivo tipo texto com o nome LST e associá-lo à impressora;
  • SYSTEM: esta unidade possui a maior parte das rotinas padrão da linguagem Pascal, não necessitando ser citada para ser usada, pois o turbo Pascal já a executa de forma automática.

Para se fazer uso deste recurso é necessário o uso da instrução uses situada antes da declaração da instrução var.

Sintaxe:

uses <unidade>;

8.2 Procedures

Um procedimento é uma estrutura de programa autônoma que está incluída num programa em Pascal. Nele podem ser colocados todos os elementos da linguagem Pascal, como se fosse um programa completo; isso é feito através de sua declaração. Um procedimento pode ser referido escrevendo simplesmente o seu nome seguido de um lista opcional de parâmetros. Quando um procedimento é referenciado, o controle de execução do programa é automaticamente transferido para o início do procedimento. As instruções de execução dentro do procedimento são então executadas, tendo em conta quaisquer declarações especiais que sejam únicas para o procedimento. Quando todas as instruções de execução tiverem sido executadas, o controle passa automaticamente para a instrução imediatamente a seguir à da chamada do procedimento.

Sintaxe:

procedure Nome( parametros )
var
   <variáveis>
begin
   <instruções>
end;

onde: nome é o nome atribuído ao procedimento e parametros são informações adicionais que serão vistas mais tarde.

A linguagem Pascal exige que os procedimentos sejam definidos antes do programa principal Para entendermos melhor o conceito de procedimento vamos ver um exemplo.

program CALCULADORA;
uses
   Crt;
var
   OPCAO : char;
   
{ ** Procedimento de Soma ** }
procedure ADICAO;
var
   X, A, B : real;
   TECLA : char;
begin
   (...)
end;

{ ** Procedimento de Multiplicacao ** }
procedure MULTIPLICA;
var
   X, A, B : real;
   TECLA : char;
begin
   (...)
end;

{ ** Programa Principal **}
begin
   (...)
end.

8.2.1 Variáveis Globais e Locais

Variáveis globais são declaradas no inicio de um programa em Pascal. Desta forma esta variável é válida dentro de qualquer função ou procedimento.

Já as variáveis locais são declaradas dentro de uma função ou procedimento e serão válidas somente para os mesmos. Desta forma podemos ter variáveis distintas, mas com o mesmo nome, em funções diferentes.

É importante perceber que uma variável global pode ser alterada dentro de qualquer função ou procedimento, no entanto isto pode gerar alguns problemas se o programador não saber usar este recurso.

8.3 Parâmetros

Os parâmetros são os pontos de comunicação com uma função ou procedimento. Com isso é possível passar informações de um programa para outro.

Sintaxe:

procedure Nome( parametroA, parametroB: tipo_dos_parametros );
var
   <variáveis>
begin
   <instruções>
end;

E para utilizar o procedimento:

Sintaxe:

nome_do_procedimento(parametroA, parametroB);

8.3.1 Passagem por Valor

Neste caso os parâmetros fornecidos ao procedimento não são alterados.

8.3.2 Passagem por Referência

O que a caracteriza é a alteração dos parâmetros fornecidos dentro do programa. Para que um procedimento receba informações desta maneira, é necessário uma pequena alteração na estrutura do procedimento ou função.

Sintaxe:

procedure Nome( parametro_por_valor: tipo_do_parametro; var parametro_por_referencia: tipo_do_parametro);
  var
     <variáveis>
  begin
     <instruções>
  end;
  

8.4 Functions

Como os procedimentos (procedures), são blocos de programas. A diferença é que todas as funções retornam um valor, seja numérico, lógico ou literal.

Sintaxe:

function <nome> [(parâmetros)] : <tipo>;
var
   <variaveis> ;
begin
   <instrucoes>;
end;

onde: nome é o nome atribuído a uma função, parâmetro é uma informação opcional e tipo é o tipo de dado a ser retornado pela função.

A definição de tipo de dado fora do parênteses, na declaração da função, indica o tipo de dado que retornará à rotina chamadora.

A variável que retorna o valor da função tem o mesmo nome da função.

Exemplo:

program CALC_ADICAO;
uses
   Crt;
   
function ADICAO (A, B : real) : real;
begin
   ADICAO := A + B;
end;

var
   NUM1, NUM2 : real;
begin
   clrscr;
   write(‘Informe o 1o. valor : ’);
   readln(NUM1);
   write(‘Informe o 2o. valor : ’);
   readln(NUM2);
   writeln;
   writeln(‘O resultado da adicao = ’, Adicao(NUM1, NUM2) :2:2 );
   writeln(‘Tecle <ENTER> para encerrar o program’);
   readln;
end.

9 ARQUIVOS

Para salvar o estado de um programa é necessário salvar o estado de suas estruturas (variáveis, vetores, registros, etc). Para isto é utilizado estruturas de arquivos, estes que são armazenados no disco rígido e que posteriormente podem ser carregados para dentro do programa.

9.1 Definição de um Arquivo

A manipulação de um arquivo em Pascal ocorre com a definição do tipo file, o qual se caracteriza por ser uma estrutura formada por elementos do mesmo tipo dispostos de forma seqüencial, tendo como finalidade fazer a comunicação entre a memória principal e a memória secundária.

Sintaxe:

type
   <arquivo> = [text][file [of <tipo>]];
var
   <variavel> : <arquivo>;

ou

<variavel> : [text][file [of <tipo>]];

onde: arquivo é o nome de um arquivo com tipo definido, tipo é o tipo de um arquivo (text, string, real, record, etc…) e variavel é a variável que será usada para representar o arquivo.

9.2 Operações de um Arquivo

Em Pascal existem algumas funções para operar arquivos. Vejamos a tabela a seguir:

Instrução Tipo Sintaxe Descrição
assign procedure assign (<variavel>, <arquivo>) Tem por finalidade associar um nome lógico de arquivo ao arquivo físico. O parâmetro <variavel> é a indicação da variável do tipo arquivo, e <arquivo> é o nome do arquivo a ser manipulado.
rewrite procedure rewrite (<variavel>) Tem por finalidade criar um arquivo para uso, utilizando o nome associado ao parâmetro <variavel>. Caso o arquivo já exista, esta instrução o apagará para criá-lo novamente.
reset procedure reset (<variavel>) Tem por finalidade abrir um arquivo existente, colocando-o disponível par leitura e gravação, utilizando o nome associado ao parâmetro <variavel>.
write procedure write(<variavel>,<dado>) Tem por finalidade escrever a informação <dado> no arquivo indicado pelo parâmetro <variavel>.
read procedure read(<variavel>,<dado>) Tem por finalidade ler a informação <dado> no arquivo indicado pelo parâmetro <variavel>.
close procedure close(<variavel>) Tem por finalidade fechar um arquivo em uso dentro de um programa. nenhum programa deve ser encerrado sem antes fechar os arquivos abertos.

9.3 Formas de Acesso em um Arquivo

9.3.1 Acesso Seqüencial

O acesso seqüencial ocorre quando o processo de gravação e leitura é feito de forma contínua, um após o outro. Desta forma, para se gravar a informação é necessário percorrer todo o arquivo a partir do primeiro registro, até localizar a primeira posição vazia. A leitura também ocorre desta maneira.

9.3.2 Acesso Direto O acesso direto ocorre através de um campo chave previamente definido. Desta forma, passa a existir um vínculo existente entre um dos campos do registro e sua posição de armazenamento, através da chave. Assim sendo, o acesso a um registro tanto para leitura como para gravação poderá ser feito de forma instantânea.

9.3.3 Acesso Indexado

O acesso indexado ocorre quando se acessa de forma direta um arquivo seqüencial. Na sua maioria, todo arquivo criado armazena os registros de forma seqüencial. A forma seqüencial de acesso se torna inconveniente, pois à medida que o arquivo aumenta de tamanho, aumenta também o tempo de acesso ao mesmo. Por isso, cria-se um índice de consulta, passando a ser esse arquivo indexado. Existirão dois arquivos, um seqüencial e outro indexado. Os acessos serão feitos com em um livro: primeiro se consulta o índice de localização, e depois procura-se o conteúdo desejado.

9.4 Arquivos do Tipo Texto

Armazenam frases, palavras e dados numéricos. No entanto, todos são armazenados no formato caractere, desta forma, os dados numéricos tem de ser convertidos na sua leitura.

  • Criando um arquivo tipo texto:
program CRIA_ARQUIVO_TEXTO;
var
   ARQUIVO_TXT : text;
begin
   assign(ARQUIVO_TXT, ‘ARQTXT.XXX’);
   rewrite(ARQUIVO_TXT);
   close(ARQUIVO_TXT);
end.

O programa acima estabelece para a variável ARQUIVO_TXT o identificador text, que tem por finalidade definir para a variável indicada o tipo de arquivo texto.

  • Gravando em um arquivo texto:
program GRAVA_ARQUIVO_TEXTO;
var
   ARQUIVO_TXT : text;
   MENSAGEM : string[50];
begin
   assign(ARQUIVO_TXT, ‘ARQTXT.XXX’);
   append(ARQUIVO_TXT);
   readln(MENSAGEM);
   writeln(ARQUIVO_TXT, MENSAGEM);
   close(ARQUIVO_TXT);
end.

* Lendo um arquivo texto:
program LER_ARQUIVO_TEXTO;
var
   ARQUIVO_TXT : text;
   MENSAGEM : string[50];
begin
   assign(ARQUIVO_TXT, ‘ARQTXT.XXX’);
   reset(ARQUIVO_TXT);
   readln(ARQUIVO_TXT , MENSAGEM);
   writeln( MENSAGEM);
   close(ARQUIVO_TXT);
end.

9.5 Arquivos com Tipo Definido

Neste formato podemos guardar as informações em nível binário. Diferente do tipo texto, desta forma os formatos são mantidos, por exemplo, um dado numérico é gravado como numérico. Ainda podemos gravar registros e outras estruturas. Nesta forma a leitura e gravação é mais rápida se comparada com arquivo texto.

  • Criando um arquivo que receba dados numéricos inteiros:
program CRIA_ARQUIVO_INTEIRO;
var
   ARQUIVO_INT : file of integer;
begin
   assign(ARQUIVO_INT, ‘ARQINT.XXX’);
   rewrite(ARQUIVO_INT);
   close(ARQUIVO_INT);
end.

O programa acima estabelece para a variável ARQUIVO_INT o identificador file of integer, que tem a finalidade de definir para a variável indicada de arquivo como sendo inteiro.

  • Gravação de um arquivo tipo inteiro:
program CADASTRA_ARQUIVO_INTEIRO;
uses
   Crt;
var
   ARQUIVO_INT : file of integer;
   NUMERI : integer;
   RESP :char;
begin
   assign(ARQUIVO_INT, ‘ARQINT.XXX’);
   reset(ARQUIVO_INT);
   RESP := ‘S’;
   while (RESP = ‘S’) or (RESP = ‘s’) do
   begin
      clrscr;
      writeln(‘Gravacao de Registros Inteiros’);
      writeln;
      seek(ARQUIVO_INT, filesize(ARQUIVO_INT));
      write(‘Informe um numero inteiro: ’);
      readln(NUMERO);
      write(ARQUIVO_INT, NUMERO);
      writeln;
      write(‘Deseja continuar ? [S/N] ’);
      readln(RESP);
   end;
   close(ARQUIVO_INT);
end.

O programa acima utiliza a função assign para associar o arquivo à variável de controle. Faz uso da instrução reset para abrir o arquivo. Um pouco abaixo é apresentada uma linha com a instrução seek(ARQUIVO_INT, filesize(ARQUIVO_INT)); que executa em um arquivo definido o mesmo efeito que a instrução append em um arquivo texto, ou seja, se o arquivo já possuir algum registro, o próximo registro será sempre colocado após o último cadastrado. A instrução filesize retorna o número de registros do arquivo e a instrução seek posiciona o ponteiro de registro em uma determinada posição do arquivo.

  • Leitura de um arquivo tipo inteiro:
program CADASTRA_ARQUIVO_INTEIRO;
uses
   Crt;
var
   ARQUIVO_INT : file of integer;
   NUMERI : integer;
   RESP :char;
begin
   assign(ARQUIVO_INT, ‘ARQINT.XXX’);
   reset(ARQUIVO_INT);
   RESP := ‘S’;
   while not eof(ARQUIVO_INT) do
   begin
      read(ARQUIVO_INT, NUMERO);
      writeln(NUMERO);
   end;
   close(ARQUIVO_INT);
end.

9.6 Arquivo com Tipo Definido de Registro

Em Pascal, existe um arquivo do tipo record, que nos permite desenvolver uma aplicação de forma mais profissional e com acessos mais rápidos.

Sintaxe:

type
   <nome_arquivo> = record
   <campos do arquivo>
end;
var
   <variavel> : <nome_arquivo>;
   <variavel> : file of <nome_arquivo>;

Exemplo:

type
   BIMESTRE = array[1..4] of real;
   REG_ALUNO = record
   FLAG : char;
   MATRICULA : integer;
   NOME : string[30];
   NOTAS : bimestre;
end;
var
   ALUNO : reg_aluno;
   ARQALU : file of reg_aluno;
  

10 EXTRAS

Unit CRT

Durante os exemplos foram utilizados algumas instruções da biblioteca CRT. Existem várias instruções que facilitam o trabalho e podem ser facilmente encontradas na internet. Exitem outras bibliotecas que aqui não foram utilizadas, mas que podem facilitar a vida do programador Pascal. A seguir as instruções utilizadas da unit CRT.

Instrução Tipo Funcionalidade
clrscr Procedure Efetua a limpeza da tela, posicionando o cursor do lado esquerdo superior.
gotoxy (coluna,linha) Procedure Permite posicionar o cursor em ponto da tela. Para utilizá-lo é necessário informar dois parâmetros: a coluna e linha para posicionamento.
readkey Function Permite retornar o valor da tecla pressionada, sendo este valor do tipo caractere. Quando utilizada em um programa, e esta função faz a leitura de apenas um caractere. Por esta razão, não necessita ser usada a tecla <ENTER> para confirmar a entrada da informação.

Compiladores

Existem inúmeros compiladores Pascal. No link abaixo existe uma grande variedade de compiladores.

http://pascaland.org/pascall.htm

Com o advento da orientação a objetos foi criado o Object Pascal que foi influenciado pelas linguagens Pascal e Smalltalk, contudo existem compiladores Object Pascal que - com poucas mudanças - é muito semelhante ao Pascal. Adicionado do paradigma de orientação a objetos, que nos dias de hoje é um importante recurso para programação em grupo.

Códigos

A seguir alguns códigos feitos em Pascal.

  • Números Amigos
program Ada19p; 
uses
   MemTypes, QuickDraw, OSIntf;
const
   MAX = 100;
var
   k, l: Integer;
   fim: string; 
function amigos(a, b: Integer): Boolean;
var
   I, j, n, soman, somam: integer; 
begin
   soman:= 0;
   somam:= 0;
   for I:= 1 to a - 1 do
      if (a mod I) = 0 then soman:= soman + I;
   for j:= 1 to b - 1 do
      if (b mod j) = 0 then somam:= somam + j;
   if (somam = a) and (soman = b) then amigos:= true else amigos:= false;
end; 
begin
   repeat
      clearscreen;
      gotoxy(33, 2);
      writeln('Programa: Números Amigos!');
      gotoxy(33, 3);
      writeln('~~~~~~~~~~~~~~~~~');
      gotoxy(36, 4);
      writeln('Paulo G.P.');
      writeln;
      writeln('Programa iniciado!');
      writeln('Procura no intervalo [0 ,', MAX, '].');
      writeln;
      for k:= 2 to MAX do
      begin
         if k = MAX / 2 then
         begin
            writeln;
            writeln('Meio da contagem!');
            writeln;
         end;
         for l:= 2 to MAX do
            if amigos(k, l) then writeln(' São amigos: ', k, ' & ', l);
      end;
      writeln;
      writeln('Terminado!');
      writeln;
      write('Repetir (s/n): ');
      readln(fim);
      uprstring(fim, true);
   until fim = 'N';
end.
  • Bubble Sort
program ordenacao;
uses crt;
const
   n = 20;
var
   vet:array[1..n]of integer;
   i,j,aux: integer;
begin
   randomize;
   {Preenche o array com valores aleatórios}
   for i := 1 to n do
      vet[i] := random(100);
   {Ordena o array}
   for i := n downto 2 do
      for j := 1 to i-1 do
         if vet[j] > vet[j+1] then 
         begin
            aux := vet[j];
            vet[j] := vet[j+1];
            vet[j+1] := aux;
         end;      
end.

Bibliografia

 
pascal-1-trabalho.txt · Last modified: 2012/03/19 19:26 by clp · [Old revisions]