Algoritmo
Pesquisas Acadêmicas: Algoritmo. Pesquise 862.000+ trabalhos acadêmicosPor: • 4/3/2015 • 8.917 Palavras (36 Páginas) • 420 Visualizações
5. Ler duas matrizes A e B, cada uma com uma dimensão para 12 elementos. Construir uma matriz C de duas dimensões, onde a primeira coluna da matriz C deverá ser formada pelos elementos da matriz A multiplicados por 2 e a segunda coluna deverá ser formada pelos elementos da matriz B subtraídos de 5.
XI REGISTROS
Anteriormente, você teve contato com a utilização de matrizes e notou que somente foi possível trabalhar com um tipo de dado por matriz. No momento em que se precisou trabalhar com dois tipos de dados diferentes, foi necessária a utilização de duas matrizes, uma de cada tipo. Para solucionar esta deficiência, poderá ser utilizada estrutura de dados registro, a qual consiste em trabalhar vários dados de tipos diferentes (os campos) em uma mesma estrutura. Por esta razão, este tipo de dado é considerado heterogêneo.
Para tanto, considere que seja informado o nome de um aluno e suas 4 notas bimestrais que deverão ser agrupados em uma mesma estrutura. A figura 6.2 mostra um exemplo do layout de um registro, o qual é o conjunto de campos. Note que o registro está formado pelos campos: Nome, Primeira Nota, Segunda Nota, Terceira Nota e Quarta Nota e podendo este ser denominado um registro de aluno.
Layout do formato de um registro com seus campos
Cadastro de Notas Escolares
Nome .................: _________________
Primeira Nota ....: _________________
Segunda Nota .....: _________________
Terceira Nota .....: _________________
Quarta Nota .......: _________________
Na estrutura da linguagem 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, conforme a seguinte sintaxe:
type
<identificador> = record
end;
<lista dos campos e seus tipos>
var
<variável> : <identificador> ;
Onde identificador é o nome do tipo registro, que será neste livro escrito em caracteres maiúsculos, em itálico, seguindo as mesmas regras de definiçãodas variáveis, e lista dos campos e seus tipos é a relação de variáveis que serão usadas como campos, bem como o seu tipo, podendo ser: real, integer, boolean, string entre outros existentes no Turbo Pascal.
Após a instrução var, deverá ser indicada a 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.
Tomando como exemplo a proposta de se criar um registro denominado ALUNO, cujos campos são NOME, NOTAI, NOTA2, NOTA3 e NOTA4, este seria assim declarado em Pascal:
type
CAD_ALUNO = record
NOME : string;
NOTAI : real;
NOTA2 : real;
NOTA3 : real;
NOTA4 : real;
end;
var
ALUNO : cad_aluno;
Perceba que o registro está sendo denominado como CAD_ALUNO, o qual é um conjunto de dados heterogêneos (um campo tipo string e quatro do tipo real). Desta forma, é possível guardar em uma mesma estrutura, vários tipos diferentes de dados.
Tanto a leitura quanto escrita de um registro são efetuadas respectivamente com as instruções read/readln e write/writeln seguidas do nome da variável do tipo registro e de seu campo correspondente separado por um caractere "." (ponto), como exemplificado a seguir.
Program LEITURA_ESCRITA;
Uses crt;
type
CAD_ALUNO = record
NOME : string;
NOTA1 : real;
NOTA2 : real;
NOTA3 : real;
NOTA4 : real;
end;
var
ALUNO : cad_aluno;
begin
clrscr;
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.
Perceba que no registro definido, existem quatro variáveis do mesmo tipo definidas para armazenar quatro notas (NOTA1, NOTA2, NOTA3 e NOTA4), desta forma, este registro poderá ser definido usando uma matriz do tipo vetor para armazenar as notas.
Tomando por base a proposta de se criar um registro denominado ALUNO, cujas
notas serão informadas em uma matriz do tipo vetor, este seria assim declarado:
type
BIMESTRE = array [1..4] of real;
CAD_ALDNO = record
end;
NOME : string;
NOTA : bimestre;
var
ALUNO : cad_aluno;
Ao ser especificado o registro CAD_ALUNO, existe nele um campo chamado NOTA do tipo bimestre, onde bimestre é a especificação de um tipo de conjunto matricial de uma única dimensão com capacidade para quatro elementos. Veja que o tipo bimestre foi definido acima do tipo CAD_ALUNO.
Manter uma ordem na definição de tipos que são dependentes de outros tipos definidos é imprescindível, pois se o tipo BIMESTRE fosse definido abaixo do tipo CAD_ALUNO, geraria um erro na execução do programa, uma vez que o compilador do Turbo Pascal consideraria como sendo tipo desconhecido. A seguir, é apresentado o código-fonte para a leitura e escrita dos dados, usando o registro de matriz.
Program LEITURA_ESCRITA;
Uses crt;
type
BIMESTRE = array[1..4] of real;
CAD_ALUNO = record
NOME : string;
end;
NOTA : bimestre;
var
ALUNO : cad_aluno;
I : byte;
begin
clrscr;
writeln ('Cadastro de aluno');
writeln ;
write ( Informe o nome .......: ' ); readln (ALUNO.NOME);
writeln;
for I :=1 to 4 do
begin
write ('Informe a ', I:2, 'a. nota ..:');
readln (ALUNO.NOTA[I]);
end;
writeln;
writeln;
writeln ('Nome ....: ' , ALUNO.NOME);
writeln;
for I :=1 to 4 do
Writeln ('Nota ', I, ' ..: ', ALUNO.NOTA[I]:2:2);
Writeln ;
Writeln ('Tecle <ENTER> para encerrar: '); readln ;
end.
Com as técnicas de programação expostas até este momento, passou-se a ter uma mobilidade bastante grande, podendo-se trabalhar de uma forma mais adequada com diversos problemas, principalmente os que envolvem a utilização de dados heterogêneos, facilitando a construção de programas mais eficientes. Porém, os programas apresentados até aqui com a utilização de registros, só fizeram menção á leitura e escrita de um único registro.
Neste momento, seria pertinente construir um programa que permitisse trabalhar com vários registros de alunos. Para exemplificar, considere que você deverá fazer um programa que faça a entrada e a saída de nome e notas de 8 alunos. isto já é familiar. Veja a seguir, a definição do tipo registro e também a definição da matriz de registros para os oito alunos:
program LEITURA_ESCRITA;
type
BIMESTRE = array[1..4] of real;
CAD_ALUNO = record
NOME : string;
NOTA : bimestre;
end;
var
ALUNO : array [1..8] of CAD_ALUNO;
Observe que após a instrução var, é indicada a variável de registro ALUNO, sendo esta um conjunto de 8 registros do tipo CAD_ALUNO, que por sua vez é formado de dois tipos de dados: o nome como caractere e a nota como bimestre. A seguir, é apresentado um programa que fará a entrada e saída dos dados de 8 alunos.
program LEITURA_ESCRITA;
type
BIMESTRE = array[1..4] of real;
CAD_ALUNO = record
NOME : string;
NOTA : bimestre;
end;
var
ALUNO : array[1..8] of cad_aluno;
I, J : byte;
begin
w r iteln( cadastro de aluno );
writeln;
for J := 1 to 8 do
begin
write('Informe nome do ', J:2,'o. aluno ...: ');
readln(ALUNO[J].NOME);
writeln;
for I :=1to 4 do
begin
write('Informe a ', 1:2, 'a. nota ......:..: ');
readln(ALUNO[J].NOTA[I]);
end;
writeln;
end;
writeln;
writeln;
for J := 1 to 8 do
begin
writeln('Nome aluno: ', J:2.' ...: ', ALUNO[J].NOME);
writeln;
for I :=1to 4 do w r iteln( 'Nota'. I, ' ...........: ',
ALUNO[J].NOTA[I]:2:2);writeln;
end;
writeln('Tecle <ENTER> para encerrar: '); readln;end;
Perceba que o looping da variável J controla o número de alunos da turma, no caso, 8 e o looping da variável f controla o número de notas, até 4 por aluno. Para cada movimentação de mais um na variável J existem quatro movimentações na variável I. Em seguida feche as janelas que estejam abertas e abra uma nova janela, digite o programa anterior, gravando-o com
o nome CLASSE.
11.1 Aplicação do Tipo Registro
Para demonstrar a utilização de programas com tabelas de dados
heterogêneos, considere um programa que efetue a feitura das 4 notas bimestrais de 8 alunos, apresentando no final, os dados dos alunos classificados por nome. A ordenação será efetuada com base no nome de cada aluno e quando estiver fora da ordem, deverão os dados ser trocados
de posição.
Program LEITURA_ORDENACAO_ESCRITA;
type
BIMESTRE = array[1..4] of real;
CAD_ALUNO = record
NOME : string;
NOTA : bimestre;
end;
var
ALUNO : array[1..8] of cad_aluno;
I, J : byte;
X : cad_aluno;
begin
(*** Rotina de entrada ***)
writeln('Cadastro de aluno');
writeln;
for J := 1 to 8 do
begin
write('Informe nome do , j:2, o.aluno...: );
readln(ALUNO[J].NOME);
writeln;
for I :=1to 4 do
begin write('Informe a ', i:2, 'a. nota ..........: ');
readln(ALUNO[J].NOTA[I]); end; writeln;end;
writeln;
(*** Rotina de ordenação ***)
for I :=1to 7 do
for J := I + 1 to 8 do
if (ALUNO[I].NOME > ALUNO[J].NOME) then
begin
X := ALUNO[I];
ALUNO[I] := ALUNO[J];
ALUNO[J] := X;
end;
writeln;
writeln('Tecle <ENTER> para ver o próximo: '); readln;
end;
(*** Rotina de saída ***]
writeln;
for J :=1to 8 do
begin
writeln('Nome aluno: ', J:2,' ...: ', ALUNO[J].NOME);
writeln;
for I :=1 to 4 do
writeln('Nota', I, ' .........:: ', ALUNO[J].NOTA[1]:2:2);
writeln;
writeln('Tecle <ENTER> para encerrar: '); readln;
end.
O programa anterior apresenta a comparação efetuada entre os nomes dos alunos. Sendo o nome do aluno atual maior que o nome do próximo aluno, é efetuada a troca não só do nome, mas de todos os elementos que estão armazenados na tabela. isto é possível uma vez que a variável X é do mesmo tipo da tabela ALUNO, no caso CAD_ALUNO. Em seguida feche as janelas que estejam abertas e abra uma nova janela, digite o programa anterior, gravando-o com o nome SORTCLAS.
11.2 Exercício
Considerando o cadastro de uma agenda de endereços, nomes e telefones, defina a estrutura de registro apropriada e construa um programa que através de um menu de seleção, esteja capacitado a efetuar:
- o cadastro das informações e sua classificação
- a pesquisa dos nomes
- alterar registro cadastrado com erro (pesquisar por nome)
- remover um determinado registro (pesquisar por nome)
Cada uma das operações acima deverá ser controlada dentro de um
if...then. Não se esqueça de deixar uma opção reservada para a saída do usuário do sistema.
ANEXO:
Tabela de cores / código no Turbo Pascal:
Dark Colors Foreground & Background
Black 0
Blue 1
Green 2
Cyan 3
Red 4
MAgente 5
Brow 6
LighGray 7
Light Colors Foregorund
Dark Gray 8
Light Blue 9
Light Green 10
Light Cyan 11
Light Red 12
Light Magenta 13
Yellow 14
White 15
Obs.: Para o texto piscar (blinking) deve ser utilizado o comando Blink ou código 128.
Módulo III
XII MODULARIZAÇÃO (Utilização De Sub-Rotinas)
A partir deste módulo, será estudada a aplicação de sub-rotinas, onde teremos contato com o conceito da criação estruturada de programas (modularização) utilizando a linguagem Pascal. Esta técnica de programação é das mais utilizadas, considerada como vantajosa no desenvolvimento de grandes programas.
12.1 As Sub-rotinas
No geral, problemas complexos exigem algoritmos complexos. Mas sempre é possível dividir um problema grande em problemas menores. Desta forma, cada parte menor tem um algoritmo mais simples, e é este trecho menor que é chamado de sub-rotina. Quando uma sub-rotina é chamada por um programa principal, ela é executada e ao seu término, o controle de processamento retorna automaticamente para a primeira linha de instrução após a linha que efetuou a sua chamada.
12.2 Tipos de Sub-rotinas
A estrutura da linguagem Pascal permite a utilização de dois tipos de rotinas definidas pelo programador, sendo Procedure (procedimento) e Function (função). Uma Procedure ou Function é, na verdade, um bloco de programa, contendo inicio e fim, identificado por um nome, através do qual será referenciado em qualquer parte do programa principal ou do programa que chamou a rotina. A diferença entre os dois tipos de sub-rotinas está no fato de uma Procedure poder ou não retornar um valor após seu processamento, enquanto uma Function sempre irá retornar um valor após seu processamento. São exatamente estes dois tipos de sub-rotinas que serão estudados nos próximos capítulos.
Além das rotinas definidas pelo programador, existe na linguagem Turbo Pascal, um conjunto de rotinas embutidas, ou seja, fornecidas pela Borland. Este tipo de rotina embutida é conhecido pelo nome de unidade, em inglês unit, e será apresentado de forma básica a seguir:
12.3 Utilização de Units
O objetivo deste tópico é apresentar de forma básica a utilização das units embutidas no Turbo Pascal.
As Units são um conjunto de rotinas prontas para serem usadas pelo programador. O conceito de unidades foi incorporado ao Turbo Pascal a partir da versão 4. Uma Unit é na realidade uma biblioteca de funções e procedimentos, a qual também pode ser criada pelo próprio programador. Abaixo, são apresentadas as unidades do Turbo Pascal e sua rápida descrição:
CRT: Esta unidade é a mais utilizada na programação do Turbo Pascal. Por esta razão, ela possui a maior parte das rotinas e variáveis de som, controle de vídeo e teclado.
DOS: Esta unidade possui as rotinas que envolvem a utilização operacional, na maior parte das vezes permitindo controle de baixo nível.
GRAPH: Esta unidade possui rotinas destinadas à manipulação da capacidade gráfica de um PC.
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, desta forma, 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. Desta forma sua sintaxe corresponde a:
uses <unidade> ; onde unidade é uma das unidades citadas acima.
Para exemplificar o uso de uma unidade, tomemos como necessidade o fato de limpar a tela do computador quando da execução de um programa, ou mesmo posicionar as mensagens em um determinado ponto da tela. Você deve ter percebido que todos os programas criados até este momento apresentam as mensagens uma embaixo da outra e não fazem a limpeza da tela (com exceção do último programa do módulo I: Program MEscolha).
Para fazer uso do recurso para limpar tela e posicionar mensagens, será usada a principal e mais utilizada unidade do Turbo Pascal, a Crt. Para tanto, feche todas as janelas abertas e carregue para a memória o programa LISTA_ NOME_ORDENADA, criado na Pg. 8 do Módulo II , como apresentado a seguir:
program LISTA_NOME_ORDENADA;
var
NOME : array[1..10] of string;
I, J : integer;
x: string;
(*** Rotina de entrada de dados ***)
begin
write1n ('Listagem de nomes');
writeln;
for I := 1 to 10 do
begin
write('Digite o ', I:2 ,'o. nome: '): readln(NOME[I]);
end;
(*** Rotina de processamento de ordenação ***)
for I :=1 to 9 do
for J := I + 1 to 10 do
if (NOME[I] > NOME[J]) then
begin
X := NOME[I];
NOME[I] := NOME[J];
NOME[J] := X;
end;
(*** Rotina de saída com dados ordenados ***)
writeln;
for I := 1 to 10 do
writeln ('Nome: ' , I:2, , NOME[I];
writeln;
writeln ('Tecle <ENTER> para encerrar: '): readln;
end.
Para se fazer uso de uma unidade do Turbo Pascal, será definida uma regra.
Após a citação da instrução uses, a unidade em uso será escrita neste livro com o primeiro caractere em maiúsculo e os demais em minúsculo, ou seja, uses Crt seguida de um ponto-e-vírgula. No caso de ser utilizada mais de uma unidade, estas deverão ser separadas uma da outra com uma virgula, da mesma maneira que as variáveis são definidas numa mesma linha. A unidade CRT irá possibilitar neste momento, fazer uso de três recursos diferentes de controle para o programa: limpeza de tela, posicionamento de mensagem e interrupção do processamento de um programa, aguardando
que seja pressionada qualquer tecla para o programa continuar. Assim sendo, observe as novas mudanças no programa a seguir:
program LISTA_NOME_ORDENADA;
uses CRT;
var
NOME : array[1..10] of string;
I, J : integer;
x: string;
TECLA: char;
(*** Rotina de entrada de dados ***)
begin
clrscr;
gotoxy (31,2); writeln ( Listagem de nomes );
writeln;
for I := 1 to 10 do
begin
write ('Digite o ', I:2 ,'o. nome: '): readln(NOME[I]);
end;
gotoxy (23,24); writeln ('Tecle algo para ver lista ordenada');
TECLA := Readkey;
(*** Rotina de processamento de ordenação ***)
for I :=1 to 9 do
for J := I + 1 to 10 do
if (NOME[I] > NOME[J]) then
begin
X := NOME[I];
NOME[I] := NOME[J];
NOME[J] := X;
end;
(*** Rotina de saída com dados ordenados ***)
clrscr;
gotoxy (31, 2); writeln ('Listagem ordenada');
writeln ;
for I := 1 to 10 do
writeln('Nome: ' , I:2, , NOME[I];
gotoxy (22,24);
writeln('Tecle algo para encerrar o programa ! '):
TECLA := Readkey;
end.
Após a alteração do programa efetue a sua gravação com um outro nome. Para tanto execute o comando File/Save as. Em seguida execute o programa e observe que primeiro a tela é limpa. Em seguida a mensagem 'Listagem de nomes' é apresentada e posicionada no meio da tela, e é solicitada a digitação dos nomes. Ao fim de dez nomes é= apresentada no meio da tela na parte inferior a mensagem 'Tecle algo para ver lista ordenada'. Ao ser pressionada qualquer tecla, é efetuada uma nova limpeza de tela, a mensagem 'Listagem ordenada' é apresentada com todos os nomes listados e na parte inferior da tela ao centro, a mensagem 'Tecle alga para encerrar o programa'.
Observe também a inclusão de uma nova variável TECLA do tipo char, que é similar ao tipo string, porém aceita apenas um caractere.
que as três somente serão executadas se antes da instrução var estiver citada a instrução uses com a referida unidade. Caso não seja indicada a unidade a ser usada, qualquer rotina a ela pertencente gerará um erro na execução do programa. No exemplo apresentado, foram utilizados dois procedimentos clrscr (apresentado no módulo 1) e gotoxy e uma função Readkey descritos a seguir:
GOTOXY(coluna,linha) Este procedimento permite posicionar o cursor
em um determinado ponto da tela. Para utilizá-lo é necessário informar dois parâmetros: o primeiro representa o da coluna que deverá ser um numérico inteiro positivo entre 1 e 80, o segundo parâmetro representa o número linha que deverá ser um valor numérico inteiro positivo entre 1 e 25.
Readkey Esta é uma função que permite retornar o valor da tecla
acionada, sendo este tipo caractere. Quando utilizada em um programa, esta função faz a leitura um caractere. Por esta razão não necessita ser usada a tecla <ENTER> para confirmar a entrada da informação.
12.4 Utilização de Procedures
Tendo uma noção de como utilizar as unidades padrão do Turbo Pascal, você aprenderá em seguida a criar as próprias sub-rotinas do tipo Procedure, que será tratada com os mesmos cuidados de programação já estudados e aplicados. Sua sintaxe é definida como:
Procedure <nome> [(parâmetros)]
var
<variáveis>
begin
<instruções>
end;
onde:
<nome> - o nome atribuído ao procedimento;
<parâmetro> - uma informação opcional (será estudada mais á frente);
Os demais detalhes (var, begin e end) de uma sub-rotina do tipo
Procedure já são conhecidos e estudados. A melhor maneira de se entender como trabalhar com este conceito é fazer a sua aplicação em um problema mais complexo.
12.4.1 . Aplicação de Procedure em um Programa
Desenvolver um programa calculadora que apresente um menu de seleções no programa principal. Este menu deverá dar ao usuário a possibilidade de escolher uma entre quatro operações aritméticas. Escolhida a opção desejada, deverá ser solicitada a entrada de dois números, e processada a operação, deverá ser exibido o resultado.
Algoritmo
Note que este programa deverá ser um conjunto de cinco rotinas sendo uma principal e 4 secundárias. A rotina principal efetuará o controle sobre as quatro rotinas secundárias, que por sua vez efetuarão o pedido de leitura de dois valores, farão a operação e apresentarão o resultado obtido. Tendo-se uma idéia da estrutura geral do programa, será escrito em separado cada algoritmo com os seus detalhes de operação. Primeiro o programa principal e depois as outras rotinas.
Programa Principal
1. Apresentar um menu de seleção com cinco opções:
a. Adição
b. Subtração
c. Multiplicação
d. Divisão
e. Fim de Programa
2. Ao ser selecionado um valor, a rotina correspondente deverá ser executada;
3. Ao se escolher o valor 5, o programa deverá ser encerrado.
Rotina 1 - Adição
1. Ler dois valores, no caso variáveis A e B;
2. Efetuar a soma das variáveis A e B, implicando o seu resultado na variável X;
3. Apresentar o valor da variável X;
4. Voltar ao programa principal.
Rotina 2 - Subtração
1. Ler dois valores, no caso variáveis A e B;
2. Efetuar a subtração das variáveis A e B, implicando o seu resultado na
variável X;
3. Apresentar o valor da variável X;
4. Voltar ao programa principal.
Rotina 3 - Multiplicação
1. Ler dois valores, no caso variáveis A e B;
2. Efetuar a multiplicação das variáveis A e B, implicando o seu resultado na
variável
X;
3. Apresentar o valor da variável X;
4. Voltar ao programa principal.
Rotina 4 - Divisão
1. Ler dois valores, no caso variáveis A e B;
2. Efetuar a divisão das variáveis A e B, implicando o seu resultado na variável X;
3. Apresentar o valor da variável X;
4. Voltar ao programa principal.
Observe que em cada rotina estarão sendo utilizadas as mesmas variáveis, porém elas não serão executadas ao mesmo tempo para todas as operações.
Serão utilizadas em separado e somente para a rotina escolhida.
Programa em Pascal
A linguagem Pascal exige que as sub-rotinas sejam definidas à frente do programa principal ou rotina chamadora. No tocante à definição do nome de um procedimento, será adotado o mesmo critério para a definição do nome de um programa. Quanto á chamada da rotina, esta será sempre escrita com o primeiro caractere em maiúsculo e os demais minúsculos. Caso o nome seja uma contração de duas palavras, poderá ser escrito com caracteres maiúsculos no meio do nome, por exemplo: ROT_ADICAO poderá ser indicado como Rot_Adicao.
program CALCULADORA;
uses Crt;
var
OPCAO : char;
{*** Sub-rotinas de cálculos ***}
procedure ROT_ADICAO;
var
X, A, B : real;
TECLA: char;
begin
clrscr;
gotoxy (32, 1); write ('Rotina de Adição');
gotoxy ( 5, 6); write ('Entre um valor para A: '); readln (A);
gotoxy ( 5, 7); write ('Entre um valor para B: '); readln (B);
X := A + B;
gotoxy ( 5,10); write ('o resultado equivale a: ', X:4:2);
gotoxy (25,24); writeln ('Tecle algo para voltar ao menu');
TECLA := Readkey ;
end;
procedure ROT_SUBTRACAO;
var
X, A, B : real;
TECLA : char;
begin
clrscr;
gotoxy(30, 1); write ('Rotina de Subtração');
gotoxy( 5, 6); write ('Entre um valor para A: ' ); readln (A);
gotoxy( 5, 7); write ('Entre um valor para B: ' ); readln (B);
X := A - B;
gotoxy( 5,10); write ('o resultado equivale a: ', X:4:2);
gotoxy(25,24); writeln ('Tecle algo para voltar ao menu');
TECLA := Readkey ;
end;
Procedure ROT_MULTIPLICACAO;
var
X, A, B : real;
TECLA : char;
begin
clrscr;
gotoxy(28, 1); write ('Rotina de Multiplicação');
gotoxy ( 5, 6); write ('Entre um valor para A: '); readln (A);
gotoxy 5, 7); write ('Entre um valor para B: '); readln (B);
X := A * B;
gotoxy ( 5,10); write ('O resultado equivale a: ', X:4:2);
gotoxy (25,24); writeln ('Tec1e algo para voltar ao menu');
TECLA := Readkey ;
end;
Procedure ROT_DIVISAO;
var
X, A, B : real;
TECLA : char;
Begin
clrscr;
gotoxy(32, 1); write ('Rotina de Divisão');
gotoxy( 5, 6); write ('Entre um valor para A: ' ); readln (A);
gotoxy( 5, 7); write ('Entre um valor para B: ' ); readln (B);
X := A / B;
gotoxy( 5,10); write('o resultado equivale a: ', X:4:2);
gotoxy(25,24); writeln('Tecle algo para voltar ao menu');
TECLA := Readkey ;
end;
{*** Programa Principal ***}
begin
OPCAO := '0';
while (OPCAO <> '5') do
begin
clrscr;
gotoxy(33, 1); write ('Menu Principal');
gotoxy(28, 6); write ('1 ............................... Soma');
gotoxy(28, 8); write ('2 ........................ Subtração');
gotoxy(28,10); write ('3 ................. Multiplicação');
gotoxy(28,12); write ('4 ........................... Divisão');
gotoxy(28,14); write ('5 ............ Fim de Programa');
gotoxy(28,18); write(' Escolha uma opção ............: ');
readln(OPCAO);
if (OPCAO = '1') then
Rot_Adicao;
if (OPCAO = '2') then
Rot_Subtracao;
if (OPCAO ='3') then
Rot_Muitiplicacao;
if (OPCAO = '4'l then
Rot_Divisao;
end.
Ou então, usando a estrutura CASE o programa principal ficaria escrito
desta forma:
{*** Programa Principal ***}
begin
OPCAO := '0';
while (OPCAO <> '5') do
begin
clrscr;
gotoxy(33, 1); write ('Menu Principal');
gotoxy(28, 6); write ('1 ............................... Soma');
gotoxy(28, 8); write ('2 ........................ Subtração');
gotoxy(28,10); write ('3 ................. Multiplicação');
gotoxy(28,12); write ('4 ........................... Divisão');
gotoxy(28,14); write ('5 ............ Fim de Programa');
gotoxy(28,18); write(' Escolha uma opção ............: ');
readln(OPCAO);
if (OPCAO <> '5') then
case OPCAO of
'1' : Rot_Adicao;
'2' : Rot_Subtracao;
'3' : Rot_Multiplicacao;
'4' : Rot_Divisao;
Else
gotoxy(27,24);
writeln ('opção invalida - Tecle algo');
OPCAO := Readkey ;
end;
end;
end.
Observe que antes da utilização da instrução case...of, está sendo
verificado com a instrução if...then se o valor da opção informado é
realmente diferente de 5. Sendo, será verificado se é 1, 2, 3 ou 4, não sendo nenhum dos valores válidos, a instrução else de case...of executará a apresentação da mensagem 'Opção invalida - Tecle algo', informando que a tentativa foi inválida.
12.5 Utilização de Function
Uma Function, assim como uma Procedure, é um bloco de programa, ao qual são válidas todas as regras já estudadas tanto de programação como de definição de uma sub-rotina, seus parâmetros e também da utilização de variáveis globais e locais. Sua diferença em relação a uma Procedure está no fato de retornar sempre um valor. O valor de uma função é retornado no próprio nome da função. Quando se diz valor, devem ser levados em consideração os valores numéricos, lógicos ou literais (string ou caracteres). Uma Function possui a seguinte sintaxe:
function <nome> [(parâmetros)] : <tipo>;
var
<variáveis>
begin
<instruções>
end;
onde:
<nome> - o nome atribuído á função;
<parâmetro> - uma informação opcional;
<tipo> - o tipo de dado a ser retornado pela função.
Os demais detalhes (var, begin e end) de uma sub-rotina do tipo Function já são conhecidos e estudados.
12.5.1 - Aplicação de Function em um Programa
As sub-rotinas do tipo Procedure através da passagem de parâmetro por referência permitem que sejam retornados valores á rotina chamadora, mas esta tarefa poderá ser simplificada com a utilização de sub-rotinas do tipo Function. Para exemplificar, considere a Procedure a seguir, usada para calcular a fatorial de um número qualquer. Observe que é necessário fornecer dois valores para os parâmetros N e FAT sendo N a entrada do valor a ser calculado (passagem de parâmet ro por valor) e FAT o valor resultado obtido como retorno (passagem de parâmetro por referência).
procedure FATORIAL (N : integer; var FAT: integer);
var
I : integer;
begin
FAT := 1;
for I := 1 to N do
FAT := FAT * I;
end;
Se a sub-rotina para o cálculo da fatorial de um número qualquer for escrita
como uma função, será necessária apenas a informação de um parâmetro,
no caso o valor do parâmetro N do qual deverá ser calculada a fatorial, pois
o resultado do cálculo será atribuído ao próprio nome da função. Veja a
seguir, como isto é feito:
function FATORIAL (N : integer) : integer;
var
I, FAT : inteiro
begin
FAT := 1;
for I := 1 to N do
FAT := FAT * I;
FATORIAL := FAT;
end;
Observe que o nome da função, no caso FATORIAL, é também o nome da variável interna que recebe o valor acumulado da variável FAT caso o número fornecido para o parâmetro N não seja zero. Pois se for zero, o valor da função FATORIAL é igualado a 1, que é o valor da fatorial de zero. Desta forma, uma função retoma um valor pelo seu próprio nome, pois é este nome, que é usado dentro do corpo da função para a recepção do valor calculado.
Outro detalhe a ser considerado numa função além do seu nome ser usado como variável de retomo, é o fato da definição do seu tipo, no caso, function FATORIAL (N : integer) : integer;, onde N está sendo
considerado como inteiro dentro dos parênteses. Isto significa que o valor fornecido pelo parâmetro N é inteiro, porém existe uma segunda definição de tipo fora dos parênteses, que é o tipo de retomo da função. Desta forma entra um valor inteiro com o parâmetro N e sai um valor inteiro para FATORIAL. Observe que poderá ser entrado um parâmetro de um tipo e retomá-lo como um tipo diferente do entrado.
Observe que na função, foi utilizada a passagem de parâmet ro por valor, no caso a variável N, pois o retomo está sendo efetuado na própria sub-rotina e não em uma variável como foi o caso da sub-rotina de procedimento equivalente.
Vale salientar que uma função também poderá trabalhar com passagem de parâmetros por valor ou referência. Vai depender muito do problema computacional a ser resolvido. Se for necessário somente informar um valor e este gerar e retomar um resultado para função (sendo esta a forma mais comum), então utiliza-se a passagem de parâmet ro por valor. Mas poderá ocorrer em alguns casos, além de se obter o retomo da função, obter-se o valor alterado do parâmetro. Neste caso, a passagem do parâmetro deverá
ser feita por referência.
Para demonstrar a utilização de programas com sub-rotinas do tipo
Function, considere os seguintes exemplos:
1º Exemplo
Desenvolver um programa que faça uso de uma sub-rotina de função que retorne o valor da adição de dois valores fornecidos como parâmetros.
Algoritmo
O problema proposto é bem simples, pois a função deve receber dois valores e retornar o resultado da adição dos mesmos, desta forma o programa principal pedirá os valores e chamará a função para ter o retorno do cálculo.
Assim sendo:
Programa Principal
1. Pedir a leitura de dois valores, no caso variáveis NUM1 e NUM2;
2. Chamar a função de soma, fornecendo como parâmetros as duas variáveis;
3. Apresentar o resultado retornado.
Sub- rotina para Adição
1. Receber dois valores fornecidos através de parâmetros;
2. Efetuar o cálculo entre os dois valores, no caso a adição;
3. Retornar para a função o resultado obtido.
Programa em Pascal
O programa principal efetua a leitura das variáveis NUM1 e NUM2,
transferindo os seus valores para os parâmetros formais A e B do tipo real, que assumem seus respectivos valores tornando-se parâmetros reais. Em seguida é processada a adição dos dois valores e o resultado é implicado na variável ADICAO (nome da função) que efetua o retorno á função, a qual também é do tipo real.
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 1º valor: '); readln (NUM1);
write ('Informe o 2º valor: '); readln (NUM2);
writeln ;
writeln ('o resultado da adição = ', Adicao (NUM1, NUM2):2:2);
writeln ('Tecle <ENTER> para encerrar o programa'); readln ;
end.
2º Exemplo
Para este exemplo deverá ser criado um programa que faça uso de uma sub-rotina de função que possibilite comparar dois valores fornecidos, retornando se os valores fornecidos são iguais ou diferentes.
Algoritmo
Como o primeiro, este problema também é simples, pois a função em
questão recebe dois valores, compara-os e retorna se são iguais ou
diferentes. Desta forma, o programa principal pedirá os valores e chamará a função para ter o retorno da condição de igualdade.
Programa Principal
1. Pedir a leitura de dois valores, no caso variáveis NUM1 e NUM2;
2. Chamar a função de comparação de igualdade, fornecendo os dois valores;
3. Apresentar o resultado retornado.
Sub- rotina para Comparação
1. Receber dois valores fornecidos através de parâmetros;
2. Efetuar a comparação entre os valores para determinar se são iguais ou diferentes;
3. Retornar para a função o resultado obtido.
Observe que este tipo de problema já indica a entrada de parâmetros de um tipo e o retorno da resposta da função de outro tipo.
Programa em Pascal
O programa principal efetua a leitura das variáveis NUM1 e NUM2,
transferindo os seus valores para os parâmetros formais A e B do tipo real, que assumem seus respectivos valores tornando-se parâmetros reais. Em seguida é processada a comparação dos dois valores e implicada á função o retorno da condição, desta forma o retorno desta função deverá ser lógico.
program COMPARACAO;
uses Crt;
function COMPARA(A, B : real) : boolean;
begin
COMPARA := A = B;
end;
var
NUM1, NUM2 : real;
begin
clrscr;
write ('Informe o 1º valor:' ); readln (NUM1);
write ('Informe o 2º valor: '); readln (NUM2);
writeln ;
if (Compara(NUM1, NUM2)) then
writeln ('Os valores fornecidos são iguais')
else
writeln ('Os valores fornecidos são diferentes');
writeln ('Tecle <ENTER> para encerrar o programa'); readln ;
end.
Módulo IV
XIII ARQUIVOS
Anteriormente, foi estudado o conceito de tabelas em memória através da utilização de matrizes. Depois foi estudado o conceito de utilização do tipo definido: registro, formando a base para a utilização de um arquivo, pois um arquivo é uma tabela de informações gravada em um meio físico (disquetes, winchesters, fitas magnéticas entre outros), enquanto as matrizes são tabelas manipuladas na memória RAM (Random Access Memory (Memória de acesso randômico). Este tipo de memória mantém as informações armazenadas enquanto o computador se mantém ligado). As matrizes são manipuladas através de um índice de controle enquanto os arquivos são manipulados por um ponteiro de registro (Um arquivo é um conjunto de registros (que poderá ser apenas um registro), que por sua vez é um conjunto de campos, sendo cada campo o conjunto de informações nele contido segundo seu tipo (caractere ou numérico). As informações NOME, ENDEREÇO, TELEFONE, IDADE são exemplos de campos. Uma ficha que contenha os campos para preenchimento será o registro ).
A principal vantagem na utilização de um arquivo está no fato de as informações armazenadas poderem ser utilizadas a qualquer momento. Outra vantagem encontrada na utilização de arquivos é o fato de poder armazenar um número maior de registros do que em uma tabela em memória, estando apenas limitado ao tamanho do meio físico utilizado para a sua gravação.
13.1 . Definição de um Arquivo
A manipulação de um arquivo em Pascal ocorrerá 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 objetivo a finalidade de fazer a comunicação entre a memória principal (RAM) e memória secundária (meios magnéticos). Assim sendo, este tipo deverá ser definido com a utilização da seguinte sintaxe em Pascal:
type
<arquivo> = [text] [file] [of <tipo>] ];
var
<variável> ; <arquivo>;
ou
var
<variável> : [ 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.);
<variável> - a variável que será usada para representar o arquivo.
13.2 - Operações em Arquivo
Um arquivo tem a capacidade de executar algumas operações, tais como:
abertura, leitura ou escrita e fechamento de um arquivo, sendo que estas operações serão conseguidas na linguagem Pascal com a utilização de algumas instruções apropriadas: Assign, rewrite, reset, write (writeln), read (readln) e Close, que poderão ser utilizadas em qualquer tipo de arquivo:
Assign
Esta instrução tem por finalidade associar um nome lógico de arquivo ao arquivo físico. O parâmetro <variável> é a indicação da variável arquivo, e <arquivo> é nome do arquivo a ser manipulado, de acordo com a seguinte sintaxe:
Assign (<variável>,<arquivo>)
Rewrite
Esta instrução tem por finalidade criar um arquivo para uso, utilizando o nome associado ao parâmetro ,variável.. Caso o arquivo já exista, esta instrução o apagará para cria-lo novamente, de acordo com a seguinte sintaxe:
Rewrite (<variável>)
Reset
Esta instrução tem por finalidade abrir um arquivo existente, colocando-o disponível para leitura e escrita, utilizando o nome associado ao parâmetro <variável>, de acordo com a seguinte sintaxe:
Reset (<variável>)
Write
Esta instrução tem por finalidade escrever a informação <dado> no arquivo indicado pelo parâmetro <variável>, de acordo com a seguinte sintaxe:
Write (<variável>,<dado>)
Read
Esta instrução tem por finalidade ler a informação <dado> no arquivo
indicado pelo parâmetro <variável>, de acordo com a seguinte sintaxe:
Read (<variável>,<dado>)
Close
Esta instrução tem por finalidade fechar um arquivo em uso dentro de
programa. Nenhum programa deve ser encerrado sem fechar os arquivos abertos. De acordo com a seguinte sintaxe:
Close (<variável>)
Obs. Os programas de manipulação de arquivos executarão sempre uma de duas operações: abertura, escrita e fechamento ou abertura, leitura e fechamento, desde que o arquivo exista.
13.3 - Formas de Acesso em um Arquivo
Os arquivos criados em meios magnéticos poderão ser acessados para leitura e escrita na forma seqüencial, direta ou indexada.
13.3.1 - Arquivo de Acesso Seqüencial
O acesso seqüencial ocorre quando o processo de gravação e leitura é feito de forma continua, um após o outro. Desta forma, para se gravar um novo registro é necessário percorrer todo o arquivo a partir do primeiro registro, registro a registro, até localizar a primeira posição vazia após o último registro. O processo de leitura também ocorre de forma seqüencial. Se o registro a ser lido é o último, primeiro será necessário ler todos os registros que o antecedem.
13.3.2 - Arquivo de Acesso Direto
O acesso direto (conhecido também por acesso randômico ) ocorre através de um campo chave (O termo chave é utilizado para estabelecer o campo de um regist ro que será ut ilizado na processo de localização de todo um registro dent ro de um arquivo. Desta forma, será possível acessar um
determinada registro diretamente, sem nos preocuparmos com os registros que o antecedem. Por exemplo, em um cadast ro de funcionários, poderá ser
ut ilizado o campo reservado para a mat ricula, como sendo a chave para a
manipulação do mesmo.) previamente definido. Desta forma, passa-se a
possuir um vinculo 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 escrita poderá ser feito de forma instantânea.
Isto implica no fato de que os registros de um arquivo direto possuem um lugar (chave) previamente "reservado" para serem armazenados.
13.3.3 - Arquivo de Acesso Indexado
O acesso indexado ocorre quando se acessa de forma direta um arquivo seqüencial. Na sua maioria, todo o 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.
Para se trabalhar com esta técnica, basta criar um arquivo direto que será o índice de consulta do arquivo seqüencial, passando este a ser o arquivo indexado. Assim sendo, existirão dois arquivos: o arquivo índice (arquivo direto) e o arquivo indexado (arquivo seqüencial). Os acessos serão feitos como em um livro, primeiro se consulta o arquivo índice, o qual possui a chave de pesquisa, no caso seria o número da página, depois basta se posicionar de forma direta na página (no caso de um livro) identificada no indice, ou seja, no registro do arquivo indexado.
13.4 - Arquivos do Tipo Texto
Iniciaremos o nosso estudo prático com o tipo de arquivo mais simples utilizado em Pascal, o tipo texto, que permite possuir armazenados registros com tamanhos diferentes (o que não ocorre com os outros tipos de arquivo).
Se você direcionar o prompt do DOS para o diretório TP terá como exemplo de um arquivo texto o arquivo FILELIST.DOC que poderá ser visualizado com o comando DOS: type filelist.doc.
Os arquivos do tipo texto estão capacitados a armazenar palavras, frases e também dados numéricos. Os números, entretanto, serão armazenados como um caractere do tipo alfanumérico. Ao serem lidos de um arquivo e passados para a memória, os dados numéricos são convertidos para o seu formato original.
13.4.1 - Criando um Arquivo
Antes de iniciar qualquer operação com arquivo, é necessário criá-lo. Para tanto, digite o programa abaixo e grave-o com o nome ARQTXT01.
program CRIA_ARQUIVO_TEXTO;
var
ARQUIVO_TXT : text;
begin
assign (ARQUIVO_TXT, 'ARQTXT.XXX' );
rewrite (ARQUIVO_TXT);
close (ARQUIVO_TXT);
end.
Após rodar o programa com o comando Run/Run, execute o comando
File/DOS Shell para visualizar o prompt do DOS. Em seguida execute o
comando DOS: dir arqtxt01.xxx, você verá a apresentação do arquivo
arqtxt01.xxx criado com zero bytes. Para voltar ao Turbo Pascal execute o
comando DOS: exit.
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.
Em seguida é utilizada a instrução assign (ARQUIVO_TXT, 'ARQTXT.XXX' ); , que efetua a associação do nome do arquivo (ARQTXT.XXX) á variável de controle ARQUIVO_TXT a qual será utilizada em todas as operações do programa para fazer referência ao arquivo em uso. Depois é utilizada a instrução rewrite (ARQUIVO_TXT);, que cria o arquivo ARQTXT.XXX, mantendo-o aberto. Por fim é utilizada a instrução close (ARQUIVO_TXT);, que efetua o fechamento do arquivo criado.
13.4.2 - Gravando Informações em um Arquivo
Tendo sido o arquivo criado este poderá ser agora utilizado para a gravação das informações que irá guardar. Digite o programa abaixo e grave-o com o nome ARQTXT02.
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.
Após rodar o programa, execute novamente o comando File/DOS Shell para visualizar o prompt do DOS. Peça o comando DOS: dir *.xxx, você verá a apresentação do arquivo arqtxt01.xxx com um número de bytes. Não se esqueça de voltar para o Turbo Pascal.
O programa acima estabelece uma variável MENSAGEM do tipo string com a capacidade de armazenar até 50 caracteres.
Para a variável ARQUIVO_TXT o identificador text, tem por finalidade definir para a variável o tipo de arquivo texto. Em seguida é utilizada novamente a instrução assign (ARQUIVO_TXT 'ARQTXT.XXX');. Depois é utilizada a instrução append (ARQUIVO_TXT);, que abre o arquivo ARQTXT.XXX para a inclusão de um dado, posicionando o
ponteiro de controle de registros sempre ao final do arquivo, ou seja, se o arquivo já possuir algum conteúdo, o próximo será sempre colocado ao final do último cadastrado anteriormente.
A instrução readln solicita a entrada de um dado, depois a instrução
writeln (ARQUIVO_TXT MENSAGEM); faz a gravação no arquivo representado pela variável de controle ARQUIVO_TXT do conteúdo
armazenado na variável MENSAGEM. Observe que a instrução write tinha sido usada até este momento para escrever dados na tela, e agora está sendo utilizada para escrever uma informação no arquivo em uso. Ao final, o arquivo é fechado.
Quando a instrução write ou writeln é utilizada para escrever um dado em um arquivo, esta não apresenta o dado no vídeo, ficando disponível apenas para a operação de escrita do arquivo.
13.4.3 . Lendo Informações de um Arquivo
A seguir, é apresento um programa que irá efetuar a leitura de um arquivo texto, mostrando no vídeo a informação armazenada com o programa anterior. Digite o programa abaixo e grave-o com o nome ARQTXT03.
program LE_ARQUIVO_TEXTO;
var
ARQUIVO_TXT : text;
MENSAGEM : string[50];
begin
assign (ARQUIVO_TXT, 'ARQTXT.XXX' );
reset (ARQUIVO_TXT);
readln (ARQUIVO_TXT, MENSAGEMI );
writeln (MENSAGEM );
close (ARQUIVO_TXT );
end.
A instrução reset(ARQUIVO_TXT); faz apenas a abertura do arquivo. Não confundir com a instrução append que faz a abertura do arquivo
posicionando o ponteiro de controle sempre após a última linha existente no arquivo. Depois, a instrução readln (ARQUIVO_TXT MENSAGEM); faz a leitura do registro no arquivo, transferindo a informação lida para a variável MENSAGEM que será apresentada no vídeo pela instrução writeln
(MENSAGEM );.
13.4.4 - Utilização de Arquivos do Tipo Texto
Neste tópico, você terá contato com um exemplo de utilização de arquivo texto em um pequeno programa de agenda.
O programa de agenda proposto deverá solicitar apenas o nome e o telefone de uma pessoa. Este programa deverá ter um menu contendo quatro opções: criar arquivo, cadastrar registro, exibir registros cadastrados e finalizar o programa. Para tanto, observe o algoritmo a seguir:
Programa Principal
1. Definir as variáveis de controle e abertura do arquivo
2. Apresentar um menu de seleção com quatro opções:
a. Criar arquivo
b. Cadastrar registro
c. Exibir registros
d. Fim de Programa
3. Ao ser selecionado um valor, a rotina correspondente deverá ser
executada;
4. Ao se escolher o valor 4, encerrar o programa.
Rotina 1 - Criar arquivo
1. Executar o comando de criação de um arquivo;
2. Fechar o arquivo;
3. Voltar ao programa principal.
Rotina 2 - Cadastrar registro
1. Abrir o arquivo para cadastramento, posicionando o ponteiro após último registro;
2. Ler o nome e o telefone;
3. Escrever os dados no arquivo;
4. Fechar o arquivo;
5. Voltar ao programa principal.
Rotina 3 - Exibir registro
1. Abrir o arquivo para leitura, posicionando o ponteiro no primeiro registro;
2. Apresentar os dados do arquivo enquanto não for encontrado o último registro;
3. Fechar o arquivo;
4. Voltar ao programa principal.
Apesar de simples, o programa dará uma boa visão, pois será necessário trabalhar com alguns novos recursos. Digite o programa a seguir, e grave-o com o nome AGENDTXT.
Program AGENDATXT;
uses
Crt;
var
ARQTXT : text;
NOME : string [40];
TELEFONE : string[8];
TECLA : char;
OPCAO: char;
(*** Rotinas de Visualização ***)
Procedure CENTER ( MENSAGEM : string);
var
TAMANHO : integer;
begin
TAMANHO := 40 + length (MENSAGEM) div 2;
Writeln (MENSAGEM:TAMANHO);
end;
Procedure WRITEXY (X, Y : byte; MENSAGEM : string);
begin '
GOTOXY (X, Y); write (MENSAGEM);
end;
Procedure LINE;
var
I : byte;
begin
for I := 1 to 80 do
write (#205);
end;
(*** Rotinas de Manipulação de Arquivos ***)
Procedure ARQUIVO;
begin
clrscr;
line;
center ('Criação de Arquivo');
line;
rewrite(ARQTXT);
gotoxy ( 1,12); Center ('Arquivo foi criado');
writexy (25,24,'Tecle algo para voltar ao menu');
TECLA := Readkey;
close(ARQTXT);
end;
Procedure CADASTRA;
begin
clrscr;
line;
center ('Cadastro de Registro');
line;
append (ARQTXT);
writexy (10, 5, 'Entre com o Nome ..........: '); readln (NOME);
writexy (10, 6, 'Entre com o Telefone ......: '); readln (TELEFONE);
writeln (ARQTXT, NOME);
writeln (ARQTXT, TELEFONE);
writexy (25,24,'Tecle algo para voltar ao menu');
TECLA := Readkey;
close (ARQTXT);
end;
procedure EXIBIR;
var
LINHA : byte;
begin
clrscr;
line;
center ('Apresentação de Registros');
line;
LINHA := 5;
Reset (ARQTXT);
while not eof (ARQTXT) do begin
readln (ARQTXT, NOME);
readln (ARQTXT, TELEFONE);
gotoxy ( 5,LINHA); write (NOME);
gotoxy (50,LINHA); write (TELEFONE);
LINHA := LINHA + 1;
end;
writexy (25,24,'Tecle algo para voltar ao menu' );
TECLA := Readkey;
Close (ARQTXT);
end;
(*** Programa Principal ***)
begin
OPCAO := '0';
Assign (ARQTXT, 'AGENDTXT.DAT');
while (OPCAO <> '4') do
begin
clrscr;
line;
center ('menu Principal');
line;
gotoxy (28, 6); write ('l ................... criar arquivo');
gotoxy (28, 8); write ('2 ........................ cadastrar');
gotoxy (28,10); write ('3 ............. Exibir registros');
gotoxy (28,12); write ('4 .......... Fim de Programa');
gotoxy (28,16); write ('Escolha uma opção ......: ');
readln (OPCAO);
if (OPCAO <> '4' ) then
case OPCAO of
'1' : Arquivo;
'2' : Cadastra;
'3' : Exibir;
else
gotoxy (27,24); writeln ('Opção Invalida - Tecle algo');
opcao := Readkey ;
end;
end;
end.
Ao fazer uso do programa, procure cadastrar poucos registros (ideal em torno de 15), pois não está sendo previsto exibir uma quantidade muito grande de dados na tela. Perceba que o programa principal associa á variável ARQTXT o arquivo AGENDTXT.DAT, que será usado nas rotinas de manipulação.
Na rotina EXIBIR, está sendo usada uma nova instrução, eof( ) , sendo esta uma função que consegue identificar o final do arquivo (eof - end of file).
Perceba que serão apresentados na tela os registros enquanto não for o fim de arquivo. Um arquivo, quando é fechado, grava na última posição um caractere de controle que pode ser identificado pela função eof(). No restante, os demais recursos do programa já são conhecidos. Lembre-se ainda que a instrução reset ( ) faz a abertura do arquivo, colocando o ponteiro de registro posicionado na primeira linha de texto. Procure utilizar o programa acima fazendo primeiro a criação do arquivo, execute alguns cadastros e encerre o programa. Saia do Turbo Pascal.
Depois volte ao Turbo Pascal, chame o programa e peça para visualizar os
dados cadastrados. Cadastre mais alguns e visualize novamente.Preste atenção ainda em um detalhe: o programa utilizado parece manipular uma matriz. Depois de cadastrar alguns registros, se for solicitado efetuar a criação do arquivo novamente, este será recriado, destruindo os dados já cadastrados.
13.5 - Arquivos com Tipo Definido
Os arquivos com tipo definido caracterizam-se por serem do tipo binário, diferente dos arquivos do tipo texto. Este arquivo permite armazenar específicos, podendo ser: integer, real, record, entre outros. Um arquivo com tipo definido executa as operações de escrita e leitura mais rápido do que os arquivos textos. Os arquivos de tipo definido estão capacitados a armazenar dados na forma de registro.
13.5.1 - Criando um Arquivo
Antes de mais nada, será criado um arquivo que esteja capacitado a receber dados numéricos inteiros. Para tanto, digite o programa abaixo e grave-o com o nome ARQINT01.
program CRIA_ARQUIVO_INTEIRO;
var
ARQUIVO_INT : file of integer;
begin
Assign (ARQUIVO_INT, 'ARQINT.XXX');
Rewrite (ARQUIVO_INT);
Close (ARQUIVO_INT);
end.
Após rodar o programa, o arquivo será criado. Caso queira verificar se o arquivo foi realmente criado, saia temporariamente para o sistema operacional e execute o comando DOS: dir arqint.xxx.
O programa acima estabelece para a variável ARQUIVO_INT o identificador file of integer, que tem por finalidade definir para a variável indicada o tipo de arquivo como sendo inteiro. Todas as outras operações são semelhantes às operações usadas para se criar um arquivo texto.
13.5.2 - Gravando Informações em um Arquivo
Estando o arquivo criado, este poderá ser agora utilizado para a gravação dos dados de tipo inteiro. Digite o programa abaixo e grave-o com o nome ARQINT02.
program CADASTRA_ARQUIVO_INTEIRO;
uses Crt;
var
ARQUIVO_INT : file of integer;
NUMERO : integer;
RESF : char;
begin
assign (ARQUIVO_INT, 'ARQINT.XXX');
reset (ARQUIVO_INT);
RESP :='S';
A seguir, é apresentado um programa que irá efetuar a leitura de um
arquivo de números inteiros, mostrando no vídeo a informação armazenada
com o programa anterior. Digite o programa abaixo e grave-o com o nome
ARQINT03.
program LE_ARQUIVO_INTEIRO;
uses Crt;
var
ARQUIVO_INT : file of integer;
NUMERO : integer;
begin
clrscr;
assign (ARQUIVO_INT, 'ARQINT.XXX');
reset (ARQUIVO_INT);
while not eof (ARQUIVO_INT) do
begin
read (ARQUIVO_INT, NUMERO);
writeln (NUMERO);
end;
Close (ARQUIVO_INT);
Readln;
end.
O programa acima é basicamente o mesmo utilizado para apresentar os
dados de um arquivo do tipo texto.
Com os programas anteriores você teve um contato com o trabalho
executado com arquivos de tipo definido. Apresentamos apenas como sendo
do tipo inteiro, uma vez que para os demais tipos as operações serão
idênticas.
13.5.4 . Utilização de Arquivos com Tipo Definido
arquivos com matrizes de uma dimensão. A primeira rotina deverá solicitar a
entrada de dez valores inteiros, armazenar os valores em uma matriz para
transferi-los a um arquivo. Depois deverá ser escrita uma segunda rotina
que leia os dados do arquivo, transferindo-os para uma matriz, para então
apresentá-los.
Digite o programa a seguir, e grave-o com o nome MATINTO1. Observe que
será criado um arquivo chamado MATINT.DBP que conterá dez valores inteiros. Perceba que assim que os elementos são fornecidos para a matriz A, estes são em seguida gravados no arquivo com a instrução
write (ARQ, A[I]).
Program MATRIZ_E_ARQUIVO;
Uses Crt;
var
A : array [1..10] of integer;
I : integer;
ARQ : file of integer;
begin
assign (ARQ. 'MATINT.DBP');
rewrite (ARQ):
clrscr;
I := 1;
while (I<=10) do
begin
write ('Digite o elemento - ' , I:2, ': ' ); readln (A([I]);
write (ARQ, A[I]);
I := I + 1;
end;
Close (ARQ);
end.
Digite o programa a seguir, e grave-o com o nome MATINT02. Observe que o programa fará a abertura e a leitura do arquivo MATINT.DBP que contém dez valores inteiros. Perceba que pelo fato de saber a quantidade de registros armazenados no arquivo, a leitura está sendo feita com a instrução
while (I<= 10) do, e não com a instrução w hile not eof (ARQ) do, apesar de também poder ser utilizada.
Program ARQUIVO_E_MATRIZ;
Uses Crt;
var
A : array[1..10] of integer;
I : integer;
ARQ : file of integer;
begin
assign (ARQ, 'MATINT.DBP');
reset (ARQ);
clrscr;
I := 1;
while (I <=10) do
begin
read(ARQ, A(1]);
write ('O registro ', 1:2, ' contem o elemento: '); writeln (A[I]:2);
I := I + 1;
end;
Close (ARQ);
end.
13.6 - Arquivo com Tipo Definido de Registro
Vejamos um exemplo mais profissional com a utilização de arquivos
gerenciados pela linguagem Pascal. Para tanto, serão criadas rotinas básicas que deverão fazer o controle de um arquivo do tipo record.
13.6.1 . Arquivo de Acesso Direto
Nos exemplos de arquivos anteriormente estudados, não se levou em
consideração a forma de acesso aos arquivos (todos os exemplos foram criados baseando-se na forma de acesso seqüencial). Para o exemplo que será construído (gerenciamento de notas escolares) no final deste módulo, será utilizada a forma de acesso direta, pois este tipo de arquivo permite o acesso imediato a cada um dos seus registros, desde que se conheça previamente a posição em que estes registros estão gravados.
As operações de leitura e escrita em um arquivo de acesso seqüencial
ocorrem através do apontamento de um indicador de registro, que é
avançado a cada operação executada, do primeiro até ao último registro.
Este indicador de registro é o ponteiro do arquivo (similar ao índice de uma tabela em memória - matriz). No caso de arquivos de acesso direto, o ponteiro pode ser movimentado para qualquer posição do arquivo, através da instrução seek, já exemplificada. Desta forma, é possível se posicionar em qualquer registro do arquivo.
As operações que são executadas em um arquivo são semelhantes ás
operações executadas em matrizes, podendo ser: alteração, remoção, classificação, pesquisa binária, pesquisa seqüencial, cadastramento, entre outras. A diferença entre uma matriz e um arquivo de acesso direto é que as operações do arquivo são executadas diretamente no arquivo.
13.6.2 - Utilização de Arquivo Direto
Para este exemplo será considerado um arquivo para gerenciar o cadastro de n alunos de uma escola, que deverá possuir os campos matricula, nome e notas, conforme a seguir:
type
BIMESTRE = array[1..4] of real;
REG_ALUNO = record
FLAG: char;
MATRICULA : integer;
NOME: string[30];
NOTAS: bimestre;
end;
Perceba que na estrutura acima, existe um campo denominado FLAG com a capacidade de guardar apenas um caractere. Este campo será utilizado especialmente na operação de remoção lógica de um determinado registro, o qual guardará o caractere '*' asterisco (este procedimento não é obrigatório, sendo apenas uma definição). Desta forma, será possível detectar se algum registro foi "removido". Estando um registro removido, poder-se-á gravar um outro registro sobre o mesmo através do controle do campo FLAG. Para o programa que será construído a seguir, o campo FLAG poderá guardar um de dois valores, o asterisco "*" para remoções lógicas ou um espaço em branco " " para determinar que o registro é ativo.
Vale lembrar que o que limita o tamanho de um arquivo é o espaço de gravação do meio físico dele.
13.6.3 - Manipulação de Arquivo Direto
O programa de gerenciamento de registros de alunos deverá ao final
executar as rotinas de: cadastramento, pesquisa, remoção e alteração em um arquivo.
A rotina de pesquisa a ser utilizada será seqüencial, uma vez que o arquivo não estará ordenado. O funcionamento do processo de pesquisa em um arquivo é semelhante ao funcionamento em uma matriz, pois será necessário percorrer todo o arquivo até localizar a informação desejada, se esta existir. Vale lembrar que aqui será necessário verificar o campo FLAG para saber se a informação pesquisada não foi previamente marcada para remoção, ou seja, contenha um asterisco. Estando o campo marcado, a informação pesquisada não deverá ser apresentada, pois não mais existe.
Esta rotina será utilizada pelas rotinas de cadastramento, alteração,
remoção e consulta.
A rotina de alteração executará em primeiro lugar uma pesquisa do registro, encontrando-o deverá apresentar os dados atuais e solicitar a informação dos novos dados. Após a informação dos novos dados, grava-se novamente o registro no arquivo exatamente na mesma posição em que estavam os dados "velhos". A rotina de remoção executará o processo chamado
remoção lógica do registro. Este processo é mais rápido, pois uma vez marcado um registro no arquivo, outro poderá ser gravado sobre o mesmo.
O programa-exemplo gravará no campo FLAG um espaço em branco para o registro ativo e um asterisco quando a rotina de remoção for executada. A rotina de cadastramento antes de inserir um novo registro, deverá pesquisar o arquivo para verificar em primeiro lugar se as "novas" informações já existem, evitando assim duplicidade de registros. Não existindo, deverá ser verificado se existe algum campo FLAG marcado com um asterisco.
Existindo, deverá gravar o novo registro na posição marcada, pois o registro anterior não é mais válido. Assim sendo, estaremos aproveitando os mesmos espaços que foram inutilizados pela rotina de remoção.
A rotina de consulta fará uma pesquisa no arquivo a fim de localizar o
registro solicitado; encontrando-o, esta rotina o apresenta para visualização.
Assim como as demais esta rotina, deverá estar preparada para
desconsiderar todo o registro removido logicamente.
A seguir, o programa (simples e "cru") de gerenciamento escolar apenas com finalidade didática e não comercial:
Program GERENCIAMENTO_ESCOLAR;
USES CRT;
type
BIMESTRE = array[1..4] of real;
REG_ALUNO = record
FLAG : char;
MATRICULA : longint;
NOME : String[30];
NOTAS : bimestre;
end;
var
ALUNO : reg_aluno;
ARQALU : file of reg_aluno;
NR_MATRIC : longint;
SISTEMA : String;
RESP, TECLA : char;
I : longint;
procedure CENTER(MENSAGEM : string);
var
TAMANHO : integer;
begin
TAMANHO := 40 + length (MENSAGEM) div 2;
writeln (MENSAGEM: TAMANHO);
end;
procedure WRITEXY(X, Y : byte; MENSAGEM : string);
begin
gotoxy(X, Y); write(MENSAGEM);
end;
procedure LINE;
var
I : LONGINT;
begin
for I := 1 to 80 do
write (#205);
end;
Procedure ACESSA_ARQUIVO;
begin
assign(ARQALU, 'CADALU2.DAT');
{$I-}
reset(ARQALU);
{SI+}
if (IORESULT= 2) then
begin
rewrite(ARQALU);
write(ARQALU, ALUNO);
end;
end;
procedure TELA;
begin
gotoxy(18, 10); clreol;
gotoxy(18,11); clreol;
gotoxy(18, 12); clreol;
gotoxy(18,13); clreol;
gotoxy(18, 14); clreol;
gotoxy(18,15); clreol;
writexy ( 1,10,'Matricula ...: ');
writexy ( 1,11,'Nome ........: ');
writexy ( 1,12,'la. Nota ....: ');
writexy ( 1,13,'2a. Nota ....: ');
writexy ( 1,14,'3a. Nota ....: ');
writexy ( 1,15,'4a. Nota ....: ');
end;
function PESQUISA(NUMERO : integer) : boolean;
var
ACHOU : boolean;
begin
ACHOU := false;
seek(ARQALU, 1);
while (not eof (ARQALU)) and (not ACHOU) dO begin
read(ARQALU, ALUNO);
ACHOU := (NUMERO = ALUNO.MATRICULA) and (ALUNO.FLAG <> '*');
end;
seek (ARQALU,filepos(ARQALU)-1);
PESQUISA := ACHOU;
end;
Procedure ROT_CADASTRAR;
begin
clrscr;
Line;
Center(SISTEMA);
Center('MODULO DE CADASTRAMENTO');
Line;
WriteXy( 1, 6,'Digite os dados abaixo:');
repeat
WriteXy ( 1,24,'Digite [0] Para encerrar o Modulo Cadastro');
Tela;
gotoxy (18,10); readln (NR_MATRIC);
gotoxy ( 1,24); clreol;
if (NR_MATRIC<> 0) then
begin
if (Pesquisa(NR_MATRIC) = true) then
begin
{ Apresenta os dados caso exista no arquivo }
gotoxy (18,10); writeln(NR_MATRIC);
gotoxy (18,11); writeln(ALUNO.NOME);
for I := 1 tO 4 dO
begin
gotoxy(18,11 + I);
writeln (ALUNO.NOTAS[I]:8:2);
end;
WriteXy(1,23,'Este registro ja esta cadastrado');
gotoxy (1,24); write ('Pressione algo para continuar.');
TECLA := readkey;
gotoxy (1,23); clreol;
end
else
begin
{ Localiza posicao para gravar registro }
seek(ARQALU, 0);
repeat
read(ARQALU,ALUNO);
Until (ALUNO.FLAG = '*') Or (eof(ARQALU));
if (ALUNO.FLAG = '*') then
seek(ARQALU,filepos(ARQALU)-1)
else
seek(ARQALU,filesize(ARQALU) );
{ Grava registro }
ALUNO.FLAG := ' ';
gotoxy (18,11); readln (ALUNO.NOME);
for I:=1 tO 4 dO
begin
gotoxy(18,11 + I);
readln(ALUNO.NOTAS[I]);
end;
ALUNO.MATRICULA := NR_MATRIC;
write(ARQALU,ALUNO);
gotoxy (1,24); write('Pressione algo para continuar...');
TECLA := readkey;
end;
end;
until (NR_MATRIC = 0);
end;
Procedure ROT_REMOVER;
begin
clrscr;
Line;
Center (SISTEMA);
Center ('MODULO DE REMOCAO');
Line;
WriteXy (1, 6,'Digite o numero de matricula:');
repeat
WriteXy (1,24,'Digite (0) Para encerrar o modulo Remocao');
Tela;
gotoxy (18,10); readln
...