1.4 - Definição de tipos de dados e estruturas
Um programa é feito de duas partes, os dados, ou melhor, a estrutura
dos dados e o algorítmo.
Na linguagem PASCAL existe uma área dentro do programa a qual
utilizamos para definirmos a estrutura dos dados.
Podemos classificar os tipos de dados em duas categorias: simples e
estruturados.
Um tipo simples é um tipo indivisível.
Podemos dizer que um dado tipo real, inteiro, boolean ou char é
um tipo simples, ou também denominado de "atômico".
TYPE
- numero=real;
- inteiro=[1..99];
VAR
Neste exemplo a variável a é uma variável
real e k é uma variável inteira.
No exemplo foi definido dois tipos: numero é um real e inteiro
é integer mas que tem a variação somente de 1 a 99.
Um tipo estruturado pode ser composto por diversos tipos atômicos.
Podemos estrutura-los como array, que já é nosso conhecido
quando utilizamos matrizes, como file, record ou set.
O tipo file representará a definição de um arquivo
seqüêncial.
O tipo record representará um conjunto fixo de variáveis
(campos).
O tipo set serão variáveis que assumirão valores
de conjuntos.
Neste capítulo vamos falar dos tipos file e record.
Veja este exemplo:
TYPE
- registro = record
- matricula : 1..999;
- nome_func: string[35];
- endereco: string[40];
- salario: real;
- end;
- arquivo = file of registro;
VAR
- cadastro: arquivo;
- funcionário:registro ;
Este exemplo define uma estrutura denominada registro composta dos campos,
ou das variáveis, matricula, nome_func, endereco e salario.
Sempre que referenciarmos funcionario estaremos referenciando todas
as variáveis que compõe o registro. Se quisermos somente
utilizar a variável salario, devemos utilizar a seguinte composição:
Foi criada também uma variável chamada cadastro.
Quando referenciarmos a variável cadastro estaremos referenciando
toda a estrutura, o arquivo e os registros que comporão este arquivo.
Agora vamos falar um pouco mais sobre arquivos.
Todos os problemas que você até hoje executou, utilizaram
os dados que estavam na memória principal do computador.
Lembre-se que uma memória principal de um computador, é
pequena, volátil.
Muitos de nossos problemas científicos e comerciais terão
que manipular com grande quantidade de informação de dados
de entrada ou saída, os quais não comportarão na memória
principal.
O que fazer? Muitos de nossos problemas científicos e comerciais
terão que armazenar informações de hoje para amanhã.
O que fazer se desligo a máquina à noite?
Respostas simplista seria:
" ... aumente a memória principal do computador...então
não desligue a máquina...!"
Mas, e se faltar energia durante a noite, ou mesmo durante o dia?
A memória do computador tá cara, no?
A saída para todas estas perguntas é a utilização
de arquivos, os quais serão armazenados em memória auxiliar.
Outros nomes de memória auxiliar, disquetes, winchester, fitas
magnéticas, memóriais secundárias etc...
Estas memórias são maiores e de gravação
permanente.
A utilização de arquivos permitirá que parte do
nosso volume de informações sejam colocados na memória
principal e parte na memória secundária.
Quando se trabalha com arquivo devemos ter sempre em mente que haverá
para cada arquivo criado, procedimentos especiais de manipulação
do arquivo.
Básicamente estes procedimentos são denominados de: inclusão,
alteração, exclusão, consulta.
Quando você ler o exemplo a seguir, da folha de pagamento, apreenderá
melhor sobre estes procedimentos.
Agora que você apreendeu a definir uma estrutura e tem uma noção
de o que é um arquivo, vamos dar os comandos PASCAL que irão
manipular esta estrutura de arquivo para você.
ASSIGN - Irá associar o nome interno do arquivo com um
nome externo no sistema operacional.Procedure assign (var File: file;
nome:string);
CLOSE - Irá fechar um arquivo aberto. Quando não
mais usarmos um arquivo devemos fecha-lo. Este procedimento demorará
um pouco, mas se faz necessário por segunrança. Procedure
close(var File:file);
EOF - (End of File) É uma função que poderá
ser utilizada para verificar se já estamos no final de um arquivo.
É uma função boolean, retornará TRUE se estiver
no fim do arquivo. Function eof(var File: file):boolean;
ERASE - Apaga um arquivo. Procedure erase(var File: file);
FILEPOS - Retorna a posição de leitura/gravação
dentro do arquivo. Function filepos(var File:file): longint;
FILESIZE - Retorna o tamanho do arquivo aberto em registros.
Function filesize(var File: file): longint;
IORESULT - Retorna o resultado da última operação
de E/S. O número 0 indica que houve sucesso no comando de entrada/saída.
Function ioresult: word;
READ/READLN - Lê os dados de um registro. Procedure
readln([var File: file;] var registro);
RENAME - Renomeia um arquivo. É possivel também
mover um arquivo. Procedure rename(var File:file; novonome:string);
RESET - Abre um arquivo existente e posiciona -se no início.
Procedure reset(var File:file);
REWRITE - Cria e abre um arquivo. Se existir todo o seu conteúdo
será perdido. Procedure rewrite(var File:file);
SEEK - Move até o registro especificado. Procedure
seek(var File:file; nunreg:logint);
WRITE/WRITELN - Grava o conteúdo de um registro. Procedure
write([var File:file ;] var registro);
Em pascal poderemos trabalhar com arquivos tipados (sequencial ou direto)
e arquivos textos.
Nesta disciplina somente nos deteremos nos arquivos tipados.
Vamos, agora, fazer um exemplo utilizando os comandos de arquivos.
Um exemplo bem corriqueiro é uma folha de pagamento.
O básico de uma folha de pagamento é manter um arquivo
que contenha os registros de todos os funcionários da empresa.
Como os funcionários casam, tem filhos, são despedidos
outros são admitidos, tem aumento de salário (é uma
possibilidade remota, mas poderá existir), a primeira idéia
que surge é que para este arquivo temos que ter posibilidade de:
primeiramente criar o arquivo, depois incluir registros.
Poder alterar, poder excluir registros também se fará
necessário.
No caso especial da folha de pagamento também deveremos ter uma
opção de calcular a folha.
De novo, para você não esquecer, " A manutenção
de um arquivo requer que possamos criar o arquivo, incluir registros, alterar,
excluir, ordenar".
Ordenar, significa classificar, porque as pessoas que serão funcionários
da empresa poderão ter nomes como Zozimo, tempos depois poderá
ser contratada a Androziana, e o patrão vai querer tudo em ordem
alfabética.
Podemos imaginar o nosso problema da seguinte forma: Ou seja, o melhor
método de resolvermos um problema extenso, é subdividi-lo
em problemas menores.
Antes de aprofundarmos nestas rotinas vamos definir o arquivo o qual
conterá uma estrutura de registros com os campos de
matricula (matric),
nome do funcionário (nome),
número de salários (ns),
número de filhos (nf),
o salário (sal) que valerá ns * o salário
mínimo(R$112,00 em setembro/96) ,
o salário família(sfam) que será
nf * (procure este valor em um jornal),
o inps que valerá conforme tabela (procure um
jornal Zero Hora), e por fim,
o salário liquido(sliq) = sal + sfam -inps.
Veja como fica o início deste programa.
- program folha;
- uses crt; (* Este comando diz ao compilador que será
utilizada a bibilioteca crt vista nos capítulos anteriores*)
- type registro = record
- matric:1..999;
- nome :string[35];
- ns :1..100;
- nf :1..20;
- sal :real;
- sfam :real;
- inps :real;
- sliq :real;
- end;
- arquivo = file of registro;
(* Com o comando type criamos uma estrutura de registro e a esta
estrutura associamos uma arquivo.
A partir deste momento nós temos dois novos tipos de dados.
O primeiro denominado registro ao qual está associado os
campos descritos na definição do problema;
O segundo denominado arquivo que conterá a estrutura dos
registros*).
- var
- cadastro: arquivo;
- func : registro;
- i,opcao : integer;
- sim : string[1];
- tamanho : longint;
- fim : boolean;
- (* Neste seqüência de comandos criamos nossas variáveis.Como
elas estão definidas no início de nosso programa, antes de
qualquer procedimento, elas serão tratadas como variáveis
globais, ou seja, estarão presentes em todos os procedimentos, para
utiliza-las é só referência-las.*)
- (* procedimento tela principal *)
- procedure telaprincipal;
- begin
- clrscr;
- highvideo;
- gotoxy(25,05);
- write(' - Sistema de Folha de Pagamento -');
- lowvideo;
- gotoxy(25,07); write('1 - Inclui Funcionários');
- gotoxy(25,09); write('2 - Exclui Funcionários');
- gotoxy(25,11); write('3 - Altera Funcionário');
- gotoxy(25,13); write('4 - Ordena Cadastro');
- gotoxy(25,15); write('5 - Calcula Folha');
- gotoxy(25,17); write('6 - Cria Arquivo Cadastro');
- gotoxy(25,19); write('7 - Fim do Programa');
- gotoxy(25,21); write(' - Digite sua opcao');
- end;
(* O procedimento tela principal, servirá como entrada do
sistema.
A partir desta tela todas as ações serão executadas.
O procedimento começa limpando a tela. clrscr que dizer clear
screen, ou limpar a tela.
Logo após o comando para deixar os caracteres com luminosidade
mais intensa highvideo.
O cursor é posicionado na linha 5, na coluna 25 e escreve
a frase: Sistema de Folha de Pagamento.
A luminosidade dos caracteres passa a ser a normal e em cada linha
são escritas frases associadas a um número.
A final a frase: Digite sua opção, sendo deixado espaço
para ser digitado a opção. *)
- (* Criação do arquivo cadastro *)
- procedure cria;
- begin
- {$I-}
- {$I+}
- if ioresult = 0 then
- repeat
- gotoxy(25,24);
- write('O arquivo ja existe. Todos os dados serao perdidos (s/n)
?');
- readln(sim);
- if (sim ='s') or (sim = 'S') then
- until (sim ='s') or (sim = 'S') or (sim = 'n') or (sim = 'N')
- else rewrite(cadastro);
- end;
(* O procedimento de criação do arquivo cadastro tem
que levar em conta que o operador desavisado pode
tentar criar o arquivo e este já existir.
O procedimento fica colocado da seguinte forma:
O comando reset(cadastro) irá abrir o arquivo, se ele não
existir a função ioresult não será zero, e
portanto o comando
else será executado o qual executará o comando rewrite(cadastro)
que irá criar o arquivo.
Mas voltando ao teste do ioresult se este for zero, isto significa
que o arquivo já foi criado, então é formulada a pergunta
ao operador se ele quer recria-lo, apagando todos os registros que
existirem.
Como o operador poderá digitar um sim ou não com letras
ninúsculas ou maiúsculas (S,s,N,n) é que optamos por
definir
todas as alternativas.
Um incremento que se poderia fazer neste procedimento seria de incluirmos
mais um teste, qual seja, se o arquivo aberto
não existir nenhum registro, então não seria
necessário recriá-lo? Implemente esta programação.*)
- (* Inclusao de funcionarios *)
- procedure inclui;
- begin
- reset(cadastro);
- tamanho:=filesize(cadastro);
- seek(cadastro,tamanho);
- repeat
- clrscr;
- gotoxy(3,10); write('Matricula..: ___');
- gotoxy(3,12); write('Nome.......: __________________________________');
- gotoxy(3,14); write('N. salarios: __');
- gotoxy(3,16); write('N.filhos...: __');
- gotoxy(16,10); readln(func.matric);
- if func.matric <> 0 then
- begin
- gotoxy(16,12); readln(func.nome);
- gotoxy(16,14); readln(func.ns);
- gotoxy(16,16); readln(func.nf);
- func.sal:=0;
- func.sfam:=0;
- func.inps:=0;
- func.sliq:=0;
- write(cadastro,func);
- end;
- until func.matric = 0;
- close(cadastro);
- end;
(*O procedimento que inclui registro, logo no início tem
uma falha. Você saberia apontar?
...leia o programa, e pense antes de ler a resposta.........
A falha é que podemos ter um operador tapado que não
criou o arquivo e já quer incluir os dados.
Outra falha no programa é que o operador poderá incluir
registros em duplicatas.
Não é testado para inclusão se o registro já
existe.
Bom, mas vamos ver como fica este procedimento :
inicialmente o arquivo é aberto (reset), após é
calculado o número de registro que este arquivo contém (
filesize),
porque em uma inclusão de registros em arquivos sequências
se dará sempre no final do arquivo.
Através do comando seek nos posicionaremos no final do arquivo.
Aí entramos em um laço. Imprimimos uma tela de mascará
onde iremos digitar, matricula, nome, número de salários
mínimos, e número de filhos.
Quando da digitação da matrícula verificamos
se o operador digitou zero.
Caso tenha digitado zero, o programa fechará o arquivo cadastro
e o procedimento inclusão estará terminado.
Caso o operador tenha digitado qualquer outro número diferente
de zero então o procedimento lerá os outros dados.
Como este procedimento não calculará os valores da
folha, quais sejam salário bruto, salário família,
inps e salário líquido,
optamos por zerar estes valores.
Então para armazenar todos os valores lidos e zerados, escrevemos
(write) no arquivo, e voltamos novamente ao laço.
Você poderia dizer porquê os valores da folha não
devem ser calculados na inclusão? *)
- (* Alteracao dos dados dos funcionarios - Procedimento incompleto
*)
- procedure altera;
- begin
- reset(cadastro);
- clrscr;
- while not eof(cadastro) do
- begin
- read(cadastro,func);
- writeln(func.matric:3,func.nome:35,func.ns:2,func.nf:2);
- end;
- delay(3000);
- close(cadastro);
- end;
- (* Exclusao de funcionarios - Procedimento incompleto*)
- procedure exclui;
- begin
- end;
- (* Ordenacao do Arquivo - Procedimento incompleto*)
- procedure ordena;
- begin
- end;
- (* Calculo da folha - Procedimento incompleto*)
- procedure calcula;
- begin
- end;
- (* Programa Principal *)
- begin
- assign(cadastro,'a:\empresa.dat');
- fim := false;
- repeat
- repeat
- telaprincipal;
- gotoxy(25,21); readln(opcao);
- until opcao in [1..7];
- case opcao of
- 1 : inclui;
- 2 : exclui;
- 3 : altera;
- 4 : ordena;
- 5 : calcula;
- 6 : cria;
- 7 : fim:= true;
- end;
- until fim;
- end.
Tente completar este exemplo.
Ufa!!! Está cansado? Vamos para o próximo
capítulo ou quer parar aqui?